コード例 #1
0
 def test_proxyName(self):
     """
     The name of a proxy class indicates which interface it proxies.
     """
     proxy = proxyForInterface(IProxiedInterface)
     self.assertEqual(proxy.__name__,
         "(Proxy for seishub.core.tests." + \
         "test_core_twisted_compatibility.IProxiedInterface)")
コード例 #2
0
 def test_original(self):
     """
     Proxy objects should have an C{original} attribute which refers to the
     original object passed to the constructor.
     """
     original = object()
     proxy = proxyForInterface(IProxiedInterface)(original)
     self.assertIdentical(proxy.original, original)
コード例 #3
0
 def test_multipleMethods(self):
     """
     [Regression test] The proxy should send its method calls to the correct
     method, not the incorrect one.
     """
     multi = MultipleMethodImplementor()
     proxy = proxyForInterface(IMultipleMethods)(multi)
     self.assertEquals(proxy.methodOne(), 1)
     self.assertEquals(proxy.methodTwo(), 2)
コード例 #4
0
 def test_proxyName(self):
     """
     The name of a proxy class indicates which interface it proxies.
     """
     proxy = proxyForInterface(IProxiedInterface)
     self.assertEquals(
         proxy.__name__,
         "(Proxy for "
         "twisted.python.test.test_components.IProxiedInterface)")
コード例 #5
0
 def test_proxyAttribute(self):
     """
     Proxy objects should proxy declared attributes, but not other
     attributes.
     """
     yayable = Yayable()
     yayable.ifaceAttribute = object()
     proxy = proxyForInterface(IProxiedInterface)(yayable)
     self.assertIdentical(proxy.ifaceAttribute, yayable.ifaceAttribute)
     self.assertRaises(AttributeError, lambda: proxy.yays)
コード例 #6
0
 def test_proxySetAttribute(self):
     """
     The attributes that proxy objects proxy should be assignable and affect
     the original object.
     """
     yayable = Yayable()
     proxy = proxyForInterface(IProxiedInterface)(yayable)
     thingy = object()
     proxy.ifaceAttribute = thingy
     self.assertIdentical(yayable.ifaceAttribute, thingy)
コード例 #7
0
 def test_proxyDeleteAttribute(self):
     """
     The attributes that proxy objects proxy should be deletable and affect
     the original object.
     """
     yayable = Yayable()
     yayable.ifaceAttribute = None
     proxy = proxyForInterface(IProxiedInterface)(yayable)
     del proxy.ifaceAttribute
     self.assertFalse(hasattr(yayable, 'ifaceAttribute'))
コード例 #8
0
 def test_proxyMethod(self):
     """
     The class created from L{proxyForInterface} passes methods on an
     interface to the object which is passed to its constructor.
     """
     klass = proxyForInterface(IProxiedInterface)
     yayable = Yayable()
     proxy = klass(yayable)
     proxy.yay()
     self.assertEquals(proxy.yay(), 2)
     self.assertEquals(yayable.yays, 2)
コード例 #9
0
ファイル: test_gce.py プロジェクト: ClusterHQ/flocker
def repeat_call_proxy_for(interface, provider):
    """
    Constructs an implementation of interface that calls the corresponding
    method on implementation twice for every call to a method.

    :interface param: The zope interface that the proxy should implement.
    :provider param: The underlying provider to proxy all method calls to.
    """
    # proxyForInterface used so that only the methods of the interface are
    # exposed. The naive implementation of _RepeatProxy forwards all methods
    # rather than just the methods that are part of the interface.
    return proxyForInterface(interface, originalAttribute="_original")(_RepeatProxy(_provider=provider))
コード例 #10
0
 def test_interfaceInheritance(self):
     """
     Proxies of subinterfaces generated with proxyForInterface should allow
     access to attributes of both the child and the base interfaces.
     """
     proxyClass = proxyForInterface(IProxiedSubInterface)
     booable = Booable()
     proxy = proxyClass(booable)
     proxy.yay()
     proxy.boo()
     self.failUnless(booable.yayed)
     self.failUnless(booable.booed)
コード例 #11
0
def loggedReactor(reactor):
    """
    Construct and return a wrapper around the given C{reactor} which provides
    all of the same interfaces, but which will log all traffic over outgoing
    TCP connections it establishes.
    """
    bases = []
    for iface in providedBy(reactor):
        if iface is IReactorTCP:
            bases.append(_TCPTrafficLoggingReactor)
        else:
            bases.append(proxyForInterface(iface, '_reactor'))
    if bases:
        return type('(Logged Reactor)', tuple(bases), {})(reactor)
    return reactor
コード例 #12
0
    def test_decoratedProxyMethod(self):
        """
        Methods of the class created from L{proxyForInterface} can be used with
        the decorator-helper L{functools.wraps}.
        """
        base = proxyForInterface(IProxiedInterface)
        class klass(base):
            @wraps(base.yay)
            def yay(self):
                self.original.yays += 1
                return base.yay(self)

        original = Yayable()
        yayable = klass(original)
        yayable.yay()
        self.assertEqual(2, original.yays)
コード例 #13
0
    def service(self, services=None):
        if services is None:
            services = (self.xmlService(),)

        #
        # Make sure aggregate DirectoryService isn't making
        # implementation assumptions about the IDirectoryService
        # objects it gets.
        #
        services = tuple((
            proxyForInterface(IDirectoryService)(s)
            for s in services
        ))

        class TestService(DirectoryService, QueryMixIn):
            pass

        return TestService("xyzzy", services)
コード例 #14
0
    def test_attributeCustomization(self):
        """
        The original attribute name can be customized via the
        C{originalAttribute} argument of L{proxyForInterface}: the attribute
        should change, but the methods of the original object should still be
        callable, and the attributes still accessible.
        """
        yayable = Yayable()
        yayable.ifaceAttribute = object()
        proxy = proxyForInterface(
            IProxiedInterface, originalAttribute='foo')(yayable)
        self.assertIdentical(proxy.foo, yayable)

        # Check the behavior
        self.assertEquals(proxy.yay(), 1)
        self.assertIdentical(proxy.ifaceAttribute, yayable.ifaceAttribute)
        thingy = object()
        proxy.ifaceAttribute = thingy
        self.assertIdentical(yayable.ifaceAttribute, thingy)
        del proxy.ifaceAttribute
        self.assertFalse(hasattr(yayable, 'ifaceAttribute'))
コード例 #15
0
ファイル: fan.py プロジェクト: david415/tubes
class Thru(proxyForInterface(IDrain, "_outDrain")):
    r"""
    A fan.L{Thru} takes an input and fans it I{thru} multiple
    drains-which-produce-founts, such as L{tubes <tubes.itube.ITube>}::

                Your Fount
             (producing "foo")
                    |
                    v
                  Thru
                    |
                  _/|\_
                _/  |  \_
               /    |    \
        foo2bar  foo2baz  foo2qux
               \_   |   _/
                 \_ | _/
                   \|/
                    |
                    v
                  Thru
                    |
                    v
                Your Drain
         (receiving a combination
             of foo, bar, baz)

    The way you would construct such a flow in code would be::

        yourFount.flowTo(Thru([series(foo2bar()),
                               series(foo2baz()),
                               series(foo2qux())])).flowTo(yourDrain)
    """
    def __init__(self, drains):
        """
        Create a L{Thru} with an iterable of L{IDrain}.

        All of the drains in C{drains} should be drains that produce a new
        L{IFount} from L{flowingFrom <IDrain.flowingFrom>}, which means they
        should be a L{series <tubes.tube.series>} of L{tubes
        <tubes.itube.ITube>}, or drains that behave like that, such as L{Thru}
        itself.

        @param drain: an iterable of L{IDrain}
        """
        self._in = In()
        self._out = Out()

        self._drains = list(drains)
        self._founts = list(None for drain in self._drains)
        self._outFounts = list(self._out.newFount() for drain in self._drains)
        self._inDrains = list(self._in.newDrain() for drain in self._drains)
        self._outDrain = self._out.drain

    def flowingFrom(self, fount):
        """
        Accept input from C{fount} and produce output filtered by all of the
        C{drain}s given to this L{Thru}'s constructor.

        @param fount: a fount whose outputs should flow through our series of
            transformations.

        @return: an output fount which aggregates all the values produced by
            the drains given to this L{Thru}'s constructor.
        """
        super(Thru, self).flowingFrom(fount)
        for idx, appDrain, outFount, inDrain in zip(count(), self._drains,
                                                    self._outFounts,
                                                    self._inDrains):
            appFount = outFount.flowTo(appDrain)
            if appFount is None:
                appFount = self._founts[idx]
            else:
                self._founts[idx] = appFount
            appFount.flowTo(inDrain)
        nextFount = self._in.fount

        # Literally copy/pasted from _SiphonDrain.flowingFrom.  Hmm.
        nextDrain = nextFount.drain
        if nextDrain is None:
            return nextFount
        return nextFount.flowTo(nextDrain)
コード例 #16
0
 class ComparisonProxy(proxyForInterface(interface, "_original")):
     def __cmp__(self, other):
         return comparison_result
コード例 #17
0
class DistReporter(proxyForInterface(IReporter)):
    """
    See module docstring.
    """
    def __init__(self, original):
        super(DistReporter, self).__init__(original)
        self.running = {}

    def startTest(self, test):
        """
        Queue test starting.
        """
        self.running[test.id()] = []
        self.running[test.id()].append((self.original.startTest, test))

    def addFailure(self, test, fail):
        """
        Queue adding a failure.
        """
        self.running[test.id()].append((self.original.addFailure, test, fail))

    def addError(self, test, error):
        """
        Queue error adding.
        """
        self.running[test.id()].append((self.original.addError, test, error))

    def addSkip(self, test, reason):
        """
        Queue adding a skip.
        """
        self.running[test.id()].append((self.original.addSkip, test, reason))

    def addUnexpectedSuccess(self, test, todo):
        """
        Queue adding an unexpected success.
        """
        self.running[test.id()].append(
            (self.original.addUnexpectedSuccess, test, todo))

    def addExpectedFailure(self, test, error, todo):
        """
        Queue adding an unexpected failure.
        """
        self.running[test.id()].append(
            (self.original.addExpectedFailure, test, error, todo))

    def addSuccess(self, test):
        """
        Queue adding a success.
        """
        self.running[test.id()].append((self.original.addSuccess, test))

    def stopTest(self, test):
        """
        Queue stopping the test, then unroll the queue.
        """
        self.running[test.id()].append((self.original.stopTest, test))
        for step in self.running[test.id()]:
            apply(step[0], step[1:])
        del self.running[test.id()]
コード例 #18
0
 def test_implements(self):
     """
     The resulting proxy implements the interface that it proxies.
     """
     proxy = proxyForInterface(IProxiedInterface)
     self.assertTrue(IProxiedInterface.implementedBy(proxy))
コード例 #19
0
 def test_implements(self):
     """
     The resulting proxy implements the interface that it proxies.
     """
     proxy = proxyForInterface(IProxiedInterface)
     self.assertTrue(IProxiedInterface.implementedBy(proxy))
コード例 #20
0
class TestResultDecorator(
        proxyForInterface(itrial.IReporter, "_originalReporter")):
    """
コード例 #21
0
 class YayableWrapper(proxyForInterface(IProxiedInterface)):
     """
コード例 #22
0
ファイル: reporter.py プロジェクト: stjordanis/twisted
class TestResultDecorator(
        proxyForInterface(itrial.IReporter,
                          "_originalReporter")  # type: ignore[misc]
):
    """
コード例 #23
0
class _SchemaBuilderProxy(components.proxyForInterface(IAMQPSchemaBuilder)):
    pass
コード例 #24
0
class HashedLeaseInfo(proxyForInterface(ILeaseInfo, "_lease_info")
                      ):  # type: ignore # unsupported dynamic base class
    """
    A ``HashedLeaseInfo`` wraps lease information in which the secrets have
    been hashed.
    """
    _lease_info = attr.ib()
    _hash = attr.ib()

    # proxyForInterface will take care of forwarding all methods on ILeaseInfo
    # to `_lease_info`.  Here we override a few of those methods to adjust
    # their behavior to make them suitable for use with hashed secrets.

    def renew(self, new_expire_time):
        # Preserve the HashedLeaseInfo wrapper around the renewed LeaseInfo.
        return attr.assoc(
            self,
            _lease_info=super(HashedLeaseInfo, self).renew(new_expire_time),
        )

    def is_renew_secret(self, candidate_secret):
        # type: (bytes) -> bool
        """
        Hash the candidate secret and compare the result to the stored hashed
        secret.
        """
        return super(HashedLeaseInfo,
                     self).is_renew_secret(self._hash(candidate_secret))

    def present_renew_secret(self):
        # type: () -> str
        """
        Present the hash of the secret with a marker indicating it is a hash.
        """
        return u"hash:" + super(HashedLeaseInfo, self).present_renew_secret()

    def is_cancel_secret(self, candidate_secret):
        # type: (bytes) -> bool
        """
        Hash the candidate secret and compare the result to the stored hashed
        secret.
        """
        if isinstance(candidate_secret, _HashedCancelSecret):
            # Someone read it off of this object in this project - probably
            # the lease crawler - and is just trying to use it to identify
            # which lease it wants to operate on.  Avoid re-hashing the value.
            #
            # It is important that this codepath is only availably internally
            # for this process to talk to itself.  If it were to be exposed to
            # clients over the network, they could just provide the hashed
            # value to avoid having to ever learn the original value.
            hashed_candidate = candidate_secret.hashed_value
        else:
            # It is not yet hashed so hash it.
            hashed_candidate = self._hash(candidate_secret)

        return super(HashedLeaseInfo, self).is_cancel_secret(hashed_candidate)

    def present_cancel_secret(self):
        # type: () -> str
        """
        Present the hash of the secret with a marker indicating it is a hash.
        """
        return u"hash:" + super(HashedLeaseInfo, self).present_cancel_secret()

    @property
    def owner_num(self):
        return self._lease_info.owner_num

    @property
    def nodeid(self):
        return self._lease_info.nodeid

    @property
    def cancel_secret(self):
        """
        Give back an opaque wrapper around the hashed cancel secret which can
        later be presented for a succesful equality comparison.
        """
        # We don't *have* the cancel secret.  We hashed it and threw away the
        # original.  That's good.  It does mean that some code that runs
        # in-process with the storage service (LeaseCheckingCrawler) runs into
        # some difficulty.  That code wants to cancel leases and does so using
        # the same interface that faces storage clients (or would face them,
        # if lease cancellation were exposed).
        #
        # Since it can't use the hashed secret to cancel a lease (that's the
        # point of the hashing) and we don't have the unhashed secret to give
        # it, instead we give it a marker that `cancel_lease` will recognize.
        # On recognizing it, if the hashed value given matches the hashed
        # value stored it is considered a match and the lease can be
        # cancelled.
        #
        # This isn't great.  Maybe the internal and external consumers of
        # cancellation should use different interfaces.
        return _HashedCancelSecret(self._lease_info.cancel_secret)
コード例 #25
0
 def test_provides(self):
     """
     The resulting proxy provides the Interface that it proxies.
     """
     proxy = proxyForInterface(IProxiedInterface)
     self.assertTrue(IProxiedInterface.providedBy(proxy))