123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- package chord_test
- import (
- "bytes"
- "testing"
- "trial/chord"
- )
- type MockVnodeRPC struct {
- err error
- pred *chord.Vnode
- not_pred *chord.Vnode
- succ_list []*chord.Vnode
- key []byte
- succ []*chord.Vnode
- skip *chord.Vnode
- }
- func (mv *MockVnodeRPC) GetPredecessor() (*chord.Vnode, error) {
- return mv.pred, mv.err
- }
- func (mv *MockVnodeRPC) Notify(vn *chord.Vnode) ([]*chord.Vnode, error) {
- mv.not_pred = vn
- return mv.succ_list, mv.err
- }
- func (mv *MockVnodeRPC) FindSuccessors(n int, key []byte) ([]*chord.Vnode, error) {
- mv.key = key
- return mv.succ, mv.err
- }
- func (mv *MockVnodeRPC) ClearPredecessor(p *chord.Vnode) error {
- mv.pred = nil
- return nil
- }
- func (mv *MockVnodeRPC) SkipSuccessor(s *chord.Vnode) error {
- mv.skip = s
- return nil
- }
- func makeLocal() *chord.LocalTransport {
- return chord.InitLocalTransport(nil).(*chord.LocalTransport)
- }
- func TestInitLocalTransport(t *testing.T) {
- local := chord.InitLocalTransport(nil).(*chord.LocalTransport)
- if local.Remote == nil {
- t.Fatalf("bad remote")
- }
- if local.Local == nil {
- t.Fatalf("missing map")
- }
- }
- func TestLocalList(t *testing.T) {
- l := makeLocal()
- vn := &chord.Vnode{Id: []byte{1}, Host: "test"}
- mockVN := &MockVnodeRPC{}
- l.Register(vn, mockVN)
- list, err := l.ListVnodes("test")
- if err != nil {
- t.Fatalf("unexpected err. %s", err)
- }
- if len(list) != 1 || list[0] != vn {
- t.Fatal("local list failed", list)
- }
- }
- func TestLocalListRemote(t *testing.T) {
- l := makeLocal()
- vn := &chord.Vnode{Id: []byte{1}, Host: "test"}
- mockVN := &MockVnodeRPC{}
- l.Register(vn, mockVN)
- _, err := l.ListVnodes("remote")
- if err == nil {
- t.Fatalf("expected err!")
- }
- }
- func TestLocalPing(t *testing.T) {
- l := makeLocal()
- vn := &chord.Vnode{Id: []byte{1}}
- mockVN := &MockVnodeRPC{}
- l.Register(vn, mockVN)
- if res, err := l.Ping(vn); !res || err != nil {
- t.Fatalf("local ping failed")
- }
- }
- func TestLocalMissingPing(t *testing.T) {
- l := makeLocal()
- vn := &chord.Vnode{Id: []byte{2}}
- mockVN := &MockVnodeRPC{}
- l.Register(vn, mockVN)
- // Print some random node
- vn2 := &chord.Vnode{Id: []byte{3}}
- if res, _ := l.Ping(vn2); res {
- t.Fatalf("ping succeeded")
- }
- }
- func TestLocalGetPredecessor(t *testing.T) {
- l := makeLocal()
- pred := &chord.Vnode{Id: []byte{10}}
- vn := &chord.Vnode{Id: []byte{42}}
- mockVN := &MockVnodeRPC{pred: pred, err: nil}
- l.Register(vn, mockVN)
- vn2 := &chord.Vnode{Id: []byte{42}}
- res, err := l.GetPredecessor(vn2)
- if err != nil {
- t.Fatalf("local GetPredecessor failed")
- }
- if res != pred {
- t.Fatalf("got wrong predecessor")
- }
- unknown := &chord.Vnode{Id: []byte{1}}
- res, err = l.GetPredecessor(unknown)
- if err == nil {
- t.Fatalf("expected error!")
- }
- }
- func TestLocalNotify(t *testing.T) {
- l := makeLocal()
- suc1 := &chord.Vnode{Id: []byte{10}}
- suc2 := &chord.Vnode{Id: []byte{20}}
- suc3 := &chord.Vnode{Id: []byte{30}}
- succ_list := []*chord.Vnode{suc1, suc2, suc3}
- mockVN := &MockVnodeRPC{succ_list: succ_list, err: nil}
- vn := &chord.Vnode{Id: []byte{0}}
- l.Register(vn, mockVN)
- self := &chord.Vnode{Id: []byte{60}}
- res, err := l.Notify(vn, self)
- if err != nil {
- t.Fatalf("local notify failed")
- }
- if res == nil || res[0] != suc1 || res[1] != suc2 || res[2] != suc3 {
- t.Fatalf("got wrong successor list")
- }
- if mockVN.not_pred != self {
- t.Fatalf("didn't get notified correctly!")
- }
- unknown := &chord.Vnode{Id: []byte{1}}
- res, err = l.Notify(unknown, self)
- if err == nil {
- t.Fatalf("remote notify should fail")
- }
- }
- func TestLocalFindSucc(t *testing.T) {
- l := makeLocal()
- suc := []*chord.Vnode{{Id: []byte{40}}}
- mockVN := &MockVnodeRPC{succ: suc, err: nil}
- vn := &chord.Vnode{Id: []byte{12}}
- l.Register(vn, mockVN)
- key := []byte("test")
- res, err := l.FindSuccessors(vn, 1, key)
- if err != nil {
- t.Fatalf("local FindSuccessor failed")
- }
- if res[0] != suc[0] {
- t.Fatalf("got wrong successor")
- }
- if bytes.Compare(mockVN.key, key) != 0 {
- t.Fatalf("didn't get key correctly!")
- }
- unknown := &chord.Vnode{Id: []byte{1}}
- res, err = l.FindSuccessors(unknown, 1, key)
- if err == nil {
- t.Fatalf("remote find should fail")
- }
- }
- func TestLocalClearPred(t *testing.T) {
- l := makeLocal()
- pred := &chord.Vnode{Id: []byte{10}}
- mockVN := &MockVnodeRPC{pred: pred}
- vn := &chord.Vnode{Id: []byte{12}}
- l.Register(vn, mockVN)
- err := l.ClearPredecessor(vn, pred)
- if err != nil {
- t.Fatalf("local ClearPredecessor failed")
- }
- if mockVN.pred != nil {
- t.Fatalf("clear failed")
- }
- unknown := &chord.Vnode{Id: []byte{1}}
- err = l.ClearPredecessor(unknown, pred)
- if err == nil {
- t.Fatalf("remote clear should fail")
- }
- }
- func TestLocalSkipSucc(t *testing.T) {
- l := makeLocal()
- suc := []*chord.Vnode{{Id: []byte{40}}}
- mockVN := &MockVnodeRPC{succ: suc}
- vn := &chord.Vnode{Id: []byte{12}}
- l.Register(vn, mockVN)
- s := &chord.Vnode{Id: []byte{40}}
- err := l.SkipSuccessor(vn, s)
- if err != nil {
- t.Fatalf("local Skip failed")
- }
- if mockVN.skip != s {
- t.Fatalf("skip failed")
- }
- unknown := &chord.Vnode{Id: []byte{1}}
- err = l.SkipSuccessor(unknown, s)
- if err == nil {
- t.Fatalf("remote skip should fail")
- }
- }
- func TestLocalDeregister(t *testing.T) {
- l := makeLocal()
- vn := &chord.Vnode{Id: []byte{1}}
- mockVN := &MockVnodeRPC{}
- l.Register(vn, mockVN)
- if res, err := l.Ping(vn); !res || err != nil {
- t.Fatalf("local ping failed")
- }
- l.Deregister(vn)
- if res, _ := l.Ping(vn); res {
- t.Fatalf("local ping succeeded")
- }
- }
- func TestBHList(t *testing.T) {
- bh := chord.BlackholeTransport{}
- res, err := bh.ListVnodes("test")
- if res != nil || err == nil {
- t.Fatalf("expected fail")
- }
- }
- func TestBHPing(t *testing.T) {
- bh := chord.BlackholeTransport{}
- vn := &chord.Vnode{Id: []byte{12}}
- res, err := bh.Ping(vn)
- if res || err != nil {
- t.Fatalf("expected fail")
- }
- }
- func TestBHGetPred(t *testing.T) {
- bh := chord.BlackholeTransport{}
- vn := &chord.Vnode{Id: []byte{12}}
- _, err := bh.GetPredecessor(vn)
- if err.Error()[:18] != "Failed to connect!" {
- t.Fatalf("expected fail")
- }
- }
- func TestBHNotify(t *testing.T) {
- bh := chord.BlackholeTransport{}
- vn := &chord.Vnode{Id: []byte{12}}
- vn2 := &chord.Vnode{Id: []byte{42}}
- _, err := bh.Notify(vn, vn2)
- if err.Error()[:18] != "Failed to connect!" {
- t.Fatalf("expected fail")
- }
- }
- func TestBHFindSuccessors(t *testing.T) {
- bh := chord.BlackholeTransport{}
- vn := &chord.Vnode{Id: []byte{12}}
- _, err := bh.FindSuccessors(vn, 1, []byte("test"))
- if err.Error()[:18] != "Failed to connect!" {
- t.Fatalf("expected fail")
- }
- }
- func TestBHClearPred(t *testing.T) {
- bh := chord.BlackholeTransport{}
- vn := &chord.Vnode{Id: []byte{12}}
- s := &chord.Vnode{Id: []byte{50}}
- err := bh.ClearPredecessor(vn, s)
- if err.Error()[:18] != "Failed to connect!" {
- t.Fatalf("expected fail")
- }
- }
- func TestBHSkipSucc(t *testing.T) {
- bh := chord.BlackholeTransport{}
- vn := &chord.Vnode{Id: []byte{12}}
- s := &chord.Vnode{Id: []byte{50}}
- err := bh.SkipSuccessor(vn, s)
- if err.Error()[:18] != "Failed to connect!" {
- t.Fatalf("expected fail")
- }
- }
|