summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/api/testing.rst2
-rw-r--r--docs/testing.rst32
-rw-r--r--kazoo/testing/__init__.py151
-rw-r--r--kazoo/tests/test_client.py2
-rw-r--r--kazoo/tests/test_lock.py13
-rw-r--r--kazoo/tests/test_security.py12
6 files changed, 10 insertions, 202 deletions
diff --git a/docs/api/testing.rst b/docs/api/testing.rst
index cca345f..b24c84a 100644
--- a/docs/api/testing.rst
+++ b/docs/api/testing.rst
@@ -10,5 +10,3 @@ Public API
.. autoclass:: KazooTestHarness
.. autoclass:: KazooTestCase
- .. autoclass:: ZookeeperErrors
- .. autoclass:: ZooError
diff --git a/docs/testing.rst b/docs/testing.rst
index cf3d52e..640aae1 100644
--- a/docs/testing.rst
+++ b/docs/testing.rst
@@ -59,35 +59,3 @@ equivalent test to the one above:
self.client.ensure_path('/test/path')
result = self.client.get('/test/path')
...
-
-Faking Zookeeper Results
-========================
-
-It can be useful to simulate errors or a connection loss when running test code
-to ensure that your program functions in a robust manner. Kazoo provides a
-:meth:`~kazoo.testing.KazooTestHarness.add_errors` method that can be passed
-an error structure composed of :class:`~kazoo.testing.ZooError` that will be
-used for the underlying Python `Zookeeper` library calls.
-
-Example:
-
-.. code-block:: python
-
- from kazoo.testing import KazooTestCase
- from kazoo.testing import ZooError
-
- class MyTest(KazooTestCase):
- def testmycode(self):
- errors = dict(
- acreate=[
- ZooError('completion', zookeeper.CONNECTIONLOSS, False),
- True,
- ZooError('call', SystemError(), False)
- ]
- )
-
- self.client.add_errors(errors)
-
- # ensure_path internally calls acreate
- self.client.ensure_path('/test/path')
- result = self.client.get('/test/path')
diff --git a/kazoo/testing/__init__.py b/kazoo/testing/__init__.py
index 5eb0881..dcc987c 100644
--- a/kazoo/testing/__init__.py
+++ b/kazoo/testing/__init__.py
@@ -3,22 +3,17 @@ import atexit
import logging
import os
import uuid
-from collections import namedtuple
import threading
import unittest
-import zookeeper
from kazoo.client import KazooClient
from kazoo.protocol.states import (
- Callback,
KazooState
)
from kazoo.testing.common import ZookeeperCluster
log = logging.getLogger(__name__)
-zookeeper.deterministic_conn_order(True)
-
CLUSTER = None
@@ -35,152 +30,6 @@ def get_global_cluster():
return CLUSTER
-class ZooError(namedtuple('ZooError', ('when', 'exception', 'allow'))):
- """A Zookeeper Error to throw instead of or in addition to executing the
- Zookeeper command
-
- Since the :class:`KazooClient` implements most of the zookeeper commands
- using the async calls, the exception could occur during the call itself
- (which is rare), or on the completion.
-
- .. attribute:: when
-
- When the exception should be tossed, can be set to 'call' or
- 'completion'.
-
- .. attribute:: exception
-
- The exception instance or Zookeeper exception code (an int).
-
- .. attribute:: allow
-
- Boolean indicating if the Zookeeper function should be called
- even though an exception is being returned. This is useful for
- reproducing rare events in Zookeeper where a connection is lost
- before a response is returned but the command ran successfully.
-
- """
-
-
-class ZookeeperErrors(object):
- """A Zookeeper proxy with errors"""
- def __init__(self, errors, handler):
- """Create a :class:`ZookeeperErrors` object that throws the
- desired errors upon calls
-
- :param errors: A dict structure keyed by the Zookeeper function
- to intercept, with the value being a list of
- :class:`ZooError`s to throw. When the list is empty
- calls will proceed as normal, include ``True`` in a
- place to allow a call to pass if desired as well.
- :param handler: The handler instance used by the KazooClient.
-
- Example::
-
- errors = dict(
- acreate=[
- ZooError('completion', zookeeper.CONNECTIONLOSS, False),
- True,
- ZooError('call', SystemError(), False)
- ]
- )
-
- self.client.add_errors(errors)
-
- This example replaces the first call to `zookeeper.acreate` with a
- CONNECTIONLOSS, and doesn't run the call in the background. The second
- call will run fine, the third will have a SystemError, and any more
- calls will proceed as usual.
-
- .. warning::
-
- Care should be taken when simulating errors that your test code
- executes the Zookeeper commands in a reliably deterministic manner.
-
- """
- for k, v in errors.items():
- v.reverse()
- self.errors = errors
- self.handler = handler
-
- def _intercept_completion(self):
- # Completion callback is always at the end
- asy = self.handler.async_result()
-
- def new_completion(handle, code, *args):
- log.info("Intercept completion, handle: %s, "
- "code: %s, args: %s", handle, code, args)
- asy.set()
- return asy, new_completion
-
- def _intercept_watcher(self):
- def new_watcher(*args):
- log.info("Intercept watcher, args: %s", args)
- return new_watcher
-
- def _call_exception(self, err, name, func, *args, **kwargs):
- if err.allow:
- # Strip completion/watch callbacks, replace with dummies
- asy = False
- if callable(args[-1]):
- asy, args[-1] = self._intercept_completion()
- if callable(args[-2]):
- args[-2] = self._intercept_watcher()
- log.debug("Calling actual function: %s", name)
- func(*args, **kwargs)
- if asy:
- asy.wait()
- log.debug("Raising desired exception: %s", err.exception)
- raise err.exception
- else:
- log.debug("Raising desired exception on call: %s",
- err.exception)
- raise err.exception
-
- def _completion_exception(self, err, name, func, *args, **kwargs):
- # Ensure args is a list
- if isinstance(args, tuple):
- args = list(args)
-
- if callable(args[-1]):
- # Replace completion callback with one that returns the
- # exception
- old_complete = args[-1]
- args[-1] = lambda handle, code, *new_args: old_complete(
- handle, err.exception, *new_args)
- if callable(args[-2]):
- # Strip the watch callback
- args[-2] = lambda *args: 1
- # Call it if we're supposed to
- if err.allow:
- log.debug("Calling actual function: %s", name)
- func(*args, **kwargs)
- else:
- # Make sure the completion callback is called
- log.debug("Returning desired exception on call: %s",
- err.exception)
- self.handler.dispatch_callback(
- Callback('completion', func, (None, err.exception))
- )
- return zookeeper.OK
-
- def __getattr__(self, name):
- func = getattr(zookeeper, name)
- err = self.errors.get(name)
- if err:
- err = err.pop()
- if not isinstance(err, ZooError):
- return func
-
- def func_wrapper(*args, **kwargs):
- if err.when == 'call':
- return self._call_exception(err, name, func, *args, **kwargs)
- else:
- return self._completion_exception(err, name, func, *args,
- **kwargs)
- return func_wrapper
-
-
class KazooTestHarness(object):
"""Harness for testing code that uses Kazoo
diff --git a/kazoo/tests/test_client.py b/kazoo/tests/test_client.py
index a7a239f..7eb9e05 100644
--- a/kazoo/tests/test_client.py
+++ b/kazoo/tests/test_client.py
@@ -5,11 +5,9 @@ import unittest
from nose.tools import eq_
from kazoo.testing import KazooTestCase
-from kazoo.testing import ZooError
from kazoo.exceptions import BadArgumentsError
from kazoo.exceptions import NoNodeError
from kazoo.exceptions import NoAuthError
-from kazoo.exceptions import ZookeeperError
from kazoo.exceptions import ConnectionLoss
diff --git a/kazoo/tests/test_lock.py b/kazoo/tests/test_lock.py
index 7d332d6..94813a3 100644
--- a/kazoo/tests/test_lock.py
+++ b/kazoo/tests/test_lock.py
@@ -1,12 +1,13 @@
import uuid
import threading
-import zookeeper
from nose.tools import eq_
-from kazoo.exceptions import CancelledError
+from kazoo.exceptions import (
+ CancelledError,
+ ConnectionLoss
+)
from kazoo.testing import KazooTestCase
-from kazoo.testing import ZooError
from kazoo.tests.util import wait
@@ -120,12 +121,6 @@ class KazooLockTests(KazooTestCase):
thread.join()
def test_lock_fail_first_call(self):
- self.add_errors(dict(
- acreate=[True, # This is our lock node create
- ZooError('completion', zookeeper.CONNECTIONLOSS, True)
- ]
- ))
-
event1 = threading.Event()
lock1 = self.client.Lock(self.lockpath, "one")
thread1 = threading.Thread(target=self._thread_lock_acquire_til_event,
diff --git a/kazoo/tests/test_security.py b/kazoo/tests/test_security.py
index 29bebdd..4a7e670 100644
--- a/kazoo/tests/test_security.py
+++ b/kazoo/tests/test_security.py
@@ -1,7 +1,7 @@
import unittest
from nose.tools import eq_
-import zookeeper
+from kazoo.security import Permissions
class TestACL(unittest.TestCase):
@@ -11,13 +11,13 @@ class TestACL(unittest.TestCase):
def test_read_acl(self):
acl = self._makeOne("digest", ":", read=True)
- eq_(acl.perms & zookeeper.PERM_READ, zookeeper.PERM_READ)
+ eq_(acl.perms & Permissions.READ, Permissions.READ)
def test_all_perms(self):
- acl = self._makeOne("digest", ":", write=True, create=True,
- delete=True, admin=True)
- for perm in [zookeeper.PERM_WRITE, zookeeper.PERM_CREATE,
- zookeeper.PERM_DELETE, zookeeper.PERM_ADMIN]:
+ acl = self._makeOne("digest", ":", read=True, write=True,
+ create=True, delete=True, admin=True)
+ for perm in [Permissions.READ, Permissions.CREATE, Permissions.WRITE,
+ Permissions.DELETE, Permissions.ADMIN]:
eq_(acl.perms & perm, perm)
def test_perm_listing(self):