Пример #1
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 := fp.Watch(store.MustCompileGlob("/ctl/cal/0"))
	nodeCh := fp.Watch(store.MustCompileGlob("/ctl/node/a/?"))

	// 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]))

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

	sort.SortInts(cs)
	assert.Equal(t, []int{'x', 'y'}, cs)
}
Пример #2
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)
}
Пример #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)
}
Пример #4
0
func TestAddRun(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", "x", 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)
	}

	pseqn := make(chan int64, 1)
	c := &Config{
		Alpha: alpha,
		Self:  "a",
		PSeqn: pseqn,
		Ops:   st.Ops,
		Out:   make(chan Packet),
	}
	m := &Manager{cfg: *c, run: runs}
	got := m.addRun(<-ch)

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

	assert.Equal(t, exp, got)
	assert.Equal(t, exp, runs[got.seqn])
	assert.Equal(t, 1, len(runs))
	assert.Equal(t, exp.seqn, <-pseqn)
}
Пример #5
0
func TestConsensusOne(t *testing.T) {
	self := "test"
	const alpha = 1
	st := store.New()

	st.Ops <- store.Op{1, store.MustEncodeSet("/ctl/node/"+self+"/addr", "1.2.3.4:5", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/cal/1", self, 0)}
	<-st.Seqns

	in := make(chan Packet)
	out := make(chan Packet)
	seqns := make(chan int64, alpha)
	props := make(chan *Prop)

	m := &Manager{
		Self:   self,
		DefRev: 2,
		Alpha:  alpha,
		In:     in,
		Out:    out,
		Ops:    st.Ops,
		PSeqn:  seqns,
		Props:  props,
		TFill:  10e9,
		Store:  st,
		Ticker: time.Tick(10e6),
	}
	go m.Run()

	go func() {
		for o := range out {
			in <- o
		}
	}()

	n := <-seqns
	w, err := st.Wait(store.Any, n)
	if err != nil {
		panic(err)
	}
	props <- &Prop{n, []byte("foo")}
	e := <-w

	exp := store.Event{
		Seqn: 3,
		Path: "/ctl/err",
		Body: "bad mutation",
		Rev:  3,
		Mut:  "foo",
		Err:  errors.New("bad mutation"),
	}

	e.Getter = nil
	assert.Equal(t, exp, e)
}
Пример #6
0
func TestConsensusOne(t *testing.T) {
	self := "test"
	const alpha = 1
	st := store.New()

	st.Ops <- store.Op{1, store.MustEncodeSet("/ctl/node/"+self+"/addr", "x", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/cal/1", self, 0)}
	<-st.Seqns

	in := make(chan Packet)
	out := make(chan Packet)
	seqns := make(chan int64, alpha)
	props := make(chan *Prop)

	cfg := &Config{
		self,
		2,
		alpha,
		in,
		out,
		st.Ops,
		seqns,
		props,
		10e9,
		st,
		time.Tick(10e6),
	}
	NewManager(cfg)

	go func() {
		for o := range out {
			in <- o
		}
	}()

	n := <-seqns
	w, err := st.Wait(store.Any, n)
	if err != nil {
		panic(err)
	}
	props <- &Prop{n, []byte("foo")}
	e := <-w

	exp := store.Event{
		Seqn: 3,
		Path: "/ctl/err",
		Body: "bad mutation",
		Rev:  3,
		Mut:  "foo",
		Err:  os.NewError("bad mutation"),
	}

	e.Getter = nil
	assert.Equal(t, exp, e)
}
Пример #7
0
func TestGetAddrs(t *testing.T) {
	st := store.New()
	defer close(st.Ops)

	st.Ops <- store.Op{1, store.MustEncodeSet(node+"/1/addr", "x", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet(node+"/2/addr", "y", 0)}
	st.Ops <- store.Op{3, store.MustEncodeSet(node+"/3/addr", "z", 0)}
	<-st.Seqns

	assert.Equal(t, map[string]bool{"x": true, "y": true, "z": true}, getAddrs(st))
}
Пример #8
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))
}
Пример #9
0
func alphaTest(t *testing.T, alpha int64) {
	runs := make(chan *run)
	st := store.New()
	defer close(st.Ops)

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

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

	for 2 != <-st.Seqns {
	}

	tr := run{
		self:  "a",
		ops:   st.Ops,
		out:   make(chan Packet),
		bound: initialWaitBound,
	}
	go generateRuns(alpha, st.Watch(store.Any), runs, tr)

	// The only way to generate a run is on an event.
	// Send a nop here to get things started.
	st.Ops <- store.Op{3, store.Nop}

	exp := &run{
		self:  "a",
		seqn:  3 + alpha,
		cals:  []string{"a"},
		addrs: map[string]bool{"x": true},
		ops:   st.Ops,
		out:   tr.out,
		bound: initialWaitBound,
	}
	exp.c = coordinator{
		crnd: 1,
		size: 1,
		quor: exp.quorum(),
	}
	exp.l = learner{
		round:  1,
		quorum: int64(exp.quorum()),
		votes:  map[string]int64{},
		voted:  map[string]bool{},
	}

	assert.Equal(t, exp, <-runs)
}
Пример #10
0
func TestGetAddrs(t *testing.T) {
	st := store.New()
	defer close(st.Ops)

	st.Ops <- store.Op{1, store.MustEncodeSet(node+"/1/addr", "x", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet(node+"/2/addr", "y", 0)}
	st.Ops <- store.Op{3, store.MustEncodeSet(node+"/3/addr", "z", 0)}
	<-st.Seqns

	addrs := getAddrs(st, []string{"1", "2", "3"})
	assert.Equal(t, []string{"x", "y", "z"}, addrs)
}
Пример #11
0
func TestManagerPumpDropsOldPackets(t *testing.T) {
	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("/ctl/cal/0", "a", 0)}

	var m Manager
	m.run = make(map[int64]*run)
	m.event(<-mustWait(st, 2))
	m.pump()
	recvPacket(&m.packet, Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(1)})})
	m.pump()
	assert.Equal(t, 0, m.Stats.WaitPackets)
}
Пример #12
0
func TestRunAfterWatch(t *testing.T) {
	alpha := int64(3)
	runs := make(chan *run)
	st := store.New()
	defer close(st.Ops)

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

	for 1 != <-st.Seqns {
	}

	tr := run{
		self:  "b",
		ops:   st.Ops,
		out:   make(chan Packet),
		bound: initialWaitBound,
	}
	go generateRuns(alpha, st.Watch(store.Any), runs, tr)

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

	exp := &run{
		self:  "b",
		seqn:  2 + alpha,
		cals:  []string{"b"},
		addrs: map[string]bool{"y": true},
		ops:   st.Ops,
		out:   tr.out,
		bound: initialWaitBound,
	}
	exp.c = coordinator{
		crnd: 1,
		size: 1,
		quor: exp.quorum(),
	}
	exp.l = learner{
		round:  1,
		quorum: int64(exp.quorum()),
		votes:  map[string]int64{},
		voted:  map[string]bool{},
	}

	assert.Equal(t, exp, <-runs)
}
Пример #13
0
func TestGetAddrs(t *testing.T) {
	st := store.New()
	defer close(st.Ops)

	st.Ops <- store.Op{1, store.MustEncodeSet(node+"/1/addr", "1.2.3.4:5", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet(node+"/2/addr", "2.3.4.5:6", 0)}
	st.Ops <- store.Op{3, store.MustEncodeSet(node+"/3/addr", "3.4.5.6:7", 0)}
	<-st.Seqns

	x, _ := net.ResolveUDPAddr("udp", "1.2.3.4:5")
	y, _ := net.ResolveUDPAddr("udp", "2.3.4.5:6")
	z, _ := net.ResolveUDPAddr("udp", "3.4.5.6:7")
	addrs := getAddrs(st, []string{"1", "2", "3"})
	assert.Equal(t, []*net.UDPAddr{x, y, z}, addrs)
}
Пример #14
0
func TestManagerDeletesSuccessfulRun(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	in := make(chan Packet)
	out := make(chan Packet, 100)
	cfg := &Config{
		Alpha: 1,
		Store: st,
		In:    in,
		Out:   out,
		Ops:   st.Ops,
	}
	m := NewManager(cfg)

	st.Ops <- store.Op{
		Seqn: 1,
		Mut:  store.MustEncodeSet(node+"/a/addr", "x", 0),
	}
	for (<-m.Stats).TotalRuns < 1 {
	}

	in <- Packet{
		Data: mustMarshal(&msg{Seqn: proto.Int64(2), Cmd: learn, Value: []byte("foo")}),
		Addr: "127.0.0.1:9999",
	}
	for (<-m.Stats).TotalRuns < 2 {
	}
	assert.Equal(t, 1, (<-m.Stats).Runs)
}
Пример #15
0
func TestManagerTickQueue(t *testing.T) {
	ticker := make(chan int64)
	st := store.New()
	defer close(st.Ops)
	in := make(chan Packet)
	cfg := &Config{
		Alpha:  1,
		Store:  st,
		In:     in,
		Ticker: ticker,
		Out:    make(chan Packet, 100),
	}
	m := NewManager(cfg)
	st.Ops <- store.Op{
		Seqn: 1,
		Mut:  store.MustEncodeSet(node+"/a/addr", "x", 0),
	}
	for (<-m.Stats).Runs < 1 {
	}

	// get it to tick for seqn 2
	in <- Packet{Data: mustMarshal(&msg{Seqn: proto.Int64(2), Cmd: propose})}
	assert.Equal(t, 1, (<-m.Stats).WaitTicks)

	ticker <- time.Nanoseconds() + initialWaitBound*2
	assert.Equal(t, int64(1), (<-m.Stats).TotalTicks)
}
Пример #16
0
func TestSession(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	fp := &test.FakeProposer{Store: st}
	go Clean(st, fp)

	ch := make(chan store.Event, 100)
	go func(c <-chan store.Event) {
		for e := range c {
			ch <- e
		}
		close(ch)
	}(st.Watch("/session/*"))

	// check-in with less than a nanosecond to live
	body := strconv.Itoa64(time.Nanoseconds() + 1)
	fp.Propose(store.MustEncodeSet("/session/a", body, store.Clobber))

	// Throw away the set
	assert.T(t, (<-ch).IsSet())

	ev := <-ch
	assert.T(t, ev.IsDel())
	assert.Equal(t, "/session/a", ev.Path)
}
Пример #17
0
func TestConsensusOne(t *testing.T) {
	self := "test"
	alpha := int64(1)
	st := store.New()

	st.Ops <- store.Op{1, store.MustEncodeSet("/ctl/node/"+self+"/addr", "x", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/cal/1", self, 0)}
	<-st.Seqns

	cmw := st.Watch(store.Any)
	in := make(chan Packet)
	out := make(chan Packet)
	seqns := make(chan int64, int(alpha))
	props := make(chan *Prop)

	NewManager(self, 0, alpha, in, out, st.Ops, seqns, props, cmw, 10e9, st)

	go func() {
		for o := range out {
			in <- o
		}
	}()

	for i := int64(3); i <= alpha+2; i++ {
		st.Ops <- store.Op{Seqn: i, Mut: store.Nop}
	}

	n := <-seqns
	w, err := st.Wait(n)
	if err != nil {
		panic(err)
	}
	props <- &Prop{n, []byte("foo")}
	e := <-w

	exp := store.Event{
		Seqn: 4,
		Path: "/ctl/err",
		Body: "bad mutation",
		Rev:  4,
		Mut:  "foo",
		Err:  os.NewError("bad mutation"),
	}

	e.Getter = nil
	assert.Equal(t, exp, e)
}
Пример #18
0
func TestManagerRemoveLastCal(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.MustEncodeSet(cal+"/1", "", -1)}

	pseqn := make(chan int64, 100)
	m := &Manager{
		Alpha: alpha,
		Self:  "a",
		PSeqn: pseqn,
		Ops:   st.Ops,
		Out:   make(chan Packet),
		run:   runs,
	}
	m.event(<-mustWait(st, 2))
	m.event(<-mustWait(st, 3))

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

	assert.Equal(t, 2, len(runs))
	assert.Equal(t, exp, runs[exp.seqn])
	assert.Equal(t, exp.seqn+1, m.next)
}
Пример #19
0
func follow(ops chan<- store.Op, ch <-chan *doozer.Event) {
	for ev := range ch {
		// store.Clobber is okay here because the event
		// has already passed through another store
		mut := store.MustEncodeSet(ev.Path, string(ev.Body), store.Clobber)
		ops <- store.Op{ev.Rev, mut}
	}
}
Пример #20
0
func alphaTest(t *testing.T, alpha int64) {
	runs := make(chan *run)
	st := store.New()
	defer close(st.Ops)

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

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

	tr := run{
		self:  "a",
		ops:   st.Ops,
		out:   make(chan Packet),
		bound: initialWaitBound,
	}
	go generateRuns(2, alpha, st, runs, tr)

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

	assert.Equal(t, exp, <-runs)
}
Пример #21
0
func encodeTimer(path string, offset int64) string {
	future := time.Nanoseconds() + offset
	muta := store.MustEncodeSet(
		path,
		strconv.Itoa64(future),
		store.Clobber,
	)
	return muta
}
Пример #22
0
func (c cloner) VisitFile(path string, f *doozer.FileInfo) {
	// store.Clobber is okay here because the event
	// has already passed through another store
	body, _, err := c.cl.Get(path, &f.Rev)
	if err != nil {
		panic(err)
	}
	mut := store.MustEncodeSet(path, string(body), store.Clobber)
	c.ch <- store.Op{f.Rev, mut}
}
Пример #23
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))
}
Пример #24
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.Nanoseconds() + initialWaitBound*2)
	assert.Equal(t, int64(1), m.Stats.TotalTicks)
}
Пример #25
0
func TestGcClean(t *testing.T) {
	st := store.New()
	defer close(st.Ops)

	go Clean(st)
	for <-st.Watches < 1 {
	} // Wait for Clean()'s Watch to take

	st.Ops <- store.Op{1, store.Nop}
	st.Ops <- store.Op{2, store.MustEncodeSet("/doozer/slot/1", "a", store.Missing)}
	st.Ops <- store.Op{3, store.MustEncodeSet("/doozer/info/a/applied", "2", store.Missing)}

	st.Ops <- store.Op{4, store.MustEncodeSet("/doozer/info/X/applied", "0", store.Missing)}
	ch := st.Watch("/x")
	st.Ops <- store.Op{5, store.MustEncodeSet("/x", "", store.Missing)}
	<-ch
	close(ch)

	ev := <-st.Wait(1)
	assert.Equal(t, store.ErrTooLate, (ev).Err)
}
Пример #26
0
func TestLearnedValueIsLearned(t *testing.T) {
	self := "test"
	alpha := int64(1)
	st := store.New()

	st.Ops <- store.Op{1, store.MustEncodeSet("/ctl/node/"+self+"/addr", "x", 0)}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/cal/1", self, 0)}
	<-st.Seqns

	cmw := st.Watch(store.Any)
	in := make(chan Packet)
	out := make(chan Packet)
	seqns := make(chan int64, int(alpha))
	props := make(chan *Prop)

	NewManager(self, 0, alpha, in, out, st.Ops, seqns, props, cmw, 10e9, st)

	v := store.MustEncodeSet("/foo", "bar", -1)
	st.Ops <- store.Op{Seqn: 3, Mut: v}

	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: rsvp})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: nominate})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: vote})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: nop})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: tick})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: learn})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: propose})}
	in <- Packet{"x", mustMarshal(&msg{Seqn: proto.Int64(3), Cmd: invite})}
	exp := Packet{"x", mustMarshal(&msg{
		Cmd:   learn,
		Seqn:  proto.Int64(3),
		Value: []byte(v),
	})}

	assert.Equal(t, exp, <-out)
}
Пример #27
0
func TestMemberSimple(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	fp := &test.FakeProposer{Store: st}
	go Clean(fp.Store, fp)

	// start our session
	fp.Propose(store.MustEncodeSet("/session/a", "foo", store.Missing))

	keys := map[string]string{
		"/doozer/slot/0":    "a",
		"/doozer/members/a": "addr",
		"/doozer/info/a/x":  "a",
		"/doozer/info/a/y":  "b",
	}

	// join the cluster
	for k, p := range keys {
		fp.Propose(store.MustEncodeSet(k, p, store.Missing))
	}

	// watch the keys to be deleted
	ch := fp.Watch("/doozer/**")

	// end the session
	fp.Propose(store.MustEncodeDel("/session/a", store.Clobber))

	// now that the session has ended, check its membership is cleaned up
	for i := 0; i < len(keys); i++ {
		ev := <-ch
		_, ok := keys[ev.Path]
		keys[ev.Path] = "", false
		assert.T(t, ok)
		assert.Equal(t, "", ev.Body)
	}
}
Пример #28
0
func TestManagerPacketProcessing(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	in := make(chan Packet)
	out := make(chan Packet, 100)
	var m Manager
	m.run = make(map[int64]*run)
	m.Alpha = 1
	m.Store = st
	m.In = in
	m.Out = out
	m.Ops = 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)}
	m.event(<-mustWait(st, 2))

	recvPacket(&m.packet, Packet{
		Data: mustMarshal(&msg{Seqn: proto.Int64(2), Cmd: learn, Value: []byte("foo")}),
		Addr: &net.UDPAddr{net.IP{127, 0, 0, 1}, 9999},
	})
	m.pump()
	assert.Equal(t, 0, m.packet.Len())
}
Пример #29
0
func TestLockSimple(t *testing.T) {
	st := store.New()
	defer close(st.Ops)
	fp := &test.FakeProposer{Store: st}
	go Clean(fp.Store, fp)

	// start our session
	fp.Propose(store.MustEncodeSet("/session/a", "1.2.3.4:55", store.Clobber))

	// lock something for a
	fp.Propose(store.MustEncodeSet("/lock/x", "a", store.Missing))
	fp.Propose(store.MustEncodeSet("/lock/y", "b", store.Missing))
	fp.Propose(store.MustEncodeSet("/lock/z", "a", store.Missing))

	// watch the locks to be deleted
	ch := fp.Watch("/lock/*")

	// end the session
	fp.Propose(store.MustEncodeDel("/session/a", store.Clobber))

	// now that the session has ended, check all locks it owned are released
	assert.Equal(t, "/lock/x", (<-ch).Path)
	assert.Equal(t, "/lock/z", (<-ch).Path)
}
Пример #30
0
func TestManagerReply(t *testing.T) {
	st := store.New()
	st.Ops <- store.Op{1, mustEncodeSet(membersDir+"a", "x")}
	st.Ops <- store.Op{2, mustEncodeSet(slotDir+"0", "a")}
	ch := make(ChanPutCloserTo)
	mg := NewManager("a", 1, st, ch)

	mut := store.MustEncodeSet("/foo", "bar", store.Clobber)
	st.Ops <- store.Op{3, mut}
	<-st.Seqns // give mg a chance to get the store.Event for seqn 3
	msg := newInvite(1)
	msg.SetSeqn(3)
	it := mg.getInstance(3)
	assert.Equal(t, instance(nil), it)
	mg.PutFrom("x", msg)
	exp := newLearn(mut)
	exp.SetSeqn(3)
	assert.Equal(t, Packet{exp, "x"}, <-ch)
}