123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- package chord_test
- import (
- "bytes"
- "crypto/sha1"
- "sort"
- "testing"
- "time"
- "trial/chord"
- )
- type MockDelegate struct {
- shutdown bool
- }
- func (m *MockDelegate) NewPredecessor(local, remoteNew, remotePrev *chord.Vnode) {
- }
- func (m *MockDelegate) Leaving(local, pred, succ *chord.Vnode) {
- }
- func (m *MockDelegate) PredecessorLeaving(local, remote *chord.Vnode) {
- }
- func (m *MockDelegate) SuccessorLeaving(local, remote *chord.Vnode) {
- }
- func (m *MockDelegate) Shutdown() {
- m.shutdown = true
- }
- func makeRing() *chord.Ring {
- conf := &chord.Config{
- NumVnodes: 5,
- NumSuccessors: 8,
- HashFunc: sha1.New,
- HashBits: 160,
- StabilizeMin: time.Second,
- StabilizeMax: 5 * time.Second,
- }
- ring := &chord.Ring{}
- ring.Init(conf, nil)
- return ring
- }
- func TestRingInit(t *testing.T) {
- // Create a ring
- ring := &chord.Ring{}
- conf := chord.DefaultConfig("test")
- ring.Init(conf, nil)
- // Test features
- if ring.Config != conf {
- t.Fatalf("wrong config")
- }
- if ring.Transport == nil {
- t.Fatalf("missing transport")
- }
- // Check the Vnodes
- for i := 0; i < conf.NumVnodes; i++ {
- if ring.Vnodes[i] == nil {
- t.Fatalf("missing vnode!")
- }
- if ring.Vnodes[i].Ring != ring {
- t.Fatalf("ring missing!")
- }
- if ring.Vnodes[i].Id == nil {
- t.Fatalf("ID not initialized!")
- }
- }
- }
- func TestRingLen(t *testing.T) {
- ring := makeRing()
- if ring.Len() != 5 {
- t.Fatalf("wrong len")
- }
- }
- func TestRingSort(t *testing.T) {
- ring := makeRing()
- sort.Sort(ring)
- if bytes.Compare(ring.Vnodes[0].Id, ring.Vnodes[1].Id) != -1 {
- t.Fatalf("bad sort")
- }
- if bytes.Compare(ring.Vnodes[1].Id, ring.Vnodes[2].Id) != -1 {
- t.Fatalf("bad sort")
- }
- if bytes.Compare(ring.Vnodes[2].Id, ring.Vnodes[3].Id) != -1 {
- t.Fatalf("bad sort")
- }
- if bytes.Compare(ring.Vnodes[3].Id, ring.Vnodes[4].Id) != -1 {
- t.Fatalf("bad sort")
- }
- }
- func TestRingNearest(t *testing.T) {
- ring := makeRing()
- ring.Vnodes[0].Id = []byte{2}
- ring.Vnodes[1].Id = []byte{4}
- ring.Vnodes[2].Id = []byte{7}
- ring.Vnodes[3].Id = []byte{10}
- ring.Vnodes[4].Id = []byte{14}
- key := []byte{6}
- near := ring.NearestVnode(key)
- if near != ring.Vnodes[1] {
- t.Fatalf("got wrong node back!")
- }
- key = []byte{0}
- near = ring.NearestVnode(key)
- if near != ring.Vnodes[4] {
- t.Fatalf("got wrong node back!")
- }
- }
- func TestRingSchedule(t *testing.T) {
- ring := makeRing()
- ring.SetLocalSuccessors()
- ring.Schedule()
- for i := 0; i < len(ring.Vnodes); i++ {
- if ring.Vnodes[i].Timer == nil {
- t.Fatalf("expected timer!")
- }
- }
- ring.StopVnodes()
- }
- func TestRingSetLocalSucc(t *testing.T) {
- ring := makeRing()
- ring.SetLocalSuccessors()
- for i := 0; i < len(ring.Vnodes); i++ {
- for j := 0; j < 4; j++ {
- if ring.Vnodes[i].Successors[j] == nil {
- t.Fatalf("expected successor!")
- }
- }
- if ring.Vnodes[i].Successors[4] != nil {
- t.Fatalf("should not have 5th successor!")
- }
- }
- // Verify the successor manually for node 3
- vn := ring.Vnodes[2]
- if vn.Successors[0] != &ring.Vnodes[3].Vnode {
- t.Fatalf("bad succ!")
- }
- if vn.Successors[1] != &ring.Vnodes[4].Vnode {
- t.Fatalf("bad succ!")
- }
- if vn.Successors[2] != &ring.Vnodes[0].Vnode {
- t.Fatalf("bad succ!")
- }
- if vn.Successors[3] != &ring.Vnodes[1].Vnode {
- t.Fatalf("bad succ!")
- }
- }
- func TestRingDelegate(t *testing.T) {
- d := &MockDelegate{}
- ring := makeRing()
- ring.SetLocalSuccessors()
- ring.Config.Delegate = d
- ring.Schedule()
- var b bool
- f := func() {
- println("run!")
- b = true
- }
- ch := ring.InvokeDelegate(f)
- if ch == nil {
- t.Fatalf("expected chan")
- }
- select {
- case <-ch:
- case <-time.After(time.Second):
- t.Fatalf("timeout")
- }
- if !b {
- t.Fatalf("b should be true")
- }
- ring.StopDelegate()
- if !d.shutdown {
- t.Fatalf("delegate did not get shutdown")
- }
- }
|