Commit 7f14e2cb authored by Kirill Smelkov's avatar Kirill Smelkov

go/zodb/fs1: tests: Factor-out commiting a transaction via ZODB/py into common place

We will soon need to be able to commit in tests for ZODB itself.
parent a6580062
...@@ -21,9 +21,15 @@ ...@@ -21,9 +21,15 @@
package xtesting package xtesting
import ( import (
"bytes"
"fmt"
"os"
"os/exec" "os/exec"
"sync" "sync"
"testing" "testing"
"lab.nexedi.com/kirr/go123/xerr"
"lab.nexedi.com/kirr/neo/go/zodb"
) )
var ( var (
...@@ -80,3 +86,45 @@ func NeedPy(t testing.TB, modules ...string) { ...@@ -80,3 +86,45 @@ func NeedPy(t testing.TB, modules ...string) {
// we verified everything - now it is ok not to skip. // we verified everything - now it is ok not to skip.
return return
} }
// ZRawObject represents raw ZODB object state.
type ZRawObject struct {
Oid zodb.Oid
Data []byte // raw serialized zodb data
}
// ZPyCommitRaw commits new transaction into database @ zurl with raw data specified by objv.
//
// The commit is performed via zodbtools/py.
func ZPyCommitRaw(zurl string, at zodb.Tid, objv ...ZRawObject) (_ zodb.Tid, err error) {
defer xerr.Contextf(&err, "%s: zpycommit @%s", zurl, at)
// prepare text input for `zodb commit`
zin := &bytes.Buffer{}
fmt.Fprintf(zin, "user %q\n", "author")
fmt.Fprintf(zin, "description %q\n", fmt.Sprintf("test commit; at=%s", at))
fmt.Fprintf(zin, "extension %q\n", "")
for _, obj := range objv {
fmt.Fprintf(zin, "obj %s %d null:00\n", obj.Oid, len(obj.Data))
zin.Write(obj.Data)
zin.WriteString("\n")
}
zin.WriteString("\n")
// run py `zodb commit`
cmd:= exec.Command("python2", "-m", "zodbtools.zodb", "commit", zurl, at.String())
cmd.Stdin = zin
cmd.Stderr = os.Stderr
out, err := cmd.Output()
if err != nil {
return zodb.InvalidTid, err
}
out = bytes.TrimSuffix(out, []byte("\n"))
tid, err := zodb.ParseTid(string(out))
if err != nil {
return zodb.InvalidTid, fmt.Errorf("committed, but invalid output: %s", err)
}
return tid, nil
}
...@@ -20,13 +20,10 @@ ...@@ -20,13 +20,10 @@
package fs1 package fs1
import ( import (
"bytes"
"context" "context"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"os"
"os/exec"
"reflect" "reflect"
"testing" "testing"
...@@ -34,7 +31,6 @@ import ( ...@@ -34,7 +31,6 @@ import (
"lab.nexedi.com/kirr/neo/go/zodb" "lab.nexedi.com/kirr/neo/go/zodb"
"lab.nexedi.com/kirr/go123/exc" "lab.nexedi.com/kirr/go123/exc"
"lab.nexedi.com/kirr/go123/xerr"
) )
// one database transaction record // one database transaction record
...@@ -354,6 +350,15 @@ func BenchmarkIterate(b *testing.B) { ...@@ -354,6 +350,15 @@ func BenchmarkIterate(b *testing.B) {
b.StopTimer() b.StopTimer()
} }
// b is syntatic sugar for byte literals.
//
// e.g.
//
// b("hello")
func b(data string) []byte {
return []byte(data)
}
// TestWatch verifies that watcher can observe commits done from outside. // TestWatch verifies that watcher can observe commits done from outside.
func TestWatch(t *testing.T) { func TestWatch(t *testing.T) {
X := exc.Raiseif X := exc.Raiseif
...@@ -362,54 +367,15 @@ func TestWatch(t *testing.T) { ...@@ -362,54 +367,15 @@ func TestWatch(t *testing.T) {
workdir := xworkdir(t) workdir := xworkdir(t)
tfs := workdir + "/t.fs" tfs := workdir + "/t.fs"
// Object represents object state to be committed. // xcommit commits new transaction into tfs with raw data specified by objv.
type Object struct { xcommit := func(at zodb.Tid, objv ...xtesting.ZRawObject) zodb.Tid {
oid zodb.Oid
data string
}
// zcommit commits new transaction into tfs with data specified by objv.
zcommit := func(at zodb.Tid, objv ...Object) (_ zodb.Tid, err error) {
defer xerr.Contextf(&err, "zcommit @%s", at)
// prepare text input for `zodb commit`
zin := &bytes.Buffer{}
fmt.Fprintf(zin, "user %q\n", "author")
fmt.Fprintf(zin, "description %q\n", fmt.Sprintf("test commit; at=%s", at))
fmt.Fprintf(zin, "extension %q\n", "")
for _, obj := range objv {
fmt.Fprintf(zin, "obj %s %d null:00\n", obj.oid, len(obj.data))
zin.WriteString(obj.data)
zin.WriteString("\n")
}
zin.WriteString("\n")
// run py `zodb commit`
cmd:= exec.Command("python2", "-m", "zodbtools.zodb", "commit", tfs, at.String())
cmd.Stdin = zin
cmd.Stderr = os.Stderr
out, err := cmd.Output()
if err != nil {
return zodb.InvalidTid, err
}
out = bytes.TrimSuffix(out, []byte("\n"))
tid, err := zodb.ParseTid(string(out))
if err != nil {
return zodb.InvalidTid, fmt.Errorf("committed, but invalid output: %s", err)
}
return tid, nil
}
xcommit := func(at zodb.Tid, objv ...Object) zodb.Tid {
t.Helper() t.Helper()
tid, err := zcommit(at, objv...); X(err) tid, err := xtesting.ZPyCommitRaw(tfs, at, objv...); X(err)
return tid return tid
} }
// force tfs creation & open tfs at go side // force tfs creation & open tfs at go side
at := xcommit(0, Object{0, "data0"}) at := xcommit(0, xtesting.ZRawObject{0, b("data0")})
watchq := make(chan zodb.CommitEvent) watchq := make(chan zodb.CommitEvent)
fs, at0 := xfsopenopt(t, tfs, &zodb.DriverOptions{ReadOnly: true, Watchq: watchq}) fs, at0 := xfsopenopt(t, tfs, &zodb.DriverOptions{ReadOnly: true, Watchq: watchq})
...@@ -453,8 +419,8 @@ func TestWatch(t *testing.T) { ...@@ -453,8 +419,8 @@ func TestWatch(t *testing.T) {
data0 := fmt.Sprintf("data0.%d", i) data0 := fmt.Sprintf("data0.%d", i)
datai := fmt.Sprintf("data%d", i) datai := fmt.Sprintf("data%d", i)
at = xcommit(at, at = xcommit(at,
Object{0, data0}, xtesting.ZRawObject{0, b(data0)},
Object{i, datai}) xtesting.ZRawObject{i, b(datai)})
// TODO also test for watcher errors // TODO also test for watcher errors
e := <-watchq e := <-watchq
......
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