Commit 44348ada authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 2b69c86d
...@@ -24,6 +24,7 @@ import ( ...@@ -24,6 +24,7 @@ import (
"bytes" "bytes"
"context" "context"
"fmt" "fmt"
"io"
"net/url" "net/url"
"os" "os"
"os/exec" "os/exec"
...@@ -149,6 +150,63 @@ type Txn struct { ...@@ -149,6 +150,63 @@ type Txn struct {
Data []*zodb.DataInfo 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 // checkLoad verifies that zdrv.Load(xid) returns expected result
func checkLoad(t *testing.T, zdrv zodb.IStorageDriver, xid zodb.Xid, expect objState) { func checkLoad(t *testing.T, zdrv zodb.IStorageDriver, xid zodb.Xid, expect objState) {
t.Helper() t.Helper()
...@@ -348,3 +406,10 @@ func DrvTestWatch(t *testing.T, zurl string, zdrvOpen zodb.DriverOpener) { ...@@ -348,3 +406,10 @@ func DrvTestWatch(t *testing.T, zurl string, zdrvOpen zodb.DriverOpener) {
func b(data string) []byte { func b(data string) []byte {
return []byte(data) 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
}
...@@ -22,11 +22,14 @@ package zeo ...@@ -22,11 +22,14 @@ package zeo
import ( import (
"context" "context"
"io/ioutil" "io/ioutil"
"net/url"
"os" "os"
"os/exec" "os/exec"
"testing" "testing"
"lab.nexedi.com/kirr/neo/go/internal/xtesting" "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/exc"
"lab.nexedi.com/kirr/go123/xerr" "lab.nexedi.com/kirr/go123/xerr"
...@@ -78,14 +81,43 @@ func (z *ZEOPySrv) Close() (err error) { ...@@ -78,14 +81,43 @@ func (z *ZEOPySrv) Close() (err error) {
} }
func TestWatch(t *testing.T) { // --------
func TestLoad(t *testing.T) {
X := exc.Raiseif X := exc.Raiseif
xtesting.NeedPy(t, "ZEO") // XXX +msgpack? needZEOpy(t)
work := xtempdir(t) work := xtempdir(t)
defer os.RemoveAll(work) 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" fs1path := work + "/1.fs"
zpy, err := StartZEOPySrv(fs1path); X(err) zpy, err := StartZEOPySrv(fs1path); X(err)
defer func() { defer func() {
err := zpy.Close(); X(err) err := zpy.Close(); X(err)
...@@ -95,6 +127,21 @@ func TestWatch(t *testing.T) { ...@@ -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 { func xtempdir(t *testing.T) string {
t.Helper() t.Helper()
tmpd, err := ioutil.TempDir("", "zeo") tmpd, err := ioutil.TempDir("", "zeo")
...@@ -103,3 +150,8 @@ func xtempdir(t *testing.T) string { ...@@ -103,3 +150,8 @@ func xtempdir(t *testing.T) string {
} }
return tmpd return tmpd
} }
func needZEOpy(t *testing.T) {
xtesting.NeedPy(t, "ZEO") // XXX +msgpack?
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment