Commit f526191c79bac2745cdea70f7097697cad0cb22e
1 parent
9b04b9bd
Exists in
dev
Command (non running) exception should not stop agent
Showing
5 changed files
with
99 additions
and
18 deletions
Show diff stats
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
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 | ... | ... |