From 44348ada78b2bc8db54c2aaf58ec86861702bf6a Mon Sep 17 00:00:00 2001 From: Kirill Smelkov <kirr@nexedi.com> Date: Sun, 5 Jul 2020 21:49:43 +0300 Subject: [PATCH] . --- go/internal/xtesting/xtesting.go | 65 ++++++++++++++++++++++++++++++++ go/zodb/storage/zeo/zeo_test.go | 56 ++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 2 deletions(-) diff --git a/go/internal/xtesting/xtesting.go b/go/internal/xtesting/xtesting.go index 76260404..52cb6933 100644 --- a/go/internal/xtesting/xtesting.go +++ b/go/internal/xtesting/xtesting.go @@ -24,6 +24,7 @@ import ( "bytes" "context" "fmt" + "io" "net/url" "os" "os/exec" @@ -149,6 +150,63 @@ type Txn struct { Data []*zodb.DataInfo } +// LoadDB loads whole content of a ZODB database. +// it returns full history of all transactions with committed data. +func LoadDB(zurl string) (_ []Txn, err error) { + xerr.Contextf(&err, "loaddb %s", zurl) + ctx := context.Background() + zstor, err := zodb.Open(ctx, zurl, &zodb.OpenOptions{ReadOnly: true}) + if err != nil { + return nil, err + } + defer func() { + err2 := zstor.Close() + if err == nil { + err = err2 + } + }() + + txnv := []Txn{} + it := zstor.Iterate(ctx, 0, zodb.TidMax) + for { + txni, dataIt, err := it.NextTxn(ctx) + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + txn := &Txn{Header: &zodb.TxnInfo{ + // clone (txni stays valid only until next iteration) + Tid: txni.Tid, + Status: txni.Status, + User: bcopy(txni.User), + Description: bcopy(txni.Description), + Extension: bcopy(txni.Extension), + }} + + for { + datai, err := dataIt.NextData(ctx) + if err != nil { + if err == io.EOF { + break + } + return nil, err + } + + txn.Data = append(txn.Data, &zodb.DataInfo{ + // clone (datai stays valid only until next iteration) + Oid: datai.Oid, + Tid: datai.Tid, + Data: bcopy(datai.Data), + DataTidHint: datai.DataTidHint, + }) + } + } + + return txnv, nil +} + // checkLoad verifies that zdrv.Load(xid) returns expected result func checkLoad(t *testing.T, zdrv zodb.IStorageDriver, xid zodb.Xid, expect objState) { t.Helper() @@ -348,3 +406,10 @@ func DrvTestWatch(t *testing.T, zurl string, zdrvOpen zodb.DriverOpener) { func b(data string) []byte { return []byte(data) } + +// bcopy makes a clone of byte slice. +func bcopy(data []byte) []byte { + d2 := make([]byte, len(data)) + copy(d2, data) + return d2 +} diff --git a/go/zodb/storage/zeo/zeo_test.go b/go/zodb/storage/zeo/zeo_test.go index e5aab0ab..1a949a57 100644 --- a/go/zodb/storage/zeo/zeo_test.go +++ b/go/zodb/storage/zeo/zeo_test.go @@ -22,11 +22,14 @@ package zeo import ( "context" "io/ioutil" + "net/url" "os" "os/exec" "testing" "lab.nexedi.com/kirr/neo/go/internal/xtesting" + "lab.nexedi.com/kirr/neo/go/zodb" + _ "lab.nexedi.com/kirr/neo/go/zodb/storage/fs1" "lab.nexedi.com/kirr/go123/exc" "lab.nexedi.com/kirr/go123/xerr" @@ -78,14 +81,43 @@ func (z *ZEOPySrv) Close() (err error) { } -func TestWatch(t *testing.T) { +// -------- + +func TestLoad(t *testing.T) { X := exc.Raiseif - xtesting.NeedPy(t, "ZEO") // XXX +msgpack? + needZEOpy(t) work := xtempdir(t) defer os.RemoveAll(work) + fs1path := work + "/1.fs" + + // copy ../fs1/testdata/1.fs -> fs1path + data, err := ioutil.ReadFile("../fs1/testdata/1.fs"); X(err) + err = ioutil.WriteFile(fs1path, data, 0644); X(err) + + txnvOk, err := xtesting.LoadDB(fs1path); X(err) + + zpy, err := StartZEOPySrv(fs1path); X(err) + defer func() { + err := zpy.Close(); X(err) + }() + + z, _, err := zeoOpen(zpy.zaddr(), &zodb.DriverOptions{ReadOnly: true}); X(err) + defer func() { + err := z.Close(); X(err) + }() + + xtesting.DrvTestLoad(t, z, txnvOk) +} + +func TestWatch(t *testing.T) { + X := exc.Raiseif + needZEOpy(t) + work := xtempdir(t) + defer os.RemoveAll(work) fs1path := work + "/1.fs" + zpy, err := StartZEOPySrv(fs1path); X(err) defer func() { err := zpy.Close(); X(err) @@ -95,6 +127,21 @@ func TestWatch(t *testing.T) { } +func zeoOpen(zurl string, opt *zodb.DriverOptions) (_ *zeo, at0 zodb.Tid, err error) { + defer xerr.Contextf(&err, "openzeo %s", zurl) + u, err := url.Parse(zurl) + if err != nil { + return nil, 0, err + } + + z, at0, err := openByURL(context.Background(), u, opt) + if err != nil { + return nil, 0, err + } + + return z.(*zeo), at0, nil +} + func xtempdir(t *testing.T) string { t.Helper() tmpd, err := ioutil.TempDir("", "zeo") @@ -103,3 +150,8 @@ func xtempdir(t *testing.T) string { } return tmpd } + + +func needZEOpy(t *testing.T) { + xtesting.NeedPy(t, "ZEO") // XXX +msgpack? +} -- 2.30.9