diff --git a/ids/id_test.go b/ids/id_test.go index af3efa4..b541ed5 100644 --- a/ids/id_test.go +++ b/ids/id_test.go @@ -5,6 +5,7 @@ package ids import ( "bytes" + "reflect" "testing" ) @@ -29,10 +30,6 @@ func TestID(t *testing.T) { if b := id.Bytes(); !bytes.Equal(hash[:], b) { t.Fatalf("ID.Bytes returned wrong bytes") } - - if str := id.String(); str != "Ba3mm8Ra8JYYebeZ9p7zw1ayorDbeD1euwxhgzSLsncKqGoNt" { - t.Fatalf("ID.String returned wrong string: %s", str) - } } func TestIDBit(t *testing.T) { @@ -79,3 +76,143 @@ func TestFromString(t *testing.T) { t.Fatal("Expected FromString to be inverse of String but it wasn't") } } + +func TestIDFromStringError(t *testing.T) { + tests := []struct { + in string + }{ + {""}, + {"foo"}, + {"foobar"}, + } + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + _, err := FromString(tt.in) + if err == nil { + t.Error("Unexpected success") + } + }) + } +} + +func TestIDMarshalJSON(t *testing.T) { + tests := []struct { + label string + in ID + out []byte + err error + }{ + {"ID{}", ID{}, []byte("null"), nil}, + {"ID(\"ava labs\")", + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + []byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""), + nil, + }, + } + for _, tt := range tests { + t.Run(tt.label, func(t *testing.T) { + out, err := tt.in.MarshalJSON() + if err != tt.err { + t.Errorf("Expected err %s, got error %v", tt.err, err) + } else if !bytes.Equal(out, tt.out) { + t.Errorf("got %q, expected %q", out, tt.out) + } + }) + } +} + +func TestIDUnmarshalJSON(t *testing.T) { + tests := []struct { + label string + in []byte + out ID + err error + }{ + {"ID{}", []byte("null"), ID{}, nil}, + {"ID(\"ava labs\")", + []byte("\"jvYi6Tn9idMi7BaymUVi9zWjg5tpmW7trfKG1AYJLKZJ2fsU7\""), + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + nil, + }, + } + for _, tt := range tests { + t.Run(tt.label, func(t *testing.T) { + foo := ID{} + err := foo.UnmarshalJSON(tt.in) + if err != tt.err { + t.Errorf("Expected err %s, got error %v", tt.err, err) + } else if foo.ID != nil && foo.Key() != tt.out.Key() { + t.Errorf("got %q, expected %q", foo.Key(), tt.out.Key()) + } + }) + } +} + +func TestIDHex(t *testing.T) { + id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}) + expected := "617661206c61627300000000000000000000000000000000000000000000000000" + actual := id.Hex() + if actual != actual { + t.Fatalf("got %s, expected %s", actual, expected) + } +} + +func TestIDString(t *testing.T) { + tests := []struct { + label string + id ID + expected string + }{ + {"ID{}", ID{}, "nil"}, + {"ID{[32]byte{24}}", NewID([32]byte{24}), "Ba3mm8Ra8JYYebeZ9p7zw1ayorDbeD1euwxhgzSLsncKqGoNt"}, + } + for _, tt := range tests { + t.Run(tt.label, func(t *testing.T) { + result := tt.id.String() + if result != tt.expected { + t.Errorf("got %q, expected %q", result, tt.expected) + } + }) + } +} + +func TestSortIDs(t *testing.T) { + ids := []ID{ + NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'W', 'a', 'l', 'l', 'e', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + } + SortIDs(ids) + expected := []ID{ + NewID([32]byte{'W', 'a', 'l', 'l', 'e', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + } + if !reflect.DeepEqual(ids, expected) { + t.Fatal("[]ID was not sorted lexographically") + } +} + +func TestIsSortedAndUnique(t *testing.T) { + unsorted := []ID{ + NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + } + if IsSortedAndUniqueIDs(unsorted) { + t.Fatal("Wrongly accepted unsorted IDs") + } + duplicated := []ID{ + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + } + if IsSortedAndUniqueIDs(duplicated) { + t.Fatal("Wrongly accepted duplicated IDs") + } + sorted := []ID{ + NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}), + } + if !IsSortedAndUniqueIDs(sorted) { + t.Fatal("Wrongly rejected sorted, unique IDs") + } +} diff --git a/ids/queue_test.go b/ids/queue_test.go new file mode 100644 index 0000000..ab0dd4e --- /dev/null +++ b/ids/queue_test.go @@ -0,0 +1,70 @@ +package ids + +import ( + "reflect" + "testing" +) + +func TestQueueSetinit(t *testing.T) { + qs := QueueSet{} + qs.init() + if qs.idList == nil { + t.Fatal("Failed to initialize") + } + list := qs.idList + qs.init() + if list != qs.idList { + t.Fatal("Mutated an already intialized queue") + } +} + +func TestQueueSetSetHead(t *testing.T) { + qs := QueueSet{} + id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}) + qs.SetHead(id) + if qs.idList == nil || id != qs.idList.Front().Value.(ID) { + t.Fatal("Failed to set head of unintilised queue") + } + + qs.SetHead(id) + if qs.idList.Len() != 1 || id != qs.idList.Front().Value.(ID) { + t.Fatal("Mutated a queue which already had the desired head") + } + + id2 := NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}) + qs.SetHead(id2) + if qs.idList.Len() != 1 || id2 != qs.idList.Front().Value.(ID) { + t.Fatal("Didn't replace the existing head") + } +} + +func TestQueueSetAppend(t *testing.T) { + qs := QueueSet{} + id := NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}) + qs.Append(id) + if qs.idList == nil || id != qs.idList.Front().Value.(ID) { + t.Fatal("Failed to append to an uninitialised queue") + } + + id2 := NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}) + qs.Append(id2) + if qs.idList.Len() != 2 || id2 != qs.idList.Back().Value.(ID) { + t.Fatal("Failed to append to the back of the queue") + } +} + +func TestQueueGetTail(t *testing.T) { + qs := QueueSet{} + tail := qs.GetTail() + if !reflect.DeepEqual(tail, ID{}) { + t.Fatalf("Empty queue returned %v, expected empty ID %v", tail, Empty) + } + + qs.Append(NewID([32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'})) + id2 := NewID([32]byte{'e', 'v', 'a', ' ', 'l', 'a', 'b', 's'}) + qs.Append(id2) + tail = qs.GetTail() + if tail != id2 { + t.Fatalf("Populated queue returned %v, expected %v", tail, id2) + } +} diff --git a/networking/voting_handlers.go b/networking/voting_handlers.go index ecc7402..4c7be62 100644 --- a/networking/voting_handlers.go +++ b/networking/voting_handlers.go @@ -366,9 +366,9 @@ func (s *Voting) PullQuery(validatorIDs ids.ShortSet, chainID ids.ID, requestID vID := validatorID if addr, exists := s.conns.GetIP(vID); exists { addrs = append(addrs, addr) - s.log.Verbo("Sending a PushQuery to %s", toIPDesc(addr)) + s.log.Verbo("Sending a PullQuery to %s", toIPDesc(addr)) } else { - s.log.Warn("Attempted to send a PushQuery message to a disconnected validator: %s", vID) + s.log.Warn("Attempted to send a PullQuery message to a disconnected validator: %s", vID) s.executor.Add(func() { s.router.QueryFailed(vID, chainID, requestID) }) } } diff --git a/utils/formatting/cb58_test.go b/utils/formatting/cb58_test.go index 74e7aae..7ecb09a 100644 --- a/utils/formatting/cb58_test.go +++ b/utils/formatting/cb58_test.go @@ -26,6 +26,59 @@ func TestCB58Single(t *testing.T) { } } +func TestCB58UnmarshalJSON(t *testing.T) { + expected := CB58{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}} + cb58 := CB58{} + err := cb58.UnmarshalJSON([]byte("\"1NVSVezva3bAtJesnUj\"")) + if err != nil { + t.Fatalf("CB58.UnmarshalJSON unexpected error unmarshalling: %s", err) + } else if !bytes.Equal(cb58.Bytes, expected.Bytes) { + t.Fatalf("CB58.UnmarshalJSON got 0x%x, expected 0x%x", cb58, expected) + } +} + +func TestCB58UnmarshalJSONNull(t *testing.T) { + cb58 := CB58{} + err := cb58.UnmarshalJSON([]byte("null")) + if err != nil { + t.Fatalf("CB58.UnmarshalJSON unexpected error unmarshalling null: %s", err) + } +} + +func TestCB58UnmarshalJSONError(t *testing.T) { + tests := []struct { + in string + expected error + }{ + {"", errMissingQuotes}, + {"\"foo", errMissingQuotes}, + {"foo", errMissingQuotes}, + {"foo\"", errMissingQuotes}, + {"\"foo\"", errMissingChecksum}, + {"\"foobar\"", errBadChecksum}, + } + cb58 := CB58{} + for _, tt := range tests { + t.Run(tt.in, func(t *testing.T) { + err := cb58.UnmarshalJSON([]byte(tt.in)) + if err != tt.expected { + t.Errorf("got error %q, expected error %q", err, tt.expected) + } + }) + } +} + +func TestCB58MarshalJSONError(t *testing.T) { + cb58 := CB58{[]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255}} + expected := []byte("\"1NVSVezva3bAtJesnUj\"") + result, err := cb58.MarshalJSON() + if err != nil { + t.Fatalf("CB58.MarshalJSON unexpected error: %s", err) + } else if !bytes.Equal(result, expected) { + t.Fatalf("CB58.MarshalJSON got %q, expected %q", result, expected) + } +} + func TestCB58ParseBytes(t *testing.T) { ui := "1NVSVezva3bAtJesnUj" cb58 := CB58{}