Beispiel #1
0
def build_goods_query(good_pbks: List[str], currency: str,
                      is_searching_for_sellers: bool) -> Query:
    """
    Build buyer or seller search query.

    Specifically, build the search query
        - to look for sellers if the agent is a buyer, or
        - to look for buyers if the agent is a seller.

    In particular, if the agent is a buyer and the demanded good public keys are {'tac_good_0', 'tac_good_2', 'tac_good_3'}, the resulting constraint expression is:

        tac_good_0 >= 1 OR tac_good_2 >= 1 OR tac_good_3 >= 1

    That is, the OEF will return all the sellers that have at least one of the good in the query
    (assuming that the sellers are registered with the data model specified).

    :param good_pbks: the list of good public keys to put in the query
    :param currency: the currency used for pricing and transacting.
    :param is_searching_for_sellers: Boolean indicating whether the query is for sellers (supply) or buyers (demand).

    :return: the query
    """
    data_model = build_goods_datamodel(good_pbks=good_pbks,
                                       is_supply=is_searching_for_sellers)
    constraints = [
        Constraint(good_pbk, ConstraintType(">=", 1)) for good_pbk in good_pbks
    ]
    constraints.append(Constraint('currency', ConstraintType("==", currency)))
    constraint_expr = cast(List[ConstraintExpr], constraints)

    if len(good_pbks) > 1:
        constraint_expr = [Or(constraint_expr)]

    query = Query(constraint_expr, model=data_model)
    return query
    def test_unregister_service_result(self):
        """Test that at the beginning, the search request returns an empty search result."""
        data_model = DataModel("foobar", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model)
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)

        # check the result
        response_envelope = self.multiplexer1.get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.sender == DEFAULT_OEF
        result = OEFSerializer().decode(response_envelope.message)
        assert result.get("type") == OEFMessage.Type.OEF_ERROR

        msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_Service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)

        # Search for the register agent
        msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=Query([Constraint("foo", ConstraintType("==", 1))]))
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)
        # check the result
        response_envelope = self.multiplexer1.get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.sender == DEFAULT_OEF
        result = OEFSerializer().decode(response_envelope.message)
        assert result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert len(result.get("agents")) == 1

        # unregister the service
        data_model = DataModel("foobar", attributes=[])
        service_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model)
        msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE, id=0, service_description=service_description,
                         service_id="Test_service")
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)

        # the same query returns empty
        # Search for the register agent
        msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=Query([Constraint("foo", ConstraintType("==", 1))]))
        msg_bytes = OEFSerializer().encode(msg)
        envelope = Envelope(to=DEFAULT_OEF, sender=self.public_key_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes)
        self.multiplexer1.put(envelope)
        # check the result
        response_envelope = self.multiplexer1.get(block=True, timeout=5.0)
        assert response_envelope.protocol_id == OEFMessage.protocol_id
        assert response_envelope.sender == DEFAULT_OEF
        result = OEFSerializer().decode(response_envelope.message)
        assert result.get("type") == OEFMessage.Type.SEARCH_RESULT
        assert len(result.get("agents")) == 0
Beispiel #3
0
 def test_and_check(self):
     """Test the and().check function."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     constraint = And([(Constraint("foo", ConstraintType("==", 1))),
                       (Constraint("bar", ConstraintType("==", "baz")))
                       ])
     assert constraint.check(description_foobar)
Beispiel #4
0
    def search_for_tac(self) -> None:
        """
        Search for active TAC Controller.

        We assume that the controller is registered as a service with the 'tac' data model
        and with an attribute version = expected_version_id.

        :return: None
        """
        query = Query(
            [Constraint("version", GtEq(self.game_instance.expected_version_id))]
        )
        search_id = self.game_instance.search.get_next_id()
        self.game_instance.search.ids_for_tac.add(search_id)

        msg = OEFMessage(
            oef_type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query
        )
        msg_bytes = OEFSerializer().encode(msg)
        self.mailbox.outbox.put_message(
            to=DEFAULT_OEF,
            sender=self.crypto.public_key,
            protocol_id=OEFMessage.protocol_id,
            message=msg_bytes,
        )
    def test_cfp(self):
        """Test that a CFP can be sent correctly."""
        cfp_bytes = FIPAMessage(
            message_id=0,
            dialogue_id=0,
            target=0,
            performative=FIPAMessage.Performative.CFP,
            query=Query([Constraint('something', ConstraintType('>', 1))]))
        self.mailbox1.outbox.put_message(
            to=self.crypto2.public_key,
            sender=self.crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=FIPASerializer().encode(cfp_bytes))
        envelope = self.mailbox2.inbox.get(block=True, timeout=5.0)
        expected_cfp_bytes = FIPASerializer().decode(envelope.message)
        assert expected_cfp_bytes == cfp_bytes

        cfp_none = FIPAMessage(message_id=0,
                               dialogue_id=0,
                               target=0,
                               performative=FIPAMessage.Performative.CFP,
                               query=None)
        self.mailbox1.outbox.put_message(
            to=self.crypto2.public_key,
            sender=self.crypto1.public_key,
            protocol_id=FIPAMessage.protocol_id,
            message=FIPASerializer().encode(cfp_none))
        envelope = self.mailbox2.inbox.get(block=True, timeout=5.0)
        expected_cfp_none = FIPASerializer().decode(envelope.message)
        assert expected_cfp_none == cfp_none
Beispiel #6
0
def build_query(good_pbks: Set[str], is_searching_for_sellers: bool) -> Query:
    """
    Build buyer or seller search query.

    Specifically, build the search query
        - to look for sellers if the agent is a buyer, or
        - to look for buyers if the agent is a seller.

    In particular, if the agent is a buyer and the demanded good public keys are {'tac_good_0', 'tac_good_2', 'tac_good_3'}, the resulting constraint expression is:

        tac_good_0 >= 1 OR tac_good_2 >= 1 OR tac_good_3 >= 1

    That is, the OEF will return all the sellers that have at least one of the good in the query
    (assuming that the sellers are registered with the data model specified).

    :param good_pbks: the good public keys to put in the query
    :param is_searching_for_sellers: Boolean indicating whether the query is for sellers (supply) or buyers (demand).

    :return: the query
    """
    data_model = None if good_pbks is None else build_datamodel(list(good_pbks), is_supply=is_searching_for_sellers)
    constraints = [Constraint(good_pbk, GtEq(1)) for good_pbk in good_pbks]

    if len(good_pbks) > 1:
        constraints = [Or(constraints)]

    query = Query(constraints, model=data_model)
    return query
Beispiel #7
0
def test_fipa_cfp_serialization():
    """Test that the serialization for the 'fipa' protocol works."""
    query = Query([Constraint('something', ConstraintType('>', 1))])
    msg = FIPAMessage(message_id=0,
                      dialogue_reference=(str(0), ''),
                      target=0,
                      performative=FIPAMessage.Performative.CFP,
                      query=query)
    msg_bytes = FIPASerializer().encode(msg)
    envelope = Envelope(to="receiver",
                        sender="sender",
                        protocol_id=FIPAMessage.protocol_id,
                        message=msg_bytes)
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope == actual_envelope

    actual_msg = FIPASerializer().decode(actual_envelope.message)
    expected_msg = msg
    assert expected_msg == actual_msg

    msg.set("query", "not_supported_query")
    with pytest.raises(ValueError, match="Query type not supported:"):
        FIPASerializer().encode(msg)
        def test_register_service(self):
            """Test that a register service request works correctly."""
            foo_datamodel = DataModel(
                "foo", [Attribute("bar", int, True, "A bar attribute.")])
            desc = Description({"bar": 1}, data_model=foo_datamodel)
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=1,
                             service_description=desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)

            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=2,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=foo_datamodel))
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))
            envelope = self.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == 2
            assert search_result.get("agents") == [self.crypto1.public_key]
        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.
            """
            request_id = 2
            data_model = DataModel("foobar", [Attribute("foo", str, True)])
            search_query = Query(
                [Constraint("foo", ConstraintType("==", "bar"))],
                model=data_model)
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=request_id,
                query=search_query)
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))

            envelope = self.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == request_id
            assert search_result.get("agents") == []
Beispiel #10
0
 def test_not_check(self):
     """Test the not().check function."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     no_constraint = Not(Constraint("foo", ConstraintType("==", 5)))
     assert no_constraint.check(description_foobar)
Beispiel #11
0
 def test_query_check(self):
     """Test that the query.check() method works."""
     attribute_foo = Attribute("foo", int, True, "a foo attribute.")
     attribute_bar = Attribute("bar", str, True, "a bar attribute.")
     data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")
     description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar)
     query = Query([
         And([
             Or([
                 Not(Constraint("foo", ConstraintType("==", 1))),
                 Not(Constraint("bar", ConstraintType("==", "baz")))
             ]),
             Constraint("foo", ConstraintType("<", 2)),
         ])
     ],
         data_model_foobar)
     assert not query.check(description=description_foobar)
Beispiel #12
0
    def get_service_query(self) -> Query:
        """
        Get the service query of the agent.

        :return: the query
        """
        query = Query([Constraint('longitude', ConstraintType("!=", 0.0))],
                      model=None)
        return query
Beispiel #13
0
    def get_service_query(self) -> Query:
        """
        Get the service query of the agent.

        :return: the query
        """
        query = Query(
            [Constraint(SEARCH_TERM, ConstraintType("==", self._country))],
            model=None)
        return query
Beispiel #14
0
    def get_game_query(self) -> Query:
        """
        Get the query for the TAC game.

        :return: the query
        """
        query = Query([
            Constraint("version", ConstraintType("==",
                                                 self.expected_version_id))
        ])
        return query
Beispiel #15
0
    def test_query(self):
        """Test that the translation for the Query class works."""
        attribute_foo = Attribute("foo", int, True, "a foo attribute.")
        attribute_bar = Attribute("bar", str, True, "a bar attribute.")
        data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")

        query = Query([
            And([
                Or([
                    Not(Constraint("foo", ConstraintType("==", 1))),
                    Not(Constraint("bar", ConstraintType("==", "baz")))
                ]),
                Constraint("foo", ConstraintType("<", 2)),
            ])
        ], data_model_foobar)

        oef_query = OEFObjectTranslator.to_oef_query(query)
        expected_query = OEFObjectTranslator.from_oef_query(oef_query)
        actual_query = query
        assert expected_query == actual_query
Beispiel #16
0
    def test_pickable_query(self):
        """Test that an istance of the Query class is pickable."""
        attribute_foo = Attribute("foo", int, True, "a foo attribute.")
        attribute_bar = Attribute("bar", str, True, "a bar attribute.")
        data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar], "A foobar data model.")

        query = Query([
            And([
                Or([
                    Not(Constraint("foo", ConstraintType("==", 1))),
                    Not(Constraint("bar", ConstraintType("==", "baz")))
                ]),
                Constraint("foo", ConstraintType("<", 2)),
            ])
        ],
            data_model_foobar)
        try:
            pickle.dumps(query)
        except Exception:
            pytest.fail("Error during pickling.")
Beispiel #17
0
    def setup(self) -> None:
        """Implement the setup for the behaviour."""
        search_query_empty_model = Query(
            [Constraint("country", ConstraintType("==", "UK"))], model=None)
        search_request = OEFMessage(oef_type=OEFMessage.Type.SEARCH_SERVICES,
                                    id=REQUEST_ID,
                                    query=search_query_empty_model)

        self.context.outbox.put_message(
            to=DEFAULT_OEF,
            sender=self.context.agent_public_key,
            protocol_id=OEFMessage.protocol_id,
            message=OEFSerializer().encode(search_request))
        def setup_class(cls):
            """
            Set the test up.

            Steps:
            - Register a service
            - Check that the registration worked.
            """
            cls.crypto1 = DefaultCrypto()
            cls.connection = OEFConnection(cls.crypto1.public_key,
                                           oef_addr="127.0.0.1",
                                           oef_port=10000)
            cls.multiplexer = Multiplexer([cls.connection])
            cls.multiplexer.connect()

            cls.request_id = 1
            cls.foo_datamodel = DataModel(
                "foo", [Attribute("bar", int, True, "A bar attribute.")])
            cls.desc = Description({"bar": 1}, data_model=cls.foo_datamodel)
            msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_SERVICE,
                             id=cls.request_id,
                             service_description=cls.desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            cls.multiplexer.put(
                Envelope(to=DEFAULT_OEF,
                         sender=cls.crypto1.public_key,
                         protocol_id=OEFMessage.protocol_id,
                         message=msg_bytes))

            time.sleep(1.0)

            cls.request_id += 1
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=cls.request_id,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=cls.foo_datamodel))
            cls.multiplexer.put(
                Envelope(to=DEFAULT_OEF,
                         sender=cls.crypto1.public_key,
                         protocol_id=OEFMessage.protocol_id,
                         message=OEFSerializer().encode(search_request)))
            envelope = cls.multiplexer.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == cls.request_id
            if search_result.get("agents") != [cls.crypto1.public_key]:
                logger.warning(
                    'search_result.get("agents") != [self.crypto1.public_key] FAILED in test_oef/test_communication.py'
                )
def test_oef_message_consistency():
    """Tests the consistency of an OEFMessage."""
    foo_datamodel = DataModel(
        "foo", [Attribute("bar", int, True, "A bar attribute.")])
    msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS,
                     id=2,
                     query=Query([Constraint("bar", ConstraintType("==", 1))],
                                 model=foo_datamodel))
    assert msg.check_consistency(), "We expect the consistency to return TRUE"
    with mock.patch("aea.protocols.oef.message.OEFMessage.Type")\
            as mock_type_enum:
        mock_type_enum.SEARCH_AGENTS.value = "unknown"
        assert not msg.check_consistency(),\
            "Expect the consistency to return False"
        def test_search_count_increases(self):
            """Test that the search count increases."""
            request_id = 1
            search_query_empty_model = Query(
                [Constraint("foo", ConstraintType("==", "bar"))], model=None)
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=request_id,
                query=search_query_empty_model)
            self.multiplexer.put(
                Envelope(to=DEFAULT_OEF,
                         sender=self.crypto1.public_key,
                         protocol_id=OEFMessage.protocol_id,
                         message=OEFSerializer().encode(search_request)))

            envelope = self.multiplexer.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id")
            assert request_id and search_result.get("agents") == []
Beispiel #21
0
 def from_oef_constraint_expr(
         cls, oef_constraint_expr: OEFConstraintExpr) -> ConstraintExpr:
     """From our query to OEF query."""
     if isinstance(oef_constraint_expr, OEFAnd):
         return And([
             cls.from_oef_constraint_expr(c)
             for c in oef_constraint_expr.constraints
         ])
     elif isinstance(oef_constraint_expr, OEFOr):
         return Or([
             cls.from_oef_constraint_expr(c)
             for c in oef_constraint_expr.constraints
         ])
     elif isinstance(oef_constraint_expr, OEFNot):
         return Not(
             cls.from_oef_constraint_expr(oef_constraint_expr.constraint))
     elif isinstance(oef_constraint_expr, OEFConstraint):
         return Constraint(oef_constraint_expr.attribute_name,
                           oef_constraint_expr.constraint)
     else:
         raise ValueError("OEF Constraint not supported.")
Beispiel #22
0
def test_fipa_cfp_serialization():
    """Test that the serialization for the 'fipa' protocol works."""
    query = Query(Constraint('something', ConstraintType('>', 1)))
    msg = FIPAMessage(message_id=0,
                      dialogue_id=0,
                      target=0,
                      performative=FIPAMessage.Performative.CFP,
                      query=query)
    msg_bytes = FIPASerializer().encode(msg)
    envelope = Envelope(to="receiver",
                        sender="sender",
                        protocol_id=FIPAMessage.protocol_id,
                        message=msg_bytes)
    envelope_bytes = envelope.encode()

    actual_envelope = Envelope.decode(envelope_bytes)
    expected_envelope = envelope
    assert expected_envelope == actual_envelope

    actual_msg = FIPASerializer().decode(actual_envelope.message)
    expected_msg = msg
    assert expected_msg == actual_msg
        def test_unregister_service(self):
            """Test that an unregister service request works correctly.

            Steps:
            2. unregister the service
            3. search for that service
            4. assert that no result is found.
            """
            self.request_id += 1
            msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_SERVICE,
                             id=self.request_id,
                             service_description=self.desc,
                             service_id="")
            msg_bytes = OEFSerializer().encode(msg)
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=msg_bytes)

            time.sleep(1.0)

            self.request_id += 1
            search_request = OEFMessage(
                oef_type=OEFMessage.Type.SEARCH_SERVICES,
                id=self.request_id,
                query=Query([Constraint("bar", ConstraintType("==", 1))],
                            model=self.foo_datamodel))
            self.mailbox1.outbox.put_message(
                to=DEFAULT_OEF,
                sender=self.crypto1.public_key,
                protocol_id=OEFMessage.protocol_id,
                message=OEFSerializer().encode(search_request))

            envelope = self.mailbox1.inbox.get(block=True, timeout=5.0)
            search_result = OEFSerializer().decode(envelope.message)
            assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT
            assert search_result.get("id") == self.request_id
            assert search_result.get("agents") == []
Beispiel #24
0
def test_oef_message_consistency():
    """Tests the consistency of an OEFMessage."""
    foo_datamodel = DataModel(
        "foo", [Attribute("bar", int, True, "A bar attribute.")])
    msg = OEFMessage(oef_type=OEFMessage.Type.SEARCH_AGENTS,
                     id=2,
                     query=Query([Constraint("bar", ConstraintType("==", 1))],
                                 model=foo_datamodel))
    assert msg.check_consistency(), "We expect the consistency to return TRUE"
    with mock.patch("aea.protocols.oef.message.OEFMessage.Type")\
            as mock_type_enum:
        mock_type_enum.SEARCH_AGENTS.value = "unknown"
        assert not msg.check_consistency(),\
            "Expect the consistency to return False"

    attribute_foo = Attribute("foo", int, True, "a foo attribute.")
    attribute_bar = Attribute("bar", str, True, "a bar attribute.")
    data_model_foobar = DataModel("foobar", [attribute_foo, attribute_bar],
                                  "A foobar data model.")
    description_foobar = Description({
        "foo": 1,
        "bar": "baz"
    },
                                     data_model=data_model_foobar)
    msg = OEFMessage(oef_type=OEFMessage.Type.REGISTER_AGENT,
                     id=0,
                     agent_description=description_foobar,
                     agent_id="public_key")
    assert msg.check_consistency()

    msg = OEFMessage(oef_type=OEFMessage.Type.UNREGISTER_AGENT,
                     id=0,
                     agent_description=description_foobar,
                     agent_id="public_key")

    assert msg.check_consistency()