Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neoppod
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Levin Zimmermann
neoppod
Commits
b621a98f
Commit
b621a98f
authored
Mar 20, 2018
by
Julien Muchembled
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
bench: new option to mesure ZEO perfs in matrix test
parent
114c7ab6
Changes
3
Show whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
161 additions
and
63 deletions
+161
-63
neo/tests/functional/__init__.py
neo/tests/functional/__init__.py
+39
-26
neo/tests/zeo_cluster.py
neo/tests/zeo_cluster.py
+62
-0
tools/matrix
tools/matrix
+60
-37
No files found.
neo/tests/functional/__init__.py
View file @
b621a98f
...
@@ -116,36 +116,31 @@ class PortAllocator(object):
...
@@ -116,36 +116,31 @@ class PortAllocator(object):
__del__
=
release
__del__
=
release
class
NEO
Process
(
object
):
class
Process
(
object
):
_coverage_fd
=
None
_coverage_fd
=
None
_coverage_prefix
=
os
.
path
.
join
(
getTempDirectory
(),
'coverage-'
)
_coverage_prefix
=
os
.
path
.
join
(
getTempDirectory
(),
'coverage-'
)
_coverage_index
=
0
_coverage_index
=
0
pid
=
0
pid
=
0
def
__init__
(
self
,
command
,
uuid
,
arg_dict
):
def
__init__
(
self
,
command
,
arg_dict
=
{}):
try
:
__import__
(
'neo.scripts.'
+
command
,
level
=
0
)
except
ImportError
:
raise
NotFound
,
'%s not found'
%
(
command
)
self
.
command
=
command
self
.
command
=
command
self
.
arg_dict
=
arg_dict
self
.
arg_dict
=
arg_dict
self
.
with_uuid
=
True
self
.
setUUID
(
uuid
)
def
start
(
self
,
with_uuid
=
True
):
def
_args
(
self
):
# Prevent starting when already forked and wait wasn't called.
if
self
.
pid
!=
0
:
raise
AlreadyRunning
,
'Already running with PID %r'
%
(
self
.
pid
,
)
command
=
self
.
command
args
=
[]
args
=
[]
self
.
with_uuid
=
with_uuid
for
arg
,
param
in
self
.
arg_dict
.
iteritems
():
for
arg
,
param
in
self
.
arg_dict
.
iteritems
():
args
.
append
(
'--'
+
arg
)
args
.
append
(
'--'
+
arg
)
if
param
is
not
None
:
if
param
is
not
None
:
args
.
append
(
str
(
param
))
args
.
append
(
str
(
param
))
if
with_uuid
:
return
args
args
+=
'--uuid'
,
str
(
self
.
uuid
)
def
start
(
self
):
# Prevent starting when already forked and wait wasn't called.
if
self
.
pid
!=
0
:
raise
AlreadyRunning
(
'Already running with PID %r'
%
self
.
pid
)
command
=
self
.
command
args
=
self
.
_args
()
global
coverage
global
coverage
if
coverage
:
if
coverage
:
cls
=
self
.
__class__
cls
=
self
.
__class__
...
@@ -179,7 +174,7 @@ class NEOProcess(object):
...
@@ -179,7 +174,7 @@ class NEOProcess(object):
os
.
close
(
self
.
_coverage_fd
)
os
.
close
(
self
.
_coverage_fd
)
os
.
write
(
w
,
'
\
0
'
)
os
.
write
(
w
,
'
\
0
'
)
sys
.
argv
=
[
command
]
+
args
sys
.
argv
=
[
command
]
+
args
getattr
(
neo
.
scripts
,
command
).
mai
n
()
self
.
ru
n
()
status
=
0
status
=
0
except
SystemExit
,
e
:
except
SystemExit
,
e
:
status
=
e
.
code
status
=
e
.
code
...
@@ -203,6 +198,9 @@ class NEOProcess(object):
...
@@ -203,6 +198,9 @@ class NEOProcess(object):
logging
.
info
(
'pid %u: %s %s'
,
logging
.
info
(
'pid %u: %s %s'
,
self
.
pid
,
command
,
' '
.
join
(
map
(
repr
,
args
)))
self
.
pid
,
command
,
' '
.
join
(
map
(
repr
,
args
)))
def
run
(
self
):
raise
NotImplementedError
def
child_coverage
(
self
):
def
child_coverage
(
self
):
r
=
self
.
_coverage_fd
r
=
self
.
_coverage_fd
if
r
is
not
None
:
if
r
is
not
None
:
...
@@ -249,11 +247,32 @@ class NEOProcess(object):
...
@@ -249,11 +247,32 @@ class NEOProcess(object):
self
.
kill
()
self
.
kill
()
self
.
wait
()
self
.
wait
()
def
getPID
(
self
):
def
isAlive
(
self
):
return
self
.
pid
try
:
return
psutil
.
Process
(
self
.
pid
).
status
()
!=
psutil
.
STATUS_ZOMBIE
except
psutil
.
NoSuchProcess
:
return
False
class
NEOProcess
(
Process
):
def
__init__
(
self
,
command
,
uuid
,
arg_dict
):
try
:
__import__
(
'neo.scripts.'
+
command
,
level
=
0
)
except
ImportError
:
raise
NotFound
(
command
+
' not found'
)
super
(
NEOProcess
,
self
).
__init__
(
command
,
arg_dict
)
self
.
setUUID
(
uuid
)
def
_args
(
self
):
args
=
super
(
NEOProcess
,
self
).
_args
()
if
self
.
uuid
:
args
+=
'--uuid'
,
str
(
self
.
uuid
)
return
args
def
run
(
self
):
getattr
(
neo
.
scripts
,
self
.
command
).
main
()
def
getUUID
(
self
):
def
getUUID
(
self
):
assert
self
.
with_uuid
,
'UUID disabled on this process'
return
self
.
uuid
return
self
.
uuid
def
setUUID
(
self
,
uuid
):
def
setUUID
(
self
,
uuid
):
...
@@ -262,12 +281,6 @@ class NEOProcess(object):
...
@@ -262,12 +281,6 @@ class NEOProcess(object):
"""
"""
self
.
uuid
=
uuid
self
.
uuid
=
uuid
def
isAlive
(
self
):
try
:
return
psutil
.
Process
(
self
.
pid
).
status
()
!=
psutil
.
STATUS_ZOMBIE
except
psutil
.
NoSuchProcess
:
return
False
class
NEOCluster
(
object
):
class
NEOCluster
(
object
):
SSL
=
None
SSL
=
None
...
...
neo/tests/zeo_cluster.py
0 → 100644
View file @
b621a98f
from
__future__
import
print_function
import
os
import
signal
import
tempfile
import
ZEO.runzeo
from
ZEO.ClientStorage
import
ClientStorage
as
_ClientStorage
from
.
import
buildUrlFromString
,
ADDRESS_TYPE
,
IP_VERSION_FORMAT_DICT
from
.functional
import
AlreadyStopped
,
PortAllocator
,
Process
class
ZEOProcess
(
Process
):
def
__init__
(
self
,
**
kw
):
super
(
ZEOProcess
,
self
).
__init__
(
'runzeo'
,
kw
)
def
run
(
self
):
from
ZEO.runzeo
import
ZEOServer
del
ZEOServer
.
handle_sigusr2
getattr
(
ZEO
,
self
.
command
).
main
()
class
ClientStorage
(
_ClientStorage
):
@
property
def
restore
(
self
):
raise
AttributeError
(
'IStorageRestoreable disabled'
)
class
ZEOCluster
(
object
):
def
start
(
self
):
self
.
zodb_storage_list
=
[]
local_ip
=
IP_VERSION_FORMAT_DICT
[
ADDRESS_TYPE
]
port_allocator
=
PortAllocator
()
port
=
port_allocator
.
allocate
(
ADDRESS_TYPE
,
local_ip
)
self
.
address
=
buildUrlFromString
(
local_ip
),
port
temp_dir
=
tempfile
.
mkdtemp
(
prefix
=
'neo_'
)
print
(
'Using temp directory'
,
temp_dir
)
self
.
zeo
=
ZEOProcess
(
address
=
'%s:%s'
%
self
.
address
,
filename
=
os
.
path
.
join
(
temp_dir
,
'Data.fs'
))
port_allocator
.
release
()
self
.
zeo
.
start
()
def
stop
(
self
):
storage_list
=
self
.
zodb_storage_list
zeo
=
self
.
zeo
del
self
.
zeo
,
self
.
zodb_storage_list
try
:
for
storage
in
storage_list
:
storage
.
close
()
zeo
.
kill
(
signal
.
SIGUSR2
)
except
AlreadyStopped
:
pass
else
:
zeo
.
child_coverage
()
zeo
.
kill
(
signal
.
SIGKILL
)
zeo
.
wait
()
def
getZODBStorage
(
self
):
storage
=
ClientStorage
(
self
.
address
)
self
.
zodb_storage_list
.
append
(
storage
)
return
storage
def
setupDB
(
self
):
pass
tools/matrix
View file @
b621a98f
#!/usr/bin/env python
#!/usr/bin/env python
from
__future__
import
print_function
import
sys
import
sys
import
os
import
os
import
math
import
math
...
@@ -17,6 +17,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -17,6 +17,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
def
add_options
(
self
,
parser
):
def
add_options
(
self
,
parser
):
parser
.
add_option
(
'-d'
,
'--datafs'
)
parser
.
add_option
(
'-d'
,
'--datafs'
)
parser
.
add_option
(
'-z'
,
'--zeo'
,
action
=
"store_true"
)
parser
.
add_option
(
''
,
'--min-storages'
,
type
=
'int'
,
default
=
1
)
parser
.
add_option
(
''
,
'--min-storages'
,
type
=
'int'
,
default
=
1
)
parser
.
add_option
(
''
,
'--max-storages'
,
type
=
'int'
,
default
=
2
)
parser
.
add_option
(
''
,
'--max-storages'
,
type
=
'int'
,
default
=
2
)
parser
.
add_option
(
''
,
'--min-replicas'
,
type
=
'int'
,
default
=
0
)
parser
.
add_option
(
''
,
'--min-replicas'
,
type
=
'int'
,
default
=
0
)
...
@@ -33,6 +34,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -33,6 +34,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
min_r
=
options
.
min_replicas
,
min_r
=
options
.
min_replicas
,
max_r
=
options
.
max_replicas
,
max_r
=
options
.
max_replicas
,
threaded
=
options
.
threaded
,
threaded
=
options
.
threaded
,
zeo
=
options
.
zeo
,
)
)
def
start
(
self
):
def
start
(
self
):
...
@@ -47,22 +49,28 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -47,22 +49,28 @@ class MatrixImportBenchmark(BenchmarkRunner):
if
storages
[
-
1
]
<
max_s
:
if
storages
[
-
1
]
<
max_s
:
storages
.
append
(
max_s
)
storages
.
append
(
max_s
)
replicas
=
range
(
min_r
,
max_r
+
1
)
replicas
=
range
(
min_r
,
max_r
+
1
)
result_list
=
[
self
.
runMatrix
(
storages
,
replicas
)
for
x
in
xrange
(
self
.
_config
.
repeat
)]
results
=
{}
results
=
{}
for
s
in
storages
:
def
merge_min
(
a
,
b
):
results
[
s
]
=
z
=
{}
for
k
,
vb
in
b
.
iteritems
():
for
r
in
replicas
:
try
:
if
r
<
s
:
va
=
a
[
k
]
x
=
[
x
[
s
][
r
]
for
x
in
result_list
if
x
[
s
][
r
]
is
not
None
]
except
KeyError
:
if
x
:
pass
z
[
r
]
=
min
(
x
)
else
:
else
:
z
[
r
]
=
None
if
type
(
va
)
is
dict
:
merge_min
(
va
,
vb
)
continue
if
vb
is
None
or
None
is
not
va
<=
vb
:
continue
a
[
k
]
=
vb
for
x
in
xrange
(
self
.
_config
.
repeat
):
merge_min
(
results
,
self
.
runMatrix
(
storages
,
replicas
))
return
self
.
buildReport
(
storages
,
replicas
,
results
)
return
self
.
buildReport
(
storages
,
replicas
,
results
)
def
runMatrix
(
self
,
storages
,
replicas
):
def
runMatrix
(
self
,
storages
,
replicas
):
stats
=
{}
stats
=
{}
if
self
.
_config
.
zeo
:
stats
[
'zeo'
]
=
self
.
runImport
()
for
s
in
storages
:
for
s
in
storages
:
stats
[
s
]
=
z
=
{}
stats
[
s
]
=
z
=
{}
for
r
in
replicas
:
for
r
in
replicas
:
...
@@ -70,7 +78,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -70,7 +78,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
z
[
r
]
=
self
.
runImport
(
1
,
s
,
r
,
12
*
s
//
(
1
+
r
))
z
[
r
]
=
self
.
runImport
(
1
,
s
,
r
,
12
*
s
//
(
1
+
r
))
return
stats
return
stats
def
runImport
(
self
,
masters
,
storages
,
replicas
,
partition
s
):
def
runImport
(
self
,
*
neo_arg
s
):
datafs
=
self
.
_config
.
datafs
datafs
=
self
.
_config
.
datafs
if
datafs
:
if
datafs
:
dfs_storage
=
FileStorage
(
file_name
=
self
.
_config
.
datafs
)
dfs_storage
=
FileStorage
(
file_name
=
self
.
_config
.
datafs
)
...
@@ -79,28 +87,36 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -79,28 +87,36 @@ class MatrixImportBenchmark(BenchmarkRunner):
import
random
,
neo
.
tests
.
stat_zodb
import
random
,
neo
.
tests
.
stat_zodb
dfs_storage
=
getattr
(
neo
.
tests
.
stat_zodb
,
datafs
)(
dfs_storage
=
getattr
(
neo
.
tests
.
stat_zodb
,
datafs
)(
random
.
Random
(
0
)).
as_storage
(
5000
)
random
.
Random
(
0
)).
as_storage
(
5000
)
print
"Import of %s with m=%s, s=%s, r=%s, p=%s"
%
(
info
=
"Import of "
+
datafs
datafs
,
masters
,
storages
,
replicas
,
partitions
)
if
neo_args
:
masters
,
storages
,
replicas
,
partitions
=
neo_args
info
+=
" with m=%s, s=%s, r=%s, p=%s"
%
(
masters
,
storages
,
replicas
,
partitions
)
if
self
.
_config
.
threaded
:
if
self
.
_config
.
threaded
:
from
neo.tests.threaded
import
NEOCluster
from
neo.tests.threaded
import
NEOCluster
else
:
else
:
from
neo.tests.functional
import
NEOCluster
from
neo.tests.functional
import
NEOCluster
neo
=
NEOCluster
(
zodb
=
NEOCluster
(
db_list
=
[
'%s_matrix_%u'
%
(
DB_PREFIX
,
i
)
for
i
in
xrange
(
storages
)],
db_list
=
[
'%s_matrix_%u'
%
(
DB_PREFIX
,
i
)
for
i
in
xrange
(
storages
)],
clear_databases
=
True
,
clear_databases
=
True
,
master_count
=
masters
,
master_count
=
masters
,
partitions
=
partitions
,
partitions
=
partitions
,
replicas
=
replicas
,
replicas
=
replicas
,
)
)
else
:
from
neo.tests.zeo_cluster
import
ZEOCluster
info
+=
" with ZEO"
zodb
=
ZEOCluster
()
print
(
info
)
try
:
try
:
neo
.
start
()
zodb
.
start
()
try
:
try
:
neo_storage
=
neo
.
getZODBStorage
()
storage
=
zodb
.
getZODBStorage
()
if
not
self
.
_config
.
threaded
:
if
n
eo_args
and
n
ot
self
.
_config
.
threaded
:
assert
len
(
neo
.
getStorageList
())
==
storages
assert
len
(
zodb
.
getStorageList
())
==
storages
neo
.
expectOudatedCells
(
number
=
0
)
zodb
.
expectOudatedCells
(
number
=
0
)
start
=
time
()
start
=
time
()
neo_
storage
.
copyTransactionsFrom
(
dfs_storage
)
storage
.
copyTransactionsFrom
(
dfs_storage
)
end
=
time
()
end
=
time
()
size
=
dfs_storage
.
getSize
()
size
=
dfs_storage
.
getSize
()
if
self
.
_size
is
None
:
if
self
.
_size
is
None
:
...
@@ -108,15 +124,14 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -108,15 +124,14 @@ class MatrixImportBenchmark(BenchmarkRunner):
else
:
else
:
assert
self
.
_size
==
size
assert
self
.
_size
==
size
finally
:
finally
:
neo
.
stop
()
zodb
.
stop
()
# Clear DB if no error happened.
# Clear DB if no error happened.
neo
.
setupDB
()
zodb
.
setupDB
()
return
end
-
start
return
end
-
start
except
:
except
:
traceback
.
print_exc
()
traceback
.
print_exc
()
self
.
error_log
+=
"Import with m=%s, s=%s, r=%s, p=%s:"
%
(
self
.
error_log
+=
"%s:
\
n
%s
\
n
"
%
(
masters
,
storages
,
replicas
,
partitions
)
info
,
''
.
join
(
traceback
.
format_exc
()))
self
.
error_log
+=
"
\
n
%s
\
n
"
%
''
.
join
(
traceback
.
format_exc
())
def
buildReport
(
self
,
storages
,
replicas
,
results
):
def
buildReport
(
self
,
storages
,
replicas
,
results
):
# draw an array with results
# draw an array with results
...
@@ -130,6 +145,14 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -130,6 +145,14 @@ class MatrixImportBenchmark(BenchmarkRunner):
report += sep
report += sep
failures = 0
failures = 0
speedlist = []
speedlist = []
if self._config.zeo:
result = results['
zeo
']
if result is None:
result = '
FAIL
'
failures += 1
else:
result = '
%
.
1
f
kB
/
s
' % (dfs_size / (result * 1e3))
self.add_status('
ZEO
', result)
for s in storages:
for s in storages:
values = []
values = []
assert s in results
assert s in results
...
@@ -151,7 +174,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
...
@@ -151,7 +174,7 @@ class MatrixImportBenchmark(BenchmarkRunner):
if failures:
if failures:
info = '
%
d
failures
' % (failures, )
info = '
%
d
failures
' % (failures, )
else:
else:
info = '
%
.
1
f
K
B
/
s
' % (sum(speedlist) / len(speedlist))
info = '
%
.
1
f
k
B
/
s
' % (sum(speedlist) / len(speedlist))
return info, report
return info, report
def main(args=None):
def main(args=None):
...
...
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