Commit 76f7e270 authored by Kirill Smelkov's avatar Kirill Smelkov

wcfs: zdata: Test ZBlk loading on all py2/py3 ZODB kinds of data we care about

Previously we were testing ZBlk loading on Go side only with data generated by
python2 and pickle protocol=2. However even on py2 there are more pickle
protocols that are in use, and also there is python3.

-> Modernize testdata/zblk_test_gen.py to use run_with_all_zodb_pickle_kinds
   that was recently added as part of nexedi/zodbtools@f9d36ba7
   and generate test data with both python2 and python3. It is handy to
   use py2py3-venv(*) to prepare python environment to do that.

   Adjust tests on Go side to verify how ZBlk is loaded for all generated zkinds.

py2_pickle1, py2_pickle2 and py2_pickle3 are handled well.
ZBlk test for py3_pickle3 currently fails with

        --- FAIL: TestZBlk/py3_pickle3 (0.01s)
    panic: ZBlk0(0000000000000002): loadBlkData: wendelin.bigfile.file_zodb.ZBlk0(0000000000000002): activate: pysetstate: expect str; got ogórek.Bytes [recovered]

and so is marked with "xfail".

We will fix tests for py3_pickle3 in follow-up patches.

(*) see nexedi/zodbtools@fac2f190
parent db6fea3d
/*.lock *.lock
/*.tmp *.tmp
/*.tr[0-9] *.tr[0-9]
#!/usr/bin/env python2 #!/usr/bin/env python
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
# Copyright (C) 2018-2021 Nexedi SA and Contributors. # Copyright (C) 2018-2024 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com> # Kirill Smelkov <kirr@nexedi.com>
# #
# This program is free software: you can Use, Study, Modify and Redistribute # This program is free software: you can Use, Study, Modify and Redistribute
...@@ -20,25 +20,33 @@ ...@@ -20,25 +20,33 @@
# See https://www.nexedi.com/licensing for rationale and options. # See https://www.nexedi.com/licensing for rationale and options.
"""zblk_test_gen.py generates test data for zblk_test.go""" """zblk_test_gen.py generates test data for zblk_test.go"""
from __future__ import print_function
from ZODB.DB import DB from ZODB.DB import DB
from ZODB.utils import u64 from ZODB.utils import u64
from wendelin.bigfile.file_zodb import ZBlk0, ZBlk1, ZBigFile from wendelin.bigfile.file_zodb import ZBlk0, ZBlk1, ZBigFile
from BTrees.IOBTree import IOBTree, IOBucket from BTrees.IOBTree import IOBTree, IOBucket
from numpy import arange from numpy import arange
import os, os.path, transaction import os, os.path, shutil, transaction
import zodbtools.test.gen_testdata # to make time predictable import zodbtools.test.gen_testdata # to make time predictable
from zodbtools.test.gen_testdata import run_with_zodb4py2_compat from zodbtools.test.gen_testdata import run_with_all_zodb_pickle_kinds, current_zkind, xtime_reset
K = 1024 K = 1024
def main(): def main():
run_with_zodb4py2_compat(main2) run_with_all_zodb_pickle_kinds(main2)
def main2(): def main2():
outfs = "testdata/zblk.fs" xtime_reset()
rm_f(outfs)
rm_f(outfs + ".index") zkind = current_zkind()
prefix = "testdata/%s" % zkind
if os.path.exists(prefix):
shutil.rmtree(prefix)
os.makedirs(prefix)
outfs = "%s/zblk.fs" % prefix
db = DB(outfs) db = DB(outfs)
conn = db.open() conn = db.open()
root = conn.root() root = conn.root()
...@@ -67,22 +75,27 @@ def main2(): ...@@ -67,22 +75,27 @@ def main2():
transaction.commit() transaction.commit()
with open("ztestdata_zblk_test.go", "w") as f: with open("ztestdata_zblk_%s_test.go" % zkind, "w") as f:
def emit(v): def emit(v):
print >>f, v print(v, file=f)
emit("// Code generated by %s; DO NOT EDIT." % __file__) emit("// Code generated by %s; DO NOT EDIT." % os.path.relpath(__file__))
emit("package zdata\n") emit("package zdata\n")
emit('import "lab.nexedi.com/kirr/neo/go/zodb"\n') emit('import "lab.nexedi.com/kirr/neo/go/zodb"\n')
emit("const zf_blksize = %d" % zf.blksize) emit("func init() {")
emit("const zf_size = %d" % ((zf.blktab.maxKey()+1)*zf.blksize)) emit('\tzblkTestDataRegistry["%s"] = ZBlkTestData{' % zkind)
emit("const z0_oid = zodb.Oid(%d)" % u64(z0._p_oid)) emit('\t\tdata_fs : "%s",' % outfs)
emit("const z1_oid = zodb.Oid(%d)" % u64(z1._p_oid)) emit("\t\tzf_blksize : %d," % zf.blksize)
emit("const zf_oid = zodb.Oid(%d)" % u64(zf._p_oid)) emit("\t\tzf_size : %d," % ((zf.blktab.maxKey()+1)*zf.blksize))
emit("const z0_rev = zodb.Tid(0x%x)" % u64(z0._p_serial)) emit("\t\tz0_oid : zodb.Oid(%d)," % u64(z0._p_oid))
emit("const z1_rev = zodb.Tid(0x%x)" % u64(z1._p_serial)) emit("\t\tz1_oid : zodb.Oid(%d)," % u64(z1._p_oid))
emit("const z0_len = %d" % len(z0.loadblkdata())) emit("\t\tzf_oid : zodb.Oid(%d)," % u64(zf._p_oid))
emit("const z1_htlen = %d" % z1ht) emit("\t\tz0_rev : zodb.Tid(0x%x)," % u64(z0._p_serial))
emit("\t\tz1_rev : zodb.Tid(0x%x)," % u64(z1._p_serial))
emit("\t\tz0_len : %d," % len(z0.loadblkdata()))
emit("\t\tz1_htlen : %d," % z1ht)
emit("\t}")
emit("}")
conn.close() conn.close()
...@@ -119,11 +132,6 @@ def assertIOBTreeHas2Buckets(t): ...@@ -119,11 +132,6 @@ def assertIOBTreeHas2Buckets(t):
assert isinstance(_[0][2], IOBucket), _[0][2] # bucket1 assert isinstance(_[0][2], IOBucket), _[0][2] # bucket1
assert isinstance(_[1], IOBucket), _[1] # .firstbucket assert isinstance(_[1], IOBucket), _[1] # .firstbucket
# rm_f is like `rm -f` in shell.
def rm_f(path):
if os.path.exists(path):
os.remove(path)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
// Copyright (C) 2018-2021 Nexedi SA and Contributors. // Copyright (C) 2018-2024 Nexedi SA and Contributors.
// Kirill Smelkov <kirr@nexedi.com> // Kirill Smelkov <kirr@nexedi.com>
// //
// This program is free software: you can Use, Study, Modify and Redistribute // This program is free software: you can Use, Study, Modify and Redistribute
...@@ -19,12 +19,14 @@ ...@@ -19,12 +19,14 @@
package zdata package zdata
//go:generate ./testdata/zblk_test_gen.py //go:generate python2 ./testdata/zblk_test_gen.py
//go:generate python3 ./testdata/zblk_test_gen.py
import ( import (
"bytes" "bytes"
"context" "context"
"encoding/binary" "encoding/binary"
"sort"
"testing" "testing"
"lab.nexedi.com/kirr/go123/exc" "lab.nexedi.com/kirr/go123/exc"
...@@ -35,13 +37,49 @@ import ( ...@@ -35,13 +37,49 @@ import (
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// ZBlkTestData describes one ZBlk test data generated by zblk_test_gen.py for particular zkind .
type ZBlkTestData struct {
data_fs string // e.g. "testdata/zblk-py2-pickle3.fs"
zf_blksize int64 // root.zbigf.blksize
zf_size int64 // size of zbigf data
z0_oid zodb.Oid // oid of root.zblk0
z1_oid zodb.Oid // oid of root.zblk1
zf_oid zodb.Oid // oid of root.zbigf
z0_rev zodb.Tid // serial of zblk0
z1_rev zodb.Tid // serial of zblk1
z0_len int // len of zblk0 data
z1_htlen int // len of head and tail in zblk1
}
// each generated testdata kind is registered in zblkTestDataRegistry.
var zblkTestDataRegistry = map[/*zkind*/string]ZBlkTestData{}
// TestZBlk verifies that ZBlk* and ZBigFile saved by Python can be read correctly by Go. // TestZBlk verifies that ZBlk* and ZBigFile saved by Python can be read correctly by Go.
// TODO also test with data saved by Python3.
func TestZBlk(t *testing.T) { func TestZBlk(t *testing.T) {
// run the test for all generated testdata kinds
zkindv := []string{}
for zkind := range zblkTestDataRegistry {
zkindv = append(zkindv, zkind)
}
sort.Strings(zkindv)
for _, zkind := range zkindv {
z := zblkTestDataRegistry[zkind]
t.Run(zkind, func(t *testing.T) {
if zkind == "py3_pickle3" {
t.Skip("xfail")
}
_TestZBlk(t, z)
})
}
}
func _TestZBlk(t *testing.T, z ZBlkTestData) {
X := exc.Raiseif X := exc.Raiseif
assert := require.New(t) assert := require.New(t)
ctx := context.Background() ctx := context.Background()
stor, err := zodb.Open(ctx, "testdata/zblk.fs", &zodb.OpenOptions{ReadOnly: true}); X(err) stor, err := zodb.Open(ctx, z.data_fs, &zodb.OpenOptions{ReadOnly: true}); X(err)
db := zodb.NewDB(stor, &zodb.DBOptions{}) db := zodb.NewDB(stor, &zodb.DBOptions{})
defer func() { defer func() {
err := db.Close(); X(err) err := db.Close(); X(err)
...@@ -53,9 +91,9 @@ func TestZBlk(t *testing.T) { ...@@ -53,9 +91,9 @@ func TestZBlk(t *testing.T) {
conn, err := db.Open(ctx, &zodb.ConnOptions{}); X(err) conn, err := db.Open(ctx, &zodb.ConnOptions{}); X(err)
xz0, err := conn.Get(ctx, z0_oid); X(err) xz0, err := conn.Get(ctx, z.z0_oid); X(err)
xz1, err := conn.Get(ctx, z1_oid); X(err) xz1, err := conn.Get(ctx, z.z1_oid); X(err)
xzf, err := conn.Get(ctx, zf_oid); X(err) xzf, err := conn.Get(ctx, z.zf_oid); X(err)
z0, ok := xz0.(*ZBlk0) z0, ok := xz0.(*ZBlk0)
if !ok { if !ok {
...@@ -82,22 +120,22 @@ func TestZBlk(t *testing.T) { ...@@ -82,22 +120,22 @@ func TestZBlk(t *testing.T) {
z0Data, z0Rev, err := z0.LoadBlkData(ctx); X(err) z0Data, z0Rev, err := z0.LoadBlkData(ctx); X(err)
z0DataOK := brange32(z0_len) z0DataOK := brange32(z.z0_len)
assert.Equal(z0Data, z0DataOK, "ZBlk0 data wrong") assert.Equal(z0Data, z0DataOK, "ZBlk0 data wrong")
assert.Equal(z0Rev, z0_rev, "ZBlk0 rev wrong") assert.Equal(z0Rev, z.z0_rev, "ZBlk0 rev wrong")
z1Data, z1Rev, err := z1.LoadBlkData(ctx); X(err) z1Data, z1Rev, err := z1.LoadBlkData(ctx); X(err)
z1DataOK := make([]byte, zf_blksize) // zeros z1DataOK := make([]byte, z.zf_blksize) // zeros
copy(z1DataOK[0:], brange32(z1_htlen)) // head copy(z1DataOK[0:], brange32(z.z1_htlen)) // head
copy(z1DataOK[len(z1DataOK)-z1_htlen:], breverse(brange32(z1_htlen))) // tail copy(z1DataOK[len(z1DataOK)-z.z1_htlen:], breverse(brange32(z.z1_htlen))) // tail
z1DataOK = bytes.TrimRight(z1DataOK, "\x00") // trailing 0 are not persisted z1DataOK = bytes.TrimRight(z1DataOK, "\x00") // trailing 0 are not persisted
assert.Equal(z1Data, z1DataOK, "ZBlk1 data wrong") assert.Equal(z1Data, z1DataOK, "ZBlk1 data wrong")
assert.Equal(z1Rev, z1_rev, "ZBlk1 rev wrong") assert.Equal(z1Rev, z.z1_rev, "ZBlk1 rev wrong")
xactivate(zf) xactivate(zf)
if zf.blksize != zf_blksize { if zf.blksize != z.zf_blksize {
t.Fatalf("zf: blksize=%d; want %d", zf.blksize, zf_blksize) t.Fatalf("zf: blksize=%d; want %d", zf.blksize, z.zf_blksize)
} }
z0_, ok, err := zf.blktab.Get(ctx, 1); X(err) z0_, ok, err := zf.blktab.Get(ctx, 1); X(err)
...@@ -111,7 +149,7 @@ func TestZBlk(t *testing.T) { ...@@ -111,7 +149,7 @@ func TestZBlk(t *testing.T) {
} }
size, _, _, err := zf.Size(ctx); X(err) size, _, _, err := zf.Size(ctx); X(err)
assert.Equal(size, int64(zf_size), "ZBigFile size wrong") assert.Equal(size, z.zf_size, "ZBigFile size wrong")
// LoadBlk // LoadBlk
......
// Code generated by testdata/zblk_test_gen.py; DO NOT EDIT.
package zdata
import "lab.nexedi.com/kirr/neo/go/zodb"
func init() {
zblkTestDataRegistry["py2_pickle1"] = ZBlkTestData{
data_fs : "testdata/py2_pickle1/zblk.fs",
zf_blksize : 2097152,
zf_size : 8388608,
z0_oid : zodb.Oid(2),
z1_oid : zodb.Oid(3),
zf_oid : zodb.Oid(1),
z0_rev : zodb.Tid(0x285cbac3851eb99),
z1_rev : zodb.Tid(0x285cbac3851eb99),
z0_len : 16384,
z1_htlen : 131072,
}
}
// Code generated by testdata/zblk_test_gen.py; DO NOT EDIT.
package zdata
import "lab.nexedi.com/kirr/neo/go/zodb"
func init() {
zblkTestDataRegistry["py2_pickle2"] = ZBlkTestData{
data_fs : "testdata/py2_pickle2/zblk.fs",
zf_blksize : 2097152,
zf_size : 8388608,
z0_oid : zodb.Oid(2),
z1_oid : zodb.Oid(3),
zf_oid : zodb.Oid(1),
z0_rev : zodb.Tid(0x285cbac3851eb99),
z1_rev : zodb.Tid(0x285cbac3851eb99),
z0_len : 16384,
z1_htlen : 131072,
}
}
// Code generated by testdata/zblk_test_gen.py; DO NOT EDIT.
package zdata
import "lab.nexedi.com/kirr/neo/go/zodb"
func init() {
zblkTestDataRegistry["py2_pickle3"] = ZBlkTestData{
data_fs : "testdata/py2_pickle3/zblk.fs",
zf_blksize : 2097152,
zf_size : 8388608,
z0_oid : zodb.Oid(2),
z1_oid : zodb.Oid(3),
zf_oid : zodb.Oid(1),
z0_rev : zodb.Tid(0x285cbac3851eb99),
z1_rev : zodb.Tid(0x285cbac3851eb99),
z0_len : 16384,
z1_htlen : 131072,
}
}
// Code generated by testdata/zblk_test_gen.py; DO NOT EDIT.
package zdata
import "lab.nexedi.com/kirr/neo/go/zodb"
func init() {
zblkTestDataRegistry["py3_pickle3"] = ZBlkTestData{
data_fs : "testdata/py3_pickle3/zblk.fs",
zf_blksize : 2097152,
zf_size : 8388608,
z0_oid : zodb.Oid(2),
z1_oid : zodb.Oid(3),
zf_oid : zodb.Oid(1),
z0_rev : zodb.Tid(0x285cbac3851eb99),
z1_rev : zodb.Tid(0x285cbac3851eb99),
z0_len : 16384,
z1_htlen : 131072,
}
}
// Code generated by ./testdata/zblk_test_gen.py; DO NOT EDIT.
package zdata
import "lab.nexedi.com/kirr/neo/go/zodb"
const zf_blksize = 2097152
const zf_size = 8388608
const z0_oid = zodb.Oid(2)
const z1_oid = zodb.Oid(3)
const zf_oid = zodb.Oid(1)
const z0_rev = zodb.Tid(0x285cbac3851eb99)
const z1_rev = zodb.Tid(0x285cbac3851eb99)
const z0_len = 16384
const z1_htlen = 131072
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