Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZEO
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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
ZEO
Commits
1ce6fd78
Commit
1ce6fd78
authored
Jul 08, 2016
by
Jim Fulton
Committed by
GitHub
Jul 08, 2016
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #41 from zopefoundation/py2
Python 2 support
parents
29bf7bc0
9b8cfe9e
Changes
17
Show whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
177 additions
and
122 deletions
+177
-122
.travis.yml
.travis.yml
+2
-0
setup.py
setup.py
+7
-5
src/ZEO/StorageServer.py
src/ZEO/StorageServer.py
+0
-1
src/ZEO/asyncio/__init__.py
src/ZEO/asyncio/__init__.py
+1
-7
src/ZEO/asyncio/base.py
src/ZEO/asyncio/base.py
+8
-2
src/ZEO/asyncio/client.py
src/ZEO/asyncio/client.py
+17
-10
src/ZEO/asyncio/mtacceptor.py
src/ZEO/asyncio/mtacceptor.py
+6
-1
src/ZEO/asyncio/server.py
src/ZEO/asyncio/server.py
+23
-19
src/ZEO/asyncio/testing.py
src/ZEO/asyncio/testing.py
+19
-7
src/ZEO/asyncio/tests.py
src/ZEO/asyncio/tests.py
+13
-6
src/ZEO/tests/forker.py
src/ZEO/tests/forker.py
+13
-2
src/ZEO/tests/protocols.test
src/ZEO/tests/protocols.test
+11
-5
src/ZEO/tests/testConfig.py
src/ZEO/tests/testConfig.py
+3
-1
src/ZEO/tests/testZEO.py
src/ZEO/tests/testZEO.py
+13
-24
src/ZEO/tests/testZEO2.py
src/ZEO/tests/testZEO2.py
+15
-16
src/ZEO/tests/testssl.py
src/ZEO/tests/testssl.py
+25
-15
tox.ini
tox.ini
+1
-1
No files found.
.travis.yml
View file @
1ce6fd78
...
...
@@ -2,6 +2,8 @@ language: python
sudo
:
false
matrix
:
include
:
-
os
:
linux
python
:
2.7
-
os
:
linux
python
:
3.4
-
os
:
linux
...
...
setup.py
View file @
1ce6fd78
...
...
@@ -21,12 +21,12 @@ if sys.version_info < (2, 7):
print
(
"This version of ZEO requires Python 2.7 or higher"
)
sys
.
exit
(
0
)
if
(
3
,
0
)
<
sys
.
version_info
<
(
3
,
3
):
print
(
"This version of ZEO requires Python 3.
3
or higher"
)
if
(
3
,
0
)
<
sys
.
version_info
<
(
3
,
4
):
print
(
"This version of ZEO requires Python 3.
4
or higher"
)
sys
.
exit
(
0
)
install_requires
=
[
'ZODB >= 5.0.0a
1
'
,
'ZODB >= 5.0.0a
5
'
,
'six'
,
'transaction >= 1.6.0'
,
'persistent >= 4.1.0'
,
...
...
@@ -38,12 +38,14 @@ install_requires = [
tests_require
=
[
'zope.testing'
,
'manuel'
,
'random2'
,
'mock'
]
if
sys
.
version_info
>=
(
3
,
5
):
install_requires
.
append
(
'uvloop'
)
if
sys
.
version_info
[:
2
]
<
(
3
,
):
install_requires
.
extend
((
'futures'
,
'trollius'
)
)
classifiers
=
"""
\
Intended Audience :: Developers
License :: OSI Approved :: Zope Public License
Programming Language :: Python :: 2
Programming Language :: Python :: 2.7
Programming Language :: Python :: 3
Programming Language :: Python :: 3.4
Programming Language :: Python :: 3.5
...
...
src/ZEO/StorageServer.py
View file @
1ce6fd78
...
...
@@ -19,7 +19,6 @@ file storage or Berkeley storage.
TODO: Need some basic access control-- a declaration of the methods
exported for invocation by the server.
"""
import
asyncio
import
codecs
import
itertools
import
logging
...
...
src/ZEO/asyncio/__init__.py
View file @
1ce6fd78
import
sys
if
sys
.
version_info
>=
(
3
,
5
):
import
asyncio
import
uvloop
asyncio
.
set_event_loop_policy
(
uvloop
.
EventLoopPolicy
())
#
src/ZEO/asyncio/base.py
View file @
1ce6fd78
from
struct
import
unpack
import
asyncio
from
.._compat
import
PY3
if
PY3
:
import
asyncio
else
:
import
trollius
as
asyncio
import
logging
import
socket
from
struct
import
unpack
import
sys
from
.marshal
import
encoder
...
...
src/ZEO/asyncio/client.py
View file @
1ce6fd78
from
.._compat
import
PY3
if
PY3
:
import
asyncio
else
:
import
trollius
as
asyncio
from
ZEO.Exceptions
import
ClientDisconnected
from
ZODB.ConflictResolution
import
ResolvedSerial
import
asyncio
import
concurrent.futures
import
logging
import
random
...
...
@@ -251,7 +257,7 @@ class Protocol(base.Protocol):
self
.
heartbeat_handle
=
self
.
loop
.
call_later
(
self
.
heartbeat_interval
,
self
.
heartbeat
)
class
Client
:
class
Client
(
object
)
:
"""asyncio low-level ZEO client interface
"""
...
...
@@ -589,7 +595,7 @@ class Client:
else
:
return
protocol
.
read_only
class
ClientRunner
:
class
ClientRunner
(
object
)
:
def
set_options
(
self
,
addrs
,
wrapper
,
cache
,
storage_key
,
read_only
,
timeout
=
30
,
disconnect_poll
=
1
,
...
...
@@ -608,7 +614,9 @@ class ClientRunner:
from
concurrent.futures
import
Future
call_soon_threadsafe
=
loop
.
call_soon_threadsafe
def
call
(
meth
,
*
args
,
timeout
=
None
):
def
call
(
meth
,
*
args
,
**
kw
):
timeout
=
kw
.
pop
(
'timeout'
,
None
)
assert
not
kw
result
=
Future
()
call_soon_threadsafe
(
meth
,
result
,
*
args
)
return
self
.
wait_for_result
(
result
,
timeout
)
...
...
@@ -624,8 +632,8 @@ class ClientRunner:
else
:
raise
def
call
(
self
,
method
,
*
args
,
timeout
=
None
):
return
self
.
__call
(
self
.
call_threadsafe
,
method
,
args
,
timeout
=
timeout
)
def
call
(
self
,
method
,
*
args
,
**
kw
):
return
self
.
__call
(
self
.
call_threadsafe
,
method
,
args
,
**
kw
)
def
call_future
(
self
,
method
,
*
args
):
# for tests
...
...
@@ -702,8 +710,8 @@ class ClientThread(ClientRunner):
self
.
thread
=
threading
.
Thread
(
target
=
self
.
run
,
name
=
"%s zeo client networking thread"
%
client
.
__name__
,
daemon
=
True
,
)
self
.
thread
.
setDaemon
(
True
)
self
.
started
=
threading
.
Event
()
self
.
thread
.
start
()
self
.
started
.
wait
()
...
...
@@ -715,7 +723,6 @@ class ClientThread(ClientRunner):
loop
=
None
try
:
loop
=
asyncio
.
new_event_loop
()
asyncio
.
set_event_loop
(
loop
)
self
.
setup_delegation
(
loop
)
self
.
started
.
set
()
loop
.
run_forever
()
...
...
@@ -741,13 +748,13 @@ class ClientThread(ClientRunner):
def
close
(
self
):
if
not
self
.
closed
:
self
.
closed
=
True
super
().
close
()
super
(
ClientThread
,
self
).
close
()
self
.
loop
.
call_soon_threadsafe
(
self
.
loop
.
stop
)
self
.
thread
.
join
(
9
)
if
self
.
exception
:
raise
self
.
exception
class
Promise
:
class
Promise
(
object
)
:
"""Lightweight future with a partial promise API.
These are lighweight because they call callbacks synchronously
...
...
src/ZEO/asyncio/mtacceptor.py
View file @
1ce6fd78
...
...
@@ -41,8 +41,13 @@ with:
in ZEO.StorageServer.
"""
from
.._compat
import
PY3
if
PY3
:
import
asyncio
else
:
import
trollius
as
asyncio
import
asyncio
import
asyncore
import
socket
import
threading
...
...
src/ZEO/asyncio/server.py
View file @
1ce6fd78
import
asyncio
from
.._compat
import
PY3
if
PY3
:
import
asyncio
else
:
import
trollius
as
asyncio
import
json
import
logging
import
os
...
...
@@ -62,7 +68,8 @@ class ServerProtocol(base.Protocol):
self
.
close
()
else
:
if
protocol_version
in
self
.
protocols
:
logger
.
info
(
"received handshake %r"
%
protocol_version
)
logger
.
info
(
"received handshake %r"
%
str
(
protocol_version
.
decode
(
'ascii'
)))
self
.
protocol_version
=
protocol_version
self
.
zeo_storage
.
notify_connected
(
self
)
else
:
...
...
@@ -142,7 +149,7 @@ def new_connection(loop, addr, socket, zeo_storage):
cr
=
loop
.
create_connection
((
lambda
:
protocol
),
sock
=
socket
)
asyncio
.
async
(
cr
,
loop
=
loop
)
class
Delay
:
class
Delay
(
object
)
:
"""Used to delay response to client for synchronous calls.
When a synchronous call is made and the original handler returns
...
...
@@ -202,25 +209,23 @@ class MTDelay(Delay):
self
.
protocol
.
call_soon_threadsafe
(
Delay
.
error
,
self
,
exc_info
)
class
Acceptor
:
class
Acceptor
(
object
)
:
def
__init__
(
self
,
storage_server
,
addr
,
ssl
):
self
.
storage_server
=
storage_server
self
.
addr
=
addr
self
.
ssl_context
=
ssl
self
.
event_loop
=
loop
=
asyncio
.
new_event_loop
()
asyncio
.
set_event_loop
(
loop
)
if
isinstance
(
addr
,
tuple
):
cr
=
loop
.
create_server
(
self
.
factory
,
addr
[
0
],
addr
[
1
],
reuse_address
=
True
,
ssl
=
ssl
)
else
:
cr
=
loop
.
create_unix_server
(
self
.
factory
,
addr
,
ssl
=
ssl
)
f
=
asyncio
.
async
(
cr
)
f
=
asyncio
.
async
(
cr
,
loop
=
loop
)
server
=
loop
.
run_until_complete
(
f
)
@
f
.
add_done_callback
def
listenting
(
f
):
server
=
f
.
result
()
self
.
server
=
server
if
isinstance
(
addr
,
tuple
)
and
addr
[
1
]
==
0
:
addrs
=
[
s
.
getsockname
()
for
s
in
server
.
sockets
]
...
...
@@ -229,9 +234,8 @@ class Acceptor:
self
.
addr
=
addrs
[
0
]
else
:
self
.
addr
=
server
.
sockets
[
0
].
getsockname
()[:
len
(
addr
)]
logger
.
info
(
"listening on %s"
,
str
(
addr
))
lo
op
.
run_until_complete
(
f
)
lo
gger
.
info
(
"listening on %s"
,
str
(
addr
)
)
def
factory
(
self
):
try
:
...
...
src/ZEO/asyncio/testing.py
View file @
1ce6fd78
import
asyncio
from
.._compat
import
PY3
if
PY3
:
import
asyncio
else
:
import
trollius
as
asyncio
try
:
ConnectionRefusedError
except
NameError
:
class
ConnectionRefusedError
(
OSError
):
pass
import
pprint
class
Loop
:
class
Loop
(
object
)
:
protocol
=
transport
=
None
...
...
@@ -75,14 +87,14 @@ class Loop:
def
stop
(
self
):
self
.
stopped
=
True
class
Handle
:
class
Handle
(
object
)
:
cancelled
=
False
def
cancel
(
self
):
self
.
cancelled
=
True
class
Transport
:
class
Transport
(
object
)
:
capacity
=
1
<<
64
paused
=
False
...
...
@@ -127,7 +139,7 @@ class Transport:
def
get_extra_info
(
self
,
name
):
return
self
.
extra
[
name
]
class
AsyncRPC
:
class
AsyncRPC
(
object
)
:
"""Adapt an asyncio API to an RPC to help hysterical tests
"""
def
__init__
(
self
,
api
):
...
...
@@ -136,7 +148,7 @@ class AsyncRPC:
def
__getattr__
(
self
,
name
):
return
lambda
*
a
,
**
kw
:
self
.
api
.
call
(
name
,
*
a
,
**
kw
)
class
ClientRunner
:
class
ClientRunner
(
object
)
:
def
__init__
(
self
,
addr
,
client
,
cache
,
storage
,
read_only
,
timeout
,
**
kw
):
...
...
@@ -152,7 +164,7 @@ class ClientRunner:
def
start
(
self
,
wait
=
True
):
pass
def
call
(
self
,
method
,
*
args
,
timeout
=
None
):
def
call
(
self
,
method
,
*
args
,
**
kw
):
return
getattr
(
self
,
method
)(
*
args
)
async
=
async_iter
=
call
...
...
src/ZEO/asyncio/tests.py
View file @
1ce6fd78
from
.._compat
import
PY3
if
PY3
:
import
asyncio
else
:
import
trollius
as
asyncio
from
zope.testing
import
setupstack
from
concurrent.futures
import
Future
from
unittest
import
mock
import
mock
from
ZODB.POSException
import
ReadOnlyError
import
asyncio
import
collections
import
logging
import
pdb
...
...
@@ -27,7 +33,8 @@ class Base(object):
def
unsized
(
self
,
data
,
unpickle
=
False
):
result
=
[]
while
data
:
size
,
message
,
*
data
=
data
size
,
message
=
data
[:
2
]
data
=
data
[
2
:]
self
.
assertEqual
(
struct
.
unpack
(
">I"
,
size
)[
0
],
len
(
message
))
if
unpickle
:
message
=
decode
(
message
)
...
...
@@ -622,7 +629,7 @@ class ClientTests(Base, setupstack.TestCase, ClientRunner):
def
test_ClientDisconnected_on_call_timeout
(
self
):
wrapper
,
cache
,
loop
,
client
,
protocol
,
transport
=
self
.
start
()
self
.
wait_for_result
=
super
().
wait_for_result
self
.
wait_for_result
=
super
(
ClientTests
,
self
).
wait_for_result
self
.
assertRaises
(
ClientDisconnected
,
self
.
call
,
'foo'
)
client
.
ready
=
False
self
.
assertRaises
(
ClientDisconnected
,
self
.
call
,
'foo'
)
...
...
@@ -686,7 +693,7 @@ class ClientTests(Base, setupstack.TestCase, ClientRunner):
self
.
assertTrue
(
handle
.
cancelled
)
class
MemoryCache
:
class
MemoryCache
(
object
)
:
def
__init__
(
self
):
# { oid -> [(start, end, data)] }
...
...
@@ -837,7 +844,7 @@ def response(*data):
def
sized
(
message
):
return
struct
.
pack
(
">I"
,
len
(
message
))
+
message
class
Logging
:
class
Logging
(
object
)
:
def
__init__
(
self
,
level
=
logging
.
ERROR
):
self
.
level
=
level
...
...
src/ZEO/tests/forker.py
View file @
1ce6fd78
...
...
@@ -175,7 +175,7 @@ def stop_runner(thread, config, qin, qout, stop_timeout=9, pid=None):
def
start_zeo_server
(
storage_conf
=
None
,
zeo_conf
=
None
,
port
=
None
,
keep
=
False
,
path
=
'Data.fs'
,
protocol
=
None
,
blob_dir
=
None
,
suicide
=
True
,
debug
=
False
,
threaded
=
False
,
start_timeout
=
150
,
name
=
None
,
threaded
=
False
,
start_timeout
=
33
,
name
=
None
,
):
"""Start a ZEO server in a separate process.
...
...
@@ -231,7 +231,15 @@ def start_zeo_server(storage_conf=None, zeo_conf=None, port=None, keep=False,
)
thread
.
daemon
=
True
thread
.
start
()
try
:
addr
=
qout
.
get
(
timeout
=
start_timeout
)
except
Exception
:
whine
(
"SERVER FAILED TO START"
)
if
thread
.
is_alive
():
whine
(
"Server thread/process is still running"
)
elif
not
threaded
:
whine
(
"Exit status"
,
thread
.
exitcode
)
raise
def
stop
(
stop_timeout
=
99
):
stop_runner
(
thread
,
tmpfile
,
qin
,
qout
,
stop_timeout
)
...
...
@@ -423,3 +431,6 @@ def debug_logging(logger='ZEO', stream='stderr', level=logging.DEBUG):
return
stop
def
whine
(
*
message
):
print
(
*
message
,
file
=
sys
.
stderr
)
sys
.
stderr
.
flush
()
src/ZEO/tests/protocols.test
View file @
1ce6fd78
...
...
@@ -24,8 +24,8 @@ A current client should be able to connect to a old server:
>>> import ZEO, ZODB.blob, transaction
>>> db = ZEO.DB(addr, client='
client
', blob_dir='
blobs
')
>>> wait_connected(db.storage)
>>>
db.storage.protocol_version
b
'
Z4
'
>>>
str(db.storage.protocol_version.decode('
ascii
'))
'
Z4
'
>>> conn = db.open()
>>> conn.root().x = 0
...
...
@@ -103,9 +103,15 @@ A current client should be able to connect to a old server:
# Note that we'
ll
have
to
pull
some
hijinks
:
# >>> import ZEO.asyncio.client
# >>> old_protocols = ZEO.asyncio.client.Protocol.protocols
# >>> ZEO.asyncio.client.Protocol.protocols = [b'Z4']
# >>> db = ZEO.DB(addr, client='client', blob_dir='blobs')
# >>> str(db.storage.protocol_version.decode('ascii'))
# 'Z4'
# >>> wait_connected(db.storage)
# >>> conn = db.open()
# >>> conn.root().x = 0
# >>> transaction.commit()
# >>> len(db.history(conn.root()._p_oid, 99))
# 2
# >>> db = ZEO.DB(addr, client='client', blob_dir='blobs')
# >>> db.storage.protocol_version
...
...
src/ZEO/tests/testConfig.py
View file @
1ce6fd78
...
...
@@ -20,7 +20,7 @@ from ZODB.config import storageFromString
from
.forker
import
start_zeo_server
class
ZEOConfigTest
(
setupstack
.
TestCase
):
class
ZEOConfigTest
Base
(
setupstack
.
TestCase
):
setUp
=
setupstack
.
setUpDirectory
...
...
@@ -86,6 +86,8 @@ class ZEOConfigTest(setupstack.TestCase):
self
.
assertEqual
(
client
.
__name__
,
name
if
name
is
not
None
else
str
(
client
.
_addr
))
class
ZEOConfigTest
(
ZEOConfigTestBase
):
def
test_default_zeo_config
(
self
,
**
client_settings
):
addr
,
stop
=
self
.
start_server
()
...
...
src/ZEO/tests/testZEO.py
View file @
1ce6fd78
...
...
@@ -172,7 +172,7 @@ class GenericTestBase(
self
.
_storage
.
registerDB
(
DummyDB
())
def
getZEOConfig
(
self
):
return
forker
.
ZEOConfig
((
'
'
,
get_port
(
self
)
))
return
forker
.
ZEOConfig
((
'
127.0.0.1'
,
0
))
def
_wrap_client
(
self
,
client
):
return
client
...
...
@@ -475,7 +475,7 @@ class ZRPCConnectionTests(ZEO.tests.ConnectionTests.CommonSetupTearDown):
handler
=
InstalledHandler
(
'ZEO.asyncio.client'
)
import
ZODB.POSException
self
.
assertRaises
(
TypeError
,
self
.
_storage
.
history
,
z64
,
None
)
self
.
assertTrue
(
" from server: builtins.TypeError"
in
str
(
handler
))
self
.
assertTrue
(
re
.
search
(
" from server: .*TypeError"
,
str
(
handler
)
))
# POSKeyErrors and ConflictErrors aren't logged:
handler
.
clear
()
...
...
@@ -557,10 +557,9 @@ class CommonBlobTests:
t
=
transaction
.
Transaction
()
try
:
self
.
_storage
.
tpc_begin
(
t
)
r1
=
self
.
_storage
.
storeBlob
(
oid
,
ZERO
,
data
,
tfname
,
''
,
t
)
r2
=
self
.
_storage
.
tpc_vote
(
t
)
revid
=
handle_serials
(
oid
,
r1
,
r2
)
self
.
_storage
.
tpc_finish
(
t
)
self
.
_storage
.
storeBlob
(
oid
,
ZERO
,
data
,
tfname
,
''
,
t
)
self
.
_storage
.
tpc_vote
(
t
)
revid
=
self
.
_storage
.
tpc_finish
(
t
)
except
:
self
.
_storage
.
tpc_abort
(
t
)
raise
...
...
@@ -598,10 +597,9 @@ class CommonBlobTests:
t
=
transaction
.
Transaction
()
try
:
self
.
_storage
.
tpc_begin
(
t
)
r1
=
self
.
_storage
.
storeBlob
(
oid
,
ZERO
,
data
,
tfname
,
''
,
t
)
r2
=
self
.
_storage
.
tpc_vote
(
t
)
serial
=
handle_serials
(
oid
,
r1
,
r2
)
self
.
_storage
.
tpc_finish
(
t
)
self
.
_storage
.
storeBlob
(
oid
,
ZERO
,
data
,
tfname
,
''
,
t
)
self
.
_storage
.
tpc_vote
(
t
)
serial
=
self
.
_storage
.
tpc_finish
(
t
)
except
:
self
.
_storage
.
tpc_abort
(
t
)
raise
...
...
@@ -665,10 +663,9 @@ class BlobAdaptedFileStorageTests(FullGenericTests, CommonBlobTests):
t
=
transaction
.
Transaction
()
try
:
self
.
_storage
.
tpc_begin
(
t
)
r1
=
self
.
_storage
.
storeBlob
(
oid
,
ZERO
,
data
,
tfname
,
''
,
t
)
r2
=
self
.
_storage
.
tpc_vote
(
t
)
revid
=
handle_serials
(
oid
,
r1
,
r2
)
self
.
_storage
.
tpc_finish
(
t
)
self
.
_storage
.
storeBlob
(
oid
,
ZERO
,
data
,
tfname
,
''
,
t
)
self
.
_storage
.
tpc_vote
(
t
)
revid
=
self
.
_storage
.
tpc_finish
(
t
)
except
:
self
.
_storage
.
tpc_abort
(
t
)
raise
...
...
@@ -690,15 +687,7 @@ class BlobAdaptedFileStorageTests(FullGenericTests, CommonBlobTests):
check_data
(
server_filename
)
# If we remove it from the cache and call loadBlob, it should
# come back. We can do this in many threads. We'll instrument
# the method that is used to request data from teh server to
# verify that it is only called once.
sendBlob_org
=
ZEO
.
ServerStub
.
StorageServer
.
sendBlob
calls
=
[]
def
sendBlob
(
self
,
oid
,
serial
):
calls
.
append
((
oid
,
serial
))
sendBlob_org
(
self
,
oid
,
serial
)
# come back. We can do this in many threads.
ZODB
.
blob
.
remove_committed
(
filename
)
returns
=
[]
...
...
@@ -1515,7 +1504,7 @@ def can_use_empty_string_for_local_host_on_client():
"""
slow_test_classes
=
[
#
BlobAdaptedFileStorageTests, BlobWritableCacheTests,
BlobAdaptedFileStorageTests
,
BlobWritableCacheTests
,
MappingStorageTests
,
DemoStorageTests
,
FileStorageTests
,
FileStorageSSLTests
,
FileStorageHexTests
,
FileStorageClientHexTests
,
...
...
src/ZEO/tests/testZEO2.py
View file @
1ce6fd78
...
...
@@ -94,8 +94,7 @@ raised to the client:
>>> zs1.tpc_abort('0') # doctest: +ELLIPSIS
Error raised in delayed method
Traceback (most recent call last):
...
ZODB.POSException.ConflictError: ...
...ConflictError: ...
error 1 database conflict error ...
The transaction is aborted by the server:
...
...
@@ -227,13 +226,13 @@ We start a transaction and vote, this leads to getting the lock.
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
>>> tid1 = start_trans(zs1)
>>> resolved1 = zs1.vote(tid1) # doctest: +ELLIPSIS
ZEO.StorageServer DEBUG
(test-addr-1) ('1') lock: transactions waiting: 0
ZEO.StorageServer BLATHER
(test-addr-1) Preparing to commit transaction: 1 objects,
108
bytes
(test-addr-1) Preparing to commit transaction: 1 objects,
...
bytes
If another client tried to vote, it's lock request will be queued and
a delay will be returned:
...
...
@@ -242,7 +241,7 @@ a delay will be returned:
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
>>> tid2 = start_trans(zs2)
>>> delay = zs2.vote(tid2)
ZEO.StorageServer DEBUG
...
...
@@ -305,55 +304,55 @@ increased, so does the logging level:
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer DEBUG
(test-addr-10) ('1') queue lock: transactions waiting: 2
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer DEBUG
(test-addr-11) ('1') queue lock: transactions waiting: 3
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer WARNING
(test-addr-12) ('1') queue lock: transactions waiting: 4
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer WARNING
(test-addr-13) ('1') queue lock: transactions waiting: 5
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer WARNING
(test-addr-14) ('1') queue lock: transactions waiting: 6
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer WARNING
(test-addr-15) ('1') queue lock: transactions waiting: 7
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer WARNING
(test-addr-16) ('1') queue lock: transactions waiting: 8
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer WARNING
(test-addr-17) ('1') queue lock: transactions waiting: 9
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
ZEO.StorageServer CRITICAL
(test-addr-18) ('1') queue lock: transactions waiting: 10
...
...
@@ -484,7 +483,7 @@ ZEOStorage as closed and see if trying to get a lock cleans it up:
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
>>> tid1 = start_trans(zs1)
>>> resolved1 = zs1.vote(tid1) # doctest: +ELLIPSIS
ZEO.StorageServer DEBUG
...
...
@@ -500,7 +499,7 @@ ZEOStorage as closed and see if trying to get a lock cleans it up:
ZEO.asyncio.base INFO
Connected server protocol
ZEO.asyncio.server INFO
received handshake
b
'Z5'
received handshake 'Z5'
>>> tid2 = start_trans(zs2)
>>> resolved2 = zs2.vote(tid2) # doctest: +ELLIPSIS
ZEO.StorageServer DEBUG
...
...
src/ZEO/tests/testssl.py
View file @
1ce6fd78
from
.._compat
import
PY3
import
mock
import
os
import
ssl
...
...
@@ -7,7 +9,7 @@ from ZODB.config import storageFromString
from
..Exceptions
import
ClientDisconnected
from
..
import
runzeo
from
.testConfig
import
ZEOConfigTest
from
.testConfig
import
ZEOConfigTest
Base
here
=
os
.
path
.
dirname
(
__file__
)
server_cert
=
os
.
path
.
join
(
here
,
'server.pem'
)
...
...
@@ -17,7 +19,7 @@ serverpw_key = os.path.join(here, 'serverpw_key.pem')
client_cert
=
os
.
path
.
join
(
here
,
'client.pem'
)
client_key
=
os
.
path
.
join
(
here
,
'client_key.pem'
)
class
SSLConfigTest
(
ZEOConfigTest
):
class
SSLConfigTest
(
ZEOConfigTest
Base
):
def
test_ssl_basic
(
self
):
# This shows that configuring ssl has an actual effect on connections.
...
...
@@ -112,8 +114,13 @@ class SSLConfigTest(ZEOConfigTest):
)
stop
()
@
mock
.
patch
((
'asyncio'
if
PY3
else
'trollius'
)
+
'.async'
)
@
mock
.
patch
((
'asyncio'
if
PY3
else
'trollius'
)
+
'.set_event_loop'
)
@
mock
.
patch
((
'asyncio'
if
PY3
else
'trollius'
)
+
'.new_event_loop'
)
class
SSLConfigTestMockiavellian
(
ZEOConfigTestBase
):
@
mock
.
patch
(
'ssl.create_default_context'
)
def
test_ssl_mockiavellian_server_no_ssl
(
self
,
factory
):
def
test_ssl_mockiavellian_server_no_ssl
(
self
,
factory
,
*
_
):
server
=
create_server
()
self
.
assertFalse
(
factory
.
called
)
self
.
assertEqual
(
server
.
acceptor
.
ssl_context
,
None
)
...
...
@@ -134,13 +141,13 @@ class SSLConfigTest(ZEOConfigTest):
self
.
assertEqual
(
context
.
check_hostname
,
check_hostname
)
@
mock
.
patch
(
'ssl.create_default_context'
)
def
test_ssl_mockiavellian_server_ssl_no_auth
(
self
,
factory
):
def
test_ssl_mockiavellian_server_ssl_no_auth
(
self
,
factory
,
*
_
):
with
self
.
assertRaises
(
SystemExit
):
# auth is required
create_server
(
certificate
=
server_cert
,
key
=
server_key
)
@
mock
.
patch
(
'ssl.create_default_context'
)
def
test_ssl_mockiavellian_server_ssl_auth_file
(
self
,
factory
):
def
test_ssl_mockiavellian_server_ssl_auth_file
(
self
,
factory
,
*
_
):
server
=
create_server
(
certificate
=
server_cert
,
key
=
server_key
,
authenticate
=
__file__
)
context
=
server
.
acceptor
.
ssl_context
...
...
@@ -148,7 +155,7 @@ class SSLConfigTest(ZEOConfigTest):
server
.
close
()
@
mock
.
patch
(
'ssl.create_default_context'
)
def
test_ssl_mockiavellian_server_ssl_auth_dir
(
self
,
factory
):
def
test_ssl_mockiavellian_server_ssl_auth_dir
(
self
,
factory
,
*
_
):
server
=
create_server
(
certificate
=
server_cert
,
key
=
server_key
,
authenticate
=
here
)
context
=
server
.
acceptor
.
ssl_context
...
...
@@ -156,7 +163,7 @@ class SSLConfigTest(ZEOConfigTest):
server
.
close
()
@
mock
.
patch
(
'ssl.create_default_context'
)
def
test_ssl_mockiavellian_server_ssl_pw
(
self
,
factory
):
def
test_ssl_mockiavellian_server_ssl_pw
(
self
,
factory
,
*
_
):
server
=
create_server
(
certificate
=
server_cert
,
key
=
server_key
,
...
...
@@ -170,7 +177,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_no_ssl
(
self
,
ClientStorage
,
factory
):
def
test_ssl_mockiavellian_client_no_ssl
(
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
()
self
.
assertFalse
(
'ssl'
in
ClientStorage
.
call_args
[
1
])
self
.
assertFalse
(
'ssl_server_hostname'
in
ClientStorage
.
call_args
[
1
])
...
...
@@ -178,7 +185,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_server_signed
(
self
,
ClientStorage
,
factory
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
(
certificate
=
client_cert
,
key
=
client_key
)
context
=
ClientStorage
.
call_args
[
1
][
'ssl'
]
...
...
@@ -191,7 +198,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_auth_dir
(
self
,
ClientStorage
,
factory
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
(
certificate
=
client_cert
,
key
=
client_key
,
authenticate
=
here
)
...
...
@@ -207,7 +214,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_auth_file
(
self
,
ClientStorage
,
factory
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
(
certificate
=
client_cert
,
key
=
client_key
,
authenticate
=
server_cert
)
...
...
@@ -223,7 +230,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_pw
(
self
,
ClientStorage
,
factory
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
(
certificate
=
client_cert
,
key
=
client_key
,
...
...
@@ -241,7 +248,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_server_hostname
(
self
,
ClientStorage
,
factory
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
(
certificate
=
client_cert
,
key
=
client_key
,
authenticate
=
server_cert
,
...
...
@@ -258,7 +265,7 @@ class SSLConfigTest(ZEOConfigTest):
@
mock
.
patch
(
'ssl.create_default_context'
)
@
mock
.
patch
(
'ZEO.ClientStorage.ClientStorage'
)
def
test_ssl_mockiavellian_client_check_hostname
(
self
,
ClientStorage
,
factory
self
,
ClientStorage
,
factory
,
*
_
):
client
=
ssl_client
(
certificate
=
client_cert
,
key
=
client_key
,
authenticate
=
server_cert
,
...
...
@@ -320,7 +327,10 @@ pwfunc = lambda : '1234'
def
test_suite
():
return
unittest
.
makeSuite
(
SSLConfigTest
)
return
unittest
.
TestSuite
((
unittest
.
makeSuite
(
SSLConfigTest
),
unittest
.
makeSuite
(
SSLConfigTestMockiavellian
),
))
# Helpers for other tests:
...
...
tox.ini
View file @
1ce6fd78
[tox]
envlist
=
py34,py35,simple
py
27,py
34,py35,simple
[testenv]
commands
=
...
...
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