From b7c6e890c038aadcc7d147594a870a2a299e5692 Mon Sep 17 00:00:00 2001 From: Etienne Pallier Date: Wed, 12 Oct 2022 17:00:22 +0200 Subject: [PATCH] Test de tous les cas d'erreur possibles dans AgentBasic --- privatedev/plugin/agent/AgentBasic.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ src/core/pyros_django/agent/Agent.py | 72 +++++++++++++----------------------------------------------------------- src/core/pyros_django/agent/AgentBasic.py | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++++------------------ 3 files changed, 123 insertions(+), 95 deletions(-) diff --git a/privatedev/plugin/agent/AgentBasic.py b/privatedev/plugin/agent/AgentBasic.py index dc243f2..a824cd4 100755 --- a/privatedev/plugin/agent/AgentBasic.py +++ b/privatedev/plugin/agent/AgentBasic.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 +import time import sys ##import utils.Logger as L @@ -24,7 +25,7 @@ class AgentBasic(Agent): # Run the assertion tests at the end TEST_WITH_FINAL_TEST = False #TEST_MAX_DURATION_SEC = None - TEST_MAX_DURATION_SEC = 100 + TEST_MAX_DURATION_SEC = 180 # Who should I send commands to ? TEST_COMMANDS_DEST = "myself" #TEST_COMMANDS_DEST = "AgentB" @@ -36,7 +37,7 @@ class AgentBasic(Agent): ("do_specific10", 10, 0), #("set_specific2", 5, 0), ("do_specific30", 3, 0), - ####("existing_but_unimplemented_cmd", 3, 0), + ("existing_but_unimplemented_cmd", 3, 0), ] # @override @@ -46,28 +47,66 @@ class AgentBasic(Agent): #("self do_stop now", 200, '', Agent.CMD_STATUS.CMD_EXECUTED), # do_stop + #("self do_stop now", 200, 'STOPPING now', Agent.CMD_STATUS.CMD_EXECUTED), #("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), #("self do_stop asap", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + # do_restart + ("self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), - #("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: existing_but_unimplemented_cmd', Agent.CMD_STATUS.CMD_EXEC_ERROR), - ("self get_specific_cmds", 200, 'do_specific10(arg1:int,arg2:int,arg3:float,arg4:str,arg5:typing.Tuple[int, str, int],arg6:typing.List[int]);do_specific30()', Agent.CMD_STATUS.CMD_EXECUTED), - ("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + #("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + # ------------------------------ + # ------ A - ERROR CASES ------- + # ------------------------------ - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', None), - - # bad parameters (missing or too many, or bad type)=> CMD_INVALID - ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID), - - # bad command => CMD_INVALID + # - Error case 1 - unimplemented command in agent specific commands list + # get_specific_cmds KO (with existing_but_unimplemented_cmd) + ("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: existing_but_unimplemented_cmd', Agent.CMD_STATUS.CMD_EXEC_ERROR), + # get_specific_cmds OK (all commands implemented) + #("self get_specific_cmds", 200, 'do_specific10(arg1:int,arg2:int,arg3:float,arg4:str,arg5:typing.Tuple[int, str, int],arg6:typing.List[int]);do_specific30()', Agent.CMD_STATUS.CMD_EXECUTED), + + # - Error case 2 - CMD_INVALID + # unknwon command ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN), ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_INVALID), - - # Existing but unimplemented cmd => CMD_UNIMPLEMENTED + # bad parameters (missing or too many, or bad type) + # missing args + ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # missing args + ("self do_specific10 2", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # - too many args + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # - bad type + ("self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # - OK + #("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), + + # - Error case 3 - CMD_UNIMPLEMENTED ("self existing_but_unimplemented_cmd", 200, '', Agent.CMD_STATUS.CMD_UNIMPLEMENTED), + # - Error case 4 - CMD_EXPIRED + # This command has a validity of 0s and thus should be tagged as "expired" + ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), + + # - Error case 5 - CMD_SKIPPED + # a) In mode ROUTINE, SPECIFIC commands should be skipped as the agent is not ATTENTIVE + ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), + # b) Back to mode ATTENTIVE, SPECIFIC commands should be executed + ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), + + # ------------------------------ + # ------ B - NORMAL CASES ------- + # ------------------------------ + + # do_restart => #iteration should restart at 1 (so at least it should be <= 4) + #("self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), + # FIXME: ajouter la possibilité d'utiliser des expressions pour tester le résultat : + #("self get_iteration_number", 200, 'EXPR:<=4', Agent.CMD_STATUS.CMD_EXECUTED), + # 1) First, 3 EXCEPTION CASES (uncomment to activate exception) # Each of these lines will stop execution with an exception # ------------------------------------------------------------ @@ -89,10 +128,6 @@ class AgentBasic(Agent): # All these commands should be executed without error, from the 1st to the last one # ------------------------------- - # This command has a validity of 0s and thus should be tagged as "expired" - ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), - # ("self set_mode ATTENTIVE", 0, "MODE = ATTENTIVE", AgentCmd.CMD_STATUS_CODES), - # Agent general command ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), ("self get_mode", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), @@ -100,7 +135,8 @@ class AgentBasic(Agent): ("self get_mode", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), # End test - ("self do_stop asap", 200, None, Agent.CMD_STATUS.CMD_EXECUTED), + ("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + ] @@ -141,6 +177,7 @@ class AgentBasic(Agent): # @override def main_loop_end(self): + self.sleep(3) print("AgentBasic LOOP END"); # @override diff --git a/src/core/pyros_django/agent/Agent.py b/src/core/pyros_django/agent/Agent.py index c2559f4..b7d365b 100755 --- a/src/core/pyros_django/agent/Agent.py +++ b/src/core/pyros_django/agent/Agent.py @@ -397,9 +397,9 @@ class Agent: # # - validity : the command is valid for this duration, afterwards you can forget it # - # - expected_res : the expected result + # - expected_res : the expected result (set to None if not to be tested) # - # - expected_status : the status of the command expected after execution (expired, killed, skipped, executed...) + # - expected_status : the status of the command expected after execution (expired, killed, skipped, executed...) (set to None if not to be tested) # # Ex : # - "AgentScheduler set_state ATTENTIVE" => means to send the command "set_state ATTENTIVE" to the agent AgentScheduler @@ -407,7 +407,7 @@ class Agent: # - "self set_state ATTENTIVE" => means to send the command "set_state ATTENTIVE" to MYSELF # - "self do_restart_loop" => means to send the command "do_restart_loop" to MYSELF (no args) # - TEST_COMMANDS_LIST: List[ Tuple[ str, int, str, Union[int,None] ] ] = [ + TEST_COMMANDS_LIST: List[ Tuple[ str, int, Union[str,None], Union[int,None] ] ] = [ # Format : ("self cmd_name cmd_args", timeout, "expected_result", expected_status), #("self do_stop now", 200, '15.5', None), @@ -1092,6 +1092,8 @@ class Agent: if cmd.name != "get_specific_cmds": cmd.set_as_unimplemented("EXCEPTION: command known but unimplemented") elif type(e) in (CmdBadArgsException, CmdUnknownException): + # set back to "pending" if ever was wrongly marked "running" + #cmd.set_as_pending() cmd.set_as_invalid("EXCEPTION: command unknown or bad args") # Execution Exception elif type(e) != CmdExecErrorException: @@ -1184,7 +1186,7 @@ class Agent: # To be overriden by subclass (AgentDevice) - def process_device_level_cmd(self): + def process_device_level_cmd(self, cmd): pass ''' log.info("(DEVICE LEVEL CMD)") @@ -1247,51 +1249,11 @@ class Agent: if self._is_agent_general_cmd(cmd): try: self._process_agent_general_cmd(cmd) - except CmdUnimplementedException as e: - #print(e) - #cmd.set_as_skipped("ERROR: Unimplemented Agent General command") - #self._cleanup_before_exist() - # This exception is managed at higher level : - raise - #except ValueError as e: - except CmdBadArgsException as e: - #print(e) - #cmd.set_as_skipped("ERROR: Bad Argument(s)") - #self._cleanup_before_exit() - # This exception is managed at higher level : + except (CmdUnimplementedException, CmdBadArgsException) : + # cmd should not be set as "running" + cmd.set_as_pending() + # These exceptions are managed at higher level : raise - #raise AgentCmdBadArgsException(cmd.name) - # Must I stop or restart ? - # cmd.args => ['arg1','arg2',...] - #print("nom", cmd.name) - ''' - if cmd.name=="do_stop": - # by default = "asap" - if cmd.args is None: cmd.full_name = "do_exit" - else: - arg = cmd.args[0] - if arg =='asap': cmd.full_name = "do_exit" - elif arg =='now': cmd.full_name = "do_abort" - else: raise CmdBadArgsException(cmd) - ''' - #print("nom", cmd.name) - #print(self.get_specific_cmds()) - #exit(0) - #if cmd.name in ('do_restart','do_exit','do_abort') : - ''' - if cmd.name in ('do_restart','do_stop'): - #print(cmd) - self.DO_MAIN_LOOP = False - if cmd.name == 'do_abort': - self._abort_current_running_cmd_if_exists() - self._cleanup_before_exit() - if cmd.name != 'do_restart': - self.DO_RESTART_LOOP = False - self._set_status(self.AGT_STATUS.EXITING) - # log last agent mode & status - self._log_agent_state() - #cmd.set_result('EXITING') - ''' return cmd # CASE 2 - AGENT SPECIFIC command @@ -1306,16 +1268,8 @@ class Agent: #self._exec_agent_cmd(cmd) #except AttributeError as e: except (CmdUnimplementedException, CmdBadArgsException) as e: - ##print(e) - #self.log_e(f"EXCEPTION: Agent level specific command '{cmd.name}' unknown (not implemented as a function) :", e) - #self.log_e("Thus => I ignore this command...") - ##log.error(f"EXCEPTION: Agent specific command '{cmd.name}' unknown (not implemented as a function) :", e) - #log.e("Thus => I ignore this command...") - #cmd.set_result("ERROR: UNIMPLEMENTED AGENT SPECIFIC COMMAND", False) + # cmd should not be set as "running" #cmd.set_as_pending() - ##cmd.set_as_skipped("ERROR: UNIMPLEMENTED AGENT SPECIFIC COMMAND") - ##self._cleanup_before_exit() - ##raise AgentCmdUnimplementedException(cmd.name) # These exceptions are managed at higher level : raise return cmd @@ -2496,7 +2450,7 @@ class Agent: log.debug(cmd.result) log.debug(self._cmdts.expected_res) ##if cmd.is_executed() and self._cmdts.expected_res: - if cmd.is_finished() and self._cmdts.expected_res: + if cmd.is_finished() and self._cmdts.expected_res is not None: actual=str(cmd.result) expected=self._cmdts.expected_res #print(actual, ' <= vs =>', expected) @@ -2505,7 +2459,7 @@ class Agent: log.debug(cmd.state) log.debug(self._cmdts.expected_status) #if hasattr(self._cmdts,'expected_status'): - if self._cmdts.expected_status: + if self._cmdts.expected_status is not None: #assert(cmd.state == self._cmdts.expected_status) actual=cmd.state expected=self._cmdts.expected_status diff --git a/src/core/pyros_django/agent/AgentBasic.py b/src/core/pyros_django/agent/AgentBasic.py index dc243f2..a824cd4 100755 --- a/src/core/pyros_django/agent/AgentBasic.py +++ b/src/core/pyros_django/agent/AgentBasic.py @@ -1,6 +1,7 @@ #!/usr/bin/env python3 +import time import sys ##import utils.Logger as L @@ -24,7 +25,7 @@ class AgentBasic(Agent): # Run the assertion tests at the end TEST_WITH_FINAL_TEST = False #TEST_MAX_DURATION_SEC = None - TEST_MAX_DURATION_SEC = 100 + TEST_MAX_DURATION_SEC = 180 # Who should I send commands to ? TEST_COMMANDS_DEST = "myself" #TEST_COMMANDS_DEST = "AgentB" @@ -36,7 +37,7 @@ class AgentBasic(Agent): ("do_specific10", 10, 0), #("set_specific2", 5, 0), ("do_specific30", 3, 0), - ####("existing_but_unimplemented_cmd", 3, 0), + ("existing_but_unimplemented_cmd", 3, 0), ] # @override @@ -46,28 +47,66 @@ class AgentBasic(Agent): #("self do_stop now", 200, '', Agent.CMD_STATUS.CMD_EXECUTED), # do_stop + #("self do_stop now", 200, 'STOPPING now', Agent.CMD_STATUS.CMD_EXECUTED), #("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), #("self do_stop asap", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + # do_restart + ("self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), - #("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: existing_but_unimplemented_cmd', Agent.CMD_STATUS.CMD_EXEC_ERROR), - ("self get_specific_cmds", 200, 'do_specific10(arg1:int,arg2:int,arg3:float,arg4:str,arg5:typing.Tuple[int, str, int],arg6:typing.List[int]);do_specific30()', Agent.CMD_STATUS.CMD_EXECUTED), - ("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + #("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + # ------------------------------ + # ------ A - ERROR CASES ------- + # ------------------------------ - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', None), - - # bad parameters (missing or too many, or bad type)=> CMD_INVALID - ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID), - - # bad command => CMD_INVALID + # - Error case 1 - unimplemented command in agent specific commands list + # get_specific_cmds KO (with existing_but_unimplemented_cmd) + ("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: existing_but_unimplemented_cmd', Agent.CMD_STATUS.CMD_EXEC_ERROR), + # get_specific_cmds OK (all commands implemented) + #("self get_specific_cmds", 200, 'do_specific10(arg1:int,arg2:int,arg3:float,arg4:str,arg5:typing.Tuple[int, str, int],arg6:typing.List[int]);do_specific30()', Agent.CMD_STATUS.CMD_EXECUTED), + + # - Error case 2 - CMD_INVALID + # unknwon command ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN), ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_INVALID), - - # Existing but unimplemented cmd => CMD_UNIMPLEMENTED + # bad parameters (missing or too many, or bad type) + # missing args + ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # missing args + ("self do_specific10 2", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # - too many args + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # - bad type + ("self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '', Agent.CMD_STATUS.CMD_INVALID), + # - OK + #("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), + + # - Error case 3 - CMD_UNIMPLEMENTED ("self existing_but_unimplemented_cmd", 200, '', Agent.CMD_STATUS.CMD_UNIMPLEMENTED), + # - Error case 4 - CMD_EXPIRED + # This command has a validity of 0s and thus should be tagged as "expired" + ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), + + # - Error case 5 - CMD_SKIPPED + # a) In mode ROUTINE, SPECIFIC commands should be skipped as the agent is not ATTENTIVE + ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), + # b) Back to mode ATTENTIVE, SPECIFIC commands should be executed + ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), + + # ------------------------------ + # ------ B - NORMAL CASES ------- + # ------------------------------ + + # do_restart => #iteration should restart at 1 (so at least it should be <= 4) + #("self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), + # FIXME: ajouter la possibilité d'utiliser des expressions pour tester le résultat : + #("self get_iteration_number", 200, 'EXPR:<=4', Agent.CMD_STATUS.CMD_EXECUTED), + # 1) First, 3 EXCEPTION CASES (uncomment to activate exception) # Each of these lines will stop execution with an exception # ------------------------------------------------------------ @@ -89,10 +128,6 @@ class AgentBasic(Agent): # All these commands should be executed without error, from the 1st to the last one # ------------------------------- - # This command has a validity of 0s and thus should be tagged as "expired" - ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), - # ("self set_mode ATTENTIVE", 0, "MODE = ATTENTIVE", AgentCmd.CMD_STATUS_CODES), - # Agent general command ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), ("self get_mode", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), @@ -100,7 +135,8 @@ class AgentBasic(Agent): ("self get_mode", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), # End test - ("self do_stop asap", 200, None, Agent.CMD_STATUS.CMD_EXECUTED), + ("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), + ] @@ -141,6 +177,7 @@ class AgentBasic(Agent): # @override def main_loop_end(self): + self.sleep(3) print("AgentBasic LOOP END"); # @override -- libgit2 0.21.2