Commit 1ce6fd78 authored by Jim Fulton's avatar Jim Fulton Committed by GitHub

Merge pull request #41 from zopefoundation/py2

Python 2 support
parents 29bf7bc0 9b8cfe9e
......@@ -2,6 +2,8 @@ language: python
sudo: false
matrix:
include:
- os: linux
python: 2.7
- os: linux
python: 3.4
- os: linux
......
......@@ -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.0a1',
'ZODB >= 5.0.0a5',
'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
......
......@@ -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
......
import sys
if sys.version_info >= (3, 5):
import asyncio
import uvloop
asyncio.set_event_loop_policy(uvloop.EventLoopPolicy())
#
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
......
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
......
......@@ -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
......
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,36 +209,33 @@ 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]
addrs = [a for a in addrs if len(a) == len(addr)]
if addrs:
self.addr = addrs[0]
else:
self.addr = server.sockets[0].getsockname()[:len(addr)]
logger.info("listening on %s", str(addr))
self.server = server
if isinstance(addr, tuple) and addr[1] == 0:
addrs = [s.getsockname() for s in server.sockets]
addrs = [a for a in addrs if len(a) == len(addr)]
if addrs:
self.addr = addrs[0]
else:
self.addr = server.sockets[0].getsockname()[:len(addr)]
loop.run_until_complete(f)
logger.info("listening on %s", str(addr))
def factory(self):
try:
......
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
......
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
......
......@@ -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()
addr = qout.get(timeout=start_timeout)
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()
......@@ -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
......
......@@ -20,7 +20,7 @@ from ZODB.config import storageFromString
from .forker import start_zeo_server
class ZEOConfigTest(setupstack.TestCase):
class ZEOConfigTestBase(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()
......
......@@ -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,
......
......@@ -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
......
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 ZEOConfigTestBase
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(ZEOConfigTestBase):
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]
envlist =
py34,py35,simple
py27,py34,py35,simple
[testenv]
commands =
......
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