221 lines
6.0 KiB
Go
221 lines
6.0 KiB
Go
package graviton
|
|
|
|
import (
|
|
"fmt"
|
|
// "io/ioutil"
|
|
// "os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var dddd_ = time.Now()
|
|
|
|
// this tests the version tree dag
|
|
// this loading of versions and whether they can be accessed and then moved forward
|
|
func TestSnapshotDAG(t *testing.T) {
|
|
|
|
store, err := NewMemStore()
|
|
require.NoError(t, err)
|
|
|
|
loop_count := uint64(5)
|
|
// now lets commit the tree 5 times
|
|
for i := uint64(0); i < loop_count; i++ {
|
|
|
|
gv, err := store.LoadSnapshot(0)
|
|
require.NoError(t, err)
|
|
|
|
tree, err := gv.GetTree("root")
|
|
require.NoError(t, err)
|
|
require.Equal(t, i, tree.snapshot_version)
|
|
|
|
key := []byte(fmt.Sprintf("%d", i+1))
|
|
value := []byte(fmt.Sprintf("%d", i+1))
|
|
require.NoError(t, tree.Put(key, value))
|
|
|
|
commit_version, err := Commit(tree)
|
|
require.NoError(t, err)
|
|
require.Equal(t, i+1, commit_version)
|
|
require.Equal(t, i+1, tree.snapshot_version)
|
|
require.Equal(t, i+1, tree.GetVersion())
|
|
|
|
}
|
|
|
|
for i := uint64(0); i < loop_count; i++ {
|
|
|
|
gv, err := store.LoadSnapshot(i + 1)
|
|
require.NoError(t, err)
|
|
|
|
tree, err := gv.GetTree("root")
|
|
require.NoError(t, err)
|
|
|
|
for j := uint64(0); j < i; j++ {
|
|
key := []byte(fmt.Sprintf("%d", j+1))
|
|
value := []byte(fmt.Sprintf("%d", j+1))
|
|
|
|
value_actual, err := tree.Get(key)
|
|
if err != nil {
|
|
fmt.Printf("value result failed j %d\n", j)
|
|
}
|
|
require.NoError(t, err)
|
|
require.Equal(t, value, value_actual)
|
|
}
|
|
}
|
|
|
|
gv, err := store.LoadSnapshot(5)
|
|
require.NoError(t, err)
|
|
|
|
highest_version, err := gv.GetTreeHighestVersion("root")
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(5), highest_version)
|
|
|
|
// now lets test we can move past in history
|
|
gv, err = store.LoadSnapshot(3)
|
|
require.NoError(t, err)
|
|
|
|
tree, err := gv.GetTree("root")
|
|
require.NoError(t, err)
|
|
|
|
key := []byte(fmt.Sprintf("%d", 4))
|
|
value := []byte(fmt.Sprintf("%d", 4))
|
|
require.NoError(t, tree.Put(key, value))
|
|
commit_version, err := Commit(tree)
|
|
require.NoError(t, err)
|
|
require.Equal(t, uint64(6), commit_version) // 5 version committed earlier
|
|
require.Equal(t, uint64(6), tree.snapshot_version)
|
|
require.Equal(t, uint64(4), tree.GetVersion()) // tree version should be 4
|
|
|
|
}
|
|
|
|
// this tests various treename entry points
|
|
func TestTreeNameLimit(t *testing.T) {
|
|
|
|
store, err := NewMemStore()
|
|
require.NoError(t, err)
|
|
gv, err := store.LoadSnapshot(0)
|
|
require.NoError(t, err)
|
|
colonname := ":root"
|
|
longname := "11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111"
|
|
|
|
tree, err := gv.GetTree(colonname)
|
|
require.Error(t, err)
|
|
tree, err = gv.GetTree(longname)
|
|
require.Error(t, err)
|
|
|
|
tree, err = gv.GetTreeWithVersion(colonname, 0)
|
|
require.Error(t, err)
|
|
|
|
gv.putTreeHighestVersion(colonname, 0)
|
|
|
|
_ = tree
|
|
|
|
}
|
|
|
|
func TestGetTreeHighestVersion(t *testing.T) {
|
|
store, err := NewMemStore()
|
|
require.NoError(t, err)
|
|
gv, err := store.LoadSnapshot(0)
|
|
require.NoError(t, err)
|
|
colonname := ":root"
|
|
|
|
var faulty_uvarint = [12]byte{0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88}
|
|
|
|
gv.vroot.Insert(gv.store, newLeaf(sum([]byte(colonname)), []byte(colonname), faulty_uvarint[:])) // we have inserted faulty data,
|
|
// lets call back and check whether its detected
|
|
|
|
_, err = gv.GetTreeHighestVersion("root")
|
|
require.Error(t, err)
|
|
|
|
_, _, err = store.loadrootusingpos(0, 1) // no bytes to read and thus error
|
|
require.Error(t, err) //
|
|
|
|
// more tests
|
|
var faulty_inner = [512]byte{3, 5, 99, 0}
|
|
findex, fpos, err := store.write(faulty_inner[:4])
|
|
require.NoError(t, err)
|
|
|
|
encode(findex, fpos, faulty_inner[:]) // inject this into vroot
|
|
gv.vroot.Insert(gv.store, newLeaf(sum([]byte(colonname)), []byte(colonname), faulty_inner[:]))
|
|
// lets call back and check whether its detected
|
|
_, err = gv.loadTree([]byte(colonname))
|
|
|
|
require.Error(t, err)
|
|
|
|
_, err = gv.loadTree([]byte("treedoesnotexist"))
|
|
require.Error(t, err)
|
|
|
|
}
|
|
|
|
/*
|
|
func TestIwriteVersionData(t *testing.T) {
|
|
store, err := NewMemStore()
|
|
require.NoError(t, err)
|
|
store.versionrootfile.Close()
|
|
require.Error(t, store.writeVersionData(0, 0, 0))
|
|
}
|
|
*/
|
|
|
|
func TestLoadSnapshot(t *testing.T) {
|
|
store, err := NewMemStore()
|
|
require.NoError(t, err)
|
|
_, err = store.LoadSnapshot(99) // trigger version is higher than available error
|
|
require.Error(t, err)
|
|
|
|
// now lets commit the tree 5 times
|
|
loop_count := uint64(5)
|
|
for i := uint64(0); i < loop_count; i++ {
|
|
gv, err := store.LoadSnapshot(0)
|
|
require.NoError(t, err)
|
|
|
|
tree, err := gv.GetTree("root")
|
|
require.NoError(t, err)
|
|
require.Equal(t, i, tree.snapshot_version)
|
|
|
|
key := []byte(fmt.Sprintf("%d", i+1))
|
|
value := []byte(fmt.Sprintf("%d", i+1))
|
|
require.NoError(t, tree.Put(key, value))
|
|
|
|
_, err = Commit(tree)
|
|
require.NoError(t, err)
|
|
}
|
|
|
|
//fmt.Printf("error %s\n", store.loadsnapshottablestoram())
|
|
|
|
store.versionrootfile.memoryfile[(loop_count-1)*8+7] = 1 // corrupt last entry
|
|
store.versionrootfile.memoryfile[(loop_count-2)*8+7] = 1 // corrupt second last entry
|
|
|
|
_, err = store.LoadSnapshot(0) // trigger recent version corruption
|
|
require.Error(t, err)
|
|
_, err = store.LoadSnapshot(4) // trigger second last version corruption
|
|
require.Error(t, err)
|
|
/*
|
|
store.version_data[24] = 2
|
|
store.version_data[24+16] = 1
|
|
_, err = store.LoadSnapshot(1) // trigger recent version corruption
|
|
require.Error(t, err)
|
|
|
|
_, _, err = store.write([]byte{3, 0, 0, 0}) // write empty inner record
|
|
_, err = store.LoadSnapshot(1) // trigger recent version corruption
|
|
require.Error(t, err)
|
|
*/
|
|
|
|
// create a complex error, where deep error is created using internal structures
|
|
store, err = NewMemStore()
|
|
require.NoError(t, err)
|
|
gv, err := store.LoadSnapshot(0)
|
|
require.NoError(t, err)
|
|
tree, err := gv.GetTree("root")
|
|
require.NoError(t, err)
|
|
|
|
var zerobuf [66000]byte
|
|
tree.Put([]byte{44}, zerobuf[:])
|
|
require.NoError(t, tree.Commit()) // version 1
|
|
tree.Put([]byte{3}, zerobuf[:]) // this also tests a leaf whether large size load for leafs work correctly
|
|
require.NoError(t, tree.Commit()) // version 2
|
|
|
|
gv, err = store.LoadSnapshot(0)
|
|
require.NoError(t, err)
|
|
|
|
}
|