mirror of
https://github.com/vocdoni/arbo.git
synced 2026-01-08 21:37:57 -05:00
Update Snapshot & Root approach to get the root always from the db, except in the cases that the tree is a snapshot, in which the root will be in memory. In this way, when a snapshot is performed and the original tree gets modifyed, the snapshot will still point to the old root. Also, the root obtained from the db, uses also the db.ReadTx, so if the root is being modifyied in the current tx (db.WriteTx), when getting the root it will be return the lastest version that is in the tx but not yet in the db.
120 lines
2.7 KiB
Go
120 lines
2.7 KiB
Go
package arbo
|
|
|
|
import (
|
|
"bytes"
|
|
"io"
|
|
"io/ioutil"
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
qt "github.com/frankban/quicktest"
|
|
"go.vocdoni.io/dvote/db/badgerdb"
|
|
)
|
|
|
|
func checkRoots(c *qt.C, tree1, tree2 *Tree) {
|
|
root1, err := tree1.Root()
|
|
c.Assert(err, qt.IsNil)
|
|
root2, err := tree2.Root()
|
|
c.Assert(err, qt.IsNil)
|
|
if !bytes.Equal(root2, root1) {
|
|
dir := "err-dump"
|
|
if _, err := os.Stat(dir); os.IsNotExist(err) {
|
|
err := os.Mkdir(dir, os.ModePerm)
|
|
c.Assert(err, qt.IsNil)
|
|
}
|
|
// store tree1
|
|
storeTree(c, tree1, dir+"/tree1")
|
|
|
|
// store tree2
|
|
storeTree(c, tree2, dir+"/tree2")
|
|
|
|
root1, err := tree1.Root()
|
|
c.Assert(err, qt.IsNil)
|
|
root2, err := tree2.Root()
|
|
c.Assert(err, qt.IsNil)
|
|
c.Check(root2, qt.DeepEquals, root1)
|
|
}
|
|
}
|
|
|
|
func storeTree(c *qt.C, tree *Tree, path string) {
|
|
dump, err := tree.Dump(nil)
|
|
c.Assert(err, qt.IsNil)
|
|
err = ioutil.WriteFile(path+"-"+time.Now().String()+".debug", dump, 0600)
|
|
c.Assert(err, qt.IsNil)
|
|
}
|
|
|
|
// nolint:unused
|
|
func readTree(c *qt.C, tree *Tree, path string) {
|
|
b, err := ioutil.ReadFile(path) //nolint:gosec
|
|
c.Assert(err, qt.IsNil)
|
|
err = tree.ImportDump(b)
|
|
c.Assert(err, qt.IsNil)
|
|
}
|
|
|
|
// nolint:unused
|
|
func importDumpLoopAdd(tree *Tree, b []byte) error {
|
|
r := bytes.NewReader(b)
|
|
var err error
|
|
for {
|
|
l := make([]byte, 2)
|
|
_, err = io.ReadFull(r, l)
|
|
if err == io.EOF {
|
|
break
|
|
} else if err != nil {
|
|
return err
|
|
}
|
|
k := make([]byte, l[0])
|
|
_, err = io.ReadFull(r, k)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
v := make([]byte, l[1])
|
|
_, err = io.ReadFull(r, v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = tree.Add(k, v)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestReadTreeDBG(t *testing.T) {
|
|
t.Skip() // test just for debugging purposes, disabled by default
|
|
|
|
c := qt.New(t)
|
|
|
|
database1, err := badgerdb.New(badgerdb.Options{Path: c.TempDir()})
|
|
c.Assert(err, qt.IsNil)
|
|
tree1, err := NewTree(database1, 100, HashFunctionBlake2b)
|
|
c.Assert(err, qt.IsNil)
|
|
|
|
database2, err := badgerdb.New(badgerdb.Options{Path: c.TempDir()})
|
|
c.Assert(err, qt.IsNil)
|
|
tree2, err := NewTree(database2, 100, HashFunctionBlake2b)
|
|
c.Assert(err, qt.IsNil)
|
|
|
|
// tree1 is generated by a loop of .Add
|
|
path := "err-dump/tree1-2021-06-03 16:45:54.104449306 +0200 CEST m=+0.073874545.debug"
|
|
b, err := ioutil.ReadFile(path)
|
|
c.Assert(err, qt.IsNil)
|
|
err = importDumpLoopAdd(tree1, b)
|
|
c.Assert(err, qt.IsNil)
|
|
|
|
// tree2 is generated by .AddBatch
|
|
path = "err-dump/tree2-2021-06-03 16:45:54.104525519 +0200 CEST m=+0.073950756.debug"
|
|
readTree(c, tree2, path)
|
|
|
|
// tree1.PrintGraphvizFirstNLevels(nil, 6)
|
|
// tree2.PrintGraphvizFirstNLevels(nil, 6)
|
|
|
|
root1, err := tree1.Root()
|
|
c.Assert(err, qt.IsNil)
|
|
root2, err := tree2.Root()
|
|
c.Assert(err, qt.IsNil)
|
|
c.Check(root2, qt.DeepEquals, root1)
|
|
}
|