Exemple #1
0
def run():
    # Ensure the input and output files do not exist initially
    if os.path.isfile(INPUT_FILE):
        os.remove(INPUT_FILE)
    if os.path.isfile(OUTPUT_FILE):
        os.remove(OUTPUT_FILE)

    # create the connection and multiplexer objects
    configuration = ConnectionConfig(
        input_file=INPUT_FILE,
        output_file=OUTPUT_FILE,
        connection_id=StubConnection.connection_id,
    )
    stub_connection = StubConnection(configuration=configuration,
                                     identity=Identity("some_agent",
                                                       "some_address"))
    multiplexer = Multiplexer([stub_connection])
    try:
        # Set the multiplexer running in a different thread
        t = Thread(target=multiplexer.connect)
        t.start()

        # Wait for everything to start up
        time.sleep(3)

        # Create a message inside an envelope and get the stub connection to pass it into the multiplexer
        message_text = (
            "multiplexer,some_agent,fetchai/default:0.4.0,\x08\x01*\x07\n\x05hello,"
        )
        with open(INPUT_FILE, "w") as f:
            write_with_lock(f, message_text)

        # Wait for the envelope to get processed
        time.sleep(2)

        # get the envelope
        envelope = multiplexer.get()  # type: Optional[Envelope]
        assert envelope is not None

        # Inspect its contents
        print(
            "Envelope received by Multiplexer: sender={}, to={}, protocol_id={}, message={}"
            .format(envelope.sender, envelope.to, envelope.protocol_id,
                    envelope.message))

        # Create a mirrored response envelope
        response_envelope = copy(envelope)
        response_envelope.to = envelope.sender
        response_envelope.sender = envelope.to

        # Send the envelope back
        multiplexer.put(response_envelope)

        # Read the output envelope generated by the multiplexer
        with open(OUTPUT_FILE, "r") as f:
            print("Envelope received from Multiplexer: " + f.readline())
    finally:
        # Shut down the multiplexer
        multiplexer.disconnect()
        t.join()
Exemple #2
0
def test_send_message_no_supported_protocol():
    """Test the case when we send an envelope with a specific connection that does not support the protocol."""
    with LocalNode() as node:
        identity_1 = Identity("", address="address_1")
        public_id = PublicId.from_str("fetchai/my_private_protocol:0.1.0")
        connection_1 = _make_local_connection(
            identity_1.address,
            node,
            restricted_to_protocols={public_id},
            excluded_protocols={public_id},
        )
        multiplexer = Multiplexer([connection_1])

        multiplexer.connect()

        with mock.patch.object(aea.mail.base.logger, "warning") as mock_logger_warning:
            protocol_id = UNKNOWN_PROTOCOL_PUBLIC_ID
            envelope = Envelope(
                to=identity_1.address,
                sender=identity_1.address,
                protocol_id=protocol_id,
                message=b"some bytes",
            )
            multiplexer.put(envelope)
            time.sleep(0.5)
            mock_logger_warning.assert_called_with(
                "Connection {} cannot handle protocol {}. Cannot send the envelope.".format(
                    connection_1.connection_id, protocol_id
                )
            )

        multiplexer.disconnect()
Exemple #3
0
    def test_communication_direct(self):
        """Test communication direct (i.e. both clients registered to same peer)."""
        for i in range(len(PUBLIC_DHT_DELEGATE_URIS)):
            uri = PUBLIC_DHT_DELEGATE_URIS[i]
            peer_public_key = PUBLIC_DHT_PUBLIC_KEYS[i]
            multiplexers = []
            try:
                temp_dir_1 = os.path.join(self.t, f"dir_{i}_1")
                os.mkdir(temp_dir_1)
                connection1 = _make_libp2p_client_connection(
                    peer_public_key=peer_public_key, uri=uri, data_dir=temp_dir_1
                )
                multiplexer1 = Multiplexer([connection1])
                multiplexer1.connect()
                multiplexers.append(multiplexer1)

                temp_dir_2 = os.path.join(self.t, f"dir_{i}_2")
                os.mkdir(temp_dir_2)
                connection2 = _make_libp2p_client_connection(
                    peer_public_key=peer_public_key, uri=uri, data_dir=temp_dir_2
                )
                multiplexer2 = Multiplexer([connection2])
                multiplexer2.connect()
                multiplexers.append(multiplexer2)

                addr_1 = connection1.address
                addr_2 = connection2.address

                msg = DefaultMessage(
                    dialogue_reference=("", ""),
                    message_id=1,
                    target=0,
                    performative=DefaultMessage.Performative.BYTES,
                    content=b"hello",
                )
                envelope = Envelope(to=addr_2, sender=addr_1, message=msg,)

                multiplexer1.put(envelope)
                delivered_envelope = multiplexer2.get(block=True, timeout=20)

                assert delivered_envelope is not None
                assert delivered_envelope.to == envelope.to
                assert delivered_envelope.sender == envelope.sender
                assert (
                    delivered_envelope.protocol_specification_id
                    == envelope.protocol_specification_id
                )
                assert delivered_envelope.message != envelope.message
                msg = DefaultMessage.serializer.decode(delivered_envelope.message)
                msg.to = delivered_envelope.to
                msg.sender = delivered_envelope.sender
                assert envelope.message == msg
            except Exception:
                raise
            finally:
                for mux in multiplexers:
                    mux.disconnect()
    def test_communication_direct(self):
        """Test communication direct."""
        for maddr in PUBLIC_DHT_MADDRS:
            multiplexers = []
            try:
                connection1 = _make_libp2p_connection(DEFAULT_PORT + 1,
                                                      relay=False,
                                                      entry_peers=[maddr])
                multiplexer1 = Multiplexer([connection1])
                self.log_files.append(connection1.node.log_file)
                multiplexer1.connect()
                multiplexers.append(multiplexer1)

                connection2 = _make_libp2p_connection(DEFAULT_PORT + 2,
                                                      relay=False,
                                                      entry_peers=[maddr])
                multiplexer2 = Multiplexer([connection2])
                self.log_files.append(connection2.node.log_file)
                multiplexer2.connect()
                multiplexers.append(multiplexer2)

                addr_1 = connection1.node.address
                addr_2 = connection2.node.address

                msg = DefaultMessage(
                    dialogue_reference=("", ""),
                    message_id=1,
                    target=0,
                    performative=DefaultMessage.Performative.BYTES,
                    content=b"hello",
                )
                envelope = Envelope(
                    to=addr_2,
                    sender=addr_1,
                    protocol_id=DefaultMessage.protocol_id,
                    message=msg,
                )

                multiplexer1.put(envelope)
                delivered_envelope = multiplexer2.get(block=True, timeout=20)

                assert delivered_envelope is not None
                assert delivered_envelope.to == envelope.to
                assert delivered_envelope.sender == envelope.sender
                assert delivered_envelope.protocol_id == envelope.protocol_id
                assert delivered_envelope.message != envelope.message
                msg = DefaultMessage.serializer.decode(
                    delivered_envelope.message)
                msg.to = delivered_envelope.to
                msg.sender = delivered_envelope.sender
                assert envelope.message == msg
            except Exception:
                raise
            finally:
                for mux in multiplexers:
                    mux.disconnect()
    def test_communication_indirect(self):
        assert (len(PUBLIC_DHT_DELEGATE_URIS) >
                1), "Test requires at least 2 public dht node"

        for i in range(len(PUBLIC_DHT_DELEGATE_URIS)):
            connection1 = _make_libp2p_client_connection(
                uri=PUBLIC_DHT_DELEGATE_URIS[i])
            multiplexer1 = Multiplexer([connection1])
            multiplexer1.connect()

            addr_1 = connection1.address
            msg = DefaultMessage(
                dialogue_reference=("", ""),
                message_id=1,
                target=0,
                performative=DefaultMessage.Performative.BYTES,
                content=b"hello",
            )

            for j in range(len(PUBLIC_DHT_DELEGATE_URIS)):
                if j == i:
                    continue

                connection2 = _make_libp2p_client_connection(
                    uri=PUBLIC_DHT_DELEGATE_URIS[j])
                multiplexer2 = Multiplexer([connection2])
                multiplexer2.connect()

                addr_2 = connection2.address
                envelope = Envelope(
                    to=addr_2,
                    sender=addr_1,
                    protocol_id=DefaultMessage.protocol_id,
                    message=msg,
                )

                multiplexer1.put(envelope)
                delivered_envelope = multiplexer2.get(block=True, timeout=20)

                try:
                    assert delivered_envelope is not None
                    assert delivered_envelope.to == envelope.to
                    assert delivered_envelope.sender == envelope.sender
                    assert delivered_envelope.protocol_id == envelope.protocol_id
                    assert delivered_envelope.message != envelope.message
                    msg = DefaultMessage.serializer.decode(
                        delivered_envelope.message)
                    assert envelope.message == msg
                except Exception:
                    multiplexer1.disconnect()
                    raise
                finally:
                    multiplexer2.disconnect()

            multiplexer1.disconnect()
Exemple #6
0
def test_send_message_no_supported_protocol():
    """Test the case when we send an envelope with a specific connection that does not support the protocol."""
    with LocalNode() as node:
        identity_1 = Identity("", address="address_1")
        connection_1 = _make_local_connection(
            identity_1.address,
            node,
            restricted_to_protocols={DefaultMessage.protocol_id},
            excluded_protocols={FipaMessage.protocol_id},
        )
        multiplexer = Multiplexer(
            [connection_1],
            protocols=[DefaultMessage, FipaMessage, UnknownProtocolMock])

        multiplexer.connect()

        with mock.patch.object(multiplexer.logger,
                               "warning") as mock_logger_warning:
            envelope = Envelope(
                to=identity_1.address,
                sender=identity_1.address,
                protocol_specification_id=FipaMessage.
                protocol_specification_id,
                message=b"some bytes",
            )
            multiplexer.put(envelope)
            time.sleep(0.5)
            mock_logger_warning.assert_called_with(
                "Connection {} does not support protocol {}. It is explicitly excluded."
                .format(connection_1.connection_id, FipaMessage.protocol_id))

        with mock.patch.object(multiplexer.logger,
                               "warning") as mock_logger_warning:
            envelope = Envelope(
                to=identity_1.address,
                sender=identity_1.address,
                protocol_specification_id=UnknownProtocolMock.
                protocol_specification_id,
                message=b"some bytes",
            )
            multiplexer.put(envelope)
            time.sleep(0.5)
            mock_logger_warning.assert_called_with(
                "Connection {} does not support protocol {}. The connection is restricted to protocols in {}."
                .format(
                    connection_1.connection_id,
                    UnknownProtocolMock.protocol_id,
                    connection_1.restricted_to_protocols,
                ))

        multiplexer.disconnect()
    def test_communication_direct(self):
        for uri in PUBLIC_DHT_DELEGATE_URIS:
            connection1 = _make_libp2p_client_connection(uri=uri)
            multiplexer1 = Multiplexer([connection1])
            multiplexer1.connect()

            connection2 = _make_libp2p_client_connection(uri=uri)
            multiplexer2 = Multiplexer([connection2])
            multiplexer2.connect()

            addr_1 = connection1.address
            addr_2 = connection2.address

            msg = DefaultMessage(
                dialogue_reference=("", ""),
                message_id=1,
                target=0,
                performative=DefaultMessage.Performative.BYTES,
                content=b"hello",
            )
            envelope = Envelope(
                to=addr_2,
                sender=addr_1,
                protocol_id=DefaultMessage.protocol_id,
                message=msg,
            )

            multiplexer1.put(envelope)
            delivered_envelope = multiplexer2.get(block=True, timeout=20)

            try:
                assert delivered_envelope is not None
                assert delivered_envelope.to == envelope.to
                assert delivered_envelope.sender == envelope.sender
                assert delivered_envelope.protocol_id == envelope.protocol_id
                assert delivered_envelope.message != envelope.message
                msg = DefaultMessage.serializer.decode(
                    delivered_envelope.message)
                assert envelope.message == msg
            except Exception:
                raise
            finally:
                multiplexer1.disconnect()
                multiplexer2.disconnect()
Exemple #8
0
def test_send_envelope_error_is_logged_by_send_loop():
    """Test that the AEAConnectionError in the '_send' method is logged by the '_send_loop'."""
    connection = _make_dummy_connection()
    multiplexer = Multiplexer([connection])
    multiplexer.connect()
    fake_connection_id = UNKNOWN_CONNECTION_PUBLIC_ID

    envelope = Envelope(
        to="",
        sender="",
        protocol_id=DefaultMessage.protocol_id,
        message=b"",
        context=EnvelopeContext(connection_id=fake_connection_id),
    )

    with unittest.mock.patch.object(aea.mail.base.logger, "error") as mock_logger_error:
        multiplexer.put(envelope)
        time.sleep(0.1)
        mock_logger_error.assert_called_with(
            "No connection registered with id: {}.".format(fake_connection_id)
        )

    multiplexer.disconnect()
Exemple #9
0
class TestSimpleSearchResult:
    """Test that a simple search result return the expected result."""
    def setup(self):
        """Set up the test."""
        self.node = LocalNode()
        self.node.start()

        self.address_1 = "address"
        self.multiplexer = Multiplexer(
            [_make_local_connection(
                self.address_1,
                self.node,
            )])

        self.multiplexer.connect()

        # register a service.
        self.dialogues = OefSearchDialogues(self.address_1)
        self.data_model = DataModel(
            "foobar",
            attributes=[
                Attribute("foo", int, True),
                Attribute("bar", str, True)
            ],
        )
        service_description = Description({
            "foo": 1,
            "bar": "baz"
        },
                                          data_model=self.data_model)
        register_service_request, self.sending_dialogue = self.dialogues.create(
            counterparty=str(OEFLocalConnection.connection_id),
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            service_description=service_description,
        )
        envelope = Envelope(
            to=register_service_request.to,
            sender=register_service_request.sender,
            message=register_service_request,
        )
        self.multiplexer.put(envelope)

    @pytest.mark.flaky(reruns=MAX_FLAKY_RERUNS
                       )  # TODO: check reasons!. quite unstable test
    def test_not_empty_search_result(self):
        """Test that the search result contains one entry after a successful registration."""
        # build and send the request
        search_services_request, sending_dialogue = self.dialogues.create(
            counterparty=str(OEFLocalConnection.connection_id),
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            query=Query(constraints=[], model=self.data_model),
        )
        envelope = Envelope(
            to=search_services_request.to,
            sender=search_services_request.sender,
            message=search_services_request,
        )
        self.multiplexer.put(envelope)

        # check the result
        response_envelope = self.multiplexer.get(block=True, timeout=2.0)
        assert (response_envelope.protocol_specification_id ==
                OefSearchMessage.protocol_specification_id)
        search_result = cast(OefSearchMessage, response_envelope.message)
        response_dialogue = self.dialogues.update(search_result)
        assert response_dialogue == sending_dialogue
        assert search_result.performative == OefSearchMessage.Performative.SEARCH_RESULT
        assert search_result.agents == (self.address_1, )

    def teardown(self):
        """Teardown the test."""
        self.multiplexer.disconnect()
        self.node.stop()
Exemple #10
0
class TestLibp2pConnectionRelayNodeRestartIncomingEnvelopes(
        BaseTestLibp2pRelay):
    """Test that connection will reliably receive envelopes after its relay node restarted"""
    @libp2p_log_on_failure
    def setup(self):
        """Set the test up"""
        super().setup()
        temp_dir_gen = os.path.join(self.t, "temp_dir_gen")
        os.mkdir(temp_dir_gen)
        self.genesis = _make_libp2p_connection(data_dir=temp_dir_gen,
                                               port=DEFAULT_PORT + 1,
                                               build_directory=self.t)

        self.multiplexer_genesis = Multiplexer([self.genesis],
                                               protocols=[DefaultMessage])
        self.multiplexer_genesis.connect()
        self.log_files.append(self.genesis.node.log_file)
        self.multiplexers.append(self.multiplexer_genesis)

        genesis_peer = self.genesis.node.multiaddrs[0]

        with open("node_key", "wb") as f:
            make_crypto(DEFAULT_LEDGER).dump(f)
            self.relay_key_path = "node_key"

        temp_dir_rel = os.path.join(self.t, "temp_dir_rel")
        os.mkdir(temp_dir_rel)
        self.relay = _make_libp2p_connection(
            data_dir=temp_dir_rel,
            port=DEFAULT_PORT + 2,
            entry_peers=[genesis_peer],
            node_key_file=self.relay_key_path,
            build_directory=self.t,
        )
        self.multiplexer_relay = Multiplexer([self.relay],
                                             protocols=[DefaultMessage])
        self.multiplexer_relay.connect()
        self.log_files.append(self.relay.node.log_file)
        self.multiplexers.append(self.multiplexer_relay)

        relay_peer = self.relay.node.multiaddrs[0]

        temp_dir_1 = os.path.join(self.t, "temp_dir_1")
        os.mkdir(temp_dir_1)
        self.connection = _make_libp2p_connection(
            data_dir=temp_dir_1,
            port=DEFAULT_PORT + 3,
            relay=False,
            entry_peers=[relay_peer],
            build_directory=self.t,
        )
        self.multiplexer = Multiplexer([self.connection],
                                       protocols=[DefaultMessage])
        self.multiplexer.connect()
        self.log_files.append(self.connection.node.log_file)
        self.multiplexers.append(self.multiplexer)

        temp_dir_2 = os.path.join(self.t, "temp_dir_2")
        os.mkdir(temp_dir_2)
        self.connection2 = _make_libp2p_connection(
            data_dir=temp_dir_2,
            port=DEFAULT_PORT + 4,
            relay=False,
            entry_peers=[relay_peer],
            build_directory=self.t,
        )
        self.multiplexer2 = Multiplexer([self.connection2],
                                        protocols=[DefaultMessage])
        self.multiplexer2.connect()
        self.log_files.append(self.connection2.node.log_file)
        self.multiplexers.append(self.multiplexer2)

    def test_connection_is_established(self):
        """Test connection established."""
        assert self.relay.is_connected is True
        assert self.connection.is_connected is True
        assert self.connection2.is_connected is True

    def test_envelope_routed_from_peer_after_relay_restart(self):
        """Test envelope routed from third peer after relay restart."""
        addr_1 = self.genesis.address
        addr_2 = self.connection.address

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"hello",
        )
        envelope = Envelope(
            to=addr_2,
            sender=addr_1,
            protocol_specification_id=DefaultMessage.protocol_specification_id,
            message=DefaultSerializer().encode(msg),
        )

        self.multiplexer_genesis.put(envelope)
        delivered_envelope = self.multiplexer.get(block=True, timeout=20)

        assert delivered_envelope is not None
        assert delivered_envelope.to == envelope.to
        assert delivered_envelope.sender == envelope.sender
        assert (delivered_envelope.protocol_specification_id ==
                envelope.protocol_specification_id)
        assert delivered_envelope.message_bytes == envelope.message_bytes

        self.multiplexer_relay.disconnect()
        self.change_state_and_wait(self.multiplexer_relay,
                                   expected_is_connected=False)

        # currently, multiplexer cannot be restarted
        self.multiplexer_relay = Multiplexer([self.relay],
                                             protocols=[DefaultMessage])
        self.multiplexer_relay.connect()
        self.change_state_and_wait(self.multiplexer_relay,
                                   expected_is_connected=True)
        self.multiplexers.append(self.multiplexer_relay)

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"helloAfterRestart",
        )
        envelope = Envelope(
            to=addr_2,
            sender=addr_1,
            protocol_specification_id=DefaultMessage.protocol_specification_id,
            message=DefaultSerializer().encode(msg),
        )

        self.multiplexer_genesis.put(envelope)

        delivered_envelope = self.multiplexer.get(block=True, timeout=20)

        assert delivered_envelope is not None
        assert delivered_envelope.to == envelope.to
        assert delivered_envelope.sender == envelope.sender
        assert (delivered_envelope.protocol_specification_id ==
                envelope.protocol_specification_id)
        assert delivered_envelope.message_bytes == envelope.message_bytes

    def test_envelope_routed_from_client_after_relay_restart(self):
        """Test envelope routed from third relay client after relay restart."""
        addr_1 = self.connection.address
        addr_2 = self.connection2.address

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"hello",
        )
        envelope = Envelope(
            to=addr_1,
            sender=addr_2,
            protocol_specification_id=DefaultMessage.protocol_specification_id,
            message=DefaultSerializer().encode(msg),
        )

        self.multiplexer2.put(envelope)
        delivered_envelope = self.multiplexer.get(block=True, timeout=20)

        assert delivered_envelope is not None
        assert delivered_envelope.to == envelope.to
        assert delivered_envelope.sender == envelope.sender
        assert (delivered_envelope.protocol_specification_id ==
                envelope.protocol_specification_id)
        assert delivered_envelope.message_bytes == envelope.message_bytes

        self.multiplexer_relay.disconnect()
        self.change_state_and_wait(self.multiplexer_relay,
                                   expected_is_connected=False)

        # currently, multiplexer cannot be restarted
        self.multiplexer_relay = Multiplexer([self.relay],
                                             protocols=[DefaultMessage])
        self.multiplexer_relay.connect()
        self.change_state_and_wait(self.multiplexer_relay,
                                   expected_is_connected=True)
        self.multiplexers.append(self.multiplexer_relay)

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"helloAfterRestart",
        )

        envelope = Envelope(
            to=addr_1,
            sender=addr_2,
            protocol_specification_id=DefaultMessage.protocol_specification_id,
            message=DefaultSerializer().encode(msg),
        )

        time.sleep(5)
        self.multiplexer2.put(envelope)
        delivered_envelope = self.multiplexer.get(block=True, timeout=20)

        assert delivered_envelope is not None
        assert delivered_envelope.to == envelope.to
        assert delivered_envelope.sender == envelope.sender
        assert (delivered_envelope.protocol_specification_id ==
                envelope.protocol_specification_id)
        assert delivered_envelope.message_bytes == envelope.message_bytes
Exemple #11
0
    class TestSearchServices:
        """Tests related to service search functionality."""
        def setup(self):
            """Set the test up."""
            self.connection = _make_oef_connection(
                FETCHAI_ADDRESS_ONE,
                oef_addr="127.0.0.1",
                oef_port=10000,
            )
            self.multiplexer = Multiplexer([self.connection])
            self.multiplexer.connect()
            self.oef_search_dialogues = OefSearchDialogues(FETCHAI_ADDRESS_ONE)

        def test_search_services_with_query_without_model(self):
            """Test that a search services request can be sent correctly.

            In this test, the query has no data model.
            """
            search_query_empty_model = Query(
                [Constraint("foo", ConstraintType("==", "bar"))], model=None)
            oef_search_request, sending_dialogue = self.oef_search_dialogues.create(
                counterparty=str(self.connection.connection_id),
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                query=search_query_empty_model,
            )
            self.multiplexer.put(
                Envelope(
                    to=oef_search_request.to,
                    sender=oef_search_request.sender,
                    protocol_id=oef_search_request.protocol_id,
                    message=oef_search_request,
                ))

            envelope = self.multiplexer.get(block=True, timeout=5.0)
            oef_search_response = envelope.message
            oef_search_dialogue = self.oef_search_dialogues.update(
                oef_search_response)
            assert (oef_search_response.performative ==
                    OefSearchMessage.Performative.SEARCH_RESULT)
            assert oef_search_dialogue is not None
            assert oef_search_dialogue == sending_dialogue
            assert oef_search_response.agents == ()

        def test_search_services_with_query_with_model(self):
            """Test that a search services request can be sent correctly.

            In this test, the query has a simple data model.
            """
            data_model = DataModel("foobar", [Attribute("foo", str, True)])
            search_query = Query(
                [Constraint("foo", ConstraintType("==", "bar"))],
                model=data_model)
            oef_search_request, sending_dialogue = self.oef_search_dialogues.create(
                counterparty=str(self.connection.connection_id),
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                query=search_query,
            )
            self.multiplexer.put(
                Envelope(
                    to=oef_search_request.to,
                    sender=oef_search_request.sender,
                    protocol_id=oef_search_request.protocol_id,
                    message=oef_search_request,
                ))

            envelope = self.multiplexer.get(block=True, timeout=5.0)
            oef_search_response = envelope.message
            oef_search_dialogue = self.oef_search_dialogues.update(
                oef_search_response)
            assert (oef_search_response.performative ==
                    OefSearchMessage.Performative.SEARCH_RESULT)
            assert oef_search_dialogue is not None
            assert oef_search_dialogue == sending_dialogue
            assert oef_search_response.agents == ()

        def test_search_services_with_distance_query(self):
            """Test that a search services request can be sent correctly.

            In this test, the query has a simple data model.
            """
            tour_eiffel = Location(48.8581064, 2.29447)
            attribute = Attribute("latlon", Location, True)
            data_model = DataModel("geolocation", [attribute])
            search_query = Query(
                [
                    Constraint(attribute.name,
                               ConstraintType("distance", (tour_eiffel, 1.0)))
                ],
                model=data_model,
            )
            oef_search_request, sending_dialogue = self.oef_search_dialogues.create(
                counterparty=str(self.connection.connection_id),
                performative=OefSearchMessage.Performative.SEARCH_SERVICES,
                query=search_query,
            )
            self.multiplexer.put(
                Envelope(
                    to=oef_search_request.to,
                    sender=oef_search_request.sender,
                    protocol_id=oef_search_request.protocol_id,
                    message=oef_search_request,
                ))
            envelope = self.multiplexer.get(block=True, timeout=5.0)
            oef_search_response = envelope.message
            oef_search_dialogue = self.oef_search_dialogues.update(
                oef_search_response)
            assert (oef_search_response.performative ==
                    OefSearchMessage.Performative.SEARCH_RESULT)
            assert oef_search_dialogue is not None
            assert oef_search_dialogue == sending_dialogue
            assert oef_search_response.agents == ()

        def teardown(self):
            """Teardowm the test."""
            self.multiplexer.disconnect()
Exemple #12
0
def test_soef():
    """Perform tests over real network."""
    # First run OEF in a separate terminal: python scripts/oef/launch.py -c ./scripts/oef/launch_config.json
    crypto = FetchAICrypto()
    identity = Identity("", address=crypto.address)

    # create the connection and multiplexer objects
    configuration = ConnectionConfig(
        api_key="TwiCIriSl0mLahw17pyqoA",
        soef_addr="soef.fetch.ai",
        soef_port=9002,
        restricted_to_protocols={
            PublicId.from_str("fetchai/oef_search:0.3.0")
        },
        connection_id=SOEFConnection.connection_id,
    )
    soef_connection = SOEFConnection(
        configuration=configuration,
        identity=identity,
    )
    multiplexer = Multiplexer([soef_connection])

    try:
        # Set the multiplexer running in a different thread
        t = Thread(target=multiplexer.connect)
        t.start()

        wait_for_condition(lambda: multiplexer.is_connected, timeout=5)

        # register an agent with location
        agent_location = Location(52.2057092, 2.1183431)
        service_instance = {"location": agent_location}
        service_description = Description(
            service_instance, data_model=models.AGENT_LOCATION_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            service_description=service_description,
        )
        envelope = Envelope(
            to="soef",
            sender=crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        logger.info("Registering agent at location=({},{}) by agent={}".format(
            agent_location.latitude,
            agent_location.longitude,
            crypto.address,
        ))
        multiplexer.put(envelope)

        # register personality pieces
        service_instance = {"piece": "genus", "value": "service"}
        service_description = Description(
            service_instance, data_model=models.AGENT_PERSONALITY_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            service_description=service_description,
        )
        envelope = Envelope(
            to="soef",
            sender=crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        logger.info("Registering agent personality")
        multiplexer.put(envelope)

        # register service key
        service_instance = {"key": "test", "value": "test"}
        service_description = Description(
            service_instance, data_model=models.SET_SERVICE_KEY_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            service_description=service_description,
        )
        envelope = Envelope(
            to="soef",
            sender=crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        logger.info("Registering agent service key")
        multiplexer.put(envelope)

        # find agents near me
        radius = 0.1
        close_to_my_service = Constraint(
            "location", ConstraintType("distance", (agent_location, radius)))
        closeness_query = Query([close_to_my_service],
                                model=models.AGENT_LOCATION_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            query=closeness_query,
        )
        envelope = Envelope(
            to="soef",
            sender=crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        logger.info(
            "Searching for agents in radius={} of myself at location=({},{})".
            format(
                radius,
                agent_location.latitude,
                agent_location.longitude,
            ))
        multiplexer.put(envelope)
        wait_for_condition(lambda: not multiplexer.in_queue.empty(),
                           timeout=20)

        # check for search results
        envelope = multiplexer.get()
        message = envelope.message
        assert len(message.agents) >= 0

        # find agents near me with filter
        radius = 0.1
        close_to_my_service = Constraint(
            "location", ConstraintType("distance", (agent_location, radius)))
        personality_filters = [
            Constraint("genus", ConstraintType("==", "vehicle")),
            Constraint("classification",
                       ConstraintType("==", "mobility.railway.train")),
        ]

        service_key_filters = [
            Constraint("test", ConstraintType("==", "test")),
        ]

        closeness_query = Query([close_to_my_service] + personality_filters +
                                service_key_filters)

        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.SEARCH_SERVICES,
            query=closeness_query,
        )
        envelope = Envelope(
            to="soef",
            sender=crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        logger.info(
            "Searching for agents in radius={} of myself at location=({},{}) with personality filters"
            .format(
                radius,
                agent_location.latitude,
                agent_location.longitude,
            ))
        time.sleep(3)  # cause requests rate limit on server :(
        multiplexer.put(envelope)
        wait_for_condition(lambda: not multiplexer.in_queue.empty(),
                           timeout=20)

        envelope = multiplexer.get()
        message = envelope.message
        assert len(message.agents) >= 0

        # test ping command
        service_description = Description({}, data_model=models.PING_MODEL)
        message = OefSearchMessage(
            performative=OefSearchMessage.Performative.REGISTER_SERVICE,
            service_description=service_description,
        )
        envelope = Envelope(
            to="soef",
            sender=crypto.address,
            protocol_id=message.protocol_id,
            message=message,
        )
        logger.info("Registering agent service key")
        multiplexer.put(envelope)
        time.sleep(3)
        assert multiplexer.in_queue.empty()

    finally:
        # Shut down the multiplexer
        multiplexer.disconnect()
        t.join()
Exemple #13
0
def test_communication():
    """Test that two multiplexer can communicate through the node."""
    with LocalNode() as node:

        multiplexer1 = Multiplexer(
            [_make_local_connection("multiplexer1", node)])
        multiplexer2 = Multiplexer(
            [_make_local_connection("multiplexer2", node)])

        multiplexer1.connect()
        multiplexer2.connect()

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"hello",
        )
        envelope = Envelope(
            to="multiplexer2",
            sender="multiplexer1",
            protocol_id=DefaultMessage.protocol_id,
            message=msg,
        )
        multiplexer1.put(envelope)

        msg = FipaMessage(
            performative=FipaMessage.Performative.CFP,
            dialogue_reference=(str(0), ""),
            message_id=1,
            target=0,
            query=Query([Constraint("something", ConstraintType(">", 1))]),
        )
        envelope = Envelope(
            to="multiplexer2",
            sender="multiplexer1",
            protocol_id=FipaMessage.protocol_id,
            message=msg,
        )
        multiplexer1.put(envelope)

        msg = FipaMessage(
            performative=FipaMessage.Performative.PROPOSE,
            dialogue_reference=(str(0), ""),
            message_id=2,
            target=1,
            proposal=Description({}),
        )

        envelope = Envelope(
            to="multiplexer2",
            sender="multiplexer1",
            protocol_id=FipaMessage.protocol_id,
            message=msg,
        )
        multiplexer1.put(envelope)

        msg = FipaMessage(
            performative=FipaMessage.Performative.ACCEPT,
            dialogue_reference=(str(0), ""),
            message_id=1,
            target=0,
        )
        envelope = Envelope(
            to="multiplexer2",
            sender="multiplexer1",
            protocol_id=FipaMessage.protocol_id,
            message=msg,
        )
        multiplexer1.put(envelope)

        msg = FipaMessage(
            performative=FipaMessage.Performative.DECLINE,
            dialogue_reference=(str(0), ""),
            message_id=1,
            target=0,
        )
        envelope = Envelope(
            to="multiplexer2",
            sender="multiplexer1",
            protocol_id=FipaMessage.protocol_id,
            message=msg,
        )
        multiplexer1.put(envelope)

        envelope = multiplexer2.get(block=True, timeout=1.0)
        msg = envelope.message
        assert envelope.protocol_id == DefaultMessage.protocol_id
        assert msg.content == b"hello"
        envelope = multiplexer2.get(block=True, timeout=1.0)
        msg = envelope.message
        assert envelope.protocol_id == FipaMessage.protocol_id
        assert msg.performative == FipaMessage.Performative.CFP
        envelope = multiplexer2.get(block=True, timeout=1.0)
        msg = envelope.message
        assert envelope.protocol_id == FipaMessage.protocol_id
        assert msg.performative == FipaMessage.Performative.PROPOSE
        envelope = multiplexer2.get(block=True, timeout=1.0)
        msg = envelope.message
        assert envelope.protocol_id == FipaMessage.protocol_id
        assert msg.performative == FipaMessage.Performative.ACCEPT
        envelope = multiplexer2.get(block=True, timeout=1.0)
        msg = envelope.message
        assert envelope.protocol_id == FipaMessage.protocol_id
        assert msg.performative == FipaMessage.Performative.DECLINE
        multiplexer1.disconnect()
        multiplexer2.disconnect()
    def test_communication_indirect(self):
        assert len(
            PUBLIC_DHT_MADDRS) > 1, "Test requires at least 2 public dht node"

        for i in range(len(PUBLIC_DHT_MADDRS)):
            connection1 = _make_libp2p_connection(
                DEFAULT_PORT + 1,
                relay=False,
                entry_peers=[PUBLIC_DHT_MADDRS[i]])
            multiplexer1 = Multiplexer([connection1])
            self.log_files.append(connection1.node.log_file)
            multiplexer1.connect()
            addr_1 = connection1.node.address

            for j in range(len(PUBLIC_DHT_MADDRS)):
                if j == i:
                    continue

                connection2 = _make_libp2p_connection(
                    DEFAULT_PORT + 2,
                    relay=False,
                    entry_peers=[PUBLIC_DHT_MADDRS[j]],
                )
                multiplexer2 = Multiplexer([connection2])
                self.log_files.append(connection2.node.log_file)
                multiplexer2.connect()

                addr_2 = connection2.node.address

                msg = DefaultMessage(
                    dialogue_reference=("", ""),
                    message_id=1,
                    target=0,
                    performative=DefaultMessage.Performative.BYTES,
                    content=b"hello",
                )
                envelope = Envelope(
                    to=addr_2,
                    sender=addr_1,
                    protocol_id=DefaultMessage.protocol_id,
                    message=msg,
                )

                multiplexer1.put(envelope)
                delivered_envelope = multiplexer2.get(block=True, timeout=20)

                try:
                    assert delivered_envelope is not None
                    assert delivered_envelope.to == envelope.to
                    assert delivered_envelope.sender == envelope.sender
                    assert delivered_envelope.protocol_id == envelope.protocol_id
                    assert delivered_envelope.message != envelope.message
                    msg = DefaultMessage.serializer.decode(
                        delivered_envelope.message)
                    assert envelope.message == msg
                except Exception:
                    multiplexer1.disconnect()
                    raise
                finally:
                    multiplexer2.disconnect()

            multiplexer1.disconnect()
Exemple #15
0
class TestExceptionHandlingOnConnectionSend:
    """Test exception handling policy on connection.send."""
    def setup(self):
        """Set up test case."""
        self.connection = _make_dummy_connection()
        self.multiplexer = Multiplexer([self.connection],
                                       protocols=[DefaultProtocolMock])
        self.multiplexer.connect()

        self.envelope = Envelope(
            to="",
            sender="",
            protocol_specification_id=DefaultMessage.protocol_specification_id,
            message=b"",
            context=EnvelopeContext(
                connection_id=self.connection.connection_id),
        )
        self.exception = ValueError("expected")

    def teardown(self):
        """Tear down test case."""
        self.multiplexer.disconnect()

    def test_log_policy(self):
        """Test just log exception."""
        with patch.object(self.connection, "send", side_effect=self.exception):
            self.multiplexer._exception_policy = ExceptionPolicyEnum.just_log
            self.multiplexer.put(self.envelope)
            time.sleep(1)
            assert not self.multiplexer._send_loop_task.done()

    def test_propagate_policy(self):
        """Test propagate exception."""
        assert self.multiplexer._exception_policy == ExceptionPolicyEnum.propagate

        with patch.object(self.connection, "send", side_effect=self.exception):
            self.multiplexer.put(self.envelope)
            time.sleep(1)
            wait_for_condition(lambda: self.multiplexer._send_loop_task.done(),
                               timeout=5)
            assert self.multiplexer._send_loop_task.exception(
            ) == self.exception

    def test_stop_policy(self):
        """Test stop multiplexer on exception."""
        with patch.object(self.connection, "send", side_effect=self.exception):
            self.multiplexer._exception_policy = ExceptionPolicyEnum.stop_and_exit
            self.multiplexer.put(self.envelope)
            time.sleep(1)
            wait_for_condition(
                lambda: self.multiplexer.connection_status.is_disconnected,
                timeout=5)

    def test_disconnect_order(self):
        """Test disconnect order: tasks first, disconnect_all next."""
        parent = MagicMock()

        async def fn():
            return

        with patch.object(
                self.multiplexer, "_stop_receive_send_loops",
                return_value=fn()) as stop_loops, patch.object(
                    self.multiplexer, "_disconnect_all",
                    return_value=fn()) as disconnect_all, patch.object(
                        self.multiplexer, "_check_and_set_disconnected_state"
                    ) as check_and_set_disconnected_state:
            parent.attach_mock(stop_loops, "stop_loops")
            parent.attach_mock(disconnect_all, "disconnect_all")
            parent.attach_mock(check_and_set_disconnected_state,
                               "check_and_set_disconnected_state")
            self.multiplexer.disconnect()
            assert parent.mock_calls == [
                call.stop_loops(),
                call.disconnect_all(),
                call.check_and_set_disconnected_state(),
            ]
Exemple #16
0
class TestLibp2pConnectionAgentMobility(BaseTestLibp2pRelay):
    """Test that connection will correctly route envelope to destination that changed its peer"""
    @libp2p_log_on_failure
    def setup(self):
        """Set the test up"""
        super().setup()
        temp_dir_gen = os.path.join(self.t, "temp_dir_gen")
        os.mkdir(temp_dir_gen)
        self.genesis = _make_libp2p_connection(data_dir=temp_dir_gen,
                                               port=DEFAULT_PORT)

        self.multiplexer_genesis = Multiplexer([self.genesis],
                                               protocols=[DefaultMessage])
        self.log_files.append(self.genesis.node.log_file)
        self.multiplexer_genesis.connect()
        self.multiplexers.append(self.multiplexer_genesis)

        genesis_peer = self.genesis.node.multiaddrs[0]

        temp_dir_1 = os.path.join(self.t, "temp_dir_1")
        os.mkdir(temp_dir_1)
        self.connection1 = _make_libp2p_connection(data_dir=temp_dir_1,
                                                   port=DEFAULT_PORT + 1,
                                                   entry_peers=[genesis_peer])
        self.multiplexer1 = Multiplexer([self.connection1],
                                        protocols=[DefaultMessage])
        self.log_files.append(self.connection1.node.log_file)
        self.multiplexer1.connect()
        self.multiplexers.append(self.multiplexer1)

        self.connection_key = make_crypto(DEFAULT_LEDGER)
        temp_dir_2 = os.path.join(self.t, "temp_dir_2")
        os.mkdir(temp_dir_2)
        self.connection2 = _make_libp2p_connection(
            data_dir=temp_dir_2,
            port=DEFAULT_PORT + 2,
            entry_peers=[genesis_peer],
            agent_key=self.connection_key,
        )
        self.multiplexer2 = Multiplexer([self.connection2],
                                        protocols=[DefaultMessage])
        self.log_files.append(self.connection2.node.log_file)
        self.multiplexer2.connect()
        self.multiplexers.append(self.multiplexer2)

    def test_connection_is_established(self):
        """Test connection established."""
        assert self.connection1.is_connected is True
        assert self.connection2.is_connected is True

    def test_envelope_routed_after_peer_changed(self):
        """Test envelope routed after peer changed."""
        addr_1 = self.connection1.address
        addr_2 = self.connection2.address

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"hello",
        )
        envelope = Envelope(
            to=addr_2,
            sender=addr_1,
            protocol_specification_id=DefaultMessage.protocol_specification_id,
            message=DefaultSerializer().encode(msg),
        )

        self.multiplexer1.put(envelope)
        delivered_envelope = self.multiplexer2.get(block=True, timeout=20)

        assert delivered_envelope is not None
        assert delivered_envelope.to == envelope.to
        assert delivered_envelope.sender == envelope.sender
        assert (delivered_envelope.protocol_specification_id ==
                envelope.protocol_specification_id)
        assert delivered_envelope.message_bytes == envelope.message_bytes

        self.multiplexer2.disconnect()
        self.change_state_and_wait(self.multiplexer2,
                                   expected_is_connected=False)

        # currently, multiplexer cannot be restarted
        self.multiplexer2 = Multiplexer([self.connection2],
                                        protocols=[DefaultMessage])
        self.multiplexer2.connect()
        self.change_state_and_wait(self.multiplexer2,
                                   expected_is_connected=True)
        self.multiplexers.append(self.multiplexer2)

        msg = DefaultMessage(
            dialogue_reference=("", ""),
            message_id=1,
            target=0,
            performative=DefaultMessage.Performative.BYTES,
            content=b"helloAfterChangingPeer",
        )
        envelope = Envelope(
            to=addr_2,
            sender=addr_1,
            protocol_specification_id=msg.protocol_specification_id,
            message=msg.encode(),
        )

        self.multiplexer1.put(envelope)

        delivered_envelope = self.multiplexer2.get(block=True, timeout=20)

        assert delivered_envelope is not None
        assert delivered_envelope.to == envelope.to
        assert delivered_envelope.sender == envelope.sender
        assert (delivered_envelope.protocol_specification_id ==
                envelope.protocol_specification_id)
        assert delivered_envelope.message_bytes == envelope.message_bytes
Exemple #17
0
    def test_communication_indirect(self):
        """Test communication indirect."""
        assert len(PUBLIC_DHT_MADDRS) > 1, "Test requires at least 2 public dht node"

        for i in range(len(PUBLIC_DHT_MADDRS)):
            multiplexers = []
            try:
                temp_dir_1 = os.path.join(self.t, f"dir_{i}__")
                os.mkdir(temp_dir_1)
                connection1 = _make_libp2p_connection(
                    port=DEFAULT_PORT + 1,
                    relay=False,
                    entry_peers=[PUBLIC_DHT_MADDRS[i]],
                    data_dir=temp_dir_1,
                )
                multiplexer1 = Multiplexer([connection1])
                self.log_files.append(connection1.node.log_file)
                multiplexer1.connect()
                multiplexers.append(multiplexer1)
                addr_1 = connection1.node.address

                for j in range(len(PUBLIC_DHT_MADDRS)):
                    if j == i:
                        continue

                    temp_dir_2 = os.path.join(self.t, f"dir_{i}_{j}")
                    os.mkdir(temp_dir_2)
                    connection2 = _make_libp2p_connection(
                        port=DEFAULT_PORT + 2,
                        relay=False,
                        entry_peers=[PUBLIC_DHT_MADDRS[j]],
                        data_dir=temp_dir_2,
                    )
                    multiplexer2 = Multiplexer([connection2])
                    self.log_files.append(connection2.node.log_file)
                    multiplexer2.connect()
                    multiplexers.append(multiplexer2)

                    addr_2 = connection2.node.address

                    msg = DefaultMessage(
                        dialogue_reference=("", ""),
                        message_id=1,
                        target=0,
                        performative=DefaultMessage.Performative.BYTES,
                        content=b"hello",
                    )
                    envelope = Envelope(to=addr_2, sender=addr_1, message=msg,)

                    multiplexer1.put(envelope)
                    delivered_envelope = multiplexer2.get(block=True, timeout=20)

                    assert delivered_envelope is not None
                    assert delivered_envelope.to == envelope.to
                    assert delivered_envelope.sender == envelope.sender
                    assert (
                        delivered_envelope.protocol_specification_id
                        == envelope.protocol_specification_id
                    )
                    assert delivered_envelope.message != envelope.message
                    msg = DefaultMessage.serializer.decode(delivered_envelope.message)
                    msg.to = delivered_envelope.to
                    msg.sender = delivered_envelope.sender
                    assert envelope.message == msg
                    multiplexer2.disconnect()
                    del multiplexers[-1]
            except Exception:
                raise
            finally:
                for mux in multiplexers:
                    mux.disconnect()