mirror of https://github.com/poanetwork/gecko.git
219 lines
5.2 KiB
Go
219 lines
5.2 KiB
Go
// (c) 2019-2020, Ava Labs, Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package ids
|
|
|
|
import (
|
|
"bytes"
|
|
"reflect"
|
|
"testing"
|
|
)
|
|
|
|
func TestID(t *testing.T) {
|
|
hash := [32]byte{24}
|
|
id := NewID(hash)
|
|
|
|
if key := id.Key(); !bytes.Equal(hash[:], key[:]) {
|
|
t.Fatalf("ID.Key returned wrong bytes")
|
|
}
|
|
|
|
prefixed := id.Prefix(0)
|
|
|
|
if key := id.Key(); !bytes.Equal(hash[:], key[:]) {
|
|
t.Fatalf("ID.Prefix mutated the ID")
|
|
}
|
|
|
|
if nextPrefix := id.Prefix(0); !prefixed.Equals(nextPrefix) {
|
|
t.Fatalf("ID.Prefix not consistant")
|
|
}
|
|
|
|
if b := id.Bytes(); !bytes.Equal(hash[:], b) {
|
|
t.Fatalf("ID.Bytes returned wrong bytes")
|
|
}
|
|
}
|
|
|
|
func TestIDBit(t *testing.T) {
|
|
id0 := NewID([32]byte{1 << 0})
|
|
id1 := NewID([32]byte{1 << 1})
|
|
id2 := NewID([32]byte{1 << 2})
|
|
id3 := NewID([32]byte{1 << 3})
|
|
id4 := NewID([32]byte{1 << 4})
|
|
id5 := NewID([32]byte{1 << 5})
|
|
id6 := NewID([32]byte{1 << 6})
|
|
id7 := NewID([32]byte{1 << 7})
|
|
id8 := NewID([32]byte{0, 1 << 0})
|
|
|
|
if id0.Bit(0) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id1.Bit(1) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id2.Bit(2) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id3.Bit(3) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id4.Bit(4) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id5.Bit(5) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id6.Bit(6) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id7.Bit(7) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
} else if id8.Bit(8) != 1 {
|
|
t.Fatalf("Wrong bit")
|
|
}
|
|
}
|
|
|
|
func TestFromString(t *testing.T) {
|
|
key := [32]byte{'a', 'v', 'a', ' ', 'l', 'a', 'b', 's'}
|
|
id := NewID(key)
|
|
idStr := id.String()
|
|
id2, err := FromString(idStr)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if id.Key() != id2.Key() {
|
|
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 := "617661206c616273000000000000000000000000000000000000000000000000"
|
|
actual := id.Hex()
|
|
if actual != expected {
|
|
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")
|
|
}
|
|
}
|