Commit 98693492 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent fa28e211
......@@ -112,6 +112,8 @@ type Stateful interface {
//
// The error returned does not need to have object/setstate prefix -
// persistent machinery is adding such prefix automatically.
//
// XXX SetState is called only on ghost.
SetState(state *mem.Buf) error
// GetState should return state of the in-RAM object as raw data.
......
......@@ -41,6 +41,10 @@ type MyObject struct {
value string
}
func NewMyObject(jar *Connection) *MyObject {
return NewPersistent(reflect.TypeOf(MyObject{}), jar).(*MyObject)
}
type myObjectState MyObject
func (o *myObjectState) DropState() {
......@@ -178,6 +182,8 @@ func (cc *zcacheControl) WantEvict(obj IPersistent) bool {
}
// Persistent tests with storage.
//
// this test covers everything at application-level: Persistent, DB, Connection, LiveCache.
func TestPersistentDB(t *testing.T) {
X := exc.Raiseif
assert := require.New(t)
......@@ -190,12 +196,11 @@ func TestPersistentDB(t *testing.T) {
zurl := work + "/1.fs"
const oid1 = 1 // XXX
const oid2 = 2
// XXX create test db via py (change both oid1 & oid2)
// XXX commit1 to test db
at1, err := ZPyCommit(zurl, 0); X(err) // XXX data
// create test db via py with 2 objects
// XXX hack as _objX go without jar.
_obj1 := NewMyObject(nil); _obj1.oid = 101; _obj1.value = "hello"
_obj2 := NewMyObject(nil); _obj2.oid = 102; _obj2.value = "world"
at1, err := ZPyCommit(zurl, 0, _obj1, _obj2); X(err)
fmt.Printf("AAA %s\n", at1)
ctx := context.Background()
......@@ -207,51 +212,51 @@ func TestPersistentDB(t *testing.T) {
txn1, ctx1 := transaction.New(ctx)
conn1, err := db.Open(ctx1, &ConnOptions{}); X(err)
// do not evict oid1 from live cache. oid2 is ok to be evicted.
// do not evict obj1 from live cache. obj2 is ok to be evicted.
zcache1 := conn1.Cache()
zcache1.SetControl(&zcacheControl{[]Oid{oid1}})
zcache1.SetControl(&zcacheControl{[]Oid{11}})
assert.Equal(conn1.At(), at1)
xobj1, err := conn1.Get(ctx1, oid1); X(err)
xobj2, err := conn1.Get(ctx1, oid2); X(err)
xobj1, err := conn1.Get(ctx1, 101); X(err)
xobj2, err := conn1.Get(ctx1, 102); X(err)
assert.Equal(ClassOf(xobj1), "t.zodb.MyObject")
assert.Equal(ClassOf(xobj2), "t.zodb.MyObject")
obj1 := xobj1.(*MyObject)
obj2 := xobj2.(*MyObject)
checkObj(obj1, conn1, oid1, InvalidTid, GHOST, 0, nil)
checkObj(obj2, conn1, oid2, InvalidTid, GHOST, 0, nil)
checkObj(obj1, conn1, 101, InvalidTid, GHOST, 0, nil)
checkObj(obj2, conn1, 102, InvalidTid, GHOST, 0, nil)
// activate: jar has to load, state changes -> uptodate
err = obj1.PActivate(ctx1); X(err)
err = obj2.PActivate(ctx1); X(err)
checkObj(obj1, conn1, oid1, at1, UPTODATE, 1, nil)
checkObj(obj2, conn1, oid2, at1, UPTODATE, 1, nil)
checkObj(obj1, conn1, 101, at1, UPTODATE, 1, nil)
checkObj(obj2, conn1, 102, at1, UPTODATE, 1, nil)
// activate again: refcnt++
err = obj1.PActivate(ctx1); X(err)
err = obj2.PActivate(ctx1); X(err)
checkObj(obj1, conn1, oid1, at1, UPTODATE, 2, nil)
checkObj(obj2, conn1, oid2, at1, UPTODATE, 2, nil)
checkObj(obj1, conn1, 101, at1, UPTODATE, 2, nil)
checkObj(obj2, conn1, 102, at1, UPTODATE, 2, nil)
// deactivate: refcnt--
obj1.PDeactivate()
obj2.PDeactivate()
checkObj(obj1, conn1, oid1, at1, UPTODATE, 1, nil)
checkObj(obj2, conn1, oid2, at1, UPTODATE, 1, nil)
checkObj(obj1, conn1, 101, at1, UPTODATE, 1, nil)
checkObj(obj2, conn1, 102, at1, UPTODATE, 1, nil)
// deactivate: state dropped for obj2, obj1 stays in live cache
obj1.PDeactivate()
obj2.PDeactivate()
checkObj(obj1, conn1, oid1, at1, UPTODATE, 0, nil)
checkObj(obj2, conn1, oid2, InvalidTid, GHOST, 0, nil)
checkObj(obj1, conn1, 101, at1, UPTODATE, 0, nil)
checkObj(obj2, conn1, 102, InvalidTid, GHOST, 0, nil)
// invalidate: obj1 state dropped
obj1.PDeactivate()
obj2.PDeactivate()
checkObj(obj1, conn1, oid1, InvalidTid, GHOST, 0, nil)
checkObj(obj2, conn1, oid2, InvalidTid, GHOST, 0, nil)
checkObj(obj1, conn1, 101, InvalidTid, GHOST, 0, nil)
checkObj(obj2, conn1, 102, InvalidTid, GHOST, 0, nil)
// XXX
......
......@@ -350,6 +350,15 @@ func BenchmarkIterate(b *testing.B) {
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.
func TestWatch(t *testing.T) {
X := exc.Raiseif
......@@ -366,7 +375,7 @@ func TestWatch(t *testing.T) {
}
// force tfs creation & open tfs at go side
at := xcommit(0, xtesting.ZRawObject{0, "data0"})
at := xcommit(0, xtesting.ZRawObject{0, b("data0")})
watchq := make(chan zodb.CommitEvent)
fs := xfsopenopt(t, tfs, &zodb.DriverOptions{ReadOnly: true, Watchq: watchq})
......@@ -407,8 +416,8 @@ func TestWatch(t *testing.T) {
data0 := fmt.Sprintf("data0.%d", i)
datai := fmt.Sprintf("data%d", i)
at = xcommit(at,
xtesting.ZRawObject{0, data0},
xtesting.ZRawObject{i, datai})
xtesting.ZRawObject{0, b(data0)},
xtesting.ZRawObject{i, b(datai)})
// TODO also test for watcher errors
e := <-watchq
......
......@@ -35,6 +35,8 @@ type PyStateful interface {
//
// The error returned does not need to have object/setstate prefix -
// persistent machinery is adding such prefix automatically.
//
// XXX PySetState is called only on ghost.
PySetState(pystate interface{}) error
// PyGetState should return state of the in-RAM object as Python data.
......
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