Commit a436e928 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent 98e3a4e5
...@@ -30,9 +30,9 @@ import transaction ...@@ -30,9 +30,9 @@ import transaction
from persistent import Persistent from persistent import Persistent
from persistent.timestamp import TimeStamp from persistent.timestamp import TimeStamp
import os, os.path, sys, subprocess import os, os.path, subprocess
from errno import EINVAL from errno import EINVAL
from golang import func, method, defer from golang import func, defer
from zodbtools.util import ashex as h, fromhex from zodbtools.util import ashex as h, fromhex
from pytest import raises from pytest import raises
...@@ -113,18 +113,71 @@ def test_join_autostart(): ...@@ -113,18 +113,71 @@ def test_join_autostart():
assert os.path.isdir(wc.mountpoint + "/head/bigfile") assert os.path.isdir(wc.mountpoint + "/head/bigfile")
# tDB is testing database/wcfs environment.
class tDB:
def __init__(t):
t.root = testdb.dbopen()
t.wc = wcfs.join(testzurl, autostart=True)
# commited: head + head history
t.head = None
t._headv = []
# fh(.wcfs/zhead) + history of zhead read from there
t._wc_zheadfh = open(t.wc.mountpoint + "/.wcfs/zhead")
t._wc_zheadv = []
def close(t):
t._wc_zheadfh.close()
t.wc.close()
dbclose(t.root)
# commit commits transaction and remembers/returns committed tid.
#
# it also stores:
#
# .head - last committed transaction ID
def commit(t):
# NOTE there is no clean way to retrieve tid of just committed transaction
# we are using last._p_serial as workaround.
t.root['_last'] = last = Persistent()
last._p_changed = 1
transaction.commit()
head = last._p_serial
print 'commit -> %s' % h(head)
t.head = head
t._headv.append(head)
return head
# wcsync makes sure wc synchronized to latest committed transaction.
def wcsync(t):
while len(t._wc_zheadv) < len(t._headv):
l = t._wc_zheadfh.readline()
#print '> zhead read: %r' % l
l = l.rstrip('\n')
wchead = fromhex(l)
i = len(t._wc_zheadv)
if wchead != t._headv[i]:
raise RuntimeError("wcsync #%d: wczhead (%s) != zhead (%s)" % (i, wchead, t._headv[i]))
t._wc_zheadv.append(wchead)
# XXX test # XXX test
# XXX parametrize zblk0, zblk1 XXX or just rely on tox? # XXX parametrize zblk0, zblk1 XXX or just rely on tox?
@func @func
def test_wcfs(): def test_wcfs():
t = tDB()
defer(t.close)
t.root['obj'] = nonfile = Persistent()
t.root['zfile'] = f = ZBigFile(blksize)
"""
root = testdb.dbopen() root = testdb.dbopen()
defer(lambda: dbclose(root)) defer(lambda: dbclose(root))
wc = wcfs.join(testzurl, autostart=True) wc = wcfs.join(testzurl, autostart=True)
defer(wc.close) defer(wc.close)
root['zfile'] = f = ZBigFile(blksize)
# commit commits transaction and remembers/returns committed tid. # commit commits transaction and remembers/returns committed tid.
# #
# NOTE there is no clean way to retrieve tid of just committed transaction # NOTE there is no clean way to retrieve tid of just committed transaction
...@@ -161,20 +214,21 @@ def test_wcfs(): ...@@ -161,20 +214,21 @@ def test_wcfs():
if wctid != Z.tidv[i]: if wctid != Z.tidv[i]:
raise RuntimeError("wcsync #%d: Z.wctid (%s) != Z.tid (%s)" % (i, wctid, Z.tidv[i])) raise RuntimeError("wcsync #%d: Z.wctid (%s) != Z.tid (%s)" % (i, wctid, Z.tidv[i]))
Z.wctidv.append(wctid) Z.wctidv.append(wctid)
"""
tid1 = commit() tid1 = t.commit()
tid2 = commit() tid2 = t.commit()
assert tidtime(tid2) > tidtime(tid1) assert tidtime(tid2) > tidtime(tid1)
wcsync() t.wcsync()
# path to head/ and head/bigfile/ under wcfs # path to head/ and head/bigfile/ under wcfs
head = wc.mountpoint + "/head" head = t.wc.mountpoint + "/head"
bigpath = head + "/bigfile" bigpath = head + "/bigfile"
# lookup to non-BigFile - must be rejected # lookup to non-BigFile - must be rejected
with raises(OSError) as exc: with raises(OSError) as exc:
os.stat("%s/%s" % (bigpath, h(last._p_oid))) os.stat("%s/%s" % (bigpath, h(nonfile._p_oid)))
assert exc.value.errno == EINVAL assert exc.value.errno == EINVAL
# path to f under wcfs # path to f under wcfs
...@@ -197,16 +251,16 @@ def test_wcfs(): ...@@ -197,16 +251,16 @@ def test_wcfs():
s = b"hello world" s = b"hello world"
memcpy(vma, s) memcpy(vma, s)
commit() t.commit()
wcsync() # sync wcfs to ZODB t.wcsync() # sync wcfs to ZODB
# we wrote "hello world" after hole'th block, but size is always mutiple of blksize. # we wrote "hello world" after hole'th block, but size is always mutiple of blksize.
fsize = (hole + 1)*blksize fsize = (hole + 1)*blksize
st = os.stat(fpath) st = os.stat(fpath)
assert st.st_size == fsize assert st.st_size == fsize
assert st.st_mtime == tidtime(Z.head) assert st.st_mtime == tidtime(t.head)
assert readfile(head + "/at") == h(Z.head) assert readfile(head + "/at") == h(t.head)
data = readfile(fpath) data = readfile(fpath)
assert len(data) == fsize assert len(data) == fsize
...@@ -218,7 +272,7 @@ def test_wcfs(): ...@@ -218,7 +272,7 @@ def test_wcfs():
# commit data again and make sure we can see both latest and snapshotted states. # commit data again and make sure we can see both latest and snapshotted states.
tcommit1 = Z.head tcommit1 = t.head
fh = f.fileh_open(_use_wcfs=False) fh = f.fileh_open(_use_wcfs=False)
vma1 = fh.mmap(hole, 1) vma1 = fh.mmap(hole, 1)
...@@ -228,16 +282,16 @@ def test_wcfs(): ...@@ -228,16 +282,16 @@ def test_wcfs():
memcpy(vma1,s1) memcpy(vma1,s1)
memcpy(vma2,s2) memcpy(vma2,s2)
commit() t.commit()
wcsync() t.wcsync()
fsize1 = fsize fsize1 = fsize
fsize = fsize1 + blksize # we added one more block fsize = fsize1 + blksize # we added one more block
st = os.stat(fpath) st = os.stat(fpath)
assert st.st_size == fsize assert st.st_size == fsize
assert st.st_mtime == tidtime(Z.head) assert st.st_mtime == tidtime(t.head)
assert readfile(head + "/at") == h(Z.head) assert readfile(head + "/at") == h(t.head)
data = readfile(fpath) data = readfile(fpath)
assert len(data) == fsize assert len(data) == fsize
...@@ -252,7 +306,7 @@ def test_wcfs(): ...@@ -252,7 +306,7 @@ def test_wcfs():
assert tail2[len(s2):] == b'\0'*(blksize - len(s2)) assert tail2[len(s2):] == b'\0'*(blksize - len(s2))
# path to f's state @tcommit1 # path to f's state @tcommit1
rev1 = wc.mountpoint + ("/@%s" % h(tcommit1)) rev1 = t.wc.mountpoint + ("/@%s" % h(tcommit1))
fpath1 = rev1 + "/bigfile/" + h(f._p_oid) fpath1 = rev1 + "/bigfile/" + h(f._p_oid)
st = os.stat(fpath1) st = os.stat(fpath1)
...@@ -270,6 +324,7 @@ def test_wcfs(): ...@@ -270,6 +324,7 @@ def test_wcfs():
# TODO pagecache state after loading (via mincore) # TODO pagecache state after loading (via mincore)
# TODO pagecahce state after .size change
def test_wcfs_invproto(): def test_wcfs_invproto():
# XXX # XXX
......
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