def __init__(self): """Initialise the dataModel.""" self.ATTRIBUTE_COUNTRY = Attribute("country", str, True) self.ATTRIBUTE_CITY = Attribute("city", str, True) super().__init__("weather_station_datamodel", [self.ATTRIBUTE_COUNTRY, self.ATTRIBUTE_CITY])
def build_goods_datamodel(good_pbks: List[str], is_supply: bool) -> DataModel: """ Build a data model for supply and demand of goods (i.e. for offered or requested goods). :param good_pbks: a list of public keys (i.e. identifiers) of the relevant goods. :param currency: the currency used for trading. :param is_supply: Boolean indicating whether it is a supply or demand data model :return: the data model. """ good_quantities_attributes = [ Attribute(good_pbk, int, True, "A good on offer.") for good_pbk in good_pbks ] currency_attribute = Attribute( 'currency', str, True, "The currency for pricing and transacting the goods.") price_attribute = Attribute('price', int, False, "The price of the goods in the currency.") seller_tx_fee_attribute = Attribute( 'seller_tx_fee', int, False, "The transaction fee payable by the seller in the currency.") buyer_tx_fee_attribute = Attribute( 'buyer_tx_fee', int, False, "The transaction fee payable by the buyer in the currency.") description = SUPPLY_DATAMODEL_NAME if is_supply else DEMAND_DATAMODEL_NAME attributes = good_quantities_attributes + [ currency_attribute, price_attribute, seller_tx_fee_attribute, buyer_tx_fee_attribute ] data_model = DataModel(description, attributes) return data_model
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)
def test_data_model(self): """Test that the translation for the DataModel 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.") oef_data_model = OEFObjectTranslator.to_oef_data_model(data_model_foobar) expected_data_model = OEFObjectTranslator.from_oef_data_model(oef_data_model) actual_data_model = data_model_foobar assert expected_data_model == actual_data_model
def test_pickable_data_model(self): """Test that an istance of the DataModel 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.") try: pickle.dumps(data_model_foobar) except Exception: pytest.fail("Error during pickling.")
def __init__(self): """Initialise the dataModel.""" self.ATTRIBUTE_LATITUDE = Attribute("latitude", float, True) self.ATTRIBUTE_LONGITUDE = Attribute("longitude", float, True) self.ATTRIBUTE_UNIQUE_ID = Attribute("unique_id", str, True) super().__init__("carpark_detection_datamodel", [ self.ATTRIBUTE_LATITUDE, self.ATTRIBUTE_LONGITUDE, self.ATTRIBUTE_UNIQUE_ID ])
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)
def test_description(self): """Test that the translation for the Description 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.") description_foobar = Description({"foo": 1, "bar": "baz"}, data_model=data_model_foobar) oef_description = OEFObjectTranslator.to_oef_description(description_foobar) expected_description = OEFObjectTranslator.from_oef_description(oef_description) actual_description = description_foobar assert expected_description == actual_description m_desc = iter(description_foobar.values) assert next(m_desc) == "foo" assert {"foo", "bar"} == set(iter(description_foobar))
def build_datamodel(good_pbks: List[str], is_supply: bool) -> DataModel: """ Build a data model for supply and demand (i.e. for offered or requested goods). :param good_pbks: the list of good public keys :param is_supply: Boolean indicating whether it is a supply or demand data model :return: the data model. """ goods_quantities_attributes = [Attribute(good_pbk, int, False) for good_pbk in good_pbks] price_attribute = Attribute("price", float, False) description = TAC_SUPPLY_DATAMODEL_NAME if is_supply else TAC_DEMAND_DATAMODEL_NAME data_model = DataModel(description, goods_quantities_attributes + [price_attribute]) return data_model
def test_propose(self): """Test that a Propose can be sent correctly.""" propose_empty = FIPAMessage( message_id=0, dialogue_id=0, target=0, performative=FIPAMessage.Performative.PROPOSE, proposal=[]) self.mailbox1.outbox.put_message( to=self.crypto2.public_key, sender=self.crypto1.public_key, protocol_id=FIPAMessage.protocol_id, message=FIPASerializer().encode(propose_empty)) envelope = self.mailbox2.inbox.get(block=True, timeout=2.0) expected_propose_empty = FIPASerializer().decode(envelope.message) assert expected_propose_empty == propose_empty propose_descriptions = FIPAMessage( message_id=0, dialogue_id=0, target=0, performative=FIPAMessage.Performative.PROPOSE, proposal=[ Description({"foo": "bar"}, DataModel("foobar", [Attribute("foo", str, True)])) ]) self.mailbox1.outbox.put_message( to=self.crypto2.public_key, sender=self.crypto1.public_key, protocol_id=FIPAMessage.protocol_id, message=FIPASerializer().encode(propose_descriptions)) envelope = self.mailbox2.inbox.get(block=True, timeout=2.0) expected_propose_descriptions = FIPASerializer().decode( envelope.message) assert expected_propose_descriptions == propose_descriptions
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_attribute(self): """Test that the translation for the Attribute class works.""" attribute = Attribute("foo", int, True, "a foo attribute.") oef_attribute = OEFObjectTranslator.to_oef_attribute(attribute) expected_attribute = OEFObjectTranslator.from_oef_attribute(oef_attribute) actual_attribute = attribute assert expected_attribute == actual_attribute
def test_pickable_attribute(self): """Test that an istance of the Attribute class is pickable.""" attribute_foo = Attribute("foo", int, True, "a foo attribute.") try: pickle.dumps(attribute_foo) except Exception: pytest.fail("Error during pickling.")
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") == []
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)
def build_goods_datamodel(good_pbks: List[str], currency: str, is_supply: bool) -> DataModel: """ Build a data model for supply and demand of goods (i.e. for offered or requested goods). :param good_pbks: a list of public keys (i.e. identifiers) of the relevant goods. :param currency: the currency used for trading. :param is_supply: Boolean indicating whether it is a supply or demand data model :return: the data model. """ goods_quantities_attributes = [ Attribute(good_pbk, int, False) for good_pbk in good_pbks ] price_attribute = Attribute(currency, float, False) description = SUPPLY_DATAMODEL_NAME if is_supply else DEMAND_DATAMODEL_NAME attributes = goods_quantities_attributes + [price_attribute] data_model = DataModel(description, attributes) return data_model
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.")
def test_oef_serialization(): """Testing the serialization of the OEF.""" 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) assert len(msg_bytes) > 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
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_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()
import logging from aea.protocols.oef.models import Description, DataModel, Attribute from aea.agent import Liveness from aea.crypto.base import Crypto from aea.mail.base import MailBox from aea.protocols.oef.message import OEFMessage from aea.protocols.oef.serialization import OEFSerializer, DEFAULT_OEF from tac.agents.controller.base.interfaces import OEFActionInterface logger = logging.getLogger(__name__) CONTROLLER_DATAMODEL = DataModel("tac", [ Attribute("version", str, True, "Version number of the TAC Controller Agent."), ]) class OEFActions(OEFActionInterface): """The OEFActions class defines the actions of an agent towards the OEF.""" def __init__(self, crypto: Crypto, liveness: Liveness, mailbox: MailBox, agent_name: str, tac_version_id: str) -> None: """ Instantiate the OEFActions. :param crypto: the crypto module :param liveness: the liveness module :param mailbox: the mailbox of the agent :param agent_name: the agent name :param tac_version: the tac version id
def from_oef_attribute(cls, oef_attribute: OEFAttribute) -> Attribute: """From an OEF attribute to our attribute.""" return Attribute(oef_attribute.name, oef_attribute.type, oef_attribute.required, oef_attribute.description)