Esempio n. 1
0
    def test_from_json_and_to_json(self, skill_path):
        """Test the 'from_json' method and 'to_json' work correctly."""
        f = open(skill_path)
        original_json = yaml.safe_load(f)

        expected_config = SkillConfig.from_json(original_json)
        assert isinstance(expected_config, SkillConfig)
        expected_json = expected_config.json
        actual_config = SkillConfig.from_json(expected_json)
        actual_json = actual_config.json
        assert expected_json == actual_json
Esempio n. 2
0
    def setup(self) -> None:
        """Set test cae instance."""
        agent_name = "MyAgent"

        builder = AEABuilder()
        builder.set_name(agent_name)
        builder.add_private_key(DEFAULT_LEDGER, COSMOS_PRIVATE_KEY_PATH)

        self.handler_called = 0

        def handler_func(*args, **kwargs):
            self.handler_called += 1

        skill_context = SkillContext()
        handler_cls = make_handler_cls_from_funcion(handler_func)
        behaviour_cls = make_behaviour_cls_from_funcion(handler_func)

        self.handler = handler_cls(name="handler1",
                                   skill_context=skill_context)
        self.behaviour = behaviour_cls(name="behaviour1",
                                       skill_context=skill_context)

        test_skill = Skill(
            SkillConfig(name="test_skill", author="fetchai"),
            skill_context=skill_context,
            handlers={"handler": self.handler},
            behaviours={"behaviour": self.behaviour},
        )
        skill_context._skill = test_skill  # weird hack

        builder.add_component_instance(test_skill)
        self.aea = builder.build()
        self.aea_tool = AeaTool(self.aea)
Esempio n. 3
0
    def make_skill(
        cls,
        config: SkillConfig = None,
        context: SkillContext = None,
        handlers: Optional[Dict[str, Type[Handler]]] = None,
    ) -> Skill:
        """
        Make a skill from optional config, context, handlers dict.

        :param config: SkillConfig
        :param context: SkillContext
        :param handlers: dict of handler types to add to skill

        :return: Skill
        """
        handlers = handlers or {}
        context = context or SkillContext()
        config = config or SkillConfig(
            name="skill_{}".format(uuid.uuid4().hex[0:5]), author="fetchai")

        handlers_instances = {
            name: handler_cls(name=name, skill_context=context)
            for name, handler_cls in handlers.items()
        }

        skill = Skill(configuration=config,
                      skill_context=context,
                      handlers=handlers_instances)
        return skill
Esempio n. 4
0
    def test_handle_internal_message_new_handlers_with_error(self):
        """Test handle internal message when an error happens while registering a new handler."""
        skill = Skill(
            SkillConfig("name", "author", "0.1.0"),
            handlers={},
            behaviours={},
            models={},
        )
        self.resources.add_skill(skill)
        new_handler = DummyHandler(name="dummy2",
                                   skill_context=skill.skill_context)
        with unittest.mock.patch.object(self.resources.handler_registry,
                                        "register",
                                        side_effect=ValueError):
            with unittest.mock.patch.object(aea.registries.filter.logger,
                                            "warning") as mock_logger_warning:
                skill.skill_context.new_handlers.put(new_handler)
                self.filter.handle_internal_messages()

        mock_logger_warning.assert_called_with(
            "Error when trying to add a new handler: ")
        assert self.decision_make_queue.empty()
        assert len(self.resources.handler_registry.fetch_all()) == 0
        # restore previous state
        self.resources.component_registry.unregister(skill.component_id)
Esempio n. 5
0
def test_storage_access_from_behaviour():
    """Test storage access from behaviour component."""
    builder = AEABuilder()
    builder.set_name("aea_1")
    builder.add_private_key(DEFAULT_LEDGER)

    skill_context = SkillContext()
    behaviour = TBehaviour(name="behaviour", skill_context=skill_context)
    test_skill = Skill(
        SkillConfig(name="test_skill", author="fetchai"),
        skill_context=skill_context,
        handlers={},
        behaviours={"behaviour": behaviour},
    )

    builder.add_component_instance(test_skill)
    builder.set_storage_uri("sqlite://:memory:")
    aea = builder.build()
    skill_context.set_agent_context(aea.context)

    aea.runtime._threaded = True
    aea.runtime.start()

    try:
        wait_for_condition(lambda: aea.is_running, timeout=10)
        wait_for_condition(lambda: behaviour.counter > 0, timeout=10)

        col = skill_context.storage.get_sync_collection(behaviour.COL_NAME)
        assert col.get(behaviour.OBJ_ID) == behaviour.OBJ_BODY
    finally:
        aea.runtime.stop()
        aea.runtime.wait_completed(sync=True, timeout=10)
Esempio n. 6
0
def test_remove_component_success():
    """Test remove registered component."""
    dep_manager = _DependenciesManager()
    protocol = ProtocolConfig("a_protocol", "author", "0.1.0")
    skill = SkillConfig("skill", "author", "0.1.0", protocols=[protocol.public_id])
    dep_manager.add_component(protocol)
    dep_manager.add_component(skill)
    dep_manager.remove_component(skill.component_id)
Esempio n. 7
0
    def test_from_json_and_to_json(self):
        """Test the 'from_json' method and 'to_json' work correctly."""
        f = open(os.path.join(CUR_PATH, "data", "dummy_skill", "skill.yaml"))
        expected_json = yaml.safe_load(f)
        config = SkillConfig.from_json(expected_json)

        assert isinstance(config, SkillConfig)
        actual_json = config.json
        assert expected_json == actual_json
Esempio n. 8
0
def test_remove_component_depends_on_fail():
    """Test component remove fails cause dependency."""
    dep_manager = _DependenciesManager()
    protocol = ProtocolConfig("a_protocol", "author", "0.1.0")
    dep_manager.add_component(protocol)
    dep_manager.add_component(
        SkillConfig("skill", "author", "0.1.0", protocols=[protocol.public_id])
    )

    with pytest.raises(
        ValueError,
        match=r"Cannot remove component .* of type .*. Other components depends on it: .*",
    ):
        dep_manager.remove_component(protocol.component_id)
Esempio n. 9
0
def make_skill(agent, handlers=None, behaviours=None) -> Skill:
    """Construct skill instance for agent from behaviours."""
    handlers = handlers or {}
    behaviours = behaviours or {}
    config = SkillConfig(name="test_skill", author="fetchai")
    skill_context = SkillContext(agent.context)
    skill = Skill(configuration=config, skill_context=skill_context)
    for name, handler_cls in handlers.items():
        handler = handler_cls(name=name, skill_context=skill_context)
        skill.handlers.update({handler.name: handler})

    for name, behaviour_cls in behaviours.items():
        behaviour = behaviour_cls(name=name, skill_context=skill_context)
        skill.behaviours.update({behaviour.name: behaviour})
    return skill
Esempio n. 10
0
    def setup_class(cls):
        """Set up the test class."""
        cls.expected_custom_component_configuration = dict(foo="bar")

        cls.skill_config = SkillConfig(
            name="skill_name",
            author="author",
            version="0.1.0",
        )

        cls.skill_config.protocols = {cls.old_protocol_id}
        cls.skill_config.contracts = {cls.old_contract_id}
        cls.skill_config.connections = {cls.old_connection_id}
        cls.skill_config.skills = {cls.old_skill_id}

        replace_component_ids(cls.skill_config, cls.replacements)
Esempio n. 11
0
def test_storage_access_from_handler():
    """Test storage access from handler component."""
    builder = AEABuilder()
    builder.set_name("aea_1")
    builder.add_private_key(DEFAULT_LEDGER)

    skill_context = SkillContext()
    handler = THandler(name="behaviour", skill_context=skill_context)
    test_skill = Skill(
        SkillConfig(name="test_skill", author="fetchai"),
        skill_context=skill_context,
        handlers={"handler": handler},
        behaviours={},
    )

    builder.add_component_instance(test_skill)
    builder.set_storage_uri("sqlite://:memory:")
    aea = builder.build()
    skill_context.set_agent_context(aea.context)

    aea.runtime._threaded = True
    aea.runtime.start()

    msg = DefaultMessage(
        dialogue_reference=("", ""),
        message_id=1,
        target=0,
        performative=DefaultMessage.Performative.BYTES,
        content=b"hello",
    )
    msg.to = aea.identity.address
    msg.sender = aea.identity.address
    envelope = Envelope(to=msg.to, sender=msg.sender, message=msg,)
    try:
        wait_for_condition(lambda: aea.is_running, timeout=10)

        aea.runtime.multiplexer.in_queue.put(envelope)

        wait_for_condition(lambda: handler.counter > 0, timeout=10)

        col = skill_context.storage.get_sync_collection(handler.COL_NAME)
        assert col.get(handler.OBJ_ID) == handler.OBJ_BODY
    finally:
        aea.runtime.stop()
        aea.runtime.wait_completed(sync=True, timeout=10)
Esempio n. 12
0
    def test_handle_internal_message_new_behaviours(self):
        """Test handle internal message when there are new behaviours to register."""
        skill = Skill(
            SkillConfig("name", "author", "0.1.0"),
            handlers={},
            behaviours={},
            models={},
        )
        self.resources.add_skill(skill)
        new_behaviour = DummyBehaviour(name="dummy2",
                                       skill_context=skill.skill_context)
        skill.skill_context.new_behaviours.put(new_behaviour)
        self.filter.handle_internal_messages()

        assert self.decision_make_queue.empty()
        assert len(self.resources.behaviour_registry.fetch_all()) == 1
        # restore previous state
        self.resources.remove_skill(skill.public_id)
        assert len(self.resources.behaviour_registry.fetch_all()) == 0
    def prepare(self, function: Callable) -> None:
        """Prepare aea_tool for testing.

        :param function: function be called on react handle or/and Behaviour.act
        :return: None
        """
        agent_name = "MyAgent"

        builder = AEABuilder()
        builder.set_name(agent_name)
        builder.add_private_key(FetchAICrypto.identifier,
                                FETCHAI_PRIVATE_KEY_PATH)

        self.function_finished = False

        def handler_func(*args, **kwargs):
            function()
            self.function_finished = True

        skill_context = SkillContext()
        handler_cls = make_handler_cls_from_funcion(handler_func)

        behaviour_cls = make_behaviour_cls_from_funcion(handler_func)

        test_skill = Skill(
            SkillConfig(name="test_skill", author="fetchai"),
            skill_context=skill_context,
            handlers={
                "handler1":
                handler_cls(name="handler1", skill_context=skill_context)
            },
            behaviours={
                "behaviour1":
                behaviour_cls(name="behaviour1", skill_context=skill_context)
            },
        )
        skill_context._skill = test_skill  # weird hack

        builder._add_component_to_resources(test_skill)
        aea = builder.build()

        self.aea_tool = AeaTool(aea)
        self.aea_tool.put_inbox(AeaTool.dummy_envelope())
Esempio n. 14
0
    def setup_class(cls):
        """Set the tests up."""
        skill_context = SkillContext()
        skill_config = SkillConfig(name="simple_skill",
                                   author="fetchai",
                                   version="0.1.0")

        class MyHandler(Handler):
            def setup(self):
                pass

            def handle(self, message: Message):
                pass

            def teardown(self):
                pass

        class MyBehaviour(Behaviour):
            def setup(self):
                pass

            def act(self):
                pass

            def teardown(self):
                pass

        cls.handler_name = "some_handler"
        cls.handler = MyHandler(skill_context=skill_context,
                                name=cls.handler_name)
        cls.model_name = "some_model"
        cls.model = Model(skill_context=skill_context, name=cls.model_name)
        cls.behaviour_name = "some_behaviour"
        cls.behaviour = MyBehaviour(skill_context=skill_context,
                                    name=cls.behaviour_name)
        cls.skill = Skill(
            skill_config,
            skill_context,
            handlers={cls.handler.name: cls.handler},
            models={cls.model.name: cls.model},
            behaviours={cls.behaviour.name: cls.behaviour},
        )
Esempio n. 15
0
    def _builder(self, agent_name="agent1", act_func=None) -> AEABuilder:
        """Build an aea instance."""
        builder = AEABuilder()
        builder.set_name(agent_name)
        builder.add_private_key(FetchAICrypto.identifier, FETCHAI_PRIVATE_KEY_PATH)

        skill_context = SkillContext()
        act_func = act_func or (lambda self: self)
        behaviour_cls = make_behaviour_cls_from_funcion(act_func)

        behaviour = behaviour_cls(name="behaviour", skill_context=skill_context)
        test_skill = Skill(
            SkillConfig(name="test_skill", author="fetchai"),
            skill_context=skill_context,
            behaviours={"behaviour": behaviour},
        )
        skill_context._skill = test_skill  # weird hack
        builder.add_component_instance(test_skill)
        builder.set_runtime_mode("async")
        return builder
Esempio n. 16
0
    def prepare(self, function: Callable) -> None:
        """Prepare aea_tool for testing.

        :param function: function be called on react handle or/and Behaviour.act
        :return: None
        """
        agent_name = "MyAgent"

        builder = AEABuilder()
        builder.set_name(agent_name)
        builder.add_private_key(DEFAULT_LEDGER, FETCHAI_PRIVATE_KEY_PATH)

        self.function_finished = False

        def handler_func(*args, **kwargs):
            function()
            self.function_finished = True

        skill_context = SkillContext()
        handler_cls = make_handler_cls_from_funcion(handler_func)

        behaviour_cls = make_behaviour_cls_from_funcion(handler_func)
        self.behaviour = behaviour_cls(name="behaviour1",
                                       skill_context=skill_context)
        test_skill = Skill(
            SkillConfig(name="test_skill", author="fetchai"),
            skill_context=skill_context,
            handlers={
                "handler1":
                handler_cls(name="handler1", skill_context=skill_context)
            },
            behaviours={"behaviour1": self.behaviour},
        )
        skill_context._skill = test_skill  # weird hack

        builder.add_component_instance(test_skill)
        aea = builder.build()
        self.aea_tool = AeaTool(aea)
        self.envelope = AeaTool.dummy_envelope()
        self.aea_tool.aea.runtime.main_loop._setup()
Esempio n. 17
0
    def test_generated_protocol_end_to_end(self):
        """Test that a generated protocol could be used in exchanging messages between two agents."""
        agent_name_1 = "my_aea_1"
        agent_name_2 = "my_aea_2"
        builder_1 = AEABuilder()
        builder_1.set_name(agent_name_1)
        builder_1.add_private_key(FetchAICrypto.identifier,
                                  self.private_key_path_1)
        builder_1.set_default_ledger(FetchAICrypto.identifier)
        builder_1.set_default_connection(
            PublicId.from_str("fetchai/oef:0.3.0"))
        builder_1.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa"))
        builder_1.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search"))
        builder_1.add_component(
            ComponentType.PROTOCOL,
            Path(ROOT_DIR, "tests", "data", "generator", "t_protocol"),
            skip_consistency_check=True,
        )
        builder_1.add_connection(
            Path(ROOT_DIR, "packages", "fetchai", "connections", "oef"))

        builder_2 = AEABuilder()
        builder_2.set_name(agent_name_2)
        builder_2.add_private_key(FetchAICrypto.identifier,
                                  self.private_key_path_2)
        builder_2.set_default_ledger(FetchAICrypto.identifier)
        builder_2.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa"))
        builder_2.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search"))
        builder_2.set_default_connection(
            PublicId.from_str("fetchai/oef:0.3.0"))
        builder_2.add_component(
            ComponentType.PROTOCOL,
            Path(ROOT_DIR, "tests", "data", "generator", "t_protocol"),
            skip_consistency_check=True,
        )
        builder_2.add_connection(
            Path(ROOT_DIR, "packages", "fetchai", "connections", "oef"))

        # create AEAs
        aea_1 = builder_1.build(
            connection_ids=[PublicId.from_str("fetchai/oef:0.3.0")])
        aea_2 = builder_2.build(
            connection_ids=[PublicId.from_str("fetchai/oef:0.3.0")])

        # message 1
        message = TProtocolMessage(
            message_id=1,
            dialogue_reference=(str(0), ""),
            target=0,
            performative=TProtocolMessage.Performative.PERFORMATIVE_PT,
            content_bytes=b"some bytes",
            content_int=42,
            content_float=42.7,
            content_bool=True,
            content_str="some string",
        )
        encoded_message_in_bytes = TProtocolSerializer().encode(message)
        envelope = Envelope(
            to=aea_2.identity.address,
            sender=aea_1.identity.address,
            protocol_id=TProtocolMessage.protocol_id,
            message=encoded_message_in_bytes,
        )

        # message 2
        message_2 = TProtocolMessage(
            message_id=2,
            dialogue_reference=(str(0), ""),
            target=1,
            performative=TProtocolMessage.Performative.PERFORMATIVE_PT,
            content_bytes=b"some other bytes",
            content_int=43,
            content_float=43.7,
            content_bool=False,
            content_str="some other string",
        )
        encoded_message_2_in_bytes = TProtocolSerializer().encode(message_2)

        # add handlers to AEA resources]
        skill_context_1 = SkillContext(aea_1.context)
        skill_1 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"),
                        skill_context_1)
        skill_context_1._skill = skill_1

        agent_1_handler = Agent1Handler(skill_context=skill_context_1,
                                        name="fake_handler_1")
        aea_1.resources._handler_registry.register(
            (
                PublicId.from_str("fetchai/fake_skill:0.1.0"),
                TProtocolMessage.protocol_id,
            ),
            agent_1_handler,
        )
        skill_context_2 = SkillContext(aea_2.context)
        skill_2 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"),
                        skill_context_2)
        skill_context_2._skill = skill_2

        agent_2_handler = Agent2Handler(
            encoded_messsage=encoded_message_2_in_bytes,
            skill_context=skill_context_2,
            name="fake_handler_2",
        )
        aea_2.resources._handler_registry.register(
            (
                PublicId.from_str("fetchai/fake_skill:0.1.0"),
                TProtocolMessage.protocol_id,
            ),
            agent_2_handler,
        )

        # Start threads
        t_1 = Thread(target=aea_1.start)
        t_2 = Thread(target=aea_2.start)
        try:
            t_1.start()
            t_2.start()
            time.sleep(1.0)
            aea_1.outbox.put(envelope)
            time.sleep(5.0)
            assert (agent_2_handler.handled_message.message_id ==
                    message.message_id
                    ), "Message from Agent 1 to 2: message ids do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference ==
                message.dialogue_reference
            ), "Message from Agent 1 to 2: dialogue references do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference[0] ==
                message.dialogue_reference[0]
            ), "Message from Agent 1 to 2: dialogue reference[0]s do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference[1] ==
                message.dialogue_reference[1]
            ), "Message from Agent 1 to 2: dialogue reference[1]s do not match"
            assert (agent_2_handler.handled_message.target == message.target
                    ), "Message from Agent 1 to 2: targets do not match"
            assert (agent_2_handler.handled_message.performative ==
                    message.performative
                    ), "Message from Agent 1 to 2: performatives do not match"
            assert (agent_2_handler.handled_message.content_bytes ==
                    message.content_bytes
                    ), "Message from Agent 1 to 2: content_bytes do not match"
            assert (agent_2_handler.handled_message.content_int ==
                    message.content_int
                    ), "Message from Agent 1 to 2: content_int do not match"
            # floats do not seem to lose some precision when serialised then deserialised using protobuf
            # assert agent_2_handler.handled_message.content_float == message.content_float, "Message from Agent 1 to 2: content_float do not match"
            assert (agent_2_handler.handled_message.content_bool ==
                    message.content_bool
                    ), "Message from Agent 1 to 2: content_bool do not match"
            assert (agent_2_handler.handled_message.content_str ==
                    message.content_str
                    ), "Message from Agent 1 to 2: content_str do not match"

            assert (
                agent_1_handler.handled_message.message_id ==
                message_2.message_id
            ), "Message from Agent 1 to 2: dialogue references do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference ==
                message_2.dialogue_reference
            ), "Message from Agent 2 to 1: dialogue references do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference[0] ==
                message_2.dialogue_reference[0]
            ), "Message from Agent 2 to 1: dialogue reference[0]s do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference[1] ==
                message_2.dialogue_reference[1]
            ), "Message from Agent 2 to 1: dialogue reference[1]s do not match"
            assert (agent_1_handler.handled_message.target == message_2.target
                    ), "Message from Agent 2 to 1: targets do not match"
            assert (agent_1_handler.handled_message.performative ==
                    message_2.performative
                    ), "Message from Agent 2 to 1: performatives do not match"
            assert (agent_1_handler.handled_message.content_bytes ==
                    message_2.content_bytes
                    ), "Message from Agent 2 to 1: content_bytes do not match"
            assert (agent_1_handler.handled_message.content_int ==
                    message_2.content_int
                    ), "Message from Agent 2 to 1: content_int do not match"
            # floats do not seem to lose some precision when serialised then deserialised using protobuf
            # assert agent_1_handler.handled_message.content_float == message_2.content_float, "Message from Agent 2 to 1: content_float do not match"
            assert (agent_1_handler.handled_message.content_bool ==
                    message_2.content_bool
                    ), "Message from Agent 2 to 1: content_bool do not match"
            assert (agent_1_handler.handled_message.content_str ==
                    message_2.content_str
                    ), "Message from Agent 2 to 1: content_str do not match"
            time.sleep(2.0)
        finally:
            aea_1.stop()
            aea_2.stop()
            t_1.join()
            t_2.join()
def run():
    # Create a private key
    create_private_key(CosmosCrypto.identifier,
                       private_key_file=COSMOS_PRIVATE_KEY_FILE_1)

    # Instantiate the builder and build the AEA
    # By default, the default protocol, error skill and stub connection are added
    builder = AEABuilder()

    builder.set_name("my_aea")

    builder.add_private_key(CosmosCrypto.identifier, COSMOS_PRIVATE_KEY_FILE_1)

    # Create our AEA
    my_aea = builder.build()

    # add a simple skill with handler
    skill_context = SkillContext(my_aea.context)
    skill_config = SkillConfig(name="simple_skill",
                               author="fetchai",
                               version="0.1.0")
    signing_handler = SigningHandler(skill_context=skill_context,
                                     name="signing_handler")
    signing_dialogues_model = SigningDialogues(skill_context=skill_context,
                                               name="signing_dialogues")

    simple_skill = Skill(
        skill_config,
        skill_context,
        handlers={signing_handler.name: signing_handler},
        models={signing_dialogues_model.name: signing_dialogues_model},
    )
    my_aea.resources.add_skill(simple_skill)

    # create a second identity
    create_private_key(CosmosCrypto.identifier,
                       private_key_file=COSMOS_PRIVATE_KEY_FILE_2)

    counterparty_wallet = Wallet(
        {CosmosCrypto.identifier: COSMOS_PRIVATE_KEY_FILE_2})

    counterparty_identity = Identity(
        name="counterparty_aea",
        addresses=counterparty_wallet.addresses,
        default_address_key=CosmosCrypto.identifier,
    )

    # create signing message for decision maker to sign
    terms = Terms(
        ledger_id=CosmosCrypto.identifier,
        sender_address=my_aea.identity.address,
        counterparty_address=counterparty_identity.address,
        amount_by_currency_id={"FET": -1},
        quantities_by_good_id={"some_service": 1},
        nonce="some_nonce",
        fee_by_currency_id={"FET": 0},
    )
    signing_dialogues = cast(SigningDialogues, skill_context.signing_dialogues)
    stub_transaction = LedgerApis.get_transfer_transaction(
        terms.ledger_id,
        terms.sender_address,
        terms.counterparty_address,
        terms.sender_payable_amount,
        terms.sender_fee,
        terms.nonce,
    )
    signing_msg = SigningMessage(
        performative=SigningMessage.Performative.SIGN_TRANSACTION,
        dialogue_reference=signing_dialogues.
        new_self_initiated_dialogue_reference(),
        skill_callback_ids=(str(skill_context.skill_id), ),
        raw_transaction=RawTransaction(CosmosCrypto.identifier,
                                       stub_transaction),
        terms=terms,
        skill_callback_info={"some_info_key": "some_info_value"},
    )
    signing_msg.counterparty = "decision_maker"
    signing_dialogue = cast(Optional[SigningDialogue],
                            signing_dialogues.update(signing_msg))
    assert signing_dialogue is not None
    my_aea.context.decision_maker_message_queue.put_nowait(signing_msg)

    # Set the AEA running in a different thread
    try:
        logger.info("STARTING AEA NOW!")
        t = Thread(target=my_aea.start)
        t.start()

        # Let it run long enough to interact with the decision maker
        time.sleep(1)
    finally:
        # Shut down the AEA
        logger.info("STOPPING AEA NOW!")
        my_aea.stop()
        t.join()
Esempio n. 19
0
    def test_gym(self, pytestconfig):
        """Run the gym skill sequence."""
        if pytestconfig.getoption("ci"):
            pytest.skip("Skipping the test since it doesn't work in CI.")
        # add packages folder
        packages_src = os.path.join(self.cwd, 'packages')
        packages_dst = os.path.join(os.getcwd(), 'packages')
        shutil.copytree(packages_src, packages_dst)

        # create agent
        result = self.runner.invoke(
            cli, [*CLI_LOG_OPTION, "create", self.agent_name],
            standalone_mode=False)
        assert result.exit_code == 0
        agent_dir_path = os.path.join(self.t, self.agent_name)
        os.chdir(agent_dir_path)

        # add packages and install dependencies
        result = self.runner.invoke(cli,
                                    [*CLI_LOG_OPTION, "add", "skill", "gym"],
                                    standalone_mode=False)
        assert result.exit_code == 0
        result = self.runner.invoke(
            cli, [*CLI_LOG_OPTION, "add", "connection", "gym"],
            standalone_mode=False)
        assert result.exit_code == 0
        result = self.runner.invoke(cli, [*CLI_LOG_OPTION, "install"],
                                    standalone_mode=False)
        assert result.exit_code == 0

        # add gyms folder from examples
        gyms_src = os.path.join(self.cwd, 'examples', 'gym_ex', 'gyms')
        gyms_dst = os.path.join(self.t, self.agent_name, 'gyms')
        shutil.copytree(gyms_src, gyms_dst)

        # change config file of gym connection
        file_src = os.path.join(self.cwd, 'tests', 'test_packages',
                                'test_skills', 'data', 'connection.yaml')
        file_dst = os.path.join(self.t, self.agent_name, 'connections', 'gym',
                                'connection.yaml')
        shutil.copyfile(file_src, file_dst)

        # change number of training steps
        skill_config_path = Path(self.t, self.agent_name, "skills", "gym",
                                 "skill.yaml")
        skill_config = SkillConfig.from_json(
            yaml.safe_load(open(skill_config_path)))
        skill_config.tasks.read("GymTask").args["nb_steps"] = 100
        yaml.safe_dump(skill_config.json, open(skill_config_path, "w"))

        process = subprocess.Popen(
            [sys.executable, '-m', 'aea.cli', "run", "--connections", "gym"],
            stdout=subprocess.PIPE,
            env=os.environ.copy())

        # check the gym run ends

        time.sleep(10.0)
        process.send_signal(signal.SIGINT)
        process.wait(timeout=5)

        assert process.returncode == 0

        poll = process.poll()
        if poll is None:
            process.terminate()
            process.wait(2)

        os.chdir(self.t)
        self.result = self.runner.invoke(
            cli, [*CLI_LOG_OPTION, "delete", self.agent_name],
            standalone_mode=False)
Esempio n. 20
0
def run():
    # Create a private key
    create_private_key(CosmosCrypto.identifier)

    # 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)

    # Instantiate the builder and build the AEA
    # By default, the default protocol, error skill and stub connection are added
    builder = AEABuilder()

    builder.set_name("my_aea")

    builder.add_private_key(CosmosCrypto.identifier, COSMOS_PRIVATE_KEY_FILE)

    # Add the echo skill (assuming it is present in the local directory 'packages')
    builder.add_skill("./packages/fetchai/skills/echo")

    # create skill and handler manually
    from aea.protocols.base import Message
    from aea.protocols.default.message import DefaultMessage
    from aea.skills.base import Handler

    class DummyHandler(Handler):
        """Dummy handler to handle messages."""

        SUPPORTED_PROTOCOL = DefaultMessage.protocol_id

        def setup(self) -> None:
            """Noop setup."""

        def teardown(self) -> None:
            """Noop teardown."""

        def handle(self, message: Message) -> None:
            """Handle incoming message."""
            self.context.logger.info("You got a message: {}".format(
                str(message)))

    config = SkillConfig(name="test_skill", author="fetchai")
    skill = Skill(configuration=config)
    dummy_handler = DummyHandler(name="dummy_handler",
                                 skill_context=skill.skill_context)
    skill.handlers.update({dummy_handler.name: dummy_handler})
    builder.add_component_instance(skill)

    # Create our AEA
    my_aea = builder.build()

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

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

        # Create a message inside an envelope and get the stub connection to pass it on to the echo skill
        message_text = (
            "my_aea,other_agent,fetchai/default:0.3.0,\x08\x01*\x07\n\x05hello,"
        )
        with open(INPUT_FILE, "w") as f:
            f.write(message_text)
            print("input message: " + message_text)

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

        # Read the output envelope generated by the echo skill
        with open(OUTPUT_FILE, "r") as f:
            print("output message: " + f.readline())
    finally:
        # Shut down the AEA
        my_aea.stop()
        t.join()
        t = None
Esempio n. 21
0
    def test_generated_protocol_end_to_end(self):
        """Test that a generated protocol could be used in exchanging messages between two agents."""
        agent_name_1 = "my_aea_1"
        agent_name_2 = "my_aea_2"
        builder_1 = AEABuilder()
        builder_1.set_name(agent_name_1)
        builder_1.add_private_key(DEFAULT_LEDGER, self.private_key_path_1)
        builder_1.set_default_ledger(DEFAULT_LEDGER)
        builder_1.set_default_connection(OEF_CONNECTION_PUBLIC_ID)
        builder_1.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")
        )
        builder_1.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")
        )
        builder_1.add_component(
            ComponentType.PROTOCOL,
            Path(PATH_TO_T_PROTOCOL),
            skip_consistency_check=True,
        )
        builder_1.add_connection(
            Path(ROOT_DIR, "packages", "fetchai", "connections", "oef")
        )

        builder_2 = AEABuilder()
        builder_2.set_name(agent_name_2)
        builder_2.add_private_key(DEFAULT_LEDGER, self.private_key_path_2)
        builder_2.set_default_ledger(DEFAULT_LEDGER)
        builder_2.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")
        )
        builder_2.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")
        )
        builder_2.set_default_connection(OEF_CONNECTION_PUBLIC_ID)
        builder_2.add_component(
            ComponentType.PROTOCOL,
            Path(PATH_TO_T_PROTOCOL),
            skip_consistency_check=True,
        )
        builder_2.add_connection(
            Path(ROOT_DIR, "packages", "fetchai", "connections", "oef")
        )

        # create AEAs
        aea_1 = builder_1.build(connection_ids=[OEF_CONNECTION_PUBLIC_ID])
        aea_2 = builder_2.build(connection_ids=[OEF_CONNECTION_PUBLIC_ID])

        # dialogues
        def role_from_first_message_1(
            message: Message, receiver_address: Address
        ) -> BaseDialogue.Role:
            """Infer the role of the agent from an incoming/outgoing first message

            :param message: an incoming/outgoing first message
            :param receiver_address: the address of the receiving agent
            :return: The role of the agent
            """
            return TProtocolDialogue.Role.ROLE_1

        agent_1_dialogues = TProtocolDialogues(
            self_address=aea_1.identity.address,
            role_from_first_message=role_from_first_message_1,
        )

        def role_from_first_message_1(
            message: Message, receiver_address: Address
        ) -> BaseDialogue.Role:
            """Infer the role of the agent from an incoming/outgoing first message

            :param message: an incoming/outgoing first message
            :param receiver_address: the address of the receiving agent
            :return: The role of the agent
            """
            return TProtocolDialogue.Role.ROLE_2

        agent_2_dialogues = TProtocolDialogues(
            self_address=aea_2.identity.address,
            role_from_first_message=role_from_first_message_1,
        )

        # messages
        message_1, aea_1_dialogue = agent_1_dialogues.create(
            counterparty=aea_2.identity.address,
            performative=TProtocolMessage.Performative.PERFORMATIVE_PT,
            content_bytes=b"some bytes",
            content_int=42,
            content_float=42.7,
            content_bool=True,
            content_str="some string",
        )
        message_1 = cast(TProtocolMessage, message_1)

        message_2, aea_2_dialogue = agent_2_dialogues.create(
            counterparty=aea_1.identity.address,
            performative=TProtocolMessage.Performative.PERFORMATIVE_PT,
            content_bytes=b"some other bytes",
            content_int=43,
            content_float=43.7,
            content_bool=False,
            content_str="some other string",
        )
        message_2 = cast(TProtocolMessage, message_2)

        # add handlers to AEA resources
        skill_context_1 = SkillContext(aea_1.context)
        skill_1 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_1)
        skill_context_1._skill = skill_1

        agent_1_handler = Agent1Handler(
            skill_context=skill_context_1,
            name="fake_handler_1",
            dialogues=agent_1_dialogues,
        )
        aea_1.resources._handler_registry.register(
            (
                PublicId.from_str("fetchai/fake_skill:0.1.0"),
                TProtocolMessage.protocol_id,
            ),
            agent_1_handler,
        )
        skill_context_2 = SkillContext(aea_2.context)
        skill_2 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_2)
        skill_context_2._skill = skill_2

        agent_2_handler = Agent2Handler(
            message=message_2,
            dialogues=agent_2_dialogues,
            skill_context=skill_context_2,
            name="fake_handler_2",
        )
        aea_2.resources._handler_registry.register(
            (
                PublicId.from_str("fetchai/fake_skill:0.1.0"),
                TProtocolMessage.protocol_id,
            ),
            agent_2_handler,
        )

        # Start threads
        t_1 = Thread(target=aea_1.start)
        t_2 = Thread(target=aea_2.start)
        try:
            t_1.start()
            t_2.start()
            time.sleep(1.0)
            aea_1.outbox.put_message(message_1)
            time.sleep(5.0)
            assert (
                agent_2_handler.handled_message.message_id == message_1.message_id
            ), "Message from Agent 1 to 2: message ids do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference
                == message_1.dialogue_reference
            ), "Message from Agent 1 to 2: dialogue references do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference[0]
                == message_1.dialogue_reference[0]
            ), "Message from Agent 1 to 2: dialogue reference[0]s do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference[1]
                == message_1.dialogue_reference[1]
            ), "Message from Agent 1 to 2: dialogue reference[1]s do not match"
            assert (
                agent_2_handler.handled_message.target == message_1.target
            ), "Message from Agent 1 to 2: targets do not match"
            assert (
                agent_2_handler.handled_message.performative == message_1.performative
            ), "Message from Agent 1 to 2: performatives do not match"
            assert (
                agent_2_handler.handled_message.content_bytes == message_1.content_bytes
            ), "Message from Agent 1 to 2: content_bytes do not match"
            assert (
                agent_2_handler.handled_message.content_int == message_1.content_int
            ), "Message from Agent 1 to 2: content_int do not match"
            # assert (
            #     agent_2_handler.handled_message.content_float == message_1.content_float # noqa: E800
            # ), "Message from Agent 1 to 2: content_float do not match"
            assert (
                agent_2_handler.handled_message.content_bool == message_1.content_bool
            ), "Message from Agent 1 to 2: content_bool do not match"
            assert (
                agent_2_handler.handled_message.content_str == message_1.content_str
            ), "Message from Agent 1 to 2: content_str do not match"

            assert (
                agent_1_handler.handled_message.message_id == message_2.message_id
            ), "Message from Agent 1 to 2: dialogue references do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference
                == message_2.dialogue_reference
            ), "Message from Agent 2 to 1: dialogue references do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference[0]
                == message_2.dialogue_reference[0]
            ), "Message from Agent 2 to 1: dialogue reference[0]s do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference[1]
                == message_2.dialogue_reference[1]
            ), "Message from Agent 2 to 1: dialogue reference[1]s do not match"
            assert (
                agent_1_handler.handled_message.target == message_2.target
            ), "Message from Agent 2 to 1: targets do not match"
            assert (
                agent_1_handler.handled_message.performative == message_2.performative
            ), "Message from Agent 2 to 1: performatives do not match"
            assert (
                agent_1_handler.handled_message.content_bytes == message_2.content_bytes
            ), "Message from Agent 2 to 1: content_bytes do not match"
            assert (
                agent_1_handler.handled_message.content_int == message_2.content_int
            ), "Message from Agent 2 to 1: content_int do not match"
            # assert (
            #     agent_1_handler.handled_message.content_float == message_2.content_float # noqa: E800
            # ), "Message from Agent 2 to 1: content_float do not match"
            assert (
                agent_1_handler.handled_message.content_bool == message_2.content_bool
            ), "Message from Agent 2 to 1: content_bool do not match"
            assert (
                agent_1_handler.handled_message.content_str == message_2.content_str
            ), "Message from Agent 2 to 1: content_str do not match"
            time.sleep(2.0)
        finally:
            aea_1.stop()
            aea_2.stop()
            t_1.join()
            t_2.join()
Esempio n. 22
0
def ipfs_hashing(
    package_hashes: Dict[str, str],
    target_dir: str,
    package_type: str,
    package_name: str,
    ipfs_hash_only: IPFSHashOnly,
):
    """Hashes a package and its components."""
    print("Processing package {} of type {}".format(package_name,
                                                    package_type))

    # load config file to get ignore patterns, dump again immediately to impose ordering
    if package_type == "agents":
        config = AgentConfig.from_json(
            yaml.safe_load(open(Path(target_dir, DEFAULT_AEA_CONFIG_FILE))))
        yaml_dump(config.json,
                  open(Path(target_dir, DEFAULT_AEA_CONFIG_FILE), "w"))
    elif package_type == "connections":
        config = ConnectionConfig.from_json(
            yaml.safe_load(
                open(Path(target_dir, DEFAULT_CONNECTION_CONFIG_FILE))))
        yaml_dump(config.json,
                  open(Path(target_dir, DEFAULT_CONNECTION_CONFIG_FILE), "w"))
    elif package_type == "contracts":
        config = ContractConfig.from_json(
            yaml.safe_load(open(Path(target_dir,
                                     DEFAULT_CONTRACT_CONFIG_FILE))))
        yaml_dump(config.json,
                  open(Path(target_dir, DEFAULT_CONTRACT_CONFIG_FILE), "w"))
    elif package_type == "protocols":
        config = ProtocolConfig.from_json(
            yaml.safe_load(open(Path(target_dir,
                                     DEFAULT_PROTOCOL_CONFIG_FILE))))
        yaml_dump(config.json,
                  open(Path(target_dir, DEFAULT_PROTOCOL_CONFIG_FILE), "w"))
    elif package_type == "skills":
        config = SkillConfig.from_json(
            yaml.safe_load(open(Path(target_dir, DEFAULT_SKILL_CONFIG_FILE))))
        yaml_dump(config.json,
                  open(Path(target_dir, DEFAULT_SKILL_CONFIG_FILE), "w"))
    config = yaml.safe_load(next(Path(target_dir).glob("*.yaml")).open())
    ignore_patterns = config.get("fingerprint_ignore_patterns", [])
    if package_type != "agents":
        # hash inner components
        fingerprints_dict = _compute_fingerprint(Path(target_dir),
                                                 ignore_patterns)
        # confirm ipfs only generates same hash:
        for file_name, ipfs_hash in fingerprints_dict.items():
            path = os.path.join(target_dir, file_name)
            ipfsho_hash = ipfs_hash_only.get(path)
            if ipfsho_hash != ipfs_hash:
                print("WARNING, hashes don't match for: {}".format(path))

        # update fingerprints
        file_name = package_type[:-1] + ".yaml"
        yaml_path = os.path.join(target_dir, file_name)
        file = open(yaml_path, mode="r")

        # read all lines at once
        whole_file = file.read()

        # close the file
        file.close()

        file = open(yaml_path, mode="r")

        # find and replace
        # TODO this can be simplified after https://github.com/fetchai/agents-aea/issues/932
        existing = ""
        fingerprint_block = False
        for line in file:
            if line.find("fingerprint:") == 0:
                existing += line
                fingerprint_block = True
            elif fingerprint_block:
                if line.find("  ") == 0:
                    # still inside fingerprint block
                    existing += line
                else:
                    # fingerprint block has ended
                    break

        if len(fingerprints_dict) > 0:
            replacement = "fingerprint:\n"
            ordered_fingerprints_dict = collections.OrderedDict(
                sorted(fingerprints_dict.items()))
            for file_name, ipfs_hash in ordered_fingerprints_dict.items():
                replacement += "  " + file_name + ": " + ipfs_hash + "\n"
        else:
            replacement = "fingerprint: {}\n"
        whole_file = whole_file.replace(existing, replacement)

        # close the file
        file.close()

        # update fingerprints
        with open(yaml_path, "w") as f:
            f.write(whole_file)

    # hash again to get outer hash (this time all files):
    # TODO we still need to ignore some files
    result_list = client.add(target_dir)
    for result_dict in result_list:
        if package_name == result_dict["Name"]:
            key = os.path.join(AUTHOR, package_type, package_name)
            package_hashes[key] = result_dict["Hash"]
    async def test_end_to_end_aea_aca(self):
        # AEA components
        ledger_apis = LedgerApis({}, FetchAICrypto.identifier)
        wallet = Wallet({FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE})
        identity = Identity(
            name="my_aea_1",
            address=wallet.addresses.get(FetchAICrypto.identifier),
            default_address_key=FetchAICrypto.identifier,
        )
        http_client_connection = HTTPClientConnection(
            address=self.aea_address,
            provider_address=self.aca_admin_address,
            provider_port=self.aca_admin_port,
        )
        resources = Resources()

        # create AEA
        aea = AEA(identity, [http_client_connection], wallet, ledger_apis,
                  resources)

        # Add http protocol to AEA resources
        http_protocol_configuration = ProtocolConfig.from_json(
            yaml.safe_load(
                open(
                    os.path.join(
                        self.cwd,
                        "packages",
                        "fetchai",
                        "protocols",
                        "http",
                        "protocol.yaml",
                    ))))
        http_protocol = Protocol(http_protocol_configuration, HttpSerializer())
        resources.add_protocol(http_protocol)

        # Request message & envelope
        request_http_message = HttpMessage(
            dialogue_reference=("", ""),
            target=0,
            message_id=1,
            performative=HttpMessage.Performative.REQUEST,
            method="GET",
            url="http://{}:{}/status".format(self.aca_admin_address,
                                             self.aca_admin_port),
            headers="",
            version="",
            bodyy=b"",
        )
        request_envelope = Envelope(
            to="ACA",
            sender="AEA",
            protocol_id=HTTP_PROTOCOL_PUBLIC_ID,
            message=HttpSerializer().encode(request_http_message),
        )

        # add a simple skill with handler
        skill_context = SkillContext(aea.context)
        skill_config = SkillConfig(name="simple_skill",
                                   author="fetchai",
                                   version="0.1.0")
        aea_handler = AEAHandler(skill_context=skill_context,
                                 name="aea_handler")
        simple_skill = Skill(skill_config,
                             skill_context,
                             handlers={aea_handler.name: aea_handler})
        resources.add_skill(simple_skill)

        # add error skill to AEA
        error_skill = Skill.from_dir(os.path.join(AEA_DIR, "skills", "error"))
        resources.add_skill(error_skill)

        # start AEA thread
        t_aea = Thread(target=aea.start)
        try:
            t_aea.start()
            time.sleep(1.0)
            aea.outbox.put(request_envelope)
            time.sleep(5.0)
            assert (aea_handler.handled_message.performative ==
                    HttpMessage.Performative.RESPONSE)
            assert aea_handler.handled_message.version == ""
            assert aea_handler.handled_message.status_code == 200
            assert aea_handler.handled_message.status_text == "OK"
            assert aea_handler.handled_message.headers is not None
            assert aea_handler.handled_message.version is not None
        finally:
            aea.stop()
            t_aea.join()
Esempio n. 24
0
def run():
    # Create a private key
    create_private_key(FetchAICrypto.identifier,
                       private_key_file=FETCHAI_PRIVATE_KEY_FILE_1)

    # Instantiate the builder and build the AEA
    # By default, the default protocol, error skill and stub connection are added
    builder = AEABuilder()

    builder.set_name("my_aea")

    builder.add_private_key(FetchAICrypto.identifier,
                            FETCHAI_PRIVATE_KEY_FILE_1)

    builder.add_ledger_api_config(FetchAICrypto.identifier,
                                  {"network": "testnet"})

    # Create our AEA
    my_aea = builder.build()

    # Generate some wealth for the default address
    try_generate_testnet_wealth(FetchAICrypto.identifier,
                                my_aea.identity.address)

    # add a simple skill with handler
    skill_context = SkillContext(my_aea.context)
    skill_config = SkillConfig(name="simple_skill",
                               author="fetchai",
                               version="0.1.0")
    tx_handler = TransactionHandler(skill_context=skill_context,
                                    name="transaction_handler")
    simple_skill = Skill(skill_config,
                         skill_context,
                         handlers={tx_handler.name: tx_handler})
    my_aea.resources.add_skill(simple_skill)

    # create a second identity
    create_private_key(FetchAICrypto.identifier,
                       private_key_file=FETCHAI_PRIVATE_KEY_FILE_2)

    counterparty_wallet = Wallet(
        {FetchAICrypto.identifier: FETCHAI_PRIVATE_KEY_FILE_2})

    counterparty_identity = Identity(
        name="counterparty_aea",
        addresses=counterparty_wallet.addresses,
        default_address_key=FetchAICrypto.identifier,
    )

    # create tx message for decision maker to process
    fetchai_ledger_api = my_aea.context.ledger_apis.apis[
        FetchAICrypto.identifier]
    tx_nonce = fetchai_ledger_api.generate_tx_nonce(
        my_aea.identity.address, counterparty_identity.address)

    tx_msg = TransactionMessage(
        performative=TransactionMessage.Performative.PROPOSE_FOR_SETTLEMENT,
        skill_callback_ids=[skill_config.public_id],
        tx_id="transaction0",
        tx_sender_addr=my_aea.identity.address,
        tx_counterparty_addr=counterparty_identity.address,
        tx_amount_by_currency_id={"FET": -1},
        tx_sender_fee=1,
        tx_counterparty_fee=0,
        tx_quantities_by_good_id={},
        ledger_id=FetchAICrypto.identifier,
        info={"some_info_key": "some_info_value"},
        tx_nonce=tx_nonce,
    )
    my_aea.context.decision_maker_message_queue.put_nowait(tx_msg)

    # Set the AEA running in a different thread
    try:
        logger.info("STARTING AEA NOW!")
        t = Thread(target=my_aea.start)
        t.start()

        # Let it run long enough to interact with the weather station
        time.sleep(20)
    finally:
        # Shut down the AEA
        logger.info("STOPPING AEA NOW!")
        my_aea.stop()
        t.join()
    async def test_end_to_end_aea_aca(self):
        """Test the end to end aea aca interaction."""
        # AEA components
        wallet = Wallet({DEFAULT_LEDGER: DEFAULT_PRIVATE_KEY_FILE})
        identity = Identity(
            name="my_aea_1",
            address=wallet.addresses.get(DEFAULT_LEDGER),
            default_address_key=DEFAULT_LEDGER,
        )
        configuration = ConnectionConfig(
            host=self.aca_admin_address,
            port=self.aca_admin_port,
            connection_id=HTTPClientConnection.connection_id,
        )
        http_client_connection = HTTPClientConnection(
            configuration=configuration,
            identity=identity,
        )
        resources = Resources()
        resources.add_connection(http_client_connection)

        # create AEA
        aea = AEA(identity, wallet, resources)

        # Add http protocol to AEA resources
        http_protocol_configuration = ProtocolConfig.from_json(
            yaml.safe_load(
                open(
                    os.path.join(
                        self.cwd,
                        "packages",
                        "fetchai",
                        "protocols",
                        "http",
                        "protocol.yaml",
                    ))))
        http_protocol = Protocol(http_protocol_configuration,
                                 HttpMessage.serializer())
        resources.add_protocol(http_protocol)

        # Request message & envelope
        request_http_message = HttpMessage(
            dialogue_reference=("", ""),
            target=0,
            message_id=1,
            performative=HttpMessage.Performative.REQUEST,
            method="GET",
            url="http://{}:{}/status".format(self.aca_admin_address,
                                             self.aca_admin_port),
            headers="",
            version="",
            body=b"",
        )
        request_http_message.to = "ACA"
        request_envelope = Envelope(
            to="ACA",
            sender="AEA",
            protocol_id=HttpMessage.protocol_id,
            message=request_http_message,
        )

        # add a simple skill with handler
        skill_context = SkillContext(aea.context)
        skill_config = SkillConfig(name="simple_skill",
                                   author="fetchai",
                                   version="0.1.0")
        aea_handler = AEAHandler(skill_context=skill_context,
                                 name="aea_handler")
        simple_skill = Skill(skill_config,
                             skill_context,
                             handlers={aea_handler.name: aea_handler})
        resources.add_skill(simple_skill)

        # add error skill to AEA
        error_skill = Skill.from_dir(os.path.join(AEA_DIR, "skills", "error"),
                                     agent_context=aea.context)
        resources.add_skill(error_skill)

        # start AEA thread
        t_aea = Thread(target=aea.start)
        try:
            t_aea.start()
            time.sleep(1.0)
            aea.outbox.put(request_envelope)
            time.sleep(5.0)
            assert (aea_handler.handled_message.performative ==
                    HttpMessage.Performative.RESPONSE)
            assert aea_handler.handled_message.version == ""
            assert aea_handler.handled_message.status_code == 200
            assert aea_handler.handled_message.status_text == "OK"
            assert aea_handler.handled_message.headers is not None
            assert aea_handler.handled_message.version is not None
        finally:
            aea.stop()
            t_aea.join()
Esempio n. 26
0
 def _make_skill(id_):
     return AEATestWrapper.make_skill(
         config=SkillConfig(name=f"sc{id_}", author="fetchai"),
         handlers={"dummy_handler": DummyHandler},
     )
Esempio n. 27
0
    def test_gym(self, pytestconfig):
        """Run the gym skill sequence."""
        if pytestconfig.getoption("ci"):
            pytest.skip("Skipping the test since it doesn't work in CI.")

        # add packages folder
        packages_src = os.path.join(self.cwd, "packages")
        packages_dst = os.path.join(self.t, "packages")
        shutil.copytree(packages_src, packages_dst)

        result = self.runner.invoke(
            cli, [*CLI_LOG_OPTION, "init", "--author", AUTHOR],
            standalone_mode=False)
        assert result.exit_code == 0

        # create agent
        result = self.runner.invoke(
            cli, [*CLI_LOG_OPTION, "create", self.agent_name],
            standalone_mode=False)
        assert result.exit_code == 0
        agent_dir_path = os.path.join(self.t, self.agent_name)
        os.chdir(agent_dir_path)

        # add packages and install dependencies
        result = self.runner.invoke(
            cli,
            [*CLI_LOG_OPTION, "add", "skill", "fetchai/gym:0.1.0"],
            standalone_mode=False,
        )
        assert result.exit_code == 0
        result = self.runner.invoke(
            cli,
            [*CLI_LOG_OPTION, "add", "connection", "fetchai/gym:0.1.0"],
            standalone_mode=False,
        )
        assert result.exit_code == 0
        result = self.runner.invoke(cli, [*CLI_LOG_OPTION, "install"],
                                    standalone_mode=False)
        assert result.exit_code == 0

        # add gyms folder from examples
        gyms_src = os.path.join(self.cwd, "examples", "gym_ex", "gyms")
        gyms_dst = os.path.join(self.t, self.agent_name, "gyms")
        shutil.copytree(gyms_src, gyms_dst)

        # change config file of gym connection
        file_src = os.path.join(ROOT_DIR, "tests", "data",
                                "gym-connection.yaml")
        file_dst = os.path.join(
            self.t,
            self.agent_name,
            "vendor",
            "fetchai",
            "connections",
            "gym",
            "connection.yaml",
        )
        shutil.copyfile(file_src, file_dst)

        # change number of training steps
        skill_config_path = Path(self.t, self.agent_name, "vendor", "fetchai",
                                 "skills", "gym", "skill.yaml")
        skill_config = SkillConfig.from_json(
            yaml.safe_load(open(skill_config_path)))
        skill_config.handlers.read("gym").args["nb_steps"] = 20
        yaml.safe_dump(skill_config.json, open(skill_config_path, "w"))

        try:
            process = subprocess.Popen(  # nosec
                [
                    sys.executable,
                    "-m",
                    "aea.cli",
                    "run",
                    "--connections",
                    "fetchai/gym:0.1.0",
                ],
                stdout=subprocess.PIPE,
                env=os.environ.copy(),
            )
            time.sleep(10.0)

            # TODO: check the run ends properly

        finally:
            process.send_signal(signal.SIGINT)
            process.wait(timeout=5)

            if not process.returncode == 0:
                poll = process.poll()
                if poll is None:
                    process.terminate()
                    process.wait(2)

            os.chdir(self.t)
            result = self.runner.invoke(
                cli, [*CLI_LOG_OPTION, "delete", self.agent_name],
                standalone_mode=False)
            assert result.exit_code == 0
Esempio n. 28
0
    def test_generated_protocol_end_to_end(self):
        """Test that a generated protocol could be used in exchanging messages between two agents."""
        agent_name_1 = "my_aea_1"
        agent_name_2 = "my_aea_2"
        builder_1 = AEABuilder()
        builder_1.set_name(agent_name_1)
        builder_1.add_private_key(DEFAULT_LEDGER, self.private_key_path_1)
        builder_1.set_default_ledger(DEFAULT_LEDGER)
        builder_1.set_default_connection(PublicId.from_str("fetchai/oef:0.7.0"))
        builder_1.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")
        )
        builder_1.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")
        )
        builder_1.add_component(
            ComponentType.PROTOCOL,
            Path(PATH_TO_T_PROTOCOL),
            skip_consistency_check=True,
        )
        builder_1.add_connection(
            Path(ROOT_DIR, "packages", "fetchai", "connections", "oef")
        )

        builder_2 = AEABuilder()
        builder_2.set_name(agent_name_2)
        builder_2.add_private_key(DEFAULT_LEDGER, self.private_key_path_2)
        builder_2.set_default_ledger(DEFAULT_LEDGER)
        builder_2.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "fipa")
        )
        builder_2.add_protocol(
            Path(ROOT_DIR, "packages", "fetchai", "protocols", "oef_search")
        )
        builder_2.set_default_connection(PublicId.from_str("fetchai/oef:0.7.0"))
        builder_2.add_component(
            ComponentType.PROTOCOL,
            Path(PATH_TO_T_PROTOCOL),
            skip_consistency_check=True,
        )
        builder_2.add_connection(
            Path(ROOT_DIR, "packages", "fetchai", "connections", "oef")
        )

        # create AEAs
        aea_1 = builder_1.build(connection_ids=[PublicId.from_str("fetchai/oef:0.7.0")])
        aea_2 = builder_2.build(connection_ids=[PublicId.from_str("fetchai/oef:0.7.0")])

        # dialogues
        dialogue_label_1 = DialogueLabel(
            (str(1), ""), aea_2.identity.address, aea_1.identity.address
        )
        aea_1_dialogue = TProtocolDialogue(
            dialogue_label_1, aea_1.identity.address, TProtocolDialogue.Role.ROLE_1
        )
        dialogue_label_2 = DialogueLabel(
            (str(1), str(1)), aea_1.identity.address, aea_1.identity.address
        )
        aea_2_dialogue = TProtocolDialogue(
            dialogue_label_2, aea_2.identity.address, TProtocolDialogue.Role.ROLE_2
        )

        # message 1
        message_1 = TProtocolMessage(
            message_id=1,
            dialogue_reference=(str(1), ""),
            target=0,
            performative=TProtocolMessage.Performative.PERFORMATIVE_PT,
            content_bytes=b"some bytes",
            content_int=42,
            content_float=42.7,
            content_bool=True,
            content_str="some string",
        )
        message_1.counterparty = aea_2.identity.address
        message_1.is_incoming = False

        # message 2
        message_2 = TProtocolMessage(
            message_id=2,
            dialogue_reference=(str(1), str(1)),
            target=1,
            performative=TProtocolMessage.Performative.PERFORMATIVE_PT,
            content_bytes=b"some other bytes",
            content_int=43,
            content_float=43.7,
            content_bool=False,
            content_str="some other string",
        )
        message_2.counterparty = aea_1.identity.address
        message_2.is_incoming = False

        # add handlers to AEA resources
        skill_context_1 = SkillContext(aea_1.context)
        skill_1 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_1)
        skill_context_1._skill = skill_1

        agent_1_handler = Agent1Handler(
            skill_context=skill_context_1,
            name="fake_handler_1",
            dialogue=aea_1_dialogue,
        )
        aea_1.resources._handler_registry.register(
            (
                PublicId.from_str("fetchai/fake_skill:0.1.0"),
                TProtocolMessage.protocol_id,
            ),
            agent_1_handler,
        )
        skill_context_2 = SkillContext(aea_2.context)
        skill_2 = Skill(SkillConfig("fake_skill", "fetchai", "0.1.0"), skill_context_2)
        skill_context_2._skill = skill_2

        agent_2_handler = Agent2Handler(
            message=message_2,
            dialogue=aea_2_dialogue,
            skill_context=skill_context_2,
            name="fake_handler_2",
        )
        aea_2.resources._handler_registry.register(
            (
                PublicId.from_str("fetchai/fake_skill:0.1.0"),
                TProtocolMessage.protocol_id,
            ),
            agent_2_handler,
        )

        # Start threads
        t_1 = Thread(target=aea_1.start)
        t_2 = Thread(target=aea_2.start)
        try:
            t_1.start()
            t_2.start()
            time.sleep(1.0)
            aea_1_dialogue.update(message_1)
            aea_1.outbox.put_message(message_1)
            time.sleep(5.0)
            assert (
                agent_2_handler.handled_message.message_id == message_1.message_id
            ), "Message from Agent 1 to 2: message ids do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference
                == message_1.dialogue_reference
            ), "Message from Agent 1 to 2: dialogue references do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference[0]
                == message_1.dialogue_reference[0]
            ), "Message from Agent 1 to 2: dialogue reference[0]s do not match"
            assert (
                agent_2_handler.handled_message.dialogue_reference[1]
                == message_1.dialogue_reference[1]
            ), "Message from Agent 1 to 2: dialogue reference[1]s do not match"
            assert (
                agent_2_handler.handled_message.target == message_1.target
            ), "Message from Agent 1 to 2: targets do not match"
            assert (
                agent_2_handler.handled_message.performative == message_1.performative
            ), "Message from Agent 1 to 2: performatives do not match"
            assert (
                agent_2_handler.handled_message.content_bytes == message_1.content_bytes
            ), "Message from Agent 1 to 2: content_bytes do not match"
            assert (
                agent_2_handler.handled_message.content_int == message_1.content_int
            ), "Message from Agent 1 to 2: content_int do not match"
            # assert (
            #     agent_2_handler.handled_message.content_float == message_1.content_float
            # ), "Message from Agent 1 to 2: content_float do not match"
            assert (
                agent_2_handler.handled_message.content_bool == message_1.content_bool
            ), "Message from Agent 1 to 2: content_bool do not match"
            assert (
                agent_2_handler.handled_message.content_str == message_1.content_str
            ), "Message from Agent 1 to 2: content_str do not match"

            assert (
                agent_1_handler.handled_message.message_id == message_2.message_id
            ), "Message from Agent 1 to 2: dialogue references do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference
                == message_2.dialogue_reference
            ), "Message from Agent 2 to 1: dialogue references do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference[0]
                == message_2.dialogue_reference[0]
            ), "Message from Agent 2 to 1: dialogue reference[0]s do not match"
            assert (
                agent_1_handler.handled_message.dialogue_reference[1]
                == message_2.dialogue_reference[1]
            ), "Message from Agent 2 to 1: dialogue reference[1]s do not match"
            assert (
                agent_1_handler.handled_message.target == message_2.target
            ), "Message from Agent 2 to 1: targets do not match"
            assert (
                agent_1_handler.handled_message.performative == message_2.performative
            ), "Message from Agent 2 to 1: performatives do not match"
            assert (
                agent_1_handler.handled_message.content_bytes == message_2.content_bytes
            ), "Message from Agent 2 to 1: content_bytes do not match"
            assert (
                agent_1_handler.handled_message.content_int == message_2.content_int
            ), "Message from Agent 2 to 1: content_int do not match"
            # assert (
            #     agent_1_handler.handled_message.content_float == message_2.content_float
            # ), "Message from Agent 2 to 1: content_float do not match"
            assert (
                agent_1_handler.handled_message.content_bool == message_2.content_bool
            ), "Message from Agent 2 to 1: content_bool do not match"
            assert (
                agent_1_handler.handled_message.content_str == message_2.content_str
            ), "Message from Agent 2 to 1: content_str do not match"
            time.sleep(2.0)
        finally:
            aea_1.stop()
            aea_2.stop()
            t_1.join()
            t_2.join()