Exemple #1
0
func TestManagerFilterPropSeqn(t *testing.T) {
	ps := make(chan int64, 100)
	st := store.New()
	defer close(st.Ops)

	m := &Manager{
		DefRev: 2,
		Alpha:  1,
		Self:   "b",
		PSeqn:  ps,
		Store:  st,
	}
	go m.Run()

	st.Ops <- store.Op{1, store.MustEncodeSet("/ctl/cal/0", "a", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/cal/1", "b", 0)}
	st.Ops <- store.Op{3, store.Nop}
	st.Ops <- store.Op{4, store.Nop}
	assert.Equal(t, int64(3), <-ps)
	assert.Equal(t, int64(5), <-ps)

	st.Ops <- store.Op{5, store.Nop}
	st.Ops <- store.Op{6, store.Nop}
	assert.Equal(t, int64(7), <-ps)
}
Exemple #2
0
func TestRunBroadcastFive(t *testing.T) {
	c := make(chan Packet, 100)
	var r run
	r.seqn = 1
	r.out = c
	r.addr = []*net.UDPAddr{
		&net.UDPAddr{net.IP{1, 2, 3, 4}, 5},
		&net.UDPAddr{net.IP{2, 3, 4, 5}, 6},
		&net.UDPAddr{net.IP{3, 4, 5, 6}, 7},
		&net.UDPAddr{net.IP{4, 5, 6, 7}, 8},
		&net.UDPAddr{net.IP{5, 6, 7, 8}, 9},
	}

	r.broadcast(newInvite(1))
	c <- Packet{}

	exp := msg{
		Seqn: proto.Int64(1),
		Cmd:  invite,
		Crnd: proto.Int64(1),
	}

	addr := make([]*net.UDPAddr, len(r.addr))
	for i := 0; i < len(r.addr); i++ {
		p := <-c
		addr[i] = p.Addr
		var got msg
		err := proto.Unmarshal(p.Data, &got)
		assert.Equal(t, nil, err)
		assert.Equal(t, exp, got)
	}

	assert.Equal(t, Packet{}, <-c)
	assert.Equal(t, r.addr, addr)
}
Exemple #3
0
func TestManagerEvent(t *testing.T) {
	const alpha = 2
	runs := make(map[int64]*run)
	st := store.New()
	defer close(st.Ops)

	st.Ops <- store.Op{
		Seqn: 1,
		Mut:  store.MustEncodeSet(node+"/a/addr", "1.2.3.4:5", 0),
	}

	st.Ops <- store.Op{
		Seqn: 2,
		Mut:  store.MustEncodeSet(cal+"/1", "a", 0),
	}

	ch, err := st.Wait(store.Any, 2)
	if err != nil {
		panic(err)
	}

	x, _ := net.ResolveUDPAddr("udp", "1.2.3.4:5")
	pseqn := make(chan int64, 1)
	m := &Manager{
		Alpha: alpha,
		Self:  "a",
		PSeqn: pseqn,
		Ops:   st.Ops,
		Out:   make(chan Packet),
		run:   runs,
	}
	m.event(<-ch)

	exp := &run{
		self:  "a",
		seqn:  2 + alpha,
		cals:  []string{"a"},
		addr:  []*net.UDPAddr{x},
		ops:   st.Ops,
		out:   m.Out,
		bound: initialWaitBound,
	}
	exp.c = coordinator{
		crnd: 1,
		size: 1,
		quor: exp.quorum(),
	}
	exp.l = learner{
		round:  1,
		size:   1,
		quorum: int64(exp.quorum()),
		votes:  map[string]int64{},
		voted:  []bool{false},
	}

	assert.Equal(t, 1, len(runs))
	assert.Equal(t, exp, runs[exp.seqn])
	assert.Equal(t, exp.seqn, <-pseqn)
	assert.Equal(t, exp.seqn+1, m.next)
}
Exemple #4
0
func TestRecvInvalidPacket(t *testing.T) {
	q := new(packets)
	x := &net.UDPAddr{net.IP{1, 2, 3, 4}, 5}
	p := recvPacket(q, Packet{x, invalidProtobuf})
	assert.Equal(t, (*packet)(nil), p)
	assert.Equal(t, 0, q.Len())
}
Exemple #5
0
func TestCoordQuorum(t *testing.T) {
	co := coordinator{
		size: 10,
		quor: 6,
		crnd: 1,
	}

	co.update(&packet{msg: *newPropose("foo")}, -1)

	got, tick := co.update(newRsvpFrom(1, 1, 0, ""))
	assert.Equal(t, (*msg)(nil), got)
	assert.Equal(t, false, tick)

	got, tick = co.update(newRsvpFrom(2, 1, 0, ""))
	assert.Equal(t, (*msg)(nil), got)
	assert.Equal(t, false, tick)

	got, tick = co.update(newRsvpFrom(3, 1, 0, ""))
	assert.Equal(t, (*msg)(nil), got)
	assert.Equal(t, false, tick)

	got, tick = co.update(newRsvpFrom(4, 1, 0, ""))
	assert.Equal(t, (*msg)(nil), got)
	assert.Equal(t, false, tick)

	got, tick = co.update(newRsvpFrom(5, 1, 0, ""))
	assert.Equal(t, (*msg)(nil), got)
	assert.Equal(t, false, tick)
}
Exemple #6
0
func TestCoordStart(t *testing.T) {
	co := coordinator{crnd: 1}

	got, tick := co.update(&packet{msg: *newPropose("foo")}, -1)
	assert.Equal(t, newInvite(1), got)
	assert.Equal(t, true, tick)
}
Exemple #7
0
func TestEventIsSet(t *testing.T) {
	p, v := "/x", "a"
	m := MustEncodeSet(p, v, Clobber)
	ev := Event{1, p, v, 1, m, nil, nil}
	assert.Equal(t, true, ev.IsSet())
	assert.Equal(t, false, ev.IsDel())
	assert.Equal(t, false, ev.IsNop())
}
Exemple #8
0
func TestRecvEmptyPacket(t *testing.T) {
	q := new(packets)
	x := &net.UDPAddr{net.IP{1, 2, 3, 4}, 5}

	p := recvPacket(q, Packet{x, []byte{}})
	assert.Equal(t, (*packet)(nil), p)
	assert.Equal(t, 0, q.Len())
}
Exemple #9
0
func TestEventIsDel(t *testing.T) {
	p := "/x"
	m := MustEncodeDel(p, Clobber)
	ev := Event{1, p, "", Missing, m, nil, nil}
	assert.Equal(t, true, ev.IsDel())
	assert.Equal(t, false, ev.IsSet())
	assert.Equal(t, false, ev.IsNop())
}
Exemple #10
0
func TestLivenessNoCheck(t *testing.T) {
	a := &net.UDPAddr{net.IP{1, 2, 3, 4}, 5}
	lv := liveness{
		prev:  5,
		ival:  3,
		times: []liverec{{a, 5}},
	}
	lv.check(7)
	assert.Equal(t, int64(5), lv.prev)
	assert.Equal(t, []liverec{{a, 5}}, lv.times)
}
Exemple #11
0
func TestSchedTrigger(t *testing.T) {
	var q triggers
	d := int64(15e8)

	t0 := time.Now().UnixNano()
	ts := t0 + d
	schedTrigger(&q, 1, t0, d)

	assert.Equal(t, 1, q.Len())
	f := q[0]
	assert.Equal(t, int64(1), f.n)
	assert.T(t, f.t == ts)
}
Exemple #12
0
func TestGcPulse(t *testing.T) {
	seqns := make(chan int64)
	defer close(seqns)
	fs := make(FakeProposer)

	go Pulse("test", seqns, fs, 1)

	seqns <- 0
	assert.Equal(t, "-1:/ctl/node/test/applied=0", <-fs)

	seqns <- 1
	assert.Equal(t, "-1:/ctl/node/test/applied=1", <-fs)
}
Exemple #13
0
func TestLivenessStaysAlive(t *testing.T) {
	shun := make(chan string, 1)
	a := &net.UDPAddr{net.IP{1, 2, 3, 4}, 5}
	lv := liveness{
		prev:    0,
		ival:    1,
		timeout: 3,
		times:   []liverec{{a, 5}},
		shun:    shun,
	}
	lv.check(7)
	assert.Equal(t, int64(7), lv.prev)
	assert.Equal(t, 0, len(shun))
	assert.Equal(t, []liverec{{a, 5}}, lv.times)
}
Exemple #14
0
func TestCoordTargetNomination(t *testing.T) {
	co := coordinator{crnd: 1, quor: 6, size: 10}

	co.update(&packet{msg: *newPropose("foo")}, -1)

	co.update(newRsvpFrom(1, 1, 0, ""))
	co.update(newRsvpFrom(2, 1, 0, ""))
	co.update(newRsvpFrom(3, 1, 0, ""))
	co.update(newRsvpFrom(4, 1, 0, ""))
	co.update(newRsvpFrom(5, 1, 0, ""))

	got, tick := co.update(newRsvpFrom(6, 1, 0, ""))
	assert.Equal(t, newNominate(1, "foo"), got)
	assert.Equal(t, false, tick)
}
Exemple #15
0
func TestCoordStartRsvp(t *testing.T) {
	co := coordinator{
		quor: 1,
		crnd: 1,
	}

	got, tick := co.update(newRsvpFrom(0, 1, 0, ""))
	assert.Equal(t, (*msg)(nil), got)
	assert.Equal(t, false, tick)

	got, tick = co.update(&packet{msg: *newPropose("foo")}, -1)

	// If the RSVPs were ignored, this will be an invite.
	// Otherwise, it'll be a nominate.
	assert.Equal(t, newInvite(1), got)
	assert.Equal(t, true, tick)
}
Exemple #16
0
func TestLivenessTimesOut(t *testing.T) {
	shun := make(chan string, 1)
	a := &net.UDPAddr{net.IP{1, 2, 3, 4}, 5}
	lv := liveness{
		prev:    0,
		ival:    1,
		timeout: 3,
		times:   []liverec{{a, 5}},
		shun:    shun,
		self:    &net.UDPAddr{net.IP{2, 3, 4, 5}, 6},
	}
	lv.check(9)
	assert.Equal(t, int64(9), lv.prev)
	assert.Equal(t, 1, len(shun))
	assert.Equal(t, "1.2.3.4:5", <-shun)
	assert.Equal(t, []liverec{}, lv.times)
}
Exemple #17
0
func TestRunProposeDelivered(t *testing.T) {
	var r run
	r.out = make(chan Packet, 100)
	r.ops = make(chan store.Op, 100)

	r.update(&packet{msg: msg{Cmd: propose}}, -1, new(triggers))
	assert.Equal(t, true, r.c.begun)
}
Exemple #18
0
func TestQuorum(t *testing.T) {
	assert.Equal(t, 1, (&run{cals: []string{"a"}}).quorum())
	assert.Equal(t, 2, (&run{cals: []string{"a", "b"}}).quorum())
	assert.Equal(t, 2, (&run{cals: []string{"a", "b", "c"}}).quorum())
	assert.Equal(t, 3, (&run{cals: []string{"a", "b", "c", "d"}}).quorum())
	assert.Equal(t, 3, (&run{cals: []string{"a", "b", "c", "d", "e"}}).quorum())
	assert.Equal(t, 4, (&run{cals: []string{"a", "b", "c", "d", "e", "f"}}).quorum())
	assert.Equal(t, 4, (&run{cals: []string{"a", "b", "c", "d", "e", "f", "g"}}).quorum())
	assert.Equal(t, 5, (&run{cals: []string{"a", "b", "c", "d", "e", "f", "g", "h"}}).quorum())
}
Exemple #19
0
func TestMemberSimple(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	fp := &test.FakeProposer{Store: st}
	c := make(chan string)
	go Clean(c, fp.Store, fp)

	fp.Propose([]byte(store.MustEncodeSet("/ctl/node/a/x", "a", store.Missing)))
	fp.Propose([]byte(store.MustEncodeSet("/ctl/node/a/y", "b", store.Missing)))
	fp.Propose([]byte(store.MustEncodeSet("/ctl/node/a/addr", "1.2.3.4", store.Missing)))
	fp.Propose([]byte(store.MustEncodeSet("/ctl/cal/0", "a", store.Missing)))

	calCh, err := fp.Wait(store.MustCompileGlob("/ctl/cal/0"), 1+<-fp.Seqns)
	if err != nil {
		panic(err)
	}
	nodeCh, err := fp.Wait(store.MustCompileGlob("/ctl/node/a/?"), 1+<-fp.Seqns)
	if err != nil {
		panic(err)
	}

	// indicate that this peer is inactive
	go func() { c <- "1.2.3.4" }()

	ev := <-calCh
	assert.T(t, ev.IsSet())
	assert.Equal(t, "", ev.Body)

	cs := []int{}

	ev = <-nodeCh
	assert.T(t, ev.IsDel())
	cs = append(cs, int(ev.Path[len(ev.Path)-1]))
	nodeCh, err = fp.Wait(store.MustCompileGlob("/ctl/node/a/?"), ev.Seqn+1)
	if err != nil {
		panic(err)
	}

	ev = <-nodeCh
	assert.T(t, ev.IsDel())
	cs = append(cs, int(ev.Path[len(ev.Path)-1]))

	sort.Ints(cs)
	assert.Equal(t, []int{'x', 'y'}, cs)
}
Exemple #20
0
func TestRunInviteDelivered(t *testing.T) {
	var r run
	r.out = make(chan Packet, 100)
	r.ops = make(chan store.Op, 100)

	r.update(&packet{msg: *newInviteSeqn1(1)}, 0, new(triggers))

	assert.Equal(t, int64(1), r.a.rnd)
}
Exemple #21
0
func TestDelRun(t *testing.T) {
	const alpha = 2
	runs := make(map[int64]*run)
	st := store.New()
	defer close(st.Ops)

	st.Ops <- store.Op{1, store.MustEncodeSet(node+"/a/addr", "x", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet(cal+"/1", "a", 0)}
	st.Ops <- store.Op{3, store.Nop}
	st.Ops <- store.Op{4, store.Nop}

	c2, err := st.Wait(store.Any, 2)
	if err != nil {
		panic(err)
	}

	c3, err := st.Wait(store.Any, 3)
	if err != nil {
		panic(err)
	}

	c4, err := st.Wait(store.Any, 4)
	if err != nil {
		panic(err)
	}

	pseqn := make(chan int64, 100)
	m := &Manager{
		Alpha: alpha,
		Self:  "a",
		PSeqn: pseqn,
		Ops:   st.Ops,
		Out:   make(chan Packet),
		run:   runs,
	}
	m.event(<-c2)
	assert.Equal(t, 1, len(m.run))
	m.event(<-c3)
	assert.Equal(t, 2, len(m.run))
	m.event(<-c4)
	assert.Equal(t, 2, len(m.run))
}
Exemple #22
0
func TestRunSchedulesTick(t *testing.T) {
	var r run
	r.seqn = 1
	r.bound = 10
	r.out = make(chan Packet, 100)
	ticks := new(triggers)

	r.update(&packet{msg: *newPropose("foo")}, -1, ticks)

	assert.Equal(t, 1, ticks.Len())
}
Exemple #23
0
func TestRunAppliesOp(t *testing.T) {
	c := make(chan store.Op, 100)
	var r run
	r.seqn = 1
	r.out = make(chan Packet, 100)
	r.ops = c
	r.l.init(1, 1)

	r.update(&packet{msg: *newVote(1, "foo")}, 0, new(triggers))
	assert.Equal(t, store.Op{1, "foo"}, <-c)
}
Exemple #24
0
func TestGetCalsPartial(t *testing.T) {
	st := store.New()
	defer close(st.Ops)

	st.Ops <- store.Op{Seqn: 1, Mut: store.MustEncodeSet(cal+"/1", "a", 0)}
	st.Ops <- store.Op{Seqn: 2, Mut: store.MustEncodeSet(cal+"/2", "", 0)}
	st.Ops <- store.Op{Seqn: 3, Mut: store.MustEncodeSet(cal+"/3", "", 0)}
	<-st.Seqns

	assert.Equal(t, []string{"a"}, getCals(st))
}
Exemple #25
0
func TestRunVoteDelivered(t *testing.T) {
	r := run{}
	r.out = make(chan Packet, 100)
	r.ops = make(chan store.Op, 100)
	r.l.init(1, 1)

	p := packet{
		msg: msg{
			Seqn:  proto.Int64(1),
			Cmd:   vote,
			Vrnd:  proto.Int64(1),
			Value: []byte("foo"),
		},
		Addr: &net.UDPAddr{net.IP{1, 2, 3, 4}, 5},
	}

	r.update(&p, 0, new(triggers))

	assert.Equal(t, true, r.l.done)
	assert.Equal(t, "foo", r.l.v)
}
Exemple #26
0
func TestLivenessMark(t *testing.T) {
	a1, err := net.ResolveUDPAddr("udp", "127.0.0.1:8046")
	if err != nil {
		panic(err)
	}
	a2, err := net.ResolveUDPAddr("udp", "127.0.0.2:8046")
	if err != nil {
		panic(err)
	}
	lv := liveness{
		timeout: 10,
		ival:    5,
		self:    a1,
		shun:    make(chan string, 100),
	}

	lv.mark(a1, 1)
	assert.Equal(t, []liverec{{a1, 1}}, lv.times)
	lv.mark(a2, 2)
	assert.Equal(t, []liverec{{a1, 1}, {a2, 2}}, lv.times)
}
Exemple #27
0
func TestRunSendsLearnerPacket(t *testing.T) {
	c := make(chan Packet, 100)
	var r run
	r.out = c
	r.ops = make(chan store.Op, 100)
	r.addr = []*net.UDPAddr{nil, nil}
	r.l.init(1, 1)

	var got msg
	exp := msg{
		Seqn:  proto.Int64(0),
		Cmd:   learn,
		Value: []byte("foo"),
	}

	r.update(&packet{msg: *newVote(1, "foo")}, 0, new(triggers))
	assert.Equal(t, 2, len(c))
	err := proto.Unmarshal((<-c).Data, &got)
	assert.Equal(t, nil, err)
	assert.Equal(t, exp, got)
}
Exemple #28
0
func TestRecvPacket(t *testing.T) {
	q := new(packets)
	x := &net.UDPAddr{net.IP{1, 2, 3, 4}, 5}

	p := recvPacket(q, Packet{x, mustMarshal(&msg{
		Seqn: proto.Int64(1),
		Cmd:  invite,
	})})
	assert.Equal(t, &packet{x, msg{Seqn: proto.Int64(1), Cmd: invite}}, p)
	p = recvPacket(q, Packet{x, mustMarshal(&msg{
		Seqn: proto.Int64(2),
		Cmd:  invite,
	})})
	assert.Equal(t, &packet{x, msg{Seqn: proto.Int64(2), Cmd: invite}}, p)
	p = recvPacket(q, Packet{x, mustMarshal(&msg{
		Seqn: proto.Int64(3),
		Cmd:  invite,
	})})
	assert.Equal(t, &packet{x, msg{Seqn: proto.Int64(3), Cmd: invite}}, p)
	assert.Equal(t, 3, q.Len())
}
Exemple #29
0
func TestGlobNonMatches(t *testing.T) {
	for _, parts := range nonMatches {
		pat, paths := parts[0], parts[1:]
		glob, err := CompileGlob(pat)
		assert.Equal(t, nil, err)
		for _, path := range paths {
			if glob.Match(path) {
				t.Errorf("pat %q should not match %q", pat, path)
			}
		}
	}
}
Exemple #30
0
func TestManagerTickQueue(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	st.Ops <- store.Op{1, store.MustEncodeSet(node+"/a/addr", "1.2.3.4:5", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/cal/0", "a", 0)}

	var m Manager
	m.run = make(map[int64]*run)
	m.Alpha = 1
	m.Store = st
	m.Out = make(chan Packet, 100)
	m.event(<-mustWait(st, 2))

	// get it to tick for seqn 3
	recvPacket(&m.packet, Packet{Data: mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: propose})})
	m.pump()
	assert.Equal(t, 1, m.tick.Len())

	m.doTick(time.Now().UnixNano() + initialWaitBound*2)
	assert.Equal(t, int64(1), m.Stats.TotalTicks)
}