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
a8fa9178
Commit
a8fa9178
authored
Feb 12, 2020
by
Kirill Smelkov
2
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
X wcfs: move client tests into client/
parent
0a8fcd9d
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
171 additions
and
132 deletions
+171
-132
wcfs/client/client_test.py
wcfs/client/client_test.py
+168
-0
wcfs/wcfs_test.py
wcfs/wcfs_test.py
+3
-132
No files found.
wcfs/client/client_test.py
0 → 100644
View file @
a8fa9178
# -*- coding: utf-8 -*-
# Copyright (C) 2018-2020 Nexedi SA and Contributors.
# Kirill Smelkov <kirr@nexedi.com>
#
# This program is free software: you can Use, Study, Modify and Redistribute
# it under the terms of the GNU General Public License version 3, or (at your
# option) any later version, as published by the Free Software Foundation.
#
# You can also Link and Combine this program with other software covered by
# the terms of any of the Free Software licenses or any of the Open Source
# Initiative approved licenses and Convey the resulting work. Corresponding
# source of such a combination shall include the source code for all other
# software used.
#
# This program is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
"""client_test.py unit-tests virtmem layer provided by wcfs client.
WCFS filesystem itself is unit-tested by wcfs/wcfs_test.py .
At functional level, the whole wendelin.core test suite is used to verify
wcfs.py/wcfs.go while running tox tests in wcfs mode.
"""
from
__future__
import
print_function
,
absolute_import
from
golang
import
func
,
defer
from
wendelin.wcfs.wcfs_test
import
tDB
,
tAt
from
wendelin.wcfs
import
wcfs_test
# XXX so that e.g. testdb is set up + ...
def
setup_module
():
wcfs_test
.
setup_module
()
def
teardown_module
():
wcfs_test
.
teardown_module
()
def
setup_function
(
f
):
wcfs_test
.
setup_function
(
f
)
def
teardown_function
(
f
):
wcfs_test
.
teardown_function
(
f
)
# tMapping provides testing environment for Mapping.
class
tMapping
(
object
):
def
__init__
(
t
,
tdb
,
mmap
):
t
.
tdb
=
tdb
t
.
mmap
=
mmap
# XXX assertCache
# assertBlk asserts that mmap[·] with · corresponding to blk reads as dataok.
# pinnedOK: {} blk -> rev of t.mmap.fileh.pinned after access.
#
# see also: tFile.assertBlk .
# NOTE contrary to tFile, pinnedOK represents full fh.pinned state, not
# only pins that wcfs sent to client after tested access.
def
assertBlk
(
t
,
blk
,
dataok
,
pinnedOK
):
assert
t
.
mmap
.
blk_start
<=
blk
<
t
.
mmap
.
blk_stop
blk_inmmap
=
blk
-
t
.
mmap
.
blk_start
if
not
isinstance
(
dataok
,
bytes
):
dataok
=
dataok
.
encode
(
'utf-8'
)
fh
=
t
.
mmap
.
fileh
assert
len
(
dataok
)
<=
fh
.
blksize
dataok
+=
b'
\
0
'
*
(
fh
.
blksize
-
len
(
dataok
))
# trailing zeros
blkview
=
t
.
mmap
.
mem
[
blk_inmmap
*
fh
.
blksize
:][:
fh
.
blksize
]
# NOTE access to memory goes _with_ GIL: this verifies that wcfs pinner
# is implemented in fully nogil mode because if that was not the case,
# the pinner would deadlock trying to acquire GIL in its thread while
# user thread that triggered the access is already holding the GIL.
#
# - - - - - -
# | |
# pinner <------.
# | | wcfs
# client -------^
# | |
# - - - - - -
# client process
#
_
=
blkview
[
0
]
assert
_
==
dataok
[
0
]
assert
blkview
.
tobytes
()
==
dataok
assert
fhpinned
(
t
.
tdb
,
fh
)
==
pinnedOK
# XXX assertData
# fhpinned(fh) returns fh.pinned with rev wrapped into tAt.
# XXX better wrap FileH into tFileH and do this automatically in .pinned ?
def
fhpinned
(
t
,
fh
):
p
=
fh
.
pinned
.
copy
()
for
blk
in
p
:
p
[
blk
]
=
tAt
(
t
,
p
[
blk
])
return
p
# test_wcfs_virtmem unit-tests virtmem layer of wcfs client.
@
func
def
test_wcfs_virtmem
():
t
=
tDB
();
zf
=
t
.
zfile
;
at0
=
t
.
at0
defer
(
t
.
close
)
pinned
=
lambda
fh
:
fhpinned
(
t
,
fh
)
at1
=
t
.
commit
(
zf
,
{
2
:
'c1'
,
3
:
'd1'
})
at2
=
t
.
commit
(
zf
,
{
2
:
'c2'
})
wconn
=
t
.
wc
.
connect
(
at1
)
defer
(
wconn
.
close
)
fh
=
wconn
.
open
(
zf
.
_p_oid
)
defer
(
fh
.
close
)
# create mmap with 1 block beyond file size
m1
=
fh
.
mmap
(
2
,
3
)
defer
(
m1
.
unmap
)
assert
m1
.
blk_start
==
2
assert
m1
.
blk_stop
==
5
assert
len
(
m1
.
mem
)
==
3
*
zf
.
blksize
tm1
=
tMapping
(
t
,
m1
)
#assertCache(m1, [0,0,0])
assert
pinned
(
fh
)
==
{}
# verify initial data reads
tm1
.
assertBlk
(
2
,
'c1'
,
{
2
:
at1
})
tm1
.
assertBlk
(
3
,
'd1'
,
{
2
:
at1
})
tm1
.
assertBlk
(
4
,
''
,
{
2
:
at1
})
# commit with growing file size -> verify data read as the same, #3 pinned.
# (#4 is not yet pinned because it was not accessed)
at3
=
t
.
commit
(
zf
,
{
3
:
'd3'
,
4
:
'e3'
})
assert
pinned
(
fh
)
==
{
2
:
at1
}
tm1
.
assertBlk
(
2
,
'c1'
,
{
2
:
at1
})
tm1
.
assertBlk
(
3
,
'd1'
,
{
2
:
at1
,
3
:
at1
})
tm1
.
assertBlk
(
4
,
''
,
{
2
:
at1
,
3
:
at1
})
# resync at1 -> at2: #2 must unpin to @head; #4 must stay as zero
wconn
.
resync
(
at2
)
assert
pinned
(
fh
)
==
{
3
:
at1
}
tm1
.
assertBlk
(
2
,
'c2'
,
{
3
:
at1
})
tm1
.
assertBlk
(
3
,
'd1'
,
{
3
:
at1
})
tm1
.
assertBlk
(
4
,
''
,
{
3
:
at1
,
4
:
at0
})
# XXX at0->ø ?
# resync at2 -> at3: #3 must unpin to @head; #4 - start to read with data
wconn
.
resync
(
at3
)
assert
pinned
(
fh
)
==
{}
tm1
.
assertBlk
(
2
,
'c2'
,
{})
tm1
.
assertBlk
(
3
,
'd3'
,
{})
tm1
.
assertBlk
(
4
,
'e3'
,
{})
# XXX resync ↓ ?
# XXX mmap after .size completely (start > size)
# XXX w mapping with RW - in sync
# XXX fh close then open again and use
# XXX open same fh twice, close once - fh2 continue to work ok
# XXX wconn.open() after wconn.close() -> error
# XXX wconn.resync() after wconn.close() -> error
# XXX all fileh / mappings become invalid after wconn.close
wcfs/wcfs_test.py
View file @
a8fa9178
...
...
@@ -17,9 +17,10 @@
#
# See COPYING file for full licensing terms.
# See https://www.nexedi.com/licensing for rationale and options.
"""wcfs_test
tests wcfs filesystem from outside as python client process
"""wcfs_test
.py tests wcfs filesystem from outside as python client process.
It also unit-tests virtmem layer of wcfs virtmem client.
Virtmem layer provided by wcfs client package is unit-tested by
wcfs/client/client_test.py .
At functional level, the whole wendelin.core test suite is used to verify
wcfs.py/wcfs.go while running tox tests in wcfs mode.
...
...
@@ -1697,136 +1698,6 @@ def test_wcfs_watch_2files():
# XXX @revX/ is automatically removed after some time
# ---- unit-tests for virtmem layer of wcfs client ----
# tMapping provides testing environment for Mapping.
class
tMapping
(
object
):
def
__init__
(
t
,
tdb
,
mmap
):
t
.
tdb
=
tdb
t
.
mmap
=
mmap
# XXX assertCache
# assertBlk asserts that mmap[·] with · corresponding to blk reads as dataok.
# pinnedOK: {} blk -> rev of t.mmap.fileh.pinned after access.
#
# see also: tFile.assertBlk .
# NOTE contrary to tFile, pinnedOK represents full fh.pinned state, not
# only pins that wcfs sent to client after tested access.
def
assertBlk
(
t
,
blk
,
dataok
,
pinnedOK
):
assert
t
.
mmap
.
blk_start
<=
blk
<
t
.
mmap
.
blk_stop
blk_inmmap
=
blk
-
t
.
mmap
.
blk_start
if
not
isinstance
(
dataok
,
bytes
):
dataok
=
dataok
.
encode
(
'utf-8'
)
fh
=
t
.
mmap
.
fileh
assert
len
(
dataok
)
<=
fh
.
blksize
dataok
+=
b'
\
0
'
*
(
fh
.
blksize
-
len
(
dataok
))
# trailing zeros
blkview
=
t
.
mmap
.
mem
[
blk_inmmap
*
fh
.
blksize
:][:
fh
.
blksize
]
# NOTE access to memory goes _with_ GIL: this verifies that wcfs pinner
# is implemented in fully nogil mode because if that was not the case,
# the pinner would deadlock trying to acquire GIL in its thread while
# user thread that triggered the access is already holding the GIL.
#
# - - - - - -
# | |
# pinner <------.
# | | wcfs
# client -------^
# | |
# - - - - - -
# client process
#
_
=
blkview
[
0
]
assert
_
==
dataok
[
0
]
assert
blkview
.
tobytes
()
==
dataok
assert
fhpinned
(
t
.
tdb
,
fh
)
==
pinnedOK
# XXX assertData
# fhpinned(fh) returns fh.pinned with rev wrapped into tAt.
# XXX better wrap FileH into tFileH and do this automatically in .pinned ?
def
fhpinned
(
t
,
fh
):
p
=
fh
.
pinned
.
copy
()
for
blk
in
p
:
p
[
blk
]
=
tAt
(
t
,
p
[
blk
])
return
p
# test_wcfs_virtmem unit-tests virtmem layer of wcfs client.
@
func
def
test_wcfs_virtmem
():
t
=
tDB
();
zf
=
t
.
zfile
;
at0
=
t
.
at0
defer
(
t
.
close
)
pinned
=
lambda
fh
:
fhpinned
(
t
,
fh
)
at1
=
t
.
commit
(
zf
,
{
2
:
'c1'
,
3
:
'd1'
})
at2
=
t
.
commit
(
zf
,
{
2
:
'c2'
})
wconn
=
t
.
wc
.
connect
(
at1
)
defer
(
wconn
.
close
)
fh
=
wconn
.
open
(
zf
.
_p_oid
)
defer
(
fh
.
close
)
# create mmap with 1 block beyond file size
m1
=
fh
.
mmap
(
2
,
3
)
defer
(
m1
.
unmap
)
assert
m1
.
blk_start
==
2
assert
m1
.
blk_stop
==
5
assert
len
(
m1
.
mem
)
==
3
*
zf
.
blksize
tm1
=
tMapping
(
t
,
m1
)
#assertCache(m1, [0,0,0])
assert
pinned
(
fh
)
==
{}
# verify initial data reads
tm1
.
assertBlk
(
2
,
'c1'
,
{
2
:
at1
})
tm1
.
assertBlk
(
3
,
'd1'
,
{
2
:
at1
})
tm1
.
assertBlk
(
4
,
''
,
{
2
:
at1
})
# commit with growing file size -> verify data read as the same, #3 pinned.
# (#4 is not yet pinned because it was not accessed)
at3
=
t
.
commit
(
zf
,
{
3
:
'd3'
,
4
:
'e3'
})
assert
pinned
(
fh
)
==
{
2
:
at1
}
tm1
.
assertBlk
(
2
,
'c1'
,
{
2
:
at1
})
tm1
.
assertBlk
(
3
,
'd1'
,
{
2
:
at1
,
3
:
at1
})
tm1
.
assertBlk
(
4
,
''
,
{
2
:
at1
,
3
:
at1
})
# resync at1 -> at2: #2 must unpin to @head; #4 must stay as zero
wconn
.
resync
(
at2
)
assert
pinned
(
fh
)
==
{
3
:
at1
}
tm1
.
assertBlk
(
2
,
'c2'
,
{
3
:
at1
})
tm1
.
assertBlk
(
3
,
'd1'
,
{
3
:
at1
})
tm1
.
assertBlk
(
4
,
''
,
{
3
:
at1
,
4
:
at0
})
# XXX at0->ø ?
# resync at2 -> at3: #3 must unpin to @head; #4 - start to read with data
wconn
.
resync
(
at3
)
assert
pinned
(
fh
)
==
{}
tm1
.
assertBlk
(
2
,
'c2'
,
{})
tm1
.
assertBlk
(
3
,
'd3'
,
{})
tm1
.
assertBlk
(
4
,
'e3'
,
{})
# XXX resync ↓ ?
# XXX mmap after .size completely (start > size)
# XXX w mapping with RW - in sync
# XXX fh close then open again and use
# XXX open same fh twice, close once - fh2 continue to work ok
# XXX wconn.open() after wconn.close() -> error
# XXX wconn.resync() after wconn.close() -> error
# XXX all fileh / mappings become invalid after wconn.close
# ---- misc ---
# readfile reads file @ path.
...
...
Kirill Smelkov
@kirr
mentioned in commit
10f7153a
·
Oct 28, 2021
mentioned in commit
10f7153a
mentioned in commit 10f7153a6b27e3dae8e02e089fce31cf20973c67
Toggle commit list
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