def test_on_register(self): """Test the _on_register method of the tac handler, the successful case.""" # setup self.game._phase = Phase.GAME_REGISTRATION incoming_message = self.build_incoming_message( message_type=TacMessage, performative=TacMessage.Performative.REGISTER, dialogue_reference=Dialogues.new_self_initiated_dialogue_reference( ), agent_name=self.agent_name, ) # before assert self.game.registration.nb_agents == 0 # operation with patch.object(self.tac_handler.context.logger, "log") as mock_logger: self.tac_handler.handle(incoming_message) # after mock_logger.assert_any_call(logging.INFO, f"agent registered: '{self.agent_name}'") assert self.game.registration.nb_agents == 1
def test_on_register_agent_name_already_exists(self): """Test the _on_register method of the tac handler where the agent name of the sender is already registered.""" # setup self.game._phase = Phase.GAME_REGISTRATION self.game._registration.register_agent("some_address", self.agent_name) incoming_message = self.build_incoming_message( message_type=TacMessage, performative=TacMessage.Performative.REGISTER, dialogue_reference=Dialogues.new_self_initiated_dialogue_reference( ), agent_name=self.agent_name, ) # operation with patch.object(self.tac_handler.context.logger, "log") as mock_logger: self.tac_handler.handle(incoming_message) # after mock_logger.assert_any_call( logging.WARNING, f"agent with this name already registered: '{self.agent_name}'", ) self.assert_quantity_in_outbox(1) has_attributes, error_str = self.message_has_attributes( actual_message=self.get_message_from_outbox(), message_type=TacMessage, performative=TacMessage.Performative.TAC_ERROR, to=COUNTERPARTY_ADDRESS, sender=self.skill.skill_context.agent_address, target=incoming_message.message_id, error_code=TacMessage.ErrorCode.AGENT_NAME_ALREADY_REGISTERED, ) assert has_attributes, error_str
def test_on_register_agent_not_in_whitelist(self): """Test the _on_register method of the tac handler where the agent is NOT in the whitelist.""" # setup self.game._phase = Phase.GAME_REGISTRATION self.parameters._whitelist = ["some_other_agent", "yet_another_agent"] incoming_message = self.build_incoming_message( message_type=TacMessage, performative=TacMessage.Performative.REGISTER, dialogue_reference=Dialogues.new_self_initiated_dialogue_reference( ), agent_name=self.agent_name, ) # operation with patch.object(self.tac_handler.context.logger, "log") as mock_logger: self.tac_handler.handle(incoming_message) # after mock_logger.assert_any_call( logging.WARNING, f"agent name not in whitelist: '{self.agent_name}'") self.assert_quantity_in_outbox(1) has_attributes, error_str = self.message_has_attributes( actual_message=self.get_message_from_outbox(), message_type=TacMessage, performative=TacMessage.Performative.TAC_ERROR, to=COUNTERPARTY_ADDRESS, sender=self.skill.skill_context.agent_address, target=incoming_message.message_id, error_code=TacMessage.ErrorCode.AGENT_NAME_NOT_IN_WHITELIST, ) assert has_attributes, error_str
def test_handle_cfp_is_matching_supply(self): """Test the _handle_cfp method of the fipa handler where is_matching_supply is True.""" # setup proposal = Description({ "ledger_id": "some_ledger_id", "price": 100, "currency_id": "FET", "service_id": "some_service_id", "quantity": 1, "tx_nonce": "some_tx_nonce", }) terms = "some_terms" data = {"data_type": "data"} incoming_message = self.build_incoming_message( message_type=FipaMessage, performative=FipaMessage.Performative.CFP, dialogue_reference=Dialogues.new_self_initiated_dialogue_reference( ), query="some_query", ) # operation with patch.object( self.strategy, "is_matching_supply", return_value=True, ): with patch.object( self.strategy, "generate_proposal_terms_and_data", return_value=(proposal, terms, data), ): with patch.object(self.fipa_handler.context.logger, "log") as mock_logger: self.fipa_handler.handle(incoming_message) # after mock_logger.assert_any_call( logging.INFO, f"received CFP from sender={COUNTERPARTY_ADDRESS[-5:]}") mock_logger.assert_any_call( logging.INFO, f"sending a PROPOSE with proposal={proposal.values} to sender={COUNTERPARTY_ADDRESS[-5:]}", ) self.assert_quantity_in_outbox(1) has_attributes, error_str = self.message_has_attributes( actual_message=self.get_message_from_outbox(), message_type=FipaMessage, performative=FipaMessage.Performative.PROPOSE, to=COUNTERPARTY_ADDRESS, sender=self.skill.skill_context.agent_address, target=incoming_message.message_id, proposal=proposal, ) assert has_attributes, error_str
def build_incoming_message( self, message_type: Type[Message], performative: Message.Performative, dialogue_reference: Optional[Tuple[str, str]] = None, message_id: Optional[int] = None, target: Optional[int] = None, to: Optional[Address] = None, sender: Address = COUNTERPARTY_ADDRESS, **kwargs, ) -> Message: """ Quickly create an incoming message with the provided attributes. For any attribute not provided, the corresponding default value in message is used. :param message_type: the type of the message :param dialogue_reference: the dialogue_reference :param message_id: the message_id :param target: the target :param performative: the performative :param to: the 'to' address :param sender: the 'sender' address :param kwargs: other attributes :return: the created incoming message """ message_attributes = dict() # type: Dict[str, Any] default_dialogue_reference = Dialogues.new_self_initiated_dialogue_reference() dialogue_reference = ( default_dialogue_reference if dialogue_reference is None else dialogue_reference ) message_attributes["dialogue_reference"] = dialogue_reference if message_id is not None: message_attributes["message_id"] = message_id if target is not None: message_attributes["target"] = target message_attributes["performative"] = performative message_attributes.update(kwargs) incoming_message = message_type(**message_attributes) incoming_message.sender = sender incoming_message.to = ( self.skill.skill_context.agent_address if to is None else to ) return incoming_message
def test_handle_cfp_not_is_matching_supply(self): """Test the _handle_cfp method of the fipa handler where is_matching_supply is False.""" # setup incoming_message = self.build_incoming_message( message_type=FipaMessage, performative=FipaMessage.Performative.CFP, dialogue_reference=Dialogues.new_self_initiated_dialogue_reference( ), query="some_query", ) # operation with patch.object(self.strategy, "is_matching_supply", return_value=False): with patch.object(self.fipa_handler.context.logger, "log") as mock_logger: self.fipa_handler.handle(incoming_message) # after mock_logger.assert_any_call( logging.INFO, f"received CFP from sender={COUNTERPARTY_ADDRESS[-5:]}") mock_logger.assert_any_call( logging.INFO, f"declined the CFP from sender={COUNTERPARTY_ADDRESS[-5:]}") self.assert_quantity_in_outbox(1) has_attributes, error_str = self.message_has_attributes( actual_message=self.get_message_from_outbox(), message_type=FipaMessage, performative=FipaMessage.Performative.DECLINE, to=COUNTERPARTY_ADDRESS, sender=self.skill.skill_context.agent_address, target=incoming_message.message_id, ) assert has_attributes, error_str
def test_on_register_not_pre_reg_phase(self): """Test the _on_register method of the tac handler where phase is NOT pre_registration.""" # setup self.game._phase = Phase.PRE_GAME incoming_message = self.build_incoming_message( message_type=TacMessage, performative=TacMessage.Performative.REGISTER, dialogue_reference=Dialogues.new_self_initiated_dialogue_reference( ), agent_name=self.agent_name, ) # operation with patch.object(self.tac_handler.context.logger, "log") as mock_logger: self.tac_handler.handle(incoming_message) # after mock_logger.assert_any_call( logging.WARNING, f"received registration outside of game registration phase: '{incoming_message}'", )
def prepare_skill_dialogue( self, dialogues: Dialogues, messages: Tuple[DialogueMessage, ...], counterparty: Address = COUNTERPARTY_ADDRESS, ) -> Dialogue: """ Quickly create a dialogue. The 'messages' argument is a tuple of DialogueMessages. For every DialogueMessage (performative, contents, is_incoming, target): - if 'is_incoming' is not provided: for the first message it is assumed False (outgoing), for any other message, it is the opposite of the one preceding it. - if 'target' is not provided: for the first message it is assumed 0, for any other message, it is the index of the message before it in the tuple of messages + 1. :param dialogues: a dialogues class :param counterparty: the message_id :param messages: the dialogue_reference :return: the created incoming message """ if len(messages) == 0: raise AEAEnforceError("the list of messages must be positive.") ( performative, contents, message_id, is_incoming, target, ) = self._extract_message_fields(messages[0], index=0, last_is_incoming=True) if is_incoming: # first message from the opponent dialogue_reference = dialogues.new_self_initiated_dialogue_reference() message = self.build_incoming_message( message_type=dialogues.message_class, dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=performative, to=self.skill.skill_context.agent_address, sender=counterparty, **contents, ) dialogue = cast(Dialogue, dialogues.update(message)) if dialogue is None: raise AEAEnforceError( "Cannot update the dialogue with message number {}".format( message_id ) ) else: # first message from self _, dialogue = dialogues.create( counterparty=counterparty, performative=performative, **contents ) for idx, dialogue_message in enumerate(messages[1:]): ( performative, contents, message_id, is_incoming, target, ) = self._extract_message_fields(dialogue_message, idx + 1, is_incoming) if is_incoming: # messages from the opponent dialogue_reference = self._non_initial_incoming_message_dialogue_reference( dialogue ) message = self.build_incoming_message( message_type=dialogues.message_class, dialogue_reference=dialogue_reference, message_id=message_id, target=target, performative=performative, to=self.skill.skill_context.agent_address, sender=counterparty, **contents, ) dialogue = cast(Dialogue, dialogues.update(message)) if dialogue is None: raise AEAEnforceError( "Cannot update the dialogue with message number {}".format( message_id ) ) else: # messages from self dialogue.reply(performative=performative, target=target, **contents) return dialogue