コード例 #1
0
ファイル: peer_test.go プロジェクト: zyxar/doozerd
func TestDoozerGetWithRev(t *testing.T) {
	var (
		l  = mustListen()
		u  = mustListenUDP(l.Addr().String())
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()
	defer u.Close()

	go Main("a", "X", "", "", "", nil, u, l, nil, 1e9, 2e9, 3e9, 101, st)

	cl := dial(l.Addr().String())

	rev1, err := cl.Set("/x", store.Missing, []byte{'a'})
	assert.Equal(t, nil, err)

	v, rev, err := cl.Get("/x", &rev1) // Use the snapshot.
	assert.Equal(t, nil, err)
	assert.Equal(t, rev1, rev)
	assert.Equal(t, []byte{'a'}, v)

	rev2, err := cl.Set("/x", rev, []byte{'b'})
	assert.Equal(t, nil, err)

	v, rev, err = cl.Get("/x", nil) // Read the new value.
	assert.Equal(t, nil, err)
	assert.Equal(t, rev2, rev)
	assert.Equal(t, []byte{'b'}, v)

	v, rev, err = cl.Get("/x", &rev1) // Read the saved value again.
	assert.Equal(t, nil, err)
	assert.Equal(t, rev1, rev)
	assert.Equal(t, []byte{'a'}, v)
}
コード例 #2
0
ファイル: peer_test.go プロジェクト: zyxar/doozerd
func TestDoozerGet(t *testing.T) {
	var (
		l  = mustListen()
		u  = mustListenUDP(l.Addr().String())
		st = store.New(store.DefaultInitialRev)
	)

	defer l.Close()
	defer u.Close()

	go Main("a", "X", "", "", "", nil, u, l, nil, 1e9, 2e9, 3e9, 101, st)

	cl := dial(l.Addr().String())

	_, err := cl.Set("/x", store.Missing, []byte{'a'})
	assert.Equal(t, nil, err)

	ents, rev, err := cl.Get("/x", nil)
	assert.Equal(t, nil, err)
	assert.NotEqual(t, store.Dir, rev)
	assert.Equal(t, []byte{'a'}, ents)

	//cl.Set("/test/a", store.Missing, []byte{'1'})
	//cl.Set("/test/b", store.Missing, []byte{'2'})
	//cl.Set("/test/c", store.Missing, []byte{'3'})

	//ents, rev, err = cl.Get("/test", 0)
	//sort.SortStrings(ents)
	//assert.Equal(t, store.Dir, rev)
	//assert.Equal(t, nil, err)
	//assert.Equal(t, []string{"a", "b", "c"}, ents)
}
コード例 #3
0
ファイル: peer_test.go プロジェクト: zyxar/doozerd
func TestDoozerGetdirOffsetLimit(t *testing.T) {
	var (
		l  = mustListen()
		u  = mustListenUDP(l.Addr().String())
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()
	defer u.Close()

	go Main("a", "X", "", "", "", nil, u, l, nil, 1e9, 2e9, 3e9, 101, st)

	cl := dial(l.Addr().String())
	cl.Set("/test/a", store.Clobber, []byte("1"))
	cl.Set("/test/b", store.Clobber, []byte("2"))
	cl.Set("/test/c", store.Clobber, []byte("3"))
	cl.Set("/test/d", store.Clobber, []byte("4"))

	rev, err := cl.Rev()
	if err != nil {
		panic(err)
	}

	names, err := cl.Getdir("/test", rev, 1, 2)
	assert.Equal(t, nil, err)
	assert.Equal(t, []string{"b", "c"}, names)
}
コード例 #4
0
ファイル: peer_test.go プロジェクト: zyxar/doozerd
func TestDoozerWaitWithRev(t *testing.T) {
	var (
		l  = mustListen()
		u  = mustListenUDP(l.Addr().String())
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()
	defer u.Close()

	go Main("a", "X", "", "", "", nil, u, l, nil, 1e9, 2e9, 3e9, 101, st)

	cl := dial(l.Addr().String())

	// Create some history
	cl.Set("/test/foo", store.Clobber, []byte("bar"))
	cl.Set("/test/fun", store.Clobber, []byte("house"))

	ev, err := cl.Wait("/test/**", 1)
	assert.Equal(t, nil, err)
	assert.Equal(t, "/test/foo", ev.Path)
	assert.Equal(t, []byte("bar"), ev.Body)
	assert.T(t, ev.IsSet())
	rev := ev.Rev + 1

	ev, err = cl.Wait("/test/**", rev)
	assert.Equal(t, nil, err)
	assert.Equal(t, "/test/fun", ev.Path)
	assert.Equal(t, []byte("house"), ev.Body)
	assert.T(t, ev.IsSet())
}
コード例 #5
0
ファイル: peer_test.go プロジェクト: zyxar/doozerd
func TestDoozerStat(t *testing.T) {
	var (
		l  = mustListen()
		u  = mustListenUDP(l.Addr().String())
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()
	defer u.Close()

	go Main("a", "X", "", "", "", nil, u, l, nil, 1e9, 2e9, 3e9, 101, st)

	cl := dial(l.Addr().String())

	cl.Set("/test/foo", store.Clobber, []byte("bar"))
	setRev, _ := cl.Set("/test/fun", store.Clobber, []byte("house"))

	ln, rev, err := cl.Stat("/test", nil)
	assert.Equal(t, nil, err)
	assert.Equal(t, store.Dir, rev)
	assert.Equal(t, int(2), ln)

	ln, rev, err = cl.Stat("/test/fun", nil)
	assert.Equal(t, nil, err)
	assert.Equal(t, setRev, rev)
	assert.Equal(t, int(5), ln)
}
コード例 #6
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestManagerPacketProcessing(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	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))

	addr, _ := net.ResolveUDPAddr("udp", "127.0.0.1:9999")
	recvPacket(&m.packet, Packet{
		Addr: addr,
		Msg:  Msg{Seqn: proto.Int64(2), Cmd: learn, Value: []byte("foo")},
	})
	m.pump()
	assert.Equal(t, 0, m.packet.Len())
}
コード例 #7
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerWaitSimple(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())
	var rev int64 = 1

	cl.Set("/test/foo", store.Clobber, []byte("bar"))
	ev, err := cl.Wait("/test/**", rev)
	assert.Equal(t, nil, err)
	assert.Equal(t, "/test/foo", ev.Path)
	assert.Equal(t, []byte("bar"), ev.Body)
	assert.T(t, ev.IsSet())
	rev = ev.Rev + 1

	cl.Set("/test/fun", store.Clobber, []byte("house"))
	ev, err = cl.Wait("/test/**", rev)
	assert.Equal(t, nil, err)
	assert.Equal(t, "/test/fun", ev.Path)
	assert.Equal(t, []byte("house"), ev.Body)
	assert.T(t, ev.IsSet())
	rev = ev.Rev + 1

	cl.Del("/test/foo", store.Clobber)
	ev, err = cl.Wait("/test/**", rev)
	assert.Equal(t, nil, err)
	assert.Equal(t, "/test/foo", ev.Path)
	assert.T(t, ev.IsDel())
}
コード例 #8
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestManagerFilterPropSeqn(t *testing.T) {
	ps := make(chan int64, 100)
	st := store.New(store.DefaultInitialRev)
	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)
}
コード例 #9
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestManagerEvent(t *testing.T) {
	const alpha = 2
	runs := make(map[int64]*run)
	st := store.New(store.DefaultInitialRev)
	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)
}
コード例 #10
0
ファイル: consensus_test.go プロジェクト: zyxar/doozerd
func TestConsensusOne(t *testing.T) {
	self := "test"
	const alpha = 1
	st := store.New(store.DefaultInitialRev)

	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)
}
コード例 #11
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestGetCalsPartial(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	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))
}
コード例 #12
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerNop(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())
	err := cl.Nop()
	assert.Equal(t, nil, err)
}
コード例 #13
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestGetAddrs(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	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
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestManagerPumpDropsOldPackets(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	defer close(st.Ops)
	x, _ := net.ResolveUDPAddr("udp", "1.2.3.4:5")
	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.event(<-mustWait(st, 2))
	m.pump()
	recvPacket(&m.packet, Packet{x, Msg{Seqn: proto.Int64(1)}})
	m.pump()
	assert.Equal(t, 0, m.Stats.WaitPackets)
}
コード例 #15
0
ファイル: member_test.go プロジェクト: zyxar/doozerd
func TestMemberSimple(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	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)
}
コード例 #16
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerGet(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())

	_, err := cl.Set("/x", store.Missing, []byte{'a'})
	assert.Equal(t, nil, err)

	ents, rev, err := cl.Get("/x", nil)
	assert.Equal(t, nil, err)
	assert.NotEqual(t, store.Dir, rev)
	assert.Equal(t, []byte{'a'}, ents)
}
コード例 #17
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerSet(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())

	for i := byte(0); i < 10; i++ {
		_, err := cl.Set("/x", store.Clobber, []byte{'0' + i})
		assert.Equal(t, nil, err)
	}

	_, err := cl.Set("/x", 0, []byte{'X'})
	assert.Equal(t, &doozer.Error{doozer.ErrOldRev, ""}, err)
}
コード例 #18
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestDelRun(t *testing.T) {
	const alpha = 2
	runs := make(map[int64]*run)
	st := store.New(store.DefaultInitialRev)
	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))
}
コード例 #19
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerGetdirMissing(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())

	rev, err := cl.Rev()
	if err != nil {
		panic(err)
	}

	names, err := cl.Getdir("/not/here", rev, 0, -1)
	assert.Equal(t, &doozer.Error{doozer.ErrNoEnt, ""}, err)
	assert.Equal(t, []string(nil), names)
}
コード例 #20
0
ファイル: manager_test.go プロジェクト: zyxar/doozerd
func TestManagerTickQueue(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	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{Msg: 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)
}
コード例 #21
0
ファイル: clean_test.go プロジェクト: zyxar/doozerd
func TestGcClean(t *testing.T) {
	st := store.New(store.DefaultInitialRev)
	defer close(st.Ops)

	ticker := make(chan time.Time)
	defer close(ticker)

	go Clean(st, 3, ticker)

	st.Ops <- store.Op{1, store.Nop}
	st.Ops <- store.Op{2, store.Nop}
	st.Ops <- store.Op{3, store.Nop}
	st.Ops <- store.Op{4, store.Nop}

	_, err := st.Wait(store.Any, 1)
	assert.Equal(t, nil, err)
	ticker <- time.Unix(0, 1)
	ticker <- time.Unix(0, 1) // Extra tick to ensure the last st.Clean has completed
	_, err = st.Wait(store.Any, 1)
	assert.Equal(t, store.ErrTooLate, err)
}
コード例 #22
0
ファイル: server_test.go プロジェクト: zyxar/doozerd
func TestServerNoAccess(t *testing.T) {
	b := make(bchan, 2)
	c := &conn{
		c:        b,
		canWrite: true,
		st:       store.New(store.DefaultInitialRev),
	}
	tx := &txn{
		c:   c,
		req: Request{Tag: proto.Int32(1)},
	}

	for i, op := range ops {
		if i != int32(Request_ACCESS) {
			op(tx)
			var exp Response_Err = Response_OTHER
			assert.Equal(t, 4, len(<-b), Request_Verb_name[i])
			assert.Equal(t, &exp, mustUnmarshal(<-b).ErrCode, Request_Verb_name[i])
		}
	}
}
コード例 #23
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerGetdirOnFile(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())

	cl.Set("/test/a", store.Clobber, []byte("1"))

	rev, err := cl.Rev()
	if err != nil {
		panic(err)
	}

	names, err := cl.Getdir("/test/a", rev, 0, -1)
	assert.Equal(t, &doozer.Error{doozer.ErrNotDir, ""}, err)
	assert.Equal(t, []string(nil), names)
}
コード例 #24
0
ファイル: server_test.go プロジェクト: zyxar/doozerd
func TestServerRo(t *testing.T) {
	b := make(bchan, 2)
	c := &conn{
		c:        b,
		canWrite: true,
		st:       store.New(store.DefaultInitialRev),
	}
	tx := &txn{
		c:   c,
		req: Request{Tag: proto.Int32(1)},
	}

	wops := []int32{int32(Request_DEL), int32(Request_NOP), int32(Request_SET)}

	for _, i := range wops {
		op := ops[i]
		op(tx)
		var exp Response_Err = Response_OTHER
		assert.Equal(t, 4, len(<-b), Request_Verb_name[i])
		assert.Equal(t, &exp, mustUnmarshal(<-b).ErrCode, Request_Verb_name[i])
	}
}
コード例 #25
0
ファイル: solo_test.go プロジェクト: zyxar/doozerd
func TestDoozerGetdirOnDir(t *testing.T) {
	var (
		l  = mustListen()
		st = store.New(store.DefaultInitialRev)
	)
	defer l.Close()

	go Main("a", "X", nil, l, nil, st, 1e6)

	cl := dial(l.Addr().String())

	cl.Set("/test/a", store.Clobber, []byte("1"))
	cl.Set("/test/b", store.Clobber, []byte("2"))
	cl.Set("/test/c", store.Clobber, []byte("3"))

	rev, err := cl.Rev()
	if err != nil {
		panic(err)
	}

	got, err := cl.Getdir("/test", rev, 0, -1)
	assert.Equal(t, nil, err)
	assert.Equal(t, []string{"a", "b", "c"}, got)
}
コード例 #26
0
ファイル: consensus_test.go プロジェクト: zyxar/doozerd
func TestConsensusTwo(t *testing.T) {
	a := "a"
	b := "b"
	x, _ := net.ResolveUDPAddr("udp", "1.2.3.4:5")
	xs := "1.2.3.4:5"
	y, _ := net.ResolveUDPAddr("udp", "2.3.4.5:6")
	ys := "2.3.4.5:6"
	const alpha = 1
	st := store.New(store.DefaultInitialRev)

	st.Ops <- store.Op{1, store.Nop}
	st.Ops <- store.Op{2, store.MustEncodeSet("/ctl/node/a/addr", xs, 0)}
	st.Ops <- store.Op{3, store.MustEncodeSet("/ctl/cal/1", a, 0)}
	st.Ops <- store.Op{4, store.MustEncodeSet("/ctl/node/b/addr", ys, 0)}
	st.Ops <- store.Op{5, store.MustEncodeSet("/ctl/cal/2", b, 0)}

	ain := make(chan Packet)
	aout := make(chan Packet)
	aseqns := make(chan int64, alpha)
	aprops := make(chan *Prop)
	am := &Manager{
		Self:   a,
		DefRev: 5,
		Alpha:  alpha,
		In:     ain,
		Out:    aout,
		Ops:    st.Ops,
		PSeqn:  aseqns,
		Props:  aprops,
		TFill:  10e9,
		Store:  st,
		Ticker: time.Tick(10e6),
	}
	go am.Run()

	bin := make(chan Packet)
	bout := make(chan Packet)
	bseqns := make(chan int64, alpha)
	bprops := make(chan *Prop)
	bm := &Manager{
		Self:   b,
		DefRev: 5,
		Alpha:  alpha,
		In:     bin,
		Out:    bout,
		Ops:    st.Ops,
		PSeqn:  bseqns,
		Props:  bprops,
		TFill:  10e9,
		Store:  st,
		Ticker: time.Tick(10e6),
	}
	go bm.Run()

	go func() {
		for o := range aout {
			if o.Addr.Port == x.Port && o.Addr.IP.Equal(x.IP) {
				go func(o Packet) { ain <- o }(o)
			} else {
				o.Addr = x
				go func(o Packet) { bin <- o }(o)
			}
		}
	}()

	go func() {
		for o := range bout {
			if o.Addr.Port == y.Port && o.Addr.IP.Equal(y.IP) {
				go func(o Packet) { bin <- o }(o)
			} else {
				o.Addr = y
				go func(o Packet) { ain <- o }(o)
			}
		}
	}()

	n := <-aseqns
	assert.Equal(t, int64(6), n)
	w, err := st.Wait(store.Any, n)
	if err != nil {
		panic(err)
	}
	aprops <- &Prop{n, []byte("foo")}
	e := <-w

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

	e.Getter = nil
	assert.Equal(t, exp, e)
}
コード例 #27
0
ファイル: doozerd.go プロジェクト: zyxar/doozerd
func main() {
	*buri = os.Getenv("DOOZER_BOOT_URI")

	flag.Usage = Usage
	flag.Parse()

	if *showVersion {
		fmt.Println("doozerd", peer.Version)
		return
	}

	if *laddr == "" {
		fmt.Fprintln(os.Stderr, "require a listen address")
		flag.Usage()
		os.Exit(1)
	}

	log.SetPrefix("DOOZER ")
	log.SetFlags(log.Ldate | log.Lmicroseconds | log.Lshortfile)

	tsock, err := net.Listen("tcp", *laddr)
	if err != nil {
		panic(err)
	}

	if *certFile != "" || *keyFile != "" {
		tsock = tlsWrap(tsock, *certFile, *keyFile)
	}

	uaddr, err := net.ResolveUDPAddr("udp", *laddr)
	if err != nil {
		panic(err)
	}

	usock, err := net.ListenUDP("udp", uaddr)
	if err != nil {
		panic(err)
	}

	var wsock net.Listener
	if *waddr == "" {
		wa, err := net.ResolveTCPAddr("tcp", *laddr)
		if err != nil {
			panic(err)
		}
		wa.Port = defWebPort
		*waddr = wa.String()
	}
	if b, err := strconv.ParseBool(*waddr); err != nil && !b {
		wsock, err = net.Listen("tcp", *waddr)
		if err != nil {
			panic(err)
		}
	}

	id := randId()
	var cl *doozer.Conn
	switch {
	case len(aaddrs) > 0 && *buri != "":
		cl = attach(*name, aaddrs)
		if cl == nil {
			cl = boot(*name, id, *laddr, *buri)
		}
	case len(aaddrs) > 0:
		cl = attach(*name, aaddrs)
		if cl == nil {
			panic("failed to attach")
		}
	case *buri != "":
		cl = boot(*name, id, *laddr, *buri)
	}

	st := store.New(*rev)

	if *soloMode {
		solo.Main(
			*name,
			id,
			cl,
			tsock,
			wsock,
			st,
			*hi,
		)
	} else {
		peer.Main(
			*name,
			id,
			*buri,
			rwsk,
			rosk,
			cl,
			usock,
			tsock,
			wsock,
			ns(*pi),
			ns(*fd),
			ns(*kt),
			*hi,
			st,
		)
	}

	panic("main exit")
}