156 lines
3.4 KiB
Go
156 lines
3.4 KiB
Go
// SPDX-License-Identifier: EUPL-1.2
|
|
|
|
package primitives
|
|
|
|
import (
|
|
"bytes"
|
|
"testing"
|
|
)
|
|
|
|
type stubNameStateDB struct {
|
|
state *NameState
|
|
err error
|
|
}
|
|
|
|
func (db stubNameStateDB) GetNameState(hash Hash) (*NameState, error) {
|
|
if db.err != nil {
|
|
return nil, db.err
|
|
}
|
|
|
|
if db.state == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
cp := db.state.Clone()
|
|
cp.NameHash = hash
|
|
return &cp, nil
|
|
}
|
|
|
|
func TestNameViewGetNameState(t *testing.T) {
|
|
var hash Hash
|
|
hash[0] = 0x42
|
|
|
|
view := NewNameView()
|
|
db := stubNameStateDB{
|
|
state: &NameState{Name: []byte("example"), Height: 7},
|
|
}
|
|
|
|
ns, err := view.GetNameStateSync(db, hash)
|
|
if err != nil {
|
|
t.Fatalf("GetNameStateSync returned error: %v", err)
|
|
}
|
|
|
|
if ns == nil {
|
|
t.Fatal("GetNameStateSync returned nil state")
|
|
}
|
|
|
|
if ns.NameHash != hash {
|
|
t.Fatalf("GetNameStateSync returned hash %x, want %x", ns.NameHash, hash)
|
|
}
|
|
|
|
ns2, err := view.GetNameState(db, hash)
|
|
if err != nil {
|
|
t.Fatalf("GetNameState returned error: %v", err)
|
|
}
|
|
|
|
if ns2 != ns {
|
|
t.Fatal("GetNameState should return the cached state")
|
|
}
|
|
|
|
missingHash := Hash{0x99}
|
|
empty, err := view.GetNameState(nil, missingHash)
|
|
if err != nil {
|
|
t.Fatalf("GetNameState(nil) returned error: %v", err)
|
|
}
|
|
|
|
if empty == nil || empty.NameHash != missingHash {
|
|
t.Fatal("GetNameState(nil) should create an empty state with the requested hash")
|
|
}
|
|
}
|
|
|
|
func TestNameUndoRoundTrip(t *testing.T) {
|
|
var hash Hash
|
|
hash[0] = 0x51
|
|
|
|
view := NewNameView()
|
|
ns := &NameState{NameHash: hash, Name: []byte("example"), Height: 10}
|
|
ns.setValue(123)
|
|
view.names[hash] = ns
|
|
|
|
undo := view.ToNameUndo()
|
|
if len(undo.Names) != 1 {
|
|
t.Fatalf("ToNameUndo produced %d entries, want 1", len(undo.Names))
|
|
}
|
|
|
|
encoded, err := undo.MarshalBinary()
|
|
if err != nil {
|
|
t.Fatalf("MarshalBinary returned error: %v", err)
|
|
}
|
|
|
|
if got := undo.GetSize(); got != len(encoded) {
|
|
t.Fatalf("GetSize() = %d, want %d", got, len(encoded))
|
|
}
|
|
|
|
var decoded NameUndo
|
|
if err := decoded.UnmarshalBinary(encoded); err != nil {
|
|
t.Fatalf("UnmarshalBinary returned error: %v", err)
|
|
}
|
|
|
|
if len(decoded.Names) != 1 {
|
|
t.Fatalf("decoded undo has %d entries, want 1", len(decoded.Names))
|
|
}
|
|
|
|
if decoded.Names[0].NameHash != hash {
|
|
t.Fatalf("decoded hash %x, want %x", decoded.Names[0].NameHash, hash)
|
|
}
|
|
|
|
if !bytes.Equal(decoded.Names[0].Delta.MarshalMust(t), undo.Names[0].Delta.MarshalMust(t)) {
|
|
t.Fatal("decoded delta did not match the original")
|
|
}
|
|
}
|
|
|
|
func TestNameUndoPreservesInsertionOrder(t *testing.T) {
|
|
view := NewNameView()
|
|
|
|
var firstHash Hash
|
|
firstHash[0] = 0x01
|
|
|
|
var secondHash Hash
|
|
secondHash[0] = 0x02
|
|
|
|
first, err := view.GetNameStateSync(nil, firstHash)
|
|
if err != nil {
|
|
t.Fatalf("GetNameStateSync(first) returned error: %v", err)
|
|
}
|
|
first.setValue(11)
|
|
|
|
second, err := view.GetNameStateSync(nil, secondHash)
|
|
if err != nil {
|
|
t.Fatalf("GetNameStateSync(second) returned error: %v", err)
|
|
}
|
|
second.setValue(22)
|
|
|
|
undo := view.ToNameUndo()
|
|
if len(undo.Names) != 2 {
|
|
t.Fatalf("ToNameUndo produced %d entries, want 2", len(undo.Names))
|
|
}
|
|
|
|
if undo.Names[0].NameHash != firstHash {
|
|
t.Fatalf("first undo entry hash = %x, want %x", undo.Names[0].NameHash, firstHash)
|
|
}
|
|
|
|
if undo.Names[1].NameHash != secondHash {
|
|
t.Fatalf("second undo entry hash = %x, want %x", undo.Names[1].NameHash, secondHash)
|
|
}
|
|
}
|
|
|
|
func (d NameDelta) MarshalMust(t *testing.T) []byte {
|
|
t.Helper()
|
|
|
|
data, err := d.MarshalBinary()
|
|
if err != nil {
|
|
t.Fatalf("MarshalBinary returned error: %v", err)
|
|
}
|
|
|
|
return data
|
|
}
|