Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
W
wendelin.core
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
Kirill Smelkov
wendelin.core
Commits
8c05bc4c
Commit
8c05bc4c
authored
Jun 07, 2019
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
4235f5c6
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
118 additions
and
5 deletions
+118
-5
wcfs/wcfs_test.py
wcfs/wcfs_test.py
+118
-5
No files found.
wcfs/wcfs_test.py
View file @
8c05bc4c
...
...
@@ -33,10 +33,11 @@ from persistent import Persistent
from
persistent.timestamp
import
TimeStamp
from
ZODB.utils
import
z64
,
u64
,
p64
import
sys
,
os
,
os
.
path
,
subprocess
,
threading
,
inspect
,
traceback
import
sys
,
os
,
os
.
path
,
subprocess
,
threading
,
inspect
,
traceback
,
re
from
errno
import
EINVAL
from
golang
import
go
,
chan
,
func
,
defer
,
select
from
golang
import
context
,
sync
,
time
from
golang.gcompat
import
qq
from
zodbtools.util
import
ashex
as
h
,
fromhex
from
pytest
import
raises
from
six
import
reraise
...
...
@@ -676,6 +677,28 @@ class tSrvReq:
# XXX also track as answered? (and don't accept with the same ID ?)
def
_parse
(
req
):
# -> (foid, blk, at|None)
# pin <foid> #<blk> @(<at>|head)
m
=
re
.
match
(
b"pin (?P<foid>[0-9a-f]{16}) #(?P<blk>[0-9]+) @(P<at>[^ ]+)$"
,
req
.
msg
)
if
m
is
None
:
raise
RuntimeError
(
"message is not valid pin request: %s"
%
qq
(
req
.
msg
))
foid
=
fromhex
(
m
.
group
(
'foid'
))
blk
=
int
(
m
.
group
(
'blk'
))
at
=
m
.
group
(
'at'
)
if
at
==
"head"
:
at
=
None
else
:
at
=
fromhex
(
at
)
return
foid
,
blk
,
at
@
property
def
foid
(
req
):
return
req
.
_parse
()[
0
]
@
property
def
blk
(
req
):
return
req
.
_parse
()[
1
]
@
property
def
at
(
req
):
return
req
.
_parse
()[
2
]
# ---- watch setup/adjust ----
...
...
@@ -768,7 +791,7 @@ def watch(twlink, zf, at): # XXX -> ?
twlink
.
_watch
(
zf
,
at
,
pinok
,
"ok"
)
# _watch sends watch request for zf@at, expects initial pins specified by pinok, and final
y
reply.
# _watch sends watch request for zf@at, expects initial pins specified by pinok, and final reply.
#
# pinok: {} blk -> at that have to be pinned.
# if replyok ends with '…' only reply prefix until the dots is checked.
...
...
@@ -776,6 +799,8 @@ def watch(twlink, zf, at): # XXX -> ?
def
_watch
(
twlink
,
zf
,
at
,
pinok
,
replyok
):
# send watch request and check that we receive pins for in-cache blocks
# changed > at. Use timeout to detect wcfs replying less pins than expected.
"""
#
# XXX detect not sent pins with timeout, or better via ack'ing previous
# pins as they come in (not waiting for all of them) and then seeing that
...
...
@@ -812,14 +837,73 @@ def _watch(twlink, zf, at, pinok, replyok):
wg.go(_)
wg.wait()
"""
def
_
(
ctx
):
reply
=
twlink
.
sendReq
(
ctx
,
b"watch %s @%s"
%
(
h
(
zf
.
_p_oid
),
h
(
at
)))
if
replyok
.
endswith
(
'…'
):
rok
=
replyok
[:
-
len
(
'…'
)]
assert
reply
[:
len
(
rok
)]
==
rok
else
:
assert
reply
==
replyok
doCheckingPin
(
_
,
{
twlink
:
pinok
})
twlink
.
_watching
[
zf
]
=
at
# doCheckingPin calls f and verifies that wcfs sends expected pins during the
# time f executes.
#
# f(ctx) # XXX + ev?
# pinokByWLink: {} tWatchLink -> {} blk -> at.
# pinfunc(wlink, foid, blk, at) | None. XXX foid -> ZBigFile?
#
# pinfunc is called after pin request is received from wcfs but before pin ack
# is replied back. pinfunc must not block.
def
doCheckingPin
(
f
,
pinokByWLink
,
pinfunc
=
None
):
# call f and check that we receive pins as specified.
# Use timeout to detect wcfs replying less pins than expected.
#
# XXX detect not sent pins with timeout, or better via ack'ing previous
# pins as they come in (not waiting for all of them) and then seeing that
# we did not received expeced pin when wcfs sends final ok?
ctx
,
cancel
=
with_timeout
()
wg
=
sync
.
WorkGroup
(
ctx
)
for
wlink
,
pinok
in
pinokByWLink
.
items
():
def
_
(
ctx
,
wlink
):
pinv
=
wlink
.
_expectPin
(
ctx
,
zf
,
pinok
)
# XXX zf?
tdelay
()
# increase probability to receive erroneous extra pins
for
p
in
pinv
:
if
pinfunc
is
not
None
:
pinfunc
(
wlink
,
p
.
foid
,
p
.
blk
,
p
.
at
)
p
.
reply
(
b"ack"
)
# check that we don't get extra pins before reply to "watch"
try
:
req
=
wlink
.
recvReq
(
ctx
)
except
Exception
as
e
:
if
e
is
context
.
canceled
:
return
# cancel is expected after seeing "ok"
reraise
(
e
,
None
,
e
.
__traceback__
)
assert
False
,
"extra pin message received: %r"
%
req
.
msg
wg
.
go
(
_
,
wlink
)
def
_
(
ctx
):
f
(
ctx
)
# cancel _expectPin waiting upon completing f
# -> error that missed pins were not received.
cancel
()
wg
.
go
(
_
)
wg
.
wait
()
# _expectPin asserts that wcfs sends expected pin messages.
#
# expect is {} blk -> at
# returns [] of received pin requests.
@
func
(
tWatchLink
)
def
_expectPin
(
twlink
,
ctx
,
zf
,
expect
):
def
_expectPin
(
twlink
,
ctx
,
zf
,
expect
):
# -> []tSrvReq
expected
=
set
()
# of expected pin messages
for
blk
,
at
in
expect
.
items
():
hat
=
h
(
at
)
if
at
is
not
None
else
'head'
...
...
@@ -969,11 +1053,13 @@ def test_wcfs():
at4
=
t
.
commit
()
f
.
assertCache
([
1
,
1
,
0
,
1
,
0
,
0
])
# FIXME a must be invalidated - see δbtree ^^^
"""
ctx, cancel = with_timeout()
wg = sync.WorkGroup(ctx)
"""
blk
=
2
pinok
=
{
2
:
at3
}
pinok
=
{
2
:
at3
}
# XXX at3 -> at <= wl.at for zf
# XXX 5, {5: ø}
# XXX 0, {0, at3} after δbtree works
...
...
@@ -981,6 +1067,32 @@ def test_wcfs():
blk_data
=
f
.
blk
(
blk
)
assert
f
.
cached
()[
blk
]
==
0
def
_
(
ctx
):
assert
f
.
cached
()[
blk
]
==
0
ev
.
append
(
'read pre'
)
# access data with released GIL so that the thread that reads data from
# head/watch can receive pin message. Be careful to handle cancelation,
# so that on error in another worker we don't stuck and the error is
# successfully propagated to wait and reported.
have_read
=
chan
(
1
)
def
_
():
b
=
read0_nogil
(
blk_data
)
have_read
.
send
(
b
)
go
(
_
)
_
,
_rx
=
select
(
ctx
.
done
().
recv
,
# 0
have_read
.
recv
,
# 1
)
if
_
==
0
:
raise
ctx
.
err
()
b
=
_rx
ev
.
append
(
'read '
+
chr
(
b
))
doCheckingPin
(
_
,
{
wl
:
pinok
})
"""
# XXX dup wrte tWatchLink._watch
ev = []
...
...
@@ -1032,7 +1144,8 @@ def test_wcfs():
wg.go(_)
wg.wait()
assert
ev
==
[
'read pre'
,
'pin rx'
,
'pin ack pre'
,
'read 4'
]
# 4 - read @head
"""
assert
ev
==
[
'read pre'
,
'pin rx'
,
'pin ack pre'
,
'read 4'
]
# 4 - read @head # XXX depend on blk
assert
f
.
cached
()[
blk
]
>
0
f
.
assertBlk
(
blk
,
'4c'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment