Twisted test - both success and error callback fire on deferred

巧了我就是萌 提交于 2019-12-24 06:45:42

问题


Writing a unit test for a twisted application. Trying to perform some asserts once deferred is resolved with a new connection (instance of Protocol), however seeing that both success and error callbacks are being fired (judging by both SUCCESS and FAIL being printed in console).

def test_send_to_new_connection(self):
    # Given
    peerAddr = ('10.22.22.190', 5060)

    # If
    self.tcp_transport.send_to('test', peerAddr)

    # Then
    assert peerAddr in self.tcp_transport._connections
    assert True == isinstance(self.tcp_transport._connections[peerAddr], Deferred)

    connection = _string_transport_connection(self.hostAddr, peerAddr, None, self.tcp_transport.connectionMade)

    def assert_cache_updated_on_connection(connection):
        print('--------- SUCCESS ----------')
        peer = connection.transport.getPeer()
        peerAddr = (peer.host, peer.port)

        assert peerAddr in self.tcp_transport._connections
        assert True == isinstance(self.tcp_transport._connections[peerAddr], Protocol)

    def assert_fail(fail):
        print('--------- FAIL ----------')

    self.tcp_transport._connections[peerAddr].addCallback(assert_cache_updated_on_connection)
    self.tcp_transport._connections[peerAddr].addErrback(assert_fail)
    # Forcing deferred to fire with mock connection
    self.tcp_transport._connections[peerAddr].callback(connection)

I thought execution of Callbacks and Errbacks was mutually exclusive. I.e. only ones or the others would run depending on deferred resolution. Why is assert_fail() also being called?


回答1:


See the "railroad" diagram in the Deferred Reference:

Notice how there are diagonal arrows from the callback side to the errback side and vice versa. At anyone single position (where a "position" is a pair of boxes side-by-side, one green and one red, with position increasing as you go down the diagram) in the callback/errback chain only one of the callback or errback will be called. However, since there are multiple positions in the chain, you can have many callbacks and many errbacks all called on a single Deferred.

In the case of your code:

  ....addCallback(assert_cache_updated_on_connection)
  ....addErrback(assert_fail)

There are two positions. The first has a callback and the second has an errback. If the callback signals failure, execution switches to the errback side for the next position - exactly where you have assert_fail.



来源:https://stackoverflow.com/questions/52005125/twisted-test-both-success-and-error-callback-fire-on-deferred

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!