Esempio n. 1
0
 def run_assertions(reactor: ReactorInterface):
     cb1 = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                          envelope=env1)
     cb2 = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                          envelope=env2)
     reactor._run_callback.assert_has_calls(
         [call(cb1), call(cb2)], any_order=False)
Esempio n. 2
0
        def assert_sub(composer: Composer):
            from cilantro.messages.reactor.reactor_command import ReactorCommand
            from cilantro.protocol.states.decorators import StateInput
            from unittest.mock import call
            # cb = ReactorCommand.create_callback(callback=StateInput.INPUT, envelope=env)
            # composer.interface.router.route_callback.assert_called_once_with(cb)

            expected_cb = call(
                ReactorCommand.create_callback(callback=StateInput.INPUT,
                                               envelope=env))
            unexpected_cb = call(
                ReactorCommand.create_callback(
                    callback=StateInput.LOOKUP_FAILED, envelope=evil_env))

            call_args = composer.manager.router.route_callback.call_args_list

            # # DEBUG STUFF
            # from cilantro.logger.base import get_logger
            # l = get_logger("assert sub")
            # l.debug('EXPECTED')
            # l.critical(expected_cb)
            # l.debug('UNEXPECTED')
            # l.critical(unexpected_cb)
            # l.important2("got dat call args: {}".format(call_args))
            # # END DEBUG STUFF

            # composer.interface.router.route_callback.assert_has_calls([expected_cb], any_order=True)

            assert expected_cb in call_args, "Expected callback {} to be in call_args {}".format(
                expected_cb, call_args)
            assert unexpected_cb not in call_args, "Did not expect callback {} to be in call_args {}".format(
                unexpected_cb, call_args)
Esempio n. 3
0
    async def _lookup_ip(self, cmd, url, vk, *args, **kwargs):
        ip, node = None, None
        try:
            node, cached = await self.dht.network.lookup_ip(vk)
            # NOTE while secure, this is a more loose connection policy
            self.log.fatal('{} resolves for {}'.format(os.getenv('HOST_IP'),
                                                       node))
            if node and not cached:
                ip = node.ip if type(node) == Node else node.split(':')[0]
                public_key = self.dht.network.ironhouse.vk2pk(vk)
                authorization = await self.dht.network.ironhouse.authenticate(
                    public_key, ip)
                self.log.fatal('{} -> {} is {}'.format(os.getenv('HOST_IP'),
                                                       node, authorization))
                if authorization != 'authorized':
                    node = None
                else:
                    n = Node(node_id=digest(vk),
                             public_key=public_key,
                             ip=ip,
                             port=self.dht.network.network_port)
                    self.dht.network.protocol.router.addContact(n)
                    self.dht.network.connect_to_neighbor(n)

                self.log.fatal([
                    item[0]
                    for item in self.dht.network.bootstrappableNeighbors()
                ])
        except Exception as e:
            delim_line = '!' * 64
            err_msg = '\n\n' + delim_line + '\n' + delim_line
            err_msg += '\n ERROR CAUGHT IN LOOKUP FUNCTION {}\ncalled \w args={}\nand kwargs={}\n'\
                        .format(args, kwargs)
            err_msg += '\nError Message: '
            err_msg += '\n\n{}'.format(traceback.format_exc())
            err_msg += '\n' + delim_line + '\n' + delim_line
            self.log.error(err_msg)

        if node is None:

            kwargs = cmd.kwargs
            callback = ReactorCommand.create_callback(
                callback=StateInput.LOOKUP_FAILED, **kwargs)
            self.log.debug(
                "Sending callback failure to mainthread {}".format(callback))
            self.socket.send(callback.serialize())
            # TODO -- send callback to SM saying hey i couldnt lookup this vk

            return

        # Send interpolated command back through pipeline
        ip = node.ip if type(node) == Node else node
        new_url = IPUtils.interpolate_url(url, ip)
        kwargs = cmd.kwargs
        kwargs['url'] = new_url
        new_cmd = ReactorCommand.create_cmd(envelope=cmd.envelope, **kwargs)

        self._execute_cmd(new_cmd)
Esempio n. 4
0
        def run_assertions(composer: Composer):
            from cilantro.messages.reactor.reactor_command import ReactorCommand
            from cilantro.protocol.states.decorators import StateInput
            from unittest.mock import call

            cb1 = ReactorCommand.create_callback(callback=StateInput.INPUT,
                                                 envelope=env1)
            cb2 = ReactorCommand.create_callback(callback=StateInput.INPUT,
                                                 envelope=env2)
            composer.manager.router.route_callback.assert_has_calls(
                [call(cb1), call(cb2)], any_order=True)
Esempio n. 5
0
    def test_1_1_n_delay(self):
        """
        Tests pub/sub 1-1 with 3 messages, and a 0.2 second delay between messages. The messages should be received in
        order they are sent
        """
        def configure_interface(reactor: ReactorInterface):
            reactor._run_callback = MagicMock()
            return reactor

        def run_assertions(reactor: ReactorInterface):
            cb1 = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                 envelope=env1)
            cb2 = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                 envelope=env2)
            reactor._run_callback.assert_has_calls(
                [call(cb1), call(cb2)], any_order=False)

        env1 = random_envelope()
        env2 = random_envelope()

        sub = MPReactorInterface(config_fn=configure_interface,
                                 assert_fn=run_assertions,
                                 name='** SUB')
        pub = MPReactorInterface(name='++ PUB')

        add_sub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.add_sub.__name__,
            url=URL,
            filter=FILTER)
        add_pub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__, SubPubExecutor.add_pub.__name__, url=URL)
        send_pub_cmd1 = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.send_pub.__name__,
            envelope=env1,
            filter=FILTER)
        send_pub_cmd2 = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.send_pub.__name__,
            envelope=env2,
            filter=FILTER)

        sub.send_cmd(add_sub_cmd)
        pub.send_cmd(add_pub_cmd)
        time.sleep(0.2)

        pub.send_cmd(send_pub_cmd1)
        time.sleep(0.1)  # Give time for first message to go through first
        pub.send_cmd(send_pub_cmd2)

        time.sleep(0.2)  # To allow both pubs to go through

        self.start()
Esempio n. 6
0
    def test_1_1_n(self):
        """
        Tests pub/sub 1-1 with 2 messages (any order with no delay in sends)
        """
        def configure_interface(reactor: ReactorInterface):
            reactor._run_callback = MagicMock()
            return reactor

        def run_assertions(reactor: ReactorInterface):
            cb1 = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                 envelope=env1)
            cb2 = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                 envelope=env2)
            reactor._run_callback.assert_has_calls(
                [call(cb1), call(cb2)], any_order=True)

        env1 = random_envelope()
        env2 = random_envelope()

        sub = MPReactorInterface(config_fn=configure_interface,
                                 assert_fn=run_assertions,
                                 name='** SUB')
        pub = MPReactorInterface(name='++ PUB')

        add_sub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.add_sub.__name__,
            url=URL,
            filter=FILTER)
        add_pub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__, SubPubExecutor.add_pub.__name__, url=URL)
        send_pub_cmd1 = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.send_pub.__name__,
            envelope=env1,
            filter=FILTER)
        send_pub_cmd2 = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.send_pub.__name__,
            envelope=env2,
            filter=FILTER)

        sub.send_cmd(add_sub_cmd)
        pub.send_cmd(add_pub_cmd)
        time.sleep(0.2)
        pub.send_cmd(send_pub_cmd1)
        pub.send_cmd(send_pub_cmd2)

        time.sleep(0.2)  # Give time for both pubs to go through

        self.start()
Esempio n. 7
0
        def assert_sub(composer: Composer):
            from cilantro.messages.reactor.reactor_command import ReactorCommand
            from cilantro.protocol.states.decorators import StateInput
            from unittest.mock import call

            callback1 = ReactorCommand.create_callback(
                callback=StateInput.INPUT, envelope=env1)
            callback2 = ReactorCommand.create_callback(
                callback=StateInput.INPUT, envelope=env2)
            calls = [call(callback1), call(callback2)]

            call_args = composer.manager.router.route_callback.call_args_list
            composer.manager.router.route_callback.assert_has_calls(
                calls, any_order=True)
Esempio n. 8
0
 def assert_sub(composer: Composer):
     from cilantro.messages.reactor.reactor_command import ReactorCommand
     from cilantro.protocol.states.decorators import StateInput
     cb = ReactorCommand.create_callback(callback=StateInput.INPUT,
                                         envelope=env)
     composer.interface.router.route_callback.assert_called_once_with(
         cb)
Esempio n. 9
0
    async def _recv_messages(self):
        try:
            # Notify parent proc that this proc is ready
            self.log.debug("reactorcore notifying main proc of ready")
            self.socket.send(CHILD_RDY_SIG)

            self.log.info(
                "-- Daemon proc listening to main proc on PAIR Socket at {} --"
                .format(self.url))
            while True:
                self.log.debug(
                    "ReactorDaemon awaiting for command from main thread...")
                cmd_bin = await self.socket.recv()
                self.log.debug("Got cmd from queue: {}".format(cmd_bin))

                if cmd_bin == KILL_SIG:
                    self.log.debug(
                        "Daemon Process got kill signal from main proc")
                    self._teardown()
                    return

                # Should from_bytes be in a try/catch? I suppose if we get a bad command from the main proc we might as well
                # blow up because this is very likely because of a development error, so no try/catch for now
                cmd = ReactorCommand.from_bytes(cmd_bin)
                assert cmd.class_name and cmd.func_name, "Received invalid command with no class/func name!"

                self._execute_cmd(cmd)

        except asyncio.CancelledError:
            self.log.warning("Daemon _recv_messages task canceled externally")
Esempio n. 10
0
 def connection_drop(self, node):
     if self.event_sock: self.event_sock.send_json({'event':'disconect', 'ip':node.ip, 'vk': self.ironhouse.pk2vk.get(node.public_key) })
     callback = ReactorCommand.create_callback(
         callback=StateInput.CONN_DROPPED,
         ip=node.ip
     )
     log.debug("Sending callback failure to mainthread {}".format(callback))
Esempio n. 11
0
 def assert_router(composer: Composer):
     from cilantro.protocol.states.decorators import StateInput
     from cilantro.messages.reactor.reactor_command import ReactorCommand
     cb = ReactorCommand.create_callback(callback=StateInput.REQUEST,
                                         envelope=request_env,
                                         header=dealer_id)
     composer.manager.router.route_callback.assert_called_with(cb)
Esempio n. 12
0
    def test_subpub_1_n_1(self):
        """
        Tests sub/pub with 1 publisher and 3 subs, with one message
        """
        def configure_interface(reactor: ReactorInterface):
            reactor._run_callback = MagicMock()
            return reactor

        def run_assertions(reactor: ReactorInterface):
            cb = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                envelope=env)
            reactor._run_callback.assert_called_once_with(cb)

        env = random_envelope()

        sub1 = MPReactorInterface(config_fn=configure_interface,
                                  assert_fn=run_assertions,
                                  name='** SUB1')
        sub2 = MPReactorInterface(config_fn=configure_interface,
                                  assert_fn=run_assertions,
                                  name='** SUB2')
        sub3 = MPReactorInterface(config_fn=configure_interface,
                                  assert_fn=run_assertions,
                                  name='** SUB3')
        pub = MPReactorInterface(name='++ PUB')

        add_sub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.add_sub.__name__,
            url=URL,
            filter=FILTER)
        add_pub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__, SubPubExecutor.add_pub.__name__, url=URL)
        send_pub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.send_pub.__name__,
            envelope=env,
            filter=FILTER)

        sub1.send_cmd(add_sub_cmd)
        sub2.send_cmd(add_sub_cmd)
        sub3.send_cmd(add_sub_cmd)
        pub.send_cmd(add_pub_cmd)
        time.sleep(0.2)
        pub.send_cmd(send_pub_cmd)

        self.start()
Esempio n. 13
0
    async def _lookup_ip(self, cmd, url, vk, *args, **kwargs):
        ip, node = None, None
        try:
            node, cached = await self.dht.network.lookup_ip(vk)
            # NOTE while secure, this is a more loose connection policy
            self.log.debugv('IP {} resolves {} into {}'.format(
                os.getenv('HOST_IP', '127.0.0.1'), vk, node))
            self.log.debugv(
                '... but is {} authorized? Until next episode!'.format(node))
            if node:
                if not self.dht.network.ironhouse.authorized_nodes.get(
                        node.id):
                    authorization = await self.dht.network.authenticate(node)
                    if not authorization:
                        node = None
            else:
                node = None

        except Exception as e:
            delim_line = '!' * 64
            err_msg = '\n\n' + delim_line + '\n' + delim_line
            err_msg += '\n ERROR CAUGHT IN LOOKUP FOR VK {}\ncalled \w args={}\nand kwargs={}\n'\
                       .format(vk, args, kwargs)
            err_msg += '\nError Message: '
            err_msg += '\n\n{}'.format(traceback.format_exc())
            err_msg += '\n' + delim_line + '\n' + delim_line
            self.log.fatal(err_msg)

        if node is None:
            kwargs = cmd.kwargs
            callback = ReactorCommand.create_callback(
                callback=StateInput.LOOKUP_FAILED, **kwargs)
            self.log.debug(
                "Sending callback failure to mainthread {}".format(callback))
            self.socket.send(callback.serialize())
            # TODO -- send callback to SM saying hey i couldnt lookup this vk

            return

        # Send interpolated command back through pipeline
        ip = node.ip if type(node) == Node else node
        new_url = IPUtils.interpolate_url(url, ip)
        kwargs = cmd.kwargs
        kwargs['url'] = new_url
        new_cmd = ReactorCommand.create_cmd(envelope=cmd.envelope, **kwargs)

        self._execute_cmd(new_cmd)
Esempio n. 14
0
 def assert_bad_sub(composer: Composer):
     from cilantro.messages.reactor.reactor_command import ReactorCommand
     from cilantro.protocol.states.decorators import StateInput
     from unittest.mock import call
     cb = call(
         ReactorCommand.create_callback(callback=StateInput.INPUT,
                                        envelope=env))
     assert cb not in composer.manager.router.route_callback.call_args_list
        def assert_sub(composer: Composer):
            from cilantro.messages.reactor.reactor_command import ReactorCommand
            from cilantro.protocol.states.decorators import StateInput
            from unittest.mock import call

            callback1 = ReactorCommand.create_callback(
                callback=StateInput.INPUT, envelope=env1)
            callback2 = ReactorCommand.create_callback(
                callback=StateInput.INPUT, envelope=env2)
            calls = [call(callback1), call(callback2)]

            call_args = composer.interface.router.route_callback.call_args_list

            assert len(call_args) == 2, "route_callback should be called exactly twice, not {} times with {}"\
                                        .format(len(call_args), call_args)
            composer.interface.router.route_callback.assert_has_calls(
                calls, any_order=True)
Esempio n. 16
0
    def test_1_1_1(self):
        """
        Tests pub/sub 1-1 (one sub one pub) with one message
        """
        def configure_interface(reactor: ReactorInterface):
            reactor._run_callback = MagicMock()
            return reactor

        def run_assertions(reactor: ReactorInterface):
            callback = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                      envelope=env)
            reactor._run_callback.assert_called_once_with(callback)

        env = random_envelope()

        sub = MPReactorInterface(config_fn=configure_interface,
                                 assert_fn=run_assertions,
                                 name='** SUB')
        pub = MPReactorInterface(name='++ PUB')

        # test
        # self.execute_python('node_1', something_silly, async=True)
        # end tests

        add_sub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.add_sub.__name__,
            url=URL,
            filter=FILTER)
        add_pub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__, SubPubExecutor.add_pub.__name__, url=URL)
        send_pub_cmd = ReactorCommand.create_cmd(
            SubPubExecutor.__name__,
            SubPubExecutor.send_pub.__name__,
            envelope=env,
            filter=FILTER)

        sub.send_cmd(add_sub_cmd)
        pub.send_cmd(add_pub_cmd)
        time.sleep(
            0.2
        )  # To allow time for subs to connect to pub before pub sends data
        pub.send_cmd(send_pub_cmd)

        self.start()
Esempio n. 17
0
    def call_on_mp(self, callback: str, header: str=None, envelope_binary: bytes=None, **kwargs):
        if header:
            kwargs['header'] = header

        cmd = ReactorCommand.create_callback(callback=callback, envelope_binary=envelope_binary, **kwargs)

        # self.log.critical("\ncalling callback cmd to reactor interface: {}".format(cmd))  # DEBUG line remove this

        self.inproc_socket.send(cmd.serialize())
Esempio n. 18
0
 def connection_drop(self):
     if self.daemon:
         callback = ReactorCommand.create_callback(
             callback=StateInput.CONN_DROPPED,
             vk=self.ironhouse.vk,
             ip=self.node.ip)
         log.debug(
             "Sending callback failure to mainthread {}".format(callback))
         self.daemon.socket.send(callback.serialize())
Esempio n. 19
0
    def test_req_1_1_1(self):
        """
        Tests dealer router 1/1 (1 dealer, 1 router) with 1 message request (dealer sends router 1 message)
        """
        def run_assertions(reactor: ReactorInterface):
            cb = ReactorCommand.create_callback(callback=ROUTE_REQ_CALLBACK,
                                                envelope=env,
                                                header=DEALER_ID)
            reactor._run_callback.assert_called_once_with(cb)

        DEALER_URL = URLS[0]
        DEALER_ID = "id-" + DEALER_URL  # irl this would a node's vk
        ROUTER_URL = URLS[1]

        env = random_envelope()

        dealer = MPReactorInterface(name='DEALER')
        router = MPReactorInterface(config_fn=config_reactor,
                                    assert_fn=run_assertions,
                                    name='ROUTER')

        add_dealer = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.add_dealer.__name__,
            url=ROUTER_URL,
            id=DEALER_ID)
        add_router = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.add_router.__name__,
            url=ROUTER_URL)
        request = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.request.__name__,
            url=ROUTER_URL,
            envelope=env)

        dealer.send_cmd(add_dealer)
        router.send_cmd(add_router)

        time.sleep(0.2)
        dealer.send_cmd(request)

        self.start()
Esempio n. 20
0
    def _lookup_failed(self, cmd: ReactorCommand):

        kwargs = cmd.kwargs
        del (kwargs['callback'])
        new_cmd = ReactorCommand.create_cmd(envelope=cmd.envelope, **kwargs)

        import time
        time.sleep(0.5)

        self.sm.composer.interface.send_cmd(new_cmd)
Esempio n. 21
0
    def test_create_with_envelope(self):
        """
        Tests creating a message with an envelope produces an object with the expected properties
        """
        sk, vk = wallet.new()
        tx = StandardTransactionBuilder.random_tx()
        sender = 'me'
        env = Envelope.create_from_message(message=tx, signing_key=sk)

        cmd = ReactorCommand.create_cmd('some_cls', 'some_func', envelope=env)

        self.assertTrue(ReactorCommand.envelope, env)
Esempio n. 22
0
    def test_create_callback(self):
        """
        Tests create_callback
        """
        callback = 'route'
        kwargs = {'cats': '18', 'dogs': 'over 9000'}

        cmd = ReactorCommand.create_callback(callback, **kwargs)

        self.assertEqual(cmd.callback, callback)
        for k in kwargs:
            self.assertEqual(cmd.kwargs[k], kwargs[k])
Esempio n. 23
0
    def test_create_with_kwargs(self):
        """
        Tests creating a message without an envelope produces an objects with the expected kwargs
        """
        kwargs = {
            'callback': 'do_something',
            'some_num': '10',
            'some_id': '0x5544ddeeff'
        }

        cmd = ReactorCommand.create(**kwargs)

        self.assertEqual(cmd.kwargs, kwargs)
Esempio n. 24
0
        def assert_sub(composer: Composer):
            from cilantro.messages.reactor.reactor_command import ReactorCommand
            from cilantro.protocol.states.decorators import StateInput
            from unittest.mock import call

            expected_calls = []
            for env in envs:
                callback = ReactorCommand.create_callback(
                    callback=StateInput.INPUT, envelope=env)
                expected_calls.append(call(callback))

            call_args = composer.manager.router.route_callback.call_args_list
            composer.manager.router.route_callback.assert_has_calls(
                expected_calls, any_order=True)
        def assert_sub(composer: Composer):
            from cilantro.messages.reactor.reactor_command import ReactorCommand
            from cilantro.protocol.states.decorators import StateInput
            from unittest.mock import call

            expected_calls = []
            for env in envs:
                callback = ReactorCommand.create_callback(
                    callback=StateInput.INPUT, envelope=env)
                expected_calls.append(call(callback))

            call_args = composer.interface.router.route_callback.call_args_list

            assert len(call_args) == len(expected_calls), "route_callback should be called exactly {} times, not {} " \
                                                          "times with {}".format(len(expected_calls), len(call_args), call_args)
            composer.interface.router.route_callback.assert_has_calls(
                expected_calls, any_order=True)
Esempio n. 26
0
    def test_create_cmd(self):
        """
        Tests create_cmd
        """
        class_name = 'TestClass'
        func_name = 'do_something_lit'

        kwargs = {'cats': '18', 'dogs': 'over 9000'}

        cmd = ReactorCommand.create_cmd(class_name, func_name, **kwargs)

        self.assertEquals(cmd.func_name, func_name)
        self.assertEqual(cmd.class_name, class_name)
        for k in kwargs:
            self.assertEqual(cmd.kwargs[k], kwargs[k])

        self.assertEqual(cmd.envelope, None)
Esempio n. 27
0
 async def _recv_messages(self):
     """
     Should be for internal use only.
     Starts listening to messages from the ReactorDaemon. This method gets run_until_complete by
     invoking .start_reactor on the ReactorInterface object.
     """
     try:
         self.log.debug(
             "~~ Reactor listening to messages from ReactorDaemon ~~")
         while True:
             self.log.debug("Waiting for callback...")
             msg = await self.socket.recv()
             callback = ReactorCommand.from_bytes(msg)
             self.log.debug("Got callback cmd <{}>".format(callback))
             self.router.route_callback(callback)
     except asyncio.CancelledError:
         self.log.debug("_recv_messages future canceled!")
Esempio n. 28
0
 def run_assertions(reactor: ReactorInterface):
     cb = ReactorCommand.create_callback(callback=ROUTE_REQ_CALLBACK,
                                         envelope=env,
                                         header=DEALER_ID)
     reactor._run_callback.assert_called_once_with(cb)
Esempio n. 29
0
    def test_req_reply_1_1_1(self):
        """
        Tests a request/reply round trip between dealer and router.
        """
        def config_dealer(reactor: ReactorInterface):
            reactor._run_callback = MagicMock()
            return reactor

        def config_router(reactor: ReactorInterface):
            def reply_effect(*args, **kwargs):
                # log = get_logger("ASSERT ROUTER SIDE EFFECT WTIH")
                # log.critical("\n\n sending reply command... \n\n")
                reactor.send_cmd(reply)
                dealer.send_cmd(reply)

            reactor._run_callback = MagicMock()
            reactor._run_callback.side_effect = reply_effect
            return reactor

        def assert_dealer(reactor: ReactorInterface):
            cb = ReactorCommand.create_callback(callback=ROUTE_CALLBACK,
                                                envelope=rep_env)
            reactor._run_callback.assert_called_once_with(cb)

        def assert_router(reactor: ReactorInterface):
            cb = ReactorCommand.create_callback(callback=ROUTE_REQ_CALLBACK,
                                                envelope=req_env,
                                                header=DEALER_ID)
            reactor._run_callback.assert_called_once_with(cb)
            # reactor._run_callback.side_effect = reply_effect

        DEALER_URL = URLS[0]
        DEALER_ID = "id-" + DEALER_URL  # irl this would a node's vk
        ROUTER_URL = URLS[1]

        req_env = random_envelope()
        rep_env = random_envelope()

        add_dealer = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.add_dealer.__name__,
            url=ROUTER_URL,
            id=DEALER_ID)
        add_router = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.add_router.__name__,
            url=ROUTER_URL)

        request = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.request.__name__,
            url=ROUTER_URL,
            envelope=req_env)
        reply = ReactorCommand.create_cmd(
            class_name=DealerRouterExecutor.__name__,
            func_name=DealerRouterExecutor.reply.__name__,
            id=DEALER_ID,
            envelope=rep_env)

        dealer = MPReactorInterface(name='DEALER',
                                    config_fn=config_dealer,
                                    assert_fn=assert_dealer)
        router = MPReactorInterface(config_fn=config_router,
                                    assert_fn=assert_router,
                                    name='ROUTER')

        dealer.send_cmd(add_dealer)
        router.send_cmd(add_router)
        time.sleep(0.2)

        dealer.send_cmd(request)

        self.start()
Esempio n. 30
0
 def send_cmd(self, cmd: ReactorCommand):
     assert isinstance(
         cmd, ReactorCommand
     ), "Only ReactorCommand instances can sent through the reactor"
     self.socket.send(cmd.serialize())