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

.

parent 9a3b7413
......@@ -166,6 +166,7 @@ class DFile:
# tDB provides database/wcfs testing environment.
#
# Database root and wcfs connection are represented by .root and .wc correspondingly.
# The database is initialized with one ZBigFile created (XXX .zfile)
#
# The primary way to access wcfs is by opening BigFiles and WatchLinks.
# A BigFile opened under tDB is represented as tFile - see .open for details.
......@@ -205,12 +206,20 @@ class tDB:
t._files = set()
t._wlinks = set()
# prepare initail objects for test: zfile, nonzfile
t.root['!file'] = t.nonzfile = Persistent()
t.root['zfile'] = t.zfile = ZBigFile(blksize)
t.at0 = t.commit()
@property
def head(t):
return t.dFtail[-1].rev
# close closes test database as well as all tracked files, watch links and wcfs.
# it also prints change history to help developer overview current testcase.
@func
def close(t):
defer(t.dump_history)
for tf in t._files.copy():
tf.close()
for tw in t._wlinks.copy():
......@@ -1176,38 +1185,33 @@ def iter_revv(t, start=z64, level=0):
# ---- actual tests to access data ----
# test_wcfs exercises wcfs functionality.
# exercise wcfs functionality without wcfs invalidation protocol.
# plain data access + wcfs handling of ZODB invalidations.
@func
def test_wcfs():
t = tDB()
def test_wcfs_basic():
t = tDB(); zf = t.zfile
defer(t.close)
defer(t.dump_history)
t.root['!file'] = nonfile = Persistent()
t.root['zfile'] = zf = ZBigFile(blksize)
at0 = t.commit()
# >>> lookup non-BigFile -> must be rejected
with raises(OSError) as exc:
t._stat(nonfile)
t._stat(t.nonzfile)
assert exc.value.errno == EINVAL
# >>> file initially empty
f = t.open(zf)
f.assertCache([])
f.assertData ([], mtime=at0)
f.assertData ([], mtime=t.at0)
# >>> (@at1) commit data -> we can see it on wcfs
t.change(zf, {2: 'c1'})
t.change(zf, {2:'c1'})
at1 = t.commit()
f.assertCache([0,0,0]) # initially not cached
f.assertData (['','','c1'], mtime=t.head)
# >>> (@at2) commit again -> we can see both latest and snapshotted states
# NOTE blocks d(4) and f(5) will be not yet accessed till "watch+commit" test phase
t.change(zf, {2: 'c2', 3: 'd2', 5: 'f2'})
# NOTE blocks d(4) and f(5) will be accessed only in the end
t.change(zf, {2:'c2', 3:'d2', 5:'f2'})
at2 = t.commit()
# f @head
......@@ -1223,7 +1227,7 @@ def test_wcfs():
# >>> (@at3) commit again without changing zf size
f2 = t.open(zf, at=at2)
t.change(zf, {2: 'c3'}) # FIXME + a3 after δbtree works (hole -> zblk)
t.change(zf, {2: 'c3', 5: 'f3'}) # FIXME + a3 after δbtree works (hole -> zblk)
at3 = t.commit()
f.assertCache([1,1,0,1,0,0])
......@@ -1239,7 +1243,7 @@ def test_wcfs():
f.assertData (['','','c3','d2','x','x'], mtime=t.head)
# f @at2
# NOTE f2 is accessed but via @at/ not head/
# NOTE f(2) is accessed but via @at/ not head/ ; f(2) in head/zf remains unaccessed
f2.assertCache([0,0,1,0,0,0])
f2.assertData (['','','c2','d2','','f2']) # XXX mtime=at2?
......@@ -1256,11 +1260,17 @@ def test_wcfs():
if f.cached() != [1,1,1,1,0,0]:
assert sum(f.cached()) > 4*1/2 # > 50%
# >>> XXX commit data to not yet accessed f part - nothing happens
# verify all blocks
f.assertData(['','','c3','d2','','f3'])
# """
# >>> invalidation protocol
print('\n\n inv. protocol \n\n')
# verify that watch setup is robust to client errors/misbehaviour.
@func
def test_wcfs_inv_watch_robust():
t = tDB(); zf = t.zfile
defer(t.close)
t.change(zf, {2:'c1'}
# closeTX/bye cancels blocked pin handlers
wl = t.openwatch()
......@@ -1282,7 +1292,7 @@ def test_wcfs():
# NOTE if wcfs.go does not fully cleanup this canceled watch and leaves it
# in half-working state, it will break on further commit, as pin to the
# watch won't be handled.
# TODO -> add explicit check for ^^^ if/when moved to separate test.
# TODO -> add explicit check for ^^^ if/when moved to separate test. XXX
# invalid requests -> wcfs replies error
wl = t.openwatch()
......@@ -1308,6 +1318,9 @@ def test_wcfs():
" head/at (@%s); …" % (h(zf._p_oid), h(atpast), h(t.head)))
wl.close()
def bbb():
# some watch setup/update requests with explicit pinok (also partly
# verifies how tWatchLink.watch computes automatic pinok)
wl = t.openwatch()
......
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