Commit 98693492 authored by Kirill Smelkov's avatar Kirill Smelkov

.

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