Commit f526191c79bac2745cdea70f7097697cad0cb22e

Authored by Etienne Pallier
1 parent 9b04b9bd
Exists in dev

Command (non running) exception should not stop agent

CHANGELOG
  1 +07-10-2022 (EP): v0.6.0.1
  2 + - Command (non running) exception should not stop agent
  3 +
1 4 06-10-2022 (AKo): v0.6.0.0
2 5 - Change typo in agent_detail, add agent state & mode, disabling button if agent not reachable
3 6 - Adding titles, changes on css of agent detail, fix agentsst sender name
... ...
VERSION
1   -0.6.0.0
2 1 \ No newline at end of file
  2 +0.6.0.1
3 3 \ No newline at end of file
... ...
src/core/pyros_django/agent/Agent.py
... ... @@ -397,7 +397,6 @@ class Agent:
397 397 #("self do_stop now", 200, '15.5', None),
398 398 ("self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '15.5', None),
399 399  
400   -
401 400 # 1) First, 3 EXCEPTION CASES (uncomment to activate exception)
402 401 # Each of these lines will stop execution with an exception
403 402 # ------------------------------------------------------------
... ... @@ -1081,17 +1080,19 @@ class Agent:
1081 1080 log.info("*"*10 + " NEXT COMMAND PROCESSING (START) " + "*"*10 + '\n')
1082 1081 try :
1083 1082 cmd = self._process_next_command_if_exists()
1084   - print(cmd)
  1083 + #print(cmd)
1085 1084 except (AgentCmdUnimplementedException, AgentCmdBadArgsException, UnknownCmdException) as e :
1086 1085 print(e)
1087 1086 log.error(f"EXCEPTION on Agent command '{e.cmd_name}'")
1088 1087 if isinstance(e.cmd, AgentCmd) :
  1088 + cmd = e.cmd
1089 1089 if type(e) is AgentCmdUnimplementedException:
1090   - e.cmd.set_as_unimplemented("EXCEPTION: command known but unimplemented")
  1090 + cmd.set_as_unimplemented("EXCEPTION: command known but unimplemented")
1091 1091 else:
1092   - e.cmd.set_as_invalid("EXCEPTION: command unknown or bad args")
1093   - self._cleanup_before_exit()
1094   - raise
  1092 + cmd.set_as_invalid("EXCEPTION: command unknown or bad args")
  1093 + # Ne pas stopper !!
  1094 + ##self._cleanup_before_exit()
  1095 + ##raise
1095 1096 log.info("*"*10 + " NEXT COMMAND PROCESSING (END) " + "*"*10 + "\n")
1096 1097  
1097 1098 # only if in TEST mode
... ... @@ -1828,6 +1829,7 @@ class Agent:
1828 1829 if not commands.exists():
1829 1830 log.info("<None>")
1830 1831 return None
  1832 +
1831 1833 "Current pending (or running) commands (time ordered):"
1832 1834 AgentCmd.show_commands(commands)
1833 1835  
... ... @@ -2096,7 +2098,7 @@ class Agent:
2096 2098  
2097 2099 # Update read time to say that the command has been READ
2098 2100 #cmd.set_read_time(False)
2099   - cmd.set_as_running()
  2101 + ##cmd.set_as_running()
2100 2102  
2101 2103 log.info("(Agent SPECIFIC cmd)")
2102 2104 # Execute method self."cmd.name"()
... ... @@ -2104,6 +2106,7 @@ class Agent:
2104 2106 try:
2105 2107 res = self._exec_cmd_from_its_name(cmd)
2106 2108 except (AgentCmdUnimplementedException, AgentCmdBadArgsException) as e:
  2109 + ##cmd.set_as_pending()
2107 2110 # These exceptions are managed at higher level :
2108 2111 raise
2109 2112 '''
... ... @@ -2149,7 +2152,7 @@ class Agent:
2149 2152 #print(methodsList)
2150 2153 func = cmd.name
2151 2154 if func not in methods_list: raise AgentCmdUnimplementedException(cmd)
2152   - f = getattr(self, func)
  2155 + ##f = getattr(self, func)
2153 2156 ###print(func, ' => ', signature(f))
2154 2157  
2155 2158 #for arg in cmd.args: print(arg)
... ... @@ -2193,10 +2196,14 @@ class Agent:
2193 2196 #print("evaluated to", type(arg), arg)
2194 2197 #except ValueError as e: newarg = arg
2195 2198 args.append(arg)
  2199 +
  2200 + cmd.set_as_running()
2196 2201 try:
2197 2202 # equivalent to calling self.func(*cmd.args)
2198 2203 return getattr(self, func)(*args)
2199 2204 except (TypeError, AttributeError, ValueError) as e:
  2205 + # set back to PENDING because this command should never has been RUNNING
  2206 + cmd.set_as_pending()
2200 2207 #raise e
2201 2208 # "from None" pour ne pas afficher l'exception AttributeError (car interne)
2202 2209 raise AgentCmdBadArgsException(cmd) from None
... ... @@ -2319,7 +2326,7 @@ class Agent:
2319 2326  
2320 2327 ###
2321 2328 # ================================================================================================
2322   - # AGENT SPECIFIC FUNCTIONS
  2329 + # AGENT SPECIFIC COMMANDS (functions)
2323 2330 # (here just to serve as examples)
2324 2331 # ================================================================================================
2325 2332 ###
... ... @@ -2447,7 +2454,8 @@ class Agent:
2447 2454  
2448 2455 log.debug(cmd.result)
2449 2456 log.debug(self._cmdts.expected_res)
2450   - if cmd.is_executed() and self._cmdts.expected_res:
  2457 + ##if cmd.is_executed() and self._cmdts.expected_res:
  2458 + if cmd.is_finished() and self._cmdts.expected_res:
2451 2459 actual=str(cmd.result)
2452 2460 expected=self._cmdts.expected_res
2453 2461 assert actual==expected, f"Cmd result (='{actual}') is not as expected (='{expected}')"
... ... @@ -2505,7 +2513,8 @@ class Agent:
2505 2513  
2506 2514 # Execution was not completed
2507 2515 #if self._cmdts.is_expired() or self._cmdts.is_skipped() or self._cmdts.is_killed():
2508   - if self._cmdts.is_skipped() or self._cmdts.is_killed():
  2516 + ##if self._cmdts.is_skipped() or self._cmdts.is_killed():
  2517 + if self._cmdts.is_finished_with_error():
2509 2518 log.info("Command was not completed")
2510 2519 # 2 possible scenarios:
2511 2520 # - (1) Send the SAME command again
... ... @@ -2521,7 +2530,7 @@ class Agent:
2521 2530 # - (2) Send next command
2522 2531 #self._cmdts = None
2523 2532  
2524   - # Execution was completeted => get result
  2533 + # Execution was completeted OK => get result
2525 2534 elif self._cmdts.is_executed():
2526 2535 cmdts_res = self._cmdts.get_result()
2527 2536 log.info(f"Cmd executed. Result is '{cmdts_res}'")
... ... @@ -2576,14 +2585,15 @@ class Agent:
2576 2585 assert last_cmd.name == self.TEST_COMMANDS_LIST[-1].split()[1]
2577 2586 assert last_cmd.name == "do_exit"
2578 2587 assert last_cmd.is_executed()
2579   - assert last_cmd.get_result() == "SHOULD BE DONE NOW"
  2588 + ##assert last_cmd.get_result() == "SHOULD BE DONE NOW"
2580 2589  
2581 2590 nb_asserted = 0
2582 2591 nb_agent_general = 0
2583 2592 nb_unknown = 0
2584 2593 nb_unimplemented = 0
2585 2594 for cmd in commands:
2586   - assert cmd.is_executed() or cmd.is_killed() or cmd.is_skipped()
  2595 + ##assert cmd.is_executed() or cmd.is_killed() or cmd.is_skipped()
  2596 + assert cmd.is_finished()
2587 2597 nb_asserted += 1
2588 2598 if cmd.is_agent_general_cmd():
2589 2599 nb_agent_general += 1
... ...
src/core/pyros_django/agent/AgentBasic.py
... ... @@ -10,6 +10,8 @@ import sys
10 10 sys.path.append("../../../..")
11 11 from src.core.pyros_django.agent.Agent import Agent, build_agent
12 12  
  13 +from typing import List, Tuple, Union, Any
  14 +
13 15 ##log = L.setupLogger("AgentXTaskLogger", "AgentX")
14 16  
15 17  
... ... @@ -28,14 +30,32 @@ class AgentBasic(Agent):
28 30 #TEST_COMMANDS_DEST = "AgentB"
29 31 # Scenario to be executed
30 32  
  33 + # @override
  34 + AGENT_SPECIFIC_COMMANDS = [
  35 + # Format : (โ€œcmd_nameโ€, timeout, exec_mode)
  36 + ("do_specific10", 10, 0),
  37 + #("set_specific2", 5, 0),
  38 + ("do_specific30", 3, 0),
  39 + ("existing_but_unimplemented_cmd", 3, 0),
  40 + ]
31 41  
  42 + # @override
32 43 TEST_COMMANDS_LIST = [
33 44  
34 45 # Format : ("self cmd_name cmd_args", timeout, "expected_result", expected_status),
35 46 #("self do_stop now", 200, '', Agent.CMD_STATUS.CMD_EXECUTED),
36   - ("self do_specific1 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', None),
37   -
38   -
  47 + ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', None),
  48 +
  49 + # bad parameters (missing or too many, or bad type)=> CMD_INVALID
  50 + ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID),
  51 +
  52 + # bad command => CMD_INVALID
  53 + ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN),
  54 + ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_INVALID),
  55 +
  56 + # Existing but unimplemented cmd => CMD_UNIMPLEMENTED
  57 + ("self existing_but_unimplemented_cmd", 200, '', Agent.CMD_STATUS.CMD_UNIMPLEMENTED),
  58 +
39 59 # 1) First, 3 EXCEPTION CASES (uncomment to activate exception)
40 60 # Each of these lines will stop execution with an exception
41 61 # ------------------------------------------------------------
... ... @@ -225,6 +245,45 @@ class AgentBasic(Agent):
225 245 return nb_asserted
226 246  
227 247  
  248 + ###
  249 + # ================================================================================================
  250 + # AGENT SPECIFIC COMMANDS (functions)
  251 + # (here just to serve as examples)
  252 + # ================================================================================================
  253 + ###
  254 +
  255 + #def do_specific1(self, arg1:int, arg2:int=2, arg3:int=3) -> int:
  256 + #def do_specific1(self, arg1:int, arg2:int=2, arg3:float=3.1, arg4:list=[1,2,3]) -> float:
  257 +
  258 + def do_specific10(self,
  259 + arg1:int,
  260 + arg2:int,
  261 + arg3:float=3.1,
  262 + arg4:str='toto',
  263 + arg5:Tuple[int,str,int]=(1,'toto',3),
  264 + #arg5:Tuple[int,int,int]=(1,2,3),
  265 + arg6:List[int]=[]
  266 + ) -> float:
  267 + '''
  268 + arg1 = int(arg1)
  269 + arg2 = int(arg2)
  270 + arg3 = float(arg3)
  271 + arg5 = ast.literal_eval(arg5)
  272 + print(arg5[1])
  273 + arg6 = ast.literal_eval(arg6)
  274 + '''
  275 + #print(arg4)
  276 + res = arg1 + arg2 + arg3 + arg5[0] + arg5[2]
  277 + if arg6: res += arg6[0]
  278 + return res
  279 +
  280 + # Undefined specific cmd
  281 + #def set_specific2(self, arg1:str, arg2:int): pass
  282 +
  283 + def do_specific30(self):
  284 + pass
  285 +
  286 +
228 287 """
229 288 =================================================================
230 289 MAIN FUNCTION
... ...
src/core/pyros_django/common/models.py
... ... @@ -968,9 +968,18 @@ class AgentCmd(models.Model):
968 968 def is_running(self):
969 969 return self.state == self.CMD_STATUS_CODES.CMD_RUNNING
970 970  
  971 + # execution finished without error
971 972 def is_executed(self):
972 973 return self.state == self.CMD_STATUS_CODES.CMD_EXECUTED
973 974  
  975 + # Cmd is finished if not pending or running
  976 + def is_finished(self):
  977 + return not (self.is_pending() or self.is_running())
  978 +
  979 + # Cmd is finished with error : finished but NOT executed
  980 + def is_finished_with_error(self):
  981 + return self.is_finished() and not self.is_executed()
  982 +
974 983 def is_skipped(self):
975 984 return self.state == self.CMD_STATUS_CODES.CMD_SKIPPED
976 985  
... ...