def _search_services(self) -> None: """ Search on OEF Service Directory. In particular, search - for sellers and their supply, or - for buyers and their demand, or - for both. :return: None """ strategy = cast(Strategy, self.context.strategy) search = cast(Search, self.context.search) if strategy.is_searching_for_sellers: query = strategy.get_own_services_query( is_searching_for_sellers=True) if query is None: self.context.logger.warning( "[{}]: Not searching the OEF for sellers because the agent demands no goods." .format(self.context.agent_name)) return None else: search_id = search.get_next_id(is_searching_for_sellers=True) self.context.logger.info( "[{}]: Searching for sellers which match the demand of the agent, search_id={}." .format(self.context.agent_name, search_id)) oef_msg = OEFMessage(type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) if strategy.is_searching_for_buyers: query = strategy.get_own_services_query( is_searching_for_sellers=False) if query is None: self.context.logger.warning( "[{}]: Not searching the OEF for buyers because the agent supplies no goods." .format(self.context.agent_name)) return None else: search_id = search.get_next_id(is_searching_for_sellers=False) self.context.logger.info( "[{}]: Searching for buyers which match the supply of the agent, search_id={}." .format(self.context.agent_name, search_id)) oef_msg = OEFMessage(type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
def _register_service(self) -> None: """ Register to the OEF Service Directory. In particular, register - as a seller, listing the goods supplied, or - as a buyer, listing the goods demanded, or - as both. :return: None """ registration = cast(Registration, self.context.registration) strategy = cast(Strategy, self.context.strategy) if strategy.is_registering_as_seller: self.context.logger.debug( "[{}]: Updating service directory as seller with goods supplied." .format(self.context.agent_name)) goods_supplied_description = strategy.get_own_service_description( is_supply=True) registration.registered_goods_supplied_description = ( goods_supplied_description) oef_msg = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=registration.get_next_id(), service_description=goods_supplied_description, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) if strategy.is_registering_as_buyer: self.context.logger.debug( "[{}]: Updating service directory as buyer with goods demanded." .format(self.context.agent_name)) goods_demanded_description = strategy.get_own_service_description( is_supply=False) registration.registered_goods_demanded_description = ( goods_demanded_description) oef_msg = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=registration.get_next_id(), service_description=goods_demanded_description, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_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( type=OEFMessage.Type.UNREGISTER_SERVICE, id=self.request_id, service_description=self.desc, service_id="", ) msg_bytes = OEFSerializer().encode(msg) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) ) time.sleep(1.0) self.request_id += 1 search_request = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=self.request_id, query=Query( [Constraint("bar", ConstraintType("==", 1))], model=self.foo_datamodel, ), ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == self.request_id assert search_result.get("agents") == []
def on_dialogue_error( self, answer_id: int, dialogue_id: int, origin: Address ) -> None: """ On dialogue error event handler. :param answer_id: the answer id. :param dialogue_id: the dialogue id. :param origin: the message sender. :return: None """ assert self.in_queue is not None assert self.loop is not None msg = OEFMessage( type=OEFMessage.Type.DIALOGUE_ERROR, id=answer_id, dialogue_id=dialogue_id, origin=origin, ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=self.address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) asyncio.run_coroutine_threadsafe( self.in_queue.put(envelope), self.loop ).result()
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( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=search_query ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == request_id assert search_result.get("agents") == []
async def _search_services(self, address: Address, search_id: int, query: Query) -> None: """ Search the agents in the local Service Directory, and send back the result. This is actually a dummy search, it will return all the registered agents with the specified data model. If the data model is not specified, it will return all the agents. :param address: the source of the search request. :param search_id: the search identifier associated with the search request. :param query: the query that constitutes the search. :return: None """ result = [] # type: List[str] if query.model is None: result = list(set(self.services.keys())) else: for agent_address, descriptions in self.services.items(): for description in descriptions: if description.data_model == query.model: result.append(agent_address) msg = OEFMessage(type=OEFMessage.Type.SEARCH_RESULT, id=search_id, agents=sorted(set(result))) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await self._send(envelope)
async def _handle_agent_message(self, envelope: Envelope) -> None: """ Forward an envelope to the right agent. :param envelope: the envelope :return: None """ destination = envelope.to if destination not in self._out_queues.keys(): msg = OEFMessage( type=OEFMessage.Type.DIALOGUE_ERROR, id=STUB_DIALOGUE_ID, dialogue_id=STUB_DIALOGUE_ID, origin=destination, ) msg_bytes = OEFSerializer().encode(msg) error_envelope = Envelope( to=envelope.sender, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await self._send(error_envelope) return else: await self._send(envelope)
def test_not_empty_search_result(self): """Test that the search result contains one entry after a successful registration.""" request_id = 1 query = Query(constraints=[], model=self.data_model) # build and send the request search_services_request = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query ) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) self.multiplexer.put(envelope) # check the result response_envelope = self.multiplexer.get(block=True, timeout=2.0) assert response_envelope.protocol_id == OEFMessage.protocol_id assert response_envelope.to == self.address_1 assert response_envelope.sender == DEFAULT_OEF search_result = OEFSerializer().decode(response_envelope.message) assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT assert search_result.get("agents") == [self.address_1]
def _unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ strategy = cast(Strategy, self.context.strategy) oef_msg_id = strategy.get_next_oef_msg_id() msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=oef_msg_id, service_description=self._registered_service_description, service_id=SERVICE_ID, ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(msg), ) self.context.logger.info( "[{}]: unregistering generic seller services from OEF.".format( self.context.agent_name ) ) self._registered_service_description = None
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 """ game = cast(Game, self.context.game) search = cast(Search, self.context.search) query = game.get_game_query() search_id = search.get_next_id() search.ids_for_tac.add(search_id) self.context.logger.info( "[{}]: Searching for TAC, search_id={}".format( self.context.agent_name, search_id ) ) oef_msg = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
def test_oef_message_oef_error(): """Tests the OEF_ERROR type of message.""" msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS, ) assert OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS, ), "Expects an oef message Error!" msg_bytes = OEFSerializer().encode(msg) assert len(msg_bytes) > 0, "Expects the length of bytes not to be Empty" deserialized_msg = OEFSerializer().decode(msg_bytes) assert msg == deserialized_msg, "Expected the deserialized_msg to me equals to msg"
def test_filtered_search_result(self): """Test that the search result contains only the entries matching the query.""" request_id = 1 query = Query(constraints=[], model=self.data_model_barfoo) # build and send the request search_services_request = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=query ) msg_bytes = OEFSerializer().encode(search_services_request) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) self.multiplexer1.put(envelope) # check the result response_envelope = InBox(self.multiplexer1).get(block=True, timeout=5.0) assert response_envelope.protocol_id == OEFMessage.protocol_id assert response_envelope.to == self.address_1 assert response_envelope.sender == DEFAULT_OEF search_result = OEFSerializer().decode(response_envelope.message) assert search_result.get("type") == OEFMessage.Type.SEARCH_RESULT assert search_result.get("agents") == [self.address_2]
def _register_tac(self) -> None: """ Register on the OEF as a TAC controller agent. :return: None. """ self._oef_msg_id += 1 desc = Description( {"version": self.context.parameters.version_id}, data_model=CONTROLLER_DATAMODEL, ) self.context.logger.info("[{}]: Registering TAC data model".format( self.context.agent_name)) oef_msg = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=self._oef_msg_id, service_description=desc, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) self._registered_desc = desc
def _register_service(self) -> None: """ Register to the OEF Service Directory. :return: None """ strategy = cast(Strategy, self.context.strategy) if strategy.has_service_description(): desc = strategy.get_service_description() self._registered_service_description = desc self._oef_msf_id += 1 msg = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=self._oef_msf_id, service_description=desc, service_id=SERVICE_ID, ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(msg), ) self.context.logger.info( "[{}]: updating car park detection services on OEF.".format( self.context.agent_name))
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( type=OEFMessage.Type.SEARCH_SERVICES, id=request_id, query=search_query_empty_model, ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == []
async def _unregister_agent(self, address: Address, msg_id: int, agent_description: Description) -> None: """ Unregister an agent. :param agent_description: :param address: the address of the service agent to be unregistered. :param msg_id: the message id of the request. :return: None """ async with self._lock: if address not in self.agents: msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=msg_id, operation=OEFMessage.OEFErrorOperation.UNREGISTER_AGENT, ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await self._send(envelope) else: self.agents[address].remove(agent_description) if len(self.agents[address]) == 0: self.agents.pop(address)
def on_oef_error( self, answer_id: int, operation: oef.messages.OEFErrorOperation ) -> None: """ On oef error event handler. :param answer_id: the answer id. :param operation: the error operation. :return: None """ assert self.in_queue is not None assert self.loop is not None try: operation = OEFMessage.OEFErrorOperation(operation) except ValueError: operation = OEFMessage.OEFErrorOperation.OTHER msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=answer_id, operation=operation ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=self.address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) asyncio.run_coroutine_threadsafe( self.in_queue.put(envelope), self.loop ).result()
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( type=OEFMessage.Type.REGISTER_SERVICE, id=1, service_description=desc, service_id="", ) msg_bytes = OEFSerializer().encode(msg) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) ) time.sleep(0.5) search_request = OEFMessage( type=OEFMessage.Type.SEARCH_SERVICES, id=2, query=Query( [Constraint("bar", ConstraintType("==", 1))], model=foo_datamodel ), ) self.multiplexer.put( Envelope( to=DEFAULT_OEF, sender=self.crypto1.address, 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") == 2 if search_result.get("agents") != [self.crypto1.address]: logger.warning( 'search_result.get("agents") != [self.crypto1.address] FAILED in test_oef/test_communication.py' )
async def test_send_oef_message(network_node): """Test the send oef message.""" address = FetchAICrypto().address oef_connection = OEFConnection( address=address, oef_addr="127.0.0.1", oef_port=10000, connection_id=PublicId("fetchai", "oef", "0.1.0"), ) oef_connection.loop = asyncio.get_event_loop() await oef_connection.connect() msg = OEFMessage( type=OEFMessage.Type.OEF_ERROR, id=0, operation=OEFMessage.OEFErrorOperation.SEARCH_AGENTS, ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=address, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) with pytest.raises(ValueError): await oef_connection.send(envelope) data_model = DataModel("foobar", attributes=[]) query = Query(constraints=[], model=data_model) msg = OEFMessage(type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=query) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=address, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) await oef_connection.send(envelope) search_result = await oef_connection.receive() assert isinstance(search_result, Envelope) await asyncio.sleep(2.0) await oef_connection.disconnect()
def _unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ registration = cast(Registration, self.context.registration) if registration.registered_goods_demanded_description is not None: oef_msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=registration.get_next_id(), service_description=registration. registered_goods_demanded_description, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) registration.registered_goods_demanded_description = None if registration.registered_goods_supplied_description is not None: oef_msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=registration.get_next_id(), service_description=registration. registered_goods_supplied_description, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) registration.registered_goods_supplied_description = None
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( type=OEFMessage.Type.REGISTER_SERVICE, id=1, service_description=desc, service_id="", ) msg_bytes = OEFSerializer().encode(msg) assert len(msg_bytes) > 0
def decode(self, obj: bytes) -> Message: """ Decode the message. :param obj: the bytes object :return: the message """ json_msg = json.loads(obj.decode("utf-8")) oef_type = OEFMessage.Type(json_msg["type"]) oef_id = json_msg["id"] new_body = copy.copy(json_msg) if oef_type in { OEFMessage.Type.REGISTER_SERVICE, OEFMessage.Type.UNREGISTER_SERVICE, }: service_description_bytes = base64.b64decode( json_msg["service_description"]) service_description = pickle.loads( service_description_bytes) # nosec new_body["service_description"] = service_description elif oef_type in { OEFMessage.Type.REGISTER_AGENT, OEFMessage.Type.UNREGISTER_AGENT, }: agent_description_bytes = base64.b64decode( json_msg["agent_description"]) agent_description = pickle.loads(agent_description_bytes) # nosec new_body["agent_description"] = agent_description elif oef_type in { OEFMessage.Type.SEARCH_SERVICES, OEFMessage.Type.SEARCH_AGENTS, }: query_bytes = base64.b64decode(json_msg["query"]) query = pickle.loads(query_bytes) # nosec new_body["query"] = query elif oef_type in {OEFMessage.Type.SEARCH_RESULT}: new_body["agents"] = list(json_msg["agents"]) elif oef_type in {OEFMessage.Type.OEF_ERROR}: operation = json_msg["operation"] new_body["operation"] = OEFMessage.OEFErrorOperation( int(operation)) oef_message = OEFMessage(type=oef_type, id=oef_id, body=new_body) return oef_message
def act(self) -> None: """ Implement the act. :return: None """ strategy = cast(Strategy, self.context.strategy) if strategy.is_searching: query = strategy.get_service_query() search_id = strategy.get_next_search_id() oef_msg = OEFMessage(type=OEFMessage.Type.SEARCH_SERVICES, id=search_id, query=query) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), )
def test_oef_message_consistency(): """Tests the consistency of an OEFMessage.""" 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( type=OEFMessage.Type.REGISTER_AGENT, id=0, agent_description=description_foobar, agent_id="address", ) with mock.patch.object(OEFMessage.Type, "__eq__", return_value=False): assert not msg._is_consistent()
def _unregister_tac(self) -> None: """ Unregister from the OEF as a TAC controller agent. :return: None. """ self._oef_msg_id += 1 self.context.logger.info("[{}]: Unregistering TAC data model".format( self.context.agent_name)) oef_msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=self._oef_msg_id, service_description=self._registered_desc, service_id="", ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(oef_msg), ) self._registered_desc = None
def setup_class(cls): """Set up the test.""" cls.node = LocalNode() cls.node.start() cls.address_1 = "address" cls.multiplexer = Multiplexer( [ OEFLocalConnection( cls.address_1, cls.node, connection_id=PublicId("fetchai", "local", "0.1.0"), ) ] ) cls.multiplexer.connect() # register a service. request_id = 1 service_id = "" cls.data_model = DataModel("foobar", attributes=[]) service_description = Description( {"foo": 1, "bar": "baz"}, data_model=cls.data_model ) register_service_request = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=request_id, service_description=service_description, service_id=service_id, ) msg_bytes = OEFSerializer().encode(register_service_request) envelope = Envelope( to=DEFAULT_OEF, sender=cls.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) cls.multiplexer.put(envelope)
def on_search_result(self, search_id: int, agents: List[Address]) -> None: """ On accept event handler. :param search_id: the search id. :param agents: the list of agents. :return: None """ assert self.in_queue is not None assert self.loop is not None msg = OEFMessage( type=OEFMessage.Type.SEARCH_RESULT, id=search_id, agents=agents ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=self.address, sender=DEFAULT_OEF, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) asyncio.run_coroutine_threadsafe( self.in_queue.put(envelope), self.loop ).result()
def _unregister_service(self) -> None: """ Unregister service from OEF Service Directory. :return: None """ if self._registered_service_description is not None: self._oef_msf_id += 1 msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_SERVICE, id=self._oef_msf_id, service_description=self._registered_service_description, service_id=SERVICE_ID, ) self.context.outbox.put_message( to=DEFAULT_OEF, sender=self.context.agent_address, protocol_id=OEFMessage.protocol_id, message=OEFSerializer().encode(msg), ) self.context.logger.info( "[{}]: unregistering car park detection services from OEF.". format(self.context.agent_name)) self._registered_service_description = None
def test_search_agent(self): """Test the registered agents, we will not find any.""" data_model = DataModel("foobar", attributes=[]) agent_description = Description({"foo": 1, "bar": "baz"}, data_model=data_model) query = Query(constraints=[], model=data_model) # Register an agent msg = OEFMessage( type=OEFMessage.Type.REGISTER_AGENT, id=0, agent_description=agent_description, agent_id="Test_agent", ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) self.multiplexer1.put(envelope) time.sleep(0.1) # Search for the register agent msg = OEFMessage(type=OEFMessage.Type.SEARCH_AGENTS, id=0, query=query) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_2, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) self.multiplexer2.put(envelope) # check the result response_envelope = self.multiplexer2.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 len(result.get("agents")) == 1, "There are registered agents!" # Send unregister message. msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_AGENT, id=0, agent_description=agent_description, agent_id="Test_agent", ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) self.multiplexer1.put(envelope) time.sleep(0.1) # Trigger error message. msg = OEFMessage( type=OEFMessage.Type.UNREGISTER_AGENT, id=0, agent_description=agent_description, agent_id="Unknown_Agent", ) msg_bytes = OEFSerializer().encode(msg) envelope = Envelope( to=DEFAULT_OEF, sender=self.address_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
def setup_class(cls): """Set up the test.""" cls.node = LocalNode() cls.node.start() cls.address_1 = "multiplexer1" cls.address_2 = "multiplexer2" cls.multiplexer1 = Multiplexer( [ OEFLocalConnection( cls.address_1, cls.node, connection_id=PublicId("fetchai", "local", "0.1.0"), ) ] ) cls.multiplexer2 = Multiplexer( [ OEFLocalConnection( cls.address_2, cls.node, connection_id=PublicId("fetchai", "local", "0.1.0"), ) ] ) cls.multiplexer1.connect() cls.multiplexer2.connect() # register 'multiplexer1' as a service 'foobar'. request_id = 1 service_id = "" cls.data_model_foobar = DataModel("foobar", attributes=[]) service_description = Description( {"foo": 1, "bar": "baz"}, data_model=cls.data_model_foobar ) register_service_request = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=request_id, service_description=service_description, service_id=service_id, ) msg_bytes = OEFSerializer().encode(register_service_request) envelope = Envelope( to=DEFAULT_OEF, sender=cls.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) cls.multiplexer1.put(envelope) time.sleep(1.0) # register 'multiplexer2' as a service 'barfoo'. cls.data_model_barfoo = DataModel("barfoo", attributes=[]) service_description = Description( {"foo": 1, "bar": "baz"}, data_model=cls.data_model_barfoo ) register_service_request = OEFMessage( type=OEFMessage.Type.REGISTER_SERVICE, id=request_id, service_description=service_description, service_id=service_id, ) msg_bytes = OEFSerializer().encode(register_service_request) envelope = Envelope( to=DEFAULT_OEF, sender=cls.address_2, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) cls.multiplexer2.put(envelope) # unregister multiplexer1 data_model = DataModel("foobar", attributes=[]) service_description = Description( {"foo": 1, "bar": "baz"}, data_model=data_model ) msg = OEFMessage( 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=cls.address_1, protocol_id=OEFMessage.protocol_id, message=msg_bytes, ) cls.multiplexer1.put(envelope)