Exemplo n.º 1
0
 def setUp(self):
     super(WorkerCacheFixture, self).setUp()
     patcher = MonkeyPatcher(
         (cache, 'cache', cache.Cache({})),
         (cache, 'initialized', True))
     self.addCleanup(patcher.restore)
     patcher.patch()
Exemplo n.º 2
0
 def test_construct_with_patches(self):
     # Constructing a 'MonkeyPatcher' with patches adds all of the given
     # patches to the patch list.
     patcher = MonkeyPatcher((self.test_object, "foo", "haha"), (self.test_object, "bar", "hehe"))
     patcher.patch()
     self.assertEquals("haha", self.test_object.foo)
     self.assertEquals("hehe", self.test_object.bar)
     self.assertEquals(self.original_object.baz, self.test_object.baz)
Exemplo n.º 3
0
 def test_construct_with_patches(self):
     # Constructing a 'MonkeyPatcher' with patches adds all of the given
     # patches to the patch list.
     patcher = MonkeyPatcher((self.test_object, 'foo', 'haha'),
                             (self.test_object, 'bar', 'hehe'))
     patcher.patch()
     self.assertEquals('haha', self.test_object.foo)
     self.assertEquals('hehe', self.test_object.bar)
     self.assertEquals(self.original_object.baz, self.test_object.baz)
Exemplo n.º 4
0
 def setUp(self):
     super().setUp()
     self.patcher = MonkeyPatcher()
     self.addCleanup(self.patcher.restore)
     # Patch sys.std* and self.std*. Use TextIOWrapper to provide an
     # identical API to the "real" stdin, stdout, and stderr objects.
     self._addStream("stdin", self._wrapStream(self._buf_in))
     self._addStream("stdout", self._wrapStream(self._buf_out))
     self._addStream("stderr", self._wrapStream(self._buf_err))
     self.patcher.patch()
Exemplo n.º 5
0
    def run(self, timeout, function, *args, **kwargs):
        """Run 'function' in a reactor.

        If 'function' returns a Deferred, the reactor will keep spinning until
        the Deferred fires and its chain completes or until the timeout is
        reached -- whichever comes first.

        :raise TimeoutError: If 'timeout' is reached before the Deferred
            returned by 'function' has completed its callback chain.
        :raise NoResultError: If the reactor is somehow interrupted before
            the Deferred returned by 'function' has completed its callback
            chain.
        :raise StaleJunkError: If there's junk in the spinner from a previous
            run.
        :return: Whatever is at the end of the function's callback chain.  If
            it's an error, then raise that.
        """
        debug = MonkeyPatcher()
        if self._debug:
            debug.add_patch(defer.Deferred, 'debug', True)
            debug.add_patch(DelayedCall, 'debug', True)
        debug.patch()
        try:
            junk = self.get_junk()
            if junk:
                raise StaleJunkError(junk)
            self._save_signals()
            self._timeout_call = self._reactor.callLater(
                timeout, self._timed_out, function, timeout)
            # Calling 'stop' on the reactor will make it impossible to
            # re-start the reactor.  Since the default signal handlers for
            # TERM, BREAK and INT all call reactor.stop(), we'll patch it over
            # with crash.  XXX: It might be a better idea to either install
            # custom signal handlers or to override the methods that are
            # Twisted's signal handlers.
            stop, self._reactor.stop = self._reactor.stop, self._reactor.crash

            def run_function():
                d = defer.maybeDeferred(function, *args, **kwargs)
                d.addCallbacks(self._got_success, self._got_failure)
                d.addBoth(self._stop_reactor)

            try:
                self._reactor.callWhenRunning(run_function)
                self._reactor.run()
            finally:
                self._reactor.stop = stop
                self._restore_signals()
            try:
                return self._get_result()
            finally:
                self._clean()
        finally:
            debug.restore()
Exemplo n.º 6
0
    def addCluster(self, protocol, rack_controller):
        """Add a new stub cluster using the given `protocol`.

        The `protocol` should be an instance of `amp.AMP`.

        :return: A `Deferred` that fires with the connected protocol
            instance.
        """
        endpoint = endpoints.UNIXClientEndpoint(reactor, self.sockfile)
        protocol = yield endpoints.connectProtocol(endpoint, protocol)

        # Mock the registration into the database, as the rack controller is
        # already created. We reset this once registration is complete so as
        # to not interfere with other tests.
        registered = rack_controller
        patcher = MonkeyPatcher()
        patcher.add_patch(rackcontrollers, "register",
                          (lambda *args, **kwargs: registered))

        # Register the rack controller with the region.
        patcher.patch()
        try:
            yield protocol.callRemote(
                region.RegisterRackController,
                system_id=rack_controller.system_id,
                hostname=rack_controller.hostname,
                interfaces={},
                url=urlparse(""),
            )
        finally:
            patcher.restore()

        defer.returnValue(protocol)
Exemplo n.º 7
0
 def configure(self):
     patcher = MonkeyPatcher()
     patcher.add_patch(current_app.conf, 'CELERY_ALWAYS_EAGER', True)
     patcher.add_patch(current_app.conf,
                       'CELERY_EAGER_PROPAGATES_EXCEPTIONS', True)
     self.addCleanup(patcher.restore)
     patcher.patch()
Exemplo n.º 8
0
    def run(self, timeout, function, *args, **kwargs):
        """Run 'function' in a reactor.

        If 'function' returns a Deferred, the reactor will keep spinning until
        the Deferred fires and its chain completes or until the timeout is
        reached -- whichever comes first.

        :raise TimeoutError: If 'timeout' is reached before the Deferred
            returned by 'function' has completed its callback chain.
        :raise NoResultError: If the reactor is somehow interrupted before
            the Deferred returned by 'function' has completed its callback
            chain.
        :raise StaleJunkError: If there's junk in the spinner from a previous
            run.
        :return: Whatever is at the end of the function's callback chain.  If
            it's an error, then raise that.
        """
        debug = MonkeyPatcher()
        if self._debug:
            debug.add_patch(defer.Deferred, 'debug', True)
            debug.add_patch(DelayedCall, 'debug', True)
        debug.patch()
        try:
            junk = self.get_junk()
            if junk:
                raise StaleJunkError(junk)
            self._save_signals()
            self._timeout_call = self._reactor.callLater(
                timeout, self._timed_out, function, timeout)
            # Calling 'stop' on the reactor will make it impossible to
            # re-start the reactor.  Since the default signal handlers for
            # TERM, BREAK and INT all call reactor.stop(), we'll patch it over
            # with crash.  XXX: It might be a better idea to either install
            # custom signal handlers or to override the methods that are
            # Twisted's signal handlers.
            real_stop, self._reactor.stop = self._reactor.stop, self._fake_stop

            def run_function():
                d = defer.maybeDeferred(function, *args, **kwargs)
                d.addCallbacks(self._got_success, self._got_failure)
                d.addBoth(self._stop_reactor)
            try:
                self._reactor.callWhenRunning(run_function)
                self._spinning = True
                self._reactor.run()
            finally:
                self._reactor.stop = real_stop
                self._restore_signals()
            try:
                return self._get_result()
            finally:
                self._clean()
        finally:
            debug.restore()
Exemplo n.º 9
0
 def setUp(self):
     super().setUp()
     self.monkey = MonkeyPatcher()
     # We need the event-loop up and running.
     if not eventloop.loop.running:
         raise RuntimeError(
             "Please start the event-loop before using this fixture.")
     self.rpc = get_service_in_eventloop("rpc").wait(10)
     # Where we're going to put the UNIX socket files.
     self.sockdir = self.useFixture(fixtures.TempDir()).path
     self.sockfile = path.join(self.sockdir, "sock")
     # Configure the RPC service with a UNIX endpoint.
     self.addCleanup(self.stop)
     self.start()
Exemplo n.º 10
0
 def setUp(self):
     super(WorkerCacheFixture, self).setUp()
     patcher = MonkeyPatcher((cache, 'cache', cache.Cache({})),
                             (cache, 'initialized', True))
     self.addCleanup(patcher.restore)
     patcher.patch()
Exemplo n.º 11
0
 def setUp(self):
     super().setUp()
     self.test_object = TestObj()
     self.original_object = TestObj()
     self.monkey_patcher = MonkeyPatcher()
Exemplo n.º 12
0
 def setUp(self):
     super(MonkeyPatcherTest, self).setUp()
     self.test_object = TestObj()
     self.original_object = TestObj()
     self.monkey_patcher = MonkeyPatcher()
Exemplo n.º 13
0
class MonkeyPatcherTest(TestCase):
    """
    Tests for 'MonkeyPatcher' monkey-patching class.
    """
    def setUp(self):
        super().setUp()
        self.test_object = TestObj()
        self.original_object = TestObj()
        self.monkey_patcher = MonkeyPatcher()

    def test_empty(self):
        # A monkey patcher without patches doesn't change a thing.
        self.monkey_patcher.patch()

        # We can't assert that all state is unchanged, but at least we can
        # check our test object.
        self.assertEquals(self.original_object.foo, self.test_object.foo)
        self.assertEquals(self.original_object.bar, self.test_object.bar)
        self.assertEquals(self.original_object.baz, self.test_object.baz)

    def test_construct_with_patches(self):
        # Constructing a 'MonkeyPatcher' with patches adds all of the given
        # patches to the patch list.
        patcher = MonkeyPatcher((self.test_object, 'foo', 'haha'),
                                (self.test_object, 'bar', 'hehe'))
        patcher.patch()
        self.assertEquals('haha', self.test_object.foo)
        self.assertEquals('hehe', self.test_object.bar)
        self.assertEquals(self.original_object.baz, self.test_object.baz)

    def test_patch_existing(self):
        # Patching an attribute that exists sets it to the value defined in the
        # patch.
        self.monkey_patcher.add_patch(self.test_object, 'foo', 'haha')
        self.monkey_patcher.patch()
        self.assertEquals(self.test_object.foo, 'haha')

    def test_patch_non_existing(self):
        # Patching a non-existing attribute sets it to the value defined in
        # the patch.
        self.monkey_patcher.add_patch(self.test_object, 'doesntexist', 'value')
        self.monkey_patcher.patch()
        self.assertEquals(self.test_object.doesntexist, 'value')

    def test_restore_non_existing(self):
        # Restoring a value that didn't exist before the patch deletes the
        # value.
        self.monkey_patcher.add_patch(self.test_object, 'doesntexist', 'value')
        self.monkey_patcher.patch()
        self.monkey_patcher.restore()
        marker = object()
        self.assertIs(marker, getattr(self.test_object, 'doesntexist', marker))

    def test_patch_already_patched(self):
        # Adding a patch for an object and attribute that already have a patch
        # overrides the existing patch.
        self.monkey_patcher.add_patch(self.test_object, 'foo', 'blah')
        self.monkey_patcher.add_patch(self.test_object, 'foo', 'BLAH')
        self.monkey_patcher.patch()
        self.assertEquals(self.test_object.foo, 'BLAH')
        self.monkey_patcher.restore()
        self.assertEquals(self.test_object.foo, self.original_object.foo)

    def test_restore_twice_is_a_no_op(self):
        # Restoring an already-restored monkey patch is a no-op.
        self.monkey_patcher.add_patch(self.test_object, 'foo', 'blah')
        self.monkey_patcher.patch()
        self.monkey_patcher.restore()
        self.assertEquals(self.test_object.foo, self.original_object.foo)
        self.monkey_patcher.restore()
        self.assertEquals(self.test_object.foo, self.original_object.foo)

    def test_run_with_patches_decoration(self):
        # run_with_patches runs the given callable, passing in all arguments
        # and keyword arguments, and returns the return value of the callable.
        log = []

        def f(a, b, c=None):
            log.append((a, b, c))
            return 'foo'

        result = self.monkey_patcher.run_with_patches(f, 1, 2, c=10)
        self.assertEquals('foo', result)
        self.assertEquals([(1, 2, 10)], log)

    def test_repeated_run_with_patches(self):
        # We can call the same function with run_with_patches more than
        # once. All patches apply for each call.
        def f():
            return (self.test_object.foo, self.test_object.bar,
                    self.test_object.baz)

        self.monkey_patcher.add_patch(self.test_object, 'foo', 'haha')
        result = self.monkey_patcher.run_with_patches(f)
        self.assertEquals(
            ('haha', self.original_object.bar, self.original_object.baz),
            result)
        result = self.monkey_patcher.run_with_patches(f)
        self.assertEquals(
            ('haha', self.original_object.bar, self.original_object.baz),
            result)

    def test_run_with_patches_restores(self):
        # run_with_patches restores the original values after the function has
        # executed.
        self.monkey_patcher.add_patch(self.test_object, 'foo', 'haha')
        self.assertEquals(self.original_object.foo, self.test_object.foo)
        self.monkey_patcher.run_with_patches(lambda: None)
        self.assertEquals(self.original_object.foo, self.test_object.foo)

    def test_run_with_patches_restores_on_exception(self):
        # run_with_patches restores the original values even when the function
        # raises an exception.
        def _():
            self.assertEquals(self.test_object.foo, 'haha')
            self.assertEquals(self.test_object.bar, 'blahblah')
            raise RuntimeError("Something went wrong!")

        self.monkey_patcher.add_patch(self.test_object, 'foo', 'haha')
        self.monkey_patcher.add_patch(self.test_object, 'bar', 'blahblah')

        self.assertThat(
            lambda: self.monkey_patcher.run_with_patches(_),
            Raises(MatchesException(RuntimeError("Something went wrong!"))))
        self.assertEquals(self.test_object.foo, self.original_object.foo)
        self.assertEquals(self.test_object.bar, self.original_object.bar)
Exemplo n.º 14
0
 def setUp(self):
     super(RabbitServerSettings, self).setUp()
     from django.conf import settings
     patcher = MonkeyPatcher()
     patcher.add_patch(settings, "RABBITMQ_HOST",
                       "%s:%d" % (self.config.hostname, self.config.port))
     patcher.add_patch(settings, "RABBITMQ_USERID", "guest")
     patcher.add_patch(settings, "RABBITMQ_PASSWORD", "guest")
     patcher.add_patch(settings, "RABBITMQ_VIRTUAL_HOST", "/")
     patcher.add_patch(settings, "RABBITMQ_PUBLISH", True)
     self.addCleanup(patcher.restore)
     patcher.patch()
Exemplo n.º 15
0
 def setUp(self):
     super(RabbitServerSettings, self).setUp()
     from django.conf import settings
     patcher = MonkeyPatcher()
     patcher.add_patch(
         settings, "RABBITMQ_HOST",
         "%s:%d" % (self.config.hostname, self.config.port))
     patcher.add_patch(settings, "RABBITMQ_USERID", "guest")
     patcher.add_patch(settings, "RABBITMQ_PASSWORD", "guest")
     patcher.add_patch(settings, "RABBITMQ_VIRTUAL_HOST", "/")
     patcher.add_patch(settings, "RABBITMQ_PUBLISH", True)
     self.addCleanup(patcher.restore)
     patcher.patch()
Exemplo n.º 16
0
class CaptureStandardIO(fixtures.Fixture):
    """Capture stdin, stdout, and stderr.

    Reading from `sys.stdin` will yield *unicode* strings, much like the
    default in Python 3. This differs from the usual behaviour in Python 2, so
    beware.

    Writing unicode strings to `sys.stdout` or `sys.stderr` will work; they'll
    be encoded with the `encoding` chosen when creating this fixture.

    `addInput(...)` should be used to prepare more input to be read.

    The `output` and `error` properties can be used to obtain what's been
    written to stdout and stderr.

    The buffers used internally have the same lifetime as the fixture
    *instance* itself, so the `output`, and `error` properties remain useful
    even after the fixture has been cleaned-up, and there's no need to capture
    them before exiting.

    However, `clearInput()`, `clearOutput()`, `clearError()`, and `clearAll()`
    can be used to truncate the buffers during this fixture's lifetime.
    """

    stdin = None
    stdout = None
    stderr = None

    def __init__(self, encoding="utf-8"):
        super().__init__()
        self.codec = codecs.lookup(encoding)
        self.encoding = encoding
        # Create new buffers.
        self._buf_in = BytesIO()
        self._buf_out = BytesIO()
        self._buf_err = BytesIO()

    def setUp(self):
        super().setUp()
        self.patcher = MonkeyPatcher()
        self.addCleanup(self.patcher.restore)
        # Patch sys.std* and self.std*. Use TextIOWrapper to provide an
        # identical API to the "real" stdin, stdout, and stderr objects.
        self._addStream("stdin", self._wrapStream(self._buf_in))
        self._addStream("stdout", self._wrapStream(self._buf_out))
        self._addStream("stderr", self._wrapStream(self._buf_err))
        self.patcher.patch()

    def _wrapStream(self, stream):
        return TextIOWrapper(stream,
                             encoding=self.encoding,
                             write_through=True)

    def _addStream(self, name, stream):
        self.patcher.add_patch(self, name, stream)
        self.patcher.add_patch(sys, name, stream)

    def addInput(self, data):
        """Add input to be read later, as a unicode string."""
        position = self._buf_in.tell()
        stream = self.codec.streamwriter(self._buf_in)
        try:
            self._buf_in.seek(0, 2)
            stream.write(data)
        finally:
            self._buf_in.seek(position)

    def getInput(self):
        """The input remaining to be read, as a unicode string."""
        position = self._buf_in.tell()
        if self.stdin is None:
            stream = self.codec.streamreader(self._buf_in)
        else:
            stream = self.stdin
        try:
            return stream.read()
        finally:
            self._buf_in.seek(position)

    def getOutput(self):
        """The output written thus far, as a unicode string."""
        if self.stdout is not None:
            self.stdout.flush()
        output_bytes = self._buf_out.getvalue()
        output_string, _ = self.codec.decode(output_bytes)
        return output_string

    def getError(self):
        """The error written thus far, as a unicode string."""
        if self.stderr is not None:
            self.stderr.flush()
        error_bytes = self._buf_err.getvalue()
        error_string, _ = self.codec.decode(error_bytes)
        return error_string

    def clearInput(self):
        """Truncate the input buffer."""
        self._buf_in.seek(0, 0)
        self._buf_in.truncate()
        if self.stdin is not None:
            self.stdin.seek(0, 0)

    def clearOutput(self):
        """Truncate the output buffer."""
        self._buf_out.seek(0, 0)
        self._buf_out.truncate()
        if self.stdout is not None:
            self.stdout.seek(0, 0)

    def clearError(self):
        """Truncate the error buffer."""
        self._buf_err.seek(0, 0)
        self._buf_err.truncate()
        if self.stderr is not None:
            self.stderr.seek(0, 0)

    def clearAll(self):
        """Truncate all buffers."""
        self.clearInput()
        self.clearOutput()
        self.clearError()
Exemplo n.º 17
0
class MonkeyPatcherTest(TestCase):
    """
    Tests for 'MonkeyPatcher' monkey-patching class.
    """

    def setUp(self):
        super(MonkeyPatcherTest, self).setUp()
        self.test_object = TestObj()
        self.original_object = TestObj()
        self.monkey_patcher = MonkeyPatcher()

    def test_empty(self):
        # A monkey patcher without patches doesn't change a thing.
        self.monkey_patcher.patch()

        # We can't assert that all state is unchanged, but at least we can
        # check our test object.
        self.assertEquals(self.original_object.foo, self.test_object.foo)
        self.assertEquals(self.original_object.bar, self.test_object.bar)
        self.assertEquals(self.original_object.baz, self.test_object.baz)

    def test_construct_with_patches(self):
        # Constructing a 'MonkeyPatcher' with patches adds all of the given
        # patches to the patch list.
        patcher = MonkeyPatcher((self.test_object, "foo", "haha"), (self.test_object, "bar", "hehe"))
        patcher.patch()
        self.assertEquals("haha", self.test_object.foo)
        self.assertEquals("hehe", self.test_object.bar)
        self.assertEquals(self.original_object.baz, self.test_object.baz)

    def test_patch_existing(self):
        # Patching an attribute that exists sets it to the value defined in the
        # patch.
        self.monkey_patcher.add_patch(self.test_object, "foo", "haha")
        self.monkey_patcher.patch()
        self.assertEquals(self.test_object.foo, "haha")

    def test_patch_non_existing(self):
        # Patching a non-existing attribute sets it to the value defined in
        # the patch.
        self.monkey_patcher.add_patch(self.test_object, "doesntexist", "value")
        self.monkey_patcher.patch()
        self.assertEquals(self.test_object.doesntexist, "value")

    def test_restore_non_existing(self):
        # Restoring a value that didn't exist before the patch deletes the
        # value.
        self.monkey_patcher.add_patch(self.test_object, "doesntexist", "value")
        self.monkey_patcher.patch()
        self.monkey_patcher.restore()
        marker = object()
        self.assertIs(marker, getattr(self.test_object, "doesntexist", marker))

    def test_patch_already_patched(self):
        # Adding a patch for an object and attribute that already have a patch
        # overrides the existing patch.
        self.monkey_patcher.add_patch(self.test_object, "foo", "blah")
        self.monkey_patcher.add_patch(self.test_object, "foo", "BLAH")
        self.monkey_patcher.patch()
        self.assertEquals(self.test_object.foo, "BLAH")
        self.monkey_patcher.restore()
        self.assertEquals(self.test_object.foo, self.original_object.foo)

    def test_restore_twice_is_a_no_op(self):
        # Restoring an already-restored monkey patch is a no-op.
        self.monkey_patcher.add_patch(self.test_object, "foo", "blah")
        self.monkey_patcher.patch()
        self.monkey_patcher.restore()
        self.assertEquals(self.test_object.foo, self.original_object.foo)
        self.monkey_patcher.restore()
        self.assertEquals(self.test_object.foo, self.original_object.foo)

    def test_run_with_patches_decoration(self):
        # run_with_patches runs the given callable, passing in all arguments
        # and keyword arguments, and returns the return value of the callable.
        log = []

        def f(a, b, c=None):
            log.append((a, b, c))
            return "foo"

        result = self.monkey_patcher.run_with_patches(f, 1, 2, c=10)
        self.assertEquals("foo", result)
        self.assertEquals([(1, 2, 10)], log)

    def test_repeated_run_with_patches(self):
        # We can call the same function with run_with_patches more than
        # once. All patches apply for each call.
        def f():
            return (self.test_object.foo, self.test_object.bar, self.test_object.baz)

        self.monkey_patcher.add_patch(self.test_object, "foo", "haha")
        result = self.monkey_patcher.run_with_patches(f)
        self.assertEquals(("haha", self.original_object.bar, self.original_object.baz), result)
        result = self.monkey_patcher.run_with_patches(f)
        self.assertEquals(("haha", self.original_object.bar, self.original_object.baz), result)

    def test_run_with_patches_restores(self):
        # run_with_patches restores the original values after the function has
        # executed.
        self.monkey_patcher.add_patch(self.test_object, "foo", "haha")
        self.assertEquals(self.original_object.foo, self.test_object.foo)
        self.monkey_patcher.run_with_patches(lambda: None)
        self.assertEquals(self.original_object.foo, self.test_object.foo)

    def test_run_with_patches_restores_on_exception(self):
        # run_with_patches restores the original values even when the function
        # raises an exception.
        def _():
            self.assertEquals(self.test_object.foo, "haha")
            self.assertEquals(self.test_object.bar, "blahblah")
            raise RuntimeError("Something went wrong!")

        self.monkey_patcher.add_patch(self.test_object, "foo", "haha")
        self.monkey_patcher.add_patch(self.test_object, "bar", "blahblah")

        self.assertThat(
            lambda: self.monkey_patcher.run_with_patches(_),
            Raises(MatchesException(RuntimeError("Something went wrong!"))),
        )
        self.assertEquals(self.test_object.foo, self.original_object.foo)
        self.assertEquals(self.test_object.bar, self.original_object.bar)