package chord_test import ( "errors" "testing" "time" "trial/go-chord" ) func TestRandStabilize(t *testing.T) { min := time.Duration(10 * time.Second) max := time.Duration(30 * time.Second) conf := &chord.Config{ StabilizeMin: min, StabilizeMax: max} var times []time.Duration for i := 0; i < 1000; i++ { after := chord.RandStabilize(conf) times = append(times, after) if after < min { t.Fatalf("after below min") } if after > max { t.Fatalf("after above max") } } collisions := 0 for idx, val := range times { for i := 0; i < len(times); i++ { if idx != i && times[i] == val { collisions += 1 } } } if collisions > 3 { t.Fatalf("too many collisions! %d", collisions) } } func TestBetween(t *testing.T) { t1 := []byte{0, 0, 0, 0} t2 := []byte{1, 0, 0, 0} k := []byte{0, 0, 5, 0} if !chord.Between(t1, t2, k) { t.Fatalf("expected k chord.Between!") } if chord.Between(t1, t2, t1) { t.Fatalf("dont expect t1 chord.Between!") } if chord.Between(t1, t2, t2) { t.Fatalf("dont expect t1 chord.Between!") } k = []byte{2, 0, 0, 0} if chord.Between(t1, t2, k) { t.Fatalf("dont expect k chord.Between!") } } func TestBetweenWrap(t *testing.T) { t1 := []byte{0xff, 0, 0, 0} t2 := []byte{1, 0, 0, 0} k := []byte{0, 0, 5, 0} if !chord.Between(t1, t2, k) { t.Fatalf("expected k chord.Between!") } k = []byte{0xff, 0xff, 0, 0} if !chord.Between(t1, t2, k) { t.Fatalf("expect k chord.Between!") } } func TestBetweenRightIncl(t *testing.T) { t1 := []byte{0, 0, 0, 0} t2 := []byte{1, 0, 0, 0} k := []byte{1, 0, 0, 0} if !chord.BetweenRightIncl(t1, t2, k) { t.Fatalf("expected k chord.Between!") } } func TestBetweenRightInclWrap(t *testing.T) { t1 := []byte{0xff, 0, 0, 0} t2 := []byte{1, 0, 0, 0} k := []byte{1, 0, 0, 0} if !chord.BetweenRightIncl(t1, t2, k) { t.Fatalf("expected k chord.Between!") } } func TestPowerOffset(t *testing.T) { id := []byte{0, 0, 0, 0} exp := 30 mod := 32 val := chord.PowerOffset(id, exp, mod) if val[0] != 64 { t.Fatalf("unexpected val! %v", val) } // 0-7, 8-15, 16-23, 24-31 id = []byte{0, 0xff, 0xff, 0xff} exp = 23 val = chord.PowerOffset(id, exp, mod) if val[0] != 1 || val[1] != 0x7f || val[2] != 0xff || val[3] != 0xff { t.Fatalf("unexpected val! %v", val) } } func TestMax(t *testing.T) { if chord.Max(-10, 10) != 10 { t.Fatalf("bad chord.Max") } if chord.Max(10, -10) != 10 { t.Fatalf("bad chord.Max") } } func TestMin(t *testing.T) { if chord.Min(-10, 10) != -10 { t.Fatalf("bad chord.Min") } if chord.Min(10, -10) != -10 { t.Fatalf("bad chord.Min") } } func TestNearestVnodesKey(t *testing.T) { Vnodes := make([]*chord.Vnode, 5) Vnodes[0] = &chord.Vnode{Id: []byte{2}} Vnodes[1] = &chord.Vnode{Id: []byte{4}} Vnodes[2] = &chord.Vnode{Id: []byte{7}} Vnodes[3] = &chord.Vnode{Id: []byte{10}} Vnodes[4] = &chord.Vnode{Id: []byte{14}} key := []byte{6} near := chord.NearestVnodeToKey(Vnodes, key) if near != Vnodes[1] { t.Fatalf("got wrong node back!") } key = []byte{0} near = chord.NearestVnodeToKey(Vnodes, key) if near != Vnodes[4] { t.Fatalf("got wrong node back!") } } func TestMergeErrors(t *testing.T) { e1 := errors.New("test1") e2 := errors.New("test2") if chord.MergeErrors(e1, nil) != e1 { t.Fatalf("bad merge") } if chord.MergeErrors(nil, e1) != e1 { t.Fatalf("bad merge") } if chord.MergeErrors(nil, nil) != nil { t.Fatalf("bad merge") } if chord.MergeErrors(e1, e2).Error() != "test1\ntest2" { t.Fatalf("bad merge") } }