Commit 0ddc9733d010523531caf944d24fa474fb1d5042
Exists in
dev
Merge branch 'dev' of https://gitlab.irap.omp.eu/epallier/pyros into dev
Showing
4 changed files
with
224 additions
and
133 deletions
Show diff stats
privatedev/plugin/agent/AgentBasic.py
... | ... | @@ -9,7 +9,7 @@ import sys |
9 | 9 | ##sys.path.append("..") |
10 | 10 | ###from agent.Agent import Agent, build_agent |
11 | 11 | sys.path.append("../../../..") |
12 | -from src.core.pyros_django.agent.Agent import Agent, build_agent | |
12 | +from src.core.pyros_django.agent.Agent import Agent, CmdExceptionExecError, build_agent | |
13 | 13 | |
14 | 14 | from typing import List, Tuple, Union, Any |
15 | 15 | |
... | ... | @@ -37,9 +37,16 @@ class AgentBasic(Agent): |
37 | 37 | ("do_specific10", 10, 0), |
38 | 38 | #("set_specific2", 5, 0), |
39 | 39 | ("do_specific30", 3, 0), |
40 | - ###("existing_but_unimplemented_cmd", 3, 0), | |
40 | + ##("cmd_existing_but_unimplemented", 3, 0), | |
41 | + ("cmd_raising_error_exec", 3, 0) | |
41 | 42 | ] |
42 | 43 | |
44 | + # Deactivate some tests, so that test scenario runs faster during DEV | |
45 | + # on DEV | |
46 | + #COMMIT_ONLY = False | |
47 | + # on commit only | |
48 | + COMMIT_ONLY = True | |
49 | + | |
43 | 50 | # @override |
44 | 51 | TEST_COMMANDS_LIST = [ |
45 | 52 | |
... | ... | @@ -54,52 +61,58 @@ class AgentBasic(Agent): |
54 | 61 | |
55 | 62 | # do_restart |
56 | 63 | |
57 | - ("self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), | |
64 | + (COMMIT_ONLY, "self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), | |
58 | 65 | #("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), |
59 | 66 | |
60 | - # ------------------------------ | |
61 | - # ------ A - ERROR CASES ------- | |
62 | - # ------------------------------ | |
67 | + # ---------------------------------------------------- | |
68 | + # ------ A - ERROR CASES - from PENDING status ------- | |
69 | + # ---------------------------------------------------- | |
63 | 70 | |
64 | 71 | # - Error case 1 - unimplemented command in agent specific commands list |
65 | - # get_specific_cmds KO (with existing_but_unimplemented_cmd) | |
66 | - #("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: existing_but_unimplemented_cmd', Agent.CMD_STATUS.CMD_EXEC_ERROR), | |
72 | + # get_specific_cmds KO (with cmd_existing_but_unimplemented) | |
73 | + ##("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: cmd_existing_but_unimplemented', Agent.CMD_STATUS.CMD_EXEC_ERROR), | |
67 | 74 | # get_specific_cmds OK (all commands implemented) |
68 | - ("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), | |
75 | + (COMMIT_ONLY, " 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();cmd_raising_error_exec()', Agent.CMD_STATUS.CMD_EXECUTED), | |
69 | 76 | |
70 | 77 | # - Error case 2 - CMD_INVALID |
71 | 78 | # unknwon command |
72 | 79 | ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN), |
73 | - ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
80 | + (COMMIT_ONLY, "self cmd_unexisting", 200, 'EXCEPTION on command cmd_unexisting: Unknown command', Agent.CMD_STATUS.CMD_INVALID), | |
74 | 81 | # bad parameters (missing or too many, or bad type) |
75 | 82 | # missing args |
76 | - ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
83 | + (COMMIT_ONLY, "self do_specific10", 200, 'EXCEPTION on command do_specific10: Command has bad, missing, or too many argument(s)', Agent.CMD_STATUS.CMD_INVALID), | |
77 | 84 | # missing args |
78 | - ("self do_specific10 2", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
85 | + (COMMIT_ONLY, "self do_specific10 2 ", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
79 | 86 | # - too many args |
80 | - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
87 | + (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
81 | 88 | # - bad type |
82 | - ("self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
89 | + (COMMIT_ONLY, "self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
83 | 90 | # - OK |
84 | 91 | #("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), |
85 | 92 | |
86 | 93 | # - Error case 3 - CMD_UNIMPLEMENTED |
87 | - ("self existing_but_unimplemented_cmd", 200, '', Agent.CMD_STATUS.CMD_UNIMPLEMENTED), | |
94 | + ##("self cmd_existing_but_unimplemented", 200, None, Agent.CMD_STATUS.CMD_UNIMPLEMENTED), | |
88 | 95 | |
89 | 96 | # - Error case 4 - CMD_EXPIRED |
90 | 97 | # This command has a validity of 0s and thus should be tagged as "expired" |
91 | - ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), | |
98 | + (COMMIT_ONLY, "self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), | |
92 | 99 | |
93 | 100 | # - Error case 5 - CMD_SKIPPED |
94 | 101 | # a) In mode ROUTINE, SPECIFIC commands should be skipped as the agent is not ATTENTIVE |
95 | - ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
96 | - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), | |
102 | + (COMMIT_ONLY, "self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
103 | + (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), | |
97 | 104 | # b) Back to mode ATTENTIVE, SPECIFIC commands should be executed |
98 | - ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
99 | - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), | |
105 | + (COMMIT_ONLY, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
106 | + (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), | |
107 | + | |
108 | + # ---------------------------------------------------- | |
109 | + # ------ B - ERROR CASES - from RUNNING status ------- | |
110 | + # ---------------------------------------------------- | |
111 | + | |
112 | + (True, "self cmd_raising_error_exec", 200, "EXCEPTION on command cmd_raising_error_exec: Error during Execution", Agent.CMD_STATUS.CMD_EXEC_ERROR), | |
100 | 113 | |
101 | 114 | # ------------------------------ |
102 | - # ------ B - NORMAL CASES ------- | |
115 | + # ------ C - NORMAL CASES ------- | |
103 | 116 | # ------------------------------ |
104 | 117 | |
105 | 118 | # do_restart => #iteration should restart at 1 (so at least it should be <= 4) |
... | ... | @@ -129,13 +142,13 @@ class AgentBasic(Agent): |
129 | 142 | # ------------------------------- |
130 | 143 | |
131 | 144 | # Agent general command |
132 | - ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
133 | - ("self get_mode", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
134 | - ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
135 | - ("self get_mode", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
145 | + (COMMIT_ONLY, "self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
146 | + (COMMIT_ONLY, "self get_mode", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
147 | + (COMMIT_ONLY, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
148 | + (COMMIT_ONLY, "self get_mode", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
136 | 149 | |
137 | 150 | # End test |
138 | - ("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), | |
151 | + (True, "self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), | |
139 | 152 | |
140 | 153 | ] |
141 | 154 | |
... | ... | @@ -324,6 +337,9 @@ class AgentBasic(Agent): |
324 | 337 | #def do_specific1(self, arg1:int, arg2:int=2, arg3:int=3) -> int: |
325 | 338 | #def do_specific1(self, arg1:int, arg2:int=2, arg3:float=3.1, arg4:list=[1,2,3]) -> float: |
326 | 339 | |
340 | + def cmd_raising_error_exec(self): | |
341 | + raise CmdExceptionExecError(self.CURRENT_CMD) | |
342 | + | |
327 | 343 | def do_specific10(self, |
328 | 344 | arg1:int, |
329 | 345 | arg2:int, | ... | ... |
src/core/pyros_django/agent/Agent.py
... | ... | @@ -41,7 +41,7 @@ and execute them on reception at each iteration : |
41 | 41 | |
42 | 42 | # For cmd parsing |
43 | 43 | from array import array |
44 | -from typing import List, Tuple, Union, Any | |
44 | +from typing import List, Tuple, Union, Any, Optional | |
45 | 45 | import ast |
46 | 46 | from inspect import signature |
47 | 47 | |
... | ... | @@ -127,6 +127,7 @@ import random |
127 | 127 | import threading |
128 | 128 | #import multiprocessing |
129 | 129 | import time |
130 | +import re | |
130 | 131 | ''' |
131 | 132 | from threading import Thread |
132 | 133 | import socket |
... | ... | @@ -259,9 +260,21 @@ class StoppableThreadEvenWhenSleeping(threading.Thread): |
259 | 260 | class CmdException(Exception): |
260 | 261 | ''' Base class for all Agent command exceptions ''' |
261 | 262 | # pass |
262 | - def __init__( self, cmd: Union[AgentCmd,str] ): | |
263 | + def __init__( self, cmd:Union[AgentCmd,str], msg:str=None): | |
263 | 264 | self.cmd = cmd |
265 | + self._msg = msg | |
264 | 266 | self.cmd_name = cmd if isinstance(cmd,str) else cmd.name |
267 | + @property | |
268 | + def msg(self): | |
269 | + msg = "EXCEPTION on command "+self.cmd_name | |
270 | + return msg if not self._msg else msg+': '+self._msg | |
271 | + # Default message if print exception | |
272 | + def __str__(self): | |
273 | + return self.msg | |
274 | + ''' | |
275 | + msg = "EXCEPTION on command "+self.cmd_name | |
276 | + return msg if not self.msg else msg+': '+self.msg | |
277 | + ''' | |
265 | 278 | ''' |
266 | 279 | def __str__(self): |
267 | 280 | return f"The Agent command '{self.cmd.name}' is unknown to the agent" |
... | ... | @@ -269,41 +282,57 @@ class CmdException(Exception): |
269 | 282 | ''' |
270 | 283 | |
271 | 284 | # --- CMD PENDING (non running) EXCEPTIONS --- |
272 | -class CmdUnknownException(CmdException): | |
285 | + | |
286 | +# @Override | |
287 | +class CmdExceptionUnknown(CmdException): | |
273 | 288 | ''' Raised when a PENDING (non running) Agent (specific) cmd is NOT known by the agent ''' |
274 | - def __str__(self): | |
275 | - return f"The Agent command '{self.cmd_name}' is unknown to the agent" | |
276 | - #return f"({type(self).__name__}): Device Generic command has no implementation in the controller" | |
289 | + # @Override | |
290 | + def __init__( self, cmd, msg:str=None): | |
291 | + super().__init__(cmd, msg if msg else "Unknown command") | |
292 | + #def __str__(self): return self.msg if self.msg else f"The Agent command '{self.cmd_name}' is unknown to the agent" | |
277 | 293 | |
278 | -class CmdUnimplementedException(CmdException): | |
294 | +# @Override | |
295 | +class CmdExceptionUnimplemented(CmdException): | |
279 | 296 | ''' Raised when a PENDING (non running) Agent Specific cmd is known by the agent but not implemented ''' |
280 | - def __str__(self): | |
281 | - return f"The Agent command '{self.cmd_name}' is known by the agent but not implemented" | |
282 | - #return f"({type(self).__name__}): Device Generic command has no implementation in the controller" | |
297 | + # @Override | |
298 | + def __init__( self, cmd, msg:str=None): | |
299 | + super().__init__(cmd, msg if msg else "Command is known by the agent but not implemented") | |
300 | + #def __str__(self): return f"The Agent command '{self.cmd_name}' is known by the agent but not implemented" | |
283 | 301 | |
284 | -class CmdBadArgsException(CmdException): | |
302 | +# @Override | |
303 | +class CmdExceptionBadArgs(CmdException): | |
285 | 304 | ''' Raised when a PENDING (non running) Agent cmd has bad, missing, or too many argument(s) ''' |
286 | - def __str__(self): | |
287 | - return f"The Agent command '{self.cmd_name}' has bad, missing, or too many argument(s)" | |
288 | - #return f"({type(self).__name__}): Device Generic command has no implementation in the controller" | |
305 | + # @Override | |
306 | + def __init__( self, cmd, msg:str=None): | |
307 | + super().__init__(cmd, msg if msg else "Command has bad, missing, or too many argument(s)") | |
308 | + #def __str__(self): return f"The Agent command '{self.cmd_name}' has bad, missing, or too many argument(s)" | |
289 | 309 | |
290 | 310 | |
291 | 311 | # --- CMD RUNNING EXCEPTIONS --- |
292 | 312 | |
293 | -class CmdExecErrorException(CmdException): | |
313 | +# @Override | |
314 | +class CmdExceptionExecError(CmdException): | |
294 | 315 | ''' Raised when a RUNNING Agent cmd has had a running error ''' |
295 | - def __str__(self): | |
296 | - return f"The running Agent command '{self.cmd_name}' has had an error (during execution)" | |
316 | + # @Override | |
317 | + def __init__( self, cmd, msg:str=None): | |
318 | + super().__init__(cmd, msg if msg else "Error during Execution") | |
319 | + #def __str__(self): return f"The running Agent command '{self.cmd_name}' has had an error (during execution)" | |
297 | 320 | |
298 | -class CmdExecTimeoutException(CmdException): | |
321 | +# @Override | |
322 | +class CmdExceptionExecTimeout(CmdException): | |
299 | 323 | ''' Raised when a RUNNING Agent cmd is timeout ''' |
300 | - def __str__(self): | |
301 | - return f"The running Agent command '{self.cmd_name}' is timeout" | |
324 | + # @Override | |
325 | + def __init__( self, cmd, msg:str=None): | |
326 | + super().__init__(cmd, msg if msg else "Execution is TIMEOUT") | |
327 | + #def __str__(self): return f"The running Agent command '{self.cmd_name}' is timeout" | |
302 | 328 | |
303 | -class CmdExecKilledException(CmdException): | |
329 | +# @Override | |
330 | +class CmdExceptionExecKilled(CmdException): | |
304 | 331 | ''' Raised when a RUNNING Agent cmd has been aborted (by another agent) ''' |
305 | - def __str__(self): | |
306 | - return f"The running Agent command '{self.cmd_name}' has been killed (by another agent)" | |
332 | + # @Override | |
333 | + def __init__( self, cmd, msg:str=None): | |
334 | + super().__init__(cmd, msg if msg else "Command was KILLED during Execution (by another agent") | |
335 | + #def __str__(self): return f"The running Agent command '{self.cmd_name}' has been killed (by another agent)" | |
307 | 336 | |
308 | 337 | ### |
309 | 338 | # ================================================================= |
... | ... | @@ -390,6 +419,8 @@ class Agent: |
390 | 419 | # |
391 | 420 | # Format : List of tuples (command, validity, expected_res, expected_status), with : |
392 | 421 | # |
422 | + # - DO_IT : execute this command yes (true) or no (false) ? (yes by default) | |
423 | + | |
393 | 424 | # - command : the format is "recipient cmd args", with : |
394 | 425 | # - recipient : name of the Agent that the command is to be sent to (use "self" to mean himself) |
395 | 426 | # - cmd : the command name |
... | ... | @@ -407,11 +438,12 @@ class Agent: |
407 | 438 | # - "self set_state ATTENTIVE" => means to send the command "set_state ATTENTIVE" to MYSELF |
408 | 439 | # - "self do_restart_loop" => means to send the command "do_restart_loop" to MYSELF (no args) |
409 | 440 | # |
410 | - TEST_COMMANDS_LIST: List[ Tuple[ str, int, Union[str,None], Union[int,None] ] ] = [ | |
441 | + #TEST_COMMANDS_LIST: List[ Tuple[ str, int, Union[str,None], Union[int,None], Optional[bool] ] ] = [ | |
442 | + TEST_COMMANDS_LIST: List[ Tuple[bool, str, int, Optional[str], Optional[int]] ] = [ | |
411 | 443 | |
412 | 444 | # Format : ("self cmd_name cmd_args", timeout, "expected_result", expected_status), |
413 | 445 | #("self do_stop now", 200, '15.5', None), |
414 | - ("self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '15.5', None), | |
446 | + (True, "self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '15.5', None), | |
415 | 447 | |
416 | 448 | # 1) First, 3 EXCEPTION CASES (uncomment to activate exception) |
417 | 449 | # Each of these lines will stop execution with an exception |
... | ... | @@ -435,38 +467,38 @@ class Agent: |
435 | 467 | # ------------------------------- |
436 | 468 | |
437 | 469 | # This command has a validity of 0s and thus should be tagged as "expired" |
438 | - ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", CMD_STATUS.CMD_EXPIRED), | |
470 | + (True, "self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", CMD_STATUS.CMD_EXPIRED), | |
439 | 471 | |
440 | 472 | # Agent general command |
441 | - ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", CMD_STATUS.CMD_EXECUTED), | |
473 | + (True, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", CMD_STATUS.CMD_EXECUTED), | |
442 | 474 | # => should get "ATTENTIVE" |
443 | - ("self get_mode", 100, "MODE is ATTENTIVE", None), | |
475 | + (True, "self get_mode", 100, "MODE is ATTENTIVE", None), | |
444 | 476 | |
445 | 477 | # => should get "7" |
446 | - ("self do_eval 3+5-1", 200, '7', None), | |
478 | + (True, "self do_eval 3+5-1", 200, '7', None), | |
447 | 479 | |
448 | 480 | # END, will not go further |
449 | 481 | #("self do_exit", 2, "STOPPING"), |
450 | 482 | |
451 | 483 | # Agent specific commands => should be executed |
452 | - ("self do_specific3", 200, '', None), | |
453 | - ("self do_exit", 500, "STOPPING", None), | |
454 | - ("self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '15.5', None), | |
484 | + (True, "self do_specific3", 200, '', None), | |
485 | + (True, "self do_exit", 500, "STOPPING", None), | |
486 | + (True, "self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '15.5', None), | |
455 | 487 | |
456 | 488 | |
457 | - ("self set_mode ROUTINE", 200, "MODE is ROUTINE", None), | |
489 | + (True, "self set_mode ROUTINE", 200, "MODE is ROUTINE", None), | |
458 | 490 | # => should get "ROUTINE" |
459 | - ("self get_mode", 200, "MODE is ROUTINE", None), | |
491 | + (True, "self get_mode", 200, "MODE is ROUTINE", None), | |
460 | 492 | # Agent specific command => should be skipped (because not ATTENTIVE) |
461 | - ("self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, "SKIPPED", None), | |
493 | + (True, "self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, "SKIPPED", None), | |
462 | 494 | |
463 | 495 | # From now on, should not run anymore process_before/after |
464 | 496 | # => and should skip next specific commands |
465 | - ("self set_mode IDLE", 200, "MODE is IDLE", None), | |
497 | + (True, "self set_mode IDLE", 200, "MODE is IDLE", None), | |
466 | 498 | # => should get "IDLE" |
467 | - ("self get_mode", 200, "MODE is IDLE", None), | |
499 | + (True, "self get_mode", 200, "MODE is IDLE", None), | |
468 | 500 | # Agent specific command => should be skipped (because not ATTENTIVE) |
469 | - ("self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, 'SKIPPED', None), | |
501 | + (True, "self do_specific1 1 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, 'SKIPPED', None), | |
470 | 502 | |
471 | 503 | # TODO: test priority commands : do_abort, do_flush_cmds, ... |
472 | 504 | # - Stop executing new commands (just let them accumulate) |
... | ... | @@ -483,10 +515,10 @@ class Agent: |
483 | 515 | ##("self do_resume_exec",), |
484 | 516 | |
485 | 517 | # Restart the restart loop (from init()) |
486 | - ("self do_restart", 200, "RESTARTING", None), | |
518 | + (True, "self do_restart", 200, "RESTARTING", None), | |
487 | 519 | |
488 | 520 | # Now stop |
489 | - ("self do_exit", 200, "STOPPING", None), | |
521 | + (True, "self do_exit", 200, "STOPPING", None), | |
490 | 522 | |
491 | 523 | ''' |
492 | 524 | # specific0 not_executed_because_idle |
... | ... | @@ -1082,27 +1114,41 @@ class Agent: |
1082 | 1114 | #print(cmd) |
1083 | 1115 | except ( |
1084 | 1116 | # PENDING (non running) cmd exceptions |
1085 | - CmdUnimplementedException, CmdBadArgsException, CmdUnknownException, | |
1117 | + CmdExceptionUnknown, CmdExceptionUnimplemented, CmdExceptionBadArgs, | |
1086 | 1118 | # RUNNING cmd exceptions |
1087 | - CmdExecErrorException, CmdExecTimeoutException, CmdExecKilledException | |
1119 | + CmdExceptionExecError, CmdExceptionExecKilled, CmdExceptionExecTimeout, | |
1088 | 1120 | ) as e : |
1089 | - #print(e) | |
1090 | - log.error(f"EXCEPTION on Agent command '{e.cmd_name}'") | |
1121 | + print(e) | |
1122 | + log.error(e) | |
1123 | + #log.error(f"EXCEPTION on Agent command '{e.cmd_name}'") | |
1091 | 1124 | if isinstance(e.cmd, AgentCmd) : |
1092 | 1125 | cmd = e.cmd |
1093 | - if type(e) is CmdUnimplementedException: | |
1094 | - if cmd.name != "get_specific_cmds": | |
1095 | - cmd.set_as_unimplemented("EXCEPTION: command known but unimplemented") | |
1096 | - elif type(e) in (CmdBadArgsException, CmdUnknownException): | |
1097 | - # set back to "pending" if ever was wrongly marked "running" | |
1098 | - #cmd.set_as_pending() | |
1099 | - cmd.set_as_invalid("EXCEPTION: command unknown or bad args") | |
1100 | - # Execution Exception | |
1101 | - elif type(e) != CmdExecErrorException: | |
1102 | - cmd.set_result("EXCEPTION: Problem during execution") | |
1126 | + # - Exception from PENGING | |
1127 | + if type(e) in (CmdExceptionUnknown, CmdExceptionUnimplemented, CmdExceptionBadArgs): | |
1128 | + if type(e) is CmdExceptionUnimplemented: | |
1129 | + if cmd.name != "get_specific_cmds": | |
1130 | + cmd.set_as_unimplemented(e.msg) | |
1131 | + #cmd.set_as_unimplemented("EXCEPTION: Command known but unimplemented") | |
1132 | + else: | |
1133 | + # set back to "pending" if ever was wrongly marked "running" | |
1134 | + #cmd.set_as_pending() | |
1135 | + cmd.set_as_invalid(e.msg) | |
1136 | + #cmd.set_as_invalid("EXCEPTION: Command unknown or bad args") | |
1137 | + # - Exception from RUNNING (Execution Exception) | |
1138 | + else: | |
1139 | + if type(e) == CmdExceptionExecError: | |
1140 | + print(e) | |
1141 | + cmd.set_as_exec_error(e.msg) | |
1142 | + print(e) | |
1143 | + #cmd.set_as_exec_error(e.msg if e.msg else "EXCEPTION: Error during execution") | |
1144 | + else: | |
1145 | + #FIXME: S'assurer que cmd.set_as_killed() or cmd.set_as_timeout() a bien รฉtรฉ fait !!! | |
1146 | + cmd.set_result(e.msg) | |
1147 | + #cmd.set_result("EXCEPTION: Problem during execution") | |
1103 | 1148 | # isinstance(e.cmd, str) |
1104 | 1149 | else: |
1105 | - raise Exception("Abnormal error case...") | |
1150 | + raise CmdException(cmd, "EXCEPTION: Abnormal error case...") | |
1151 | + #raise Exception("EXCEPTION: Abnormal error case...") | |
1106 | 1152 | |
1107 | 1153 | |
1108 | 1154 | |
... | ... | @@ -1251,7 +1297,7 @@ class Agent: |
1251 | 1297 | if self._is_agent_general_cmd(cmd): |
1252 | 1298 | try: |
1253 | 1299 | self._process_agent_general_cmd(cmd) |
1254 | - except (CmdUnimplementedException, CmdBadArgsException) : | |
1300 | + except (CmdExceptionUnimplemented, CmdExceptionBadArgs) : | |
1255 | 1301 | # cmd should not be set as "running" |
1256 | 1302 | cmd.set_as_pending() |
1257 | 1303 | # These exceptions are managed at higher level : |
... | ... | @@ -1269,7 +1315,7 @@ class Agent: |
1269 | 1315 | self._process_agent_specific_cmd(cmd) |
1270 | 1316 | #self._exec_agent_cmd(cmd) |
1271 | 1317 | #except AttributeError as e: |
1272 | - except (CmdUnimplementedException, CmdBadArgsException) as e: | |
1318 | + except (CmdExceptionUnimplemented, CmdExceptionBadArgs) as e: | |
1273 | 1319 | # cmd should not be set as "running" |
1274 | 1320 | #cmd.set_as_pending() |
1275 | 1321 | # These exceptions are managed at higher level : |
... | ... | @@ -1291,7 +1337,7 @@ class Agent: |
1291 | 1337 | ##cmd.set_as_skipped("ERROR: INVALID AGENT COMMAND") |
1292 | 1338 | ##self._cleanup_before_exit() |
1293 | 1339 | ##raise UnknownCmdException(cmd.name) |
1294 | - raise CmdUnknownException(cmd) | |
1340 | + raise CmdExceptionUnknown(cmd) | |
1295 | 1341 | |
1296 | 1342 | #print() |
1297 | 1343 | #log.info("*"*10 + " NEXT COMMAND PROCESSING (END) " + "*"*10 + "\n") |
... | ... | @@ -1447,7 +1493,7 @@ class Agent: |
1447 | 1493 | try: |
1448 | 1494 | f = getattr(self, cmd_name) |
1449 | 1495 | except AttributeError: |
1450 | - raise CmdUnimplementedException(cmd_name) from None | |
1496 | + raise CmdExceptionUnimplemented(cmd_name) from None | |
1451 | 1497 | args = signature(f) |
1452 | 1498 | #specific_commands += str(args) |
1453 | 1499 | specific_commands += "(" |
... | ... | @@ -1485,9 +1531,9 @@ class Agent: |
1485 | 1531 | |
1486 | 1532 | def get_status(self): |
1487 | 1533 | return self.status |
1488 | - # @deprecated | |
1534 | + | |
1489 | 1535 | def get_state(self): |
1490 | - return self.get_status() | |
1536 | + return f"MODE {self.get_mode()} ; STATUS {self.get_status()} ; ITERATION #{self._iter_num}" | |
1491 | 1537 | |
1492 | 1538 | def _set_status(self, status:str): |
1493 | 1539 | #self.printd(f"[{status}] (switching from status {self.status})") |
... | ... | @@ -1797,7 +1843,7 @@ class Agent: |
1797 | 1843 | which is relevant to this agent. |
1798 | 1844 | Commands are read in chronological order |
1799 | 1845 | """ |
1800 | - self._set_status(self.AGT_STATUS.IN_GET_NEXT_CMD) | |
1846 | + self._set_and_log_status(self.AGT_STATUS.IN_GET_NEXT_CMD) | |
1801 | 1847 | log.info("Looking for a new command to process (sent by another agent):") |
1802 | 1848 | |
1803 | 1849 | # 1) Get all pending commands for me (return if None) |
... | ... | @@ -2046,12 +2092,12 @@ class Agent: |
2046 | 2092 | |
2047 | 2093 | elif cmd_name == "set_mode": |
2048 | 2094 | #if not cmd_args: raise ValueError() |
2049 | - if not cmd_args: raise CmdBadArgsException(cmd) | |
2095 | + if not cmd_args: raise CmdExceptionBadArgs(cmd) | |
2050 | 2096 | mode = cmd_args[0] |
2051 | 2097 | if mode == "IDLE": self.set_idle() |
2052 | 2098 | elif mode == "ROUTINE": self.set_routine() |
2053 | 2099 | elif mode == "ATTENTIVE": self.set_attentive() |
2054 | - else: raise CmdBadArgsException(cmd) | |
2100 | + else: raise CmdExceptionBadArgs(cmd) | |
2055 | 2101 | #cmd.set_result("I am now " + state) |
2056 | 2102 | result = "MODE is " + mode |
2057 | 2103 | #time.sleep(1) |
... | ... | @@ -2066,7 +2112,7 @@ class Agent: |
2066 | 2112 | |
2067 | 2113 | elif cmd_name == "do_eval": |
2068 | 2114 | #if not cmd_args: raise ValueError() |
2069 | - if not cmd_args: raise CmdBadArgsException(cmd) | |
2115 | + if not cmd_args: raise CmdExceptionBadArgs(cmd) | |
2070 | 2116 | #cmd.set_result(eval(cmd_args)) |
2071 | 2117 | #result = eval(cmd_args) |
2072 | 2118 | result = self.do_eval(cmd_args[0]) |
... | ... | @@ -2075,10 +2121,10 @@ class Agent: |
2075 | 2121 | # CmdUnimplementedException if one specific command (in the list) is unknown |
2076 | 2122 | try: |
2077 | 2123 | result = self.get_specific_cmds() |
2078 | - except CmdUnimplementedException as e: | |
2124 | + except CmdExceptionUnimplemented as e: | |
2079 | 2125 | # raise CmdUnimplementedException("get_specific_cmds.unknown_cmd_name") |
2080 | - cmd.set_as_exec_error("EXCEPTION - One specific cmd is unimplemented: "+e.cmd_name) | |
2081 | - raise CmdExecErrorException(cmd) from None | |
2126 | + #cmd.set_as_exec_error("EXCEPTION - One specific cmd is unimplemented: "+e.cmd_name) | |
2127 | + raise CmdExceptionExecError(cmd, "EXCEPTION - One specific cmd is unimplemented => "+e.cmd_name) from None | |
2082 | 2128 | |
2083 | 2129 | cmd.set_as_processed(result) |
2084 | 2130 | log.info("...Agent level GENERAL cmd has been executed") |
... | ... | @@ -2114,7 +2160,7 @@ class Agent: |
2114 | 2160 | # This can raise an exception (caught by this method caller) |
2115 | 2161 | try: |
2116 | 2162 | res = self._exec_cmd_from_its_name(cmd) |
2117 | - except (CmdUnimplementedException, CmdBadArgsException) as e: | |
2163 | + except (CmdExceptionUnimplemented, CmdExceptionBadArgs) as e: | |
2118 | 2164 | ##cmd.set_as_pending() |
2119 | 2165 | # These exceptions are managed at higher level : |
2120 | 2166 | raise |
... | ... | @@ -2160,7 +2206,7 @@ class Agent: |
2160 | 2206 | methods_list = [method for method in dir(self) if callable(getattr(self, method))] |
2161 | 2207 | #print(methodsList) |
2162 | 2208 | func = cmd.name |
2163 | - if func not in methods_list: raise CmdUnimplementedException(cmd) | |
2209 | + if func not in methods_list: raise CmdExceptionUnimplemented(cmd) | |
2164 | 2210 | ##f = getattr(self, func) |
2165 | 2211 | ###print(func, ' => ', signature(f)) |
2166 | 2212 | |
... | ... | @@ -2188,9 +2234,10 @@ class Agent: |
2188 | 2234 | return getattr(self, func)(*args) |
2189 | 2235 | ''' |
2190 | 2236 | args = [] |
2237 | + print(cmd.args) | |
2191 | 2238 | # Convert all args to their real type |
2192 | 2239 | for arg in cmd.args: |
2193 | - #print(arg) | |
2240 | + print(arg) | |
2194 | 2241 | #try: |
2195 | 2242 | # Evaluate arg only if it is not a word (letters) : |
2196 | 2243 | # - a word like "toto" is not evaluated => stays as is (=str) |
... | ... | @@ -2217,7 +2264,7 @@ class Agent: |
2217 | 2264 | cmd.set_as_pending() |
2218 | 2265 | #raise e |
2219 | 2266 | # "from None" pour ne pas afficher l'exception AttributeError (car interne) |
2220 | - raise CmdBadArgsException(cmd) from None | |
2267 | + raise CmdExceptionBadArgs(cmd) from None | |
2221 | 2268 | #print("I know this specific command but it is not yet implemented : ", func) |
2222 | 2269 | ##tb = sys.exc_info()[2] |
2223 | 2270 | ##raise AgentCmdUnimplementedException(cmd).with_traceback(tb) |
... | ... | @@ -2287,7 +2334,7 @@ class Agent: |
2287 | 2334 | # NOT PRIO |
2288 | 2335 | if what == "noprio": pass |
2289 | 2336 | # Bad arg |
2290 | - raise CmdBadArgsException(self.CURRENT_CMD) | |
2337 | + raise CmdExceptionBadArgs(self.CURRENT_CMD) | |
2291 | 2338 | |
2292 | 2339 | # Stop currently running cmd or routine |
2293 | 2340 | def do_stop_current(self, what:str): |
... | ... | @@ -2297,7 +2344,7 @@ class Agent: |
2297 | 2344 | self.do_stop_current_cmd() |
2298 | 2345 | self.do_stop_current_routine() |
2299 | 2346 | # Bad arg |
2300 | - raise CmdBadArgsException(self.CURRENT_CMD) | |
2347 | + raise CmdExceptionBadArgs(self.CURRENT_CMD) | |
2301 | 2348 | def do_stop_current_cmd(self): |
2302 | 2349 | pass |
2303 | 2350 | def do_stop_current_routine(self): |
... | ... | @@ -2309,7 +2356,7 @@ class Agent: |
2309 | 2356 | def do_stop(self, when:str='asap'): self.do_stop_or_restart(False, when) |
2310 | 2357 | def do_restart(self, when:str='asap'): self.do_stop_or_restart(True, when) |
2311 | 2358 | def do_stop_or_restart(self, restart:bool=False, when:str='asap'): |
2312 | - if when not in ('asap','now','noprio'): raise CmdBadArgsException(self.CURRENT_CMD) | |
2359 | + if when not in ('asap','now','noprio'): raise CmdExceptionBadArgs(self.CURRENT_CMD) | |
2313 | 2360 | # NOT PRIO |
2314 | 2361 | if when == "noprio": |
2315 | 2362 | pass |
... | ... | @@ -2419,13 +2466,14 @@ class Agent: |
2419 | 2466 | |
2420 | 2467 | def _TEST_get_next_command_to_send(self)->AgentCmd: |
2421 | 2468 | #cmd_full_name, validity, res_expected, after_status = next(self.TEST_COMMANDS, (None,None,None,None)) |
2422 | - cmd_full_name, validity, expected_res, expected_status = next(self.TEST_COMMANDS, (None,None,None,None)) | |
2469 | + DO_IT = False | |
2470 | + while not DO_IT: | |
2471 | + DO_IT, cmd_full_name, validity, expected_res, expected_status = next(self.TEST_COMMANDS, (False,None,None,None,None)) | |
2423 | 2472 | #print(expected_final_status) |
2424 | 2473 | #print(cmd_full_name, res_expected) |
2425 | 2474 | #return cmd_name |
2426 | 2475 | if cmd_full_name is None: return None |
2427 | - # Remove excessive spaces | |
2428 | - import re | |
2476 | + # Remove excessive spaces => already done in AgentCmd.create() | |
2429 | 2477 | cmd_full_name = re.sub(r"\s+", " ", cmd_full_name).strip() |
2430 | 2478 | if ' ' not in cmd_full_name: raise Exception('Command is malformed:', cmd_full_name) |
2431 | 2479 | agent_recipient, cmd_name_and_args = cmd_full_name.split(' ', 1) | ... | ... |
src/core/pyros_django/agent/AgentBasic.py
... | ... | @@ -9,7 +9,7 @@ import sys |
9 | 9 | ##sys.path.append("..") |
10 | 10 | ###from agent.Agent import Agent, build_agent |
11 | 11 | sys.path.append("../../../..") |
12 | -from src.core.pyros_django.agent.Agent import Agent, build_agent | |
12 | +from src.core.pyros_django.agent.Agent import Agent, CmdExceptionExecError, build_agent | |
13 | 13 | |
14 | 14 | from typing import List, Tuple, Union, Any |
15 | 15 | |
... | ... | @@ -37,9 +37,16 @@ class AgentBasic(Agent): |
37 | 37 | ("do_specific10", 10, 0), |
38 | 38 | #("set_specific2", 5, 0), |
39 | 39 | ("do_specific30", 3, 0), |
40 | - ###("existing_but_unimplemented_cmd", 3, 0), | |
40 | + ##("cmd_existing_but_unimplemented", 3, 0), | |
41 | + ("cmd_raising_error_exec", 3, 0) | |
41 | 42 | ] |
42 | 43 | |
44 | + # Deactivate some tests, so that test scenario runs faster during DEV | |
45 | + # on DEV | |
46 | + #COMMIT_ONLY = False | |
47 | + # on commit only | |
48 | + COMMIT_ONLY = True | |
49 | + | |
43 | 50 | # @override |
44 | 51 | TEST_COMMANDS_LIST = [ |
45 | 52 | |
... | ... | @@ -54,52 +61,58 @@ class AgentBasic(Agent): |
54 | 61 | |
55 | 62 | # do_restart |
56 | 63 | |
57 | - ("self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), | |
64 | + (COMMIT_ONLY, "self do_restart now", 200, 'RESTARTING now', Agent.CMD_STATUS.CMD_EXECUTED), | |
58 | 65 | #("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), |
59 | 66 | |
60 | - # ------------------------------ | |
61 | - # ------ A - ERROR CASES ------- | |
62 | - # ------------------------------ | |
67 | + # ---------------------------------------------------- | |
68 | + # ------ A - ERROR CASES - from PENDING status ------- | |
69 | + # ---------------------------------------------------- | |
63 | 70 | |
64 | 71 | # - Error case 1 - unimplemented command in agent specific commands list |
65 | - # get_specific_cmds KO (with existing_but_unimplemented_cmd) | |
66 | - #("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: existing_but_unimplemented_cmd', Agent.CMD_STATUS.CMD_EXEC_ERROR), | |
72 | + # get_specific_cmds KO (with cmd_existing_but_unimplemented) | |
73 | + ##("self get_specific_cmds", 200, 'EXCEPTION - One specific cmd is unimplemented: cmd_existing_but_unimplemented', Agent.CMD_STATUS.CMD_EXEC_ERROR), | |
67 | 74 | # get_specific_cmds OK (all commands implemented) |
68 | - ("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), | |
75 | + (COMMIT_ONLY, " 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();cmd_raising_error_exec()', Agent.CMD_STATUS.CMD_EXECUTED), | |
69 | 76 | |
70 | 77 | # - Error case 2 - CMD_INVALID |
71 | 78 | # unknwon command |
72 | 79 | ##FIXME: ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_UNKNOWN), |
73 | - ("self unexisting_cmd", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
80 | + (COMMIT_ONLY, "self cmd_unexisting", 200, 'EXCEPTION on command cmd_unexisting: Unknown command', Agent.CMD_STATUS.CMD_INVALID), | |
74 | 81 | # bad parameters (missing or too many, or bad type) |
75 | 82 | # missing args |
76 | - ("self do_specific10", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
83 | + (COMMIT_ONLY, "self do_specific10", 200, 'EXCEPTION on command do_specific10: Command has bad, missing, or too many argument(s)', Agent.CMD_STATUS.CMD_INVALID), | |
77 | 84 | # missing args |
78 | - ("self do_specific10 2", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
85 | + (COMMIT_ONLY, "self do_specific10 2 ", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
79 | 86 | # - too many args |
80 | - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
87 | + (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9] 4", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
81 | 88 | # - bad type |
82 | - ("self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '', Agent.CMD_STATUS.CMD_INVALID), | |
89 | + (COMMIT_ONLY, "self do_specific10 'toto' 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_INVALID), | |
83 | 90 | # - OK |
84 | 91 | #("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), |
85 | 92 | |
86 | 93 | # - Error case 3 - CMD_UNIMPLEMENTED |
87 | - ("self existing_but_unimplemented_cmd", 200, '', Agent.CMD_STATUS.CMD_UNIMPLEMENTED), | |
94 | + ##("self cmd_existing_but_unimplemented", 200, None, Agent.CMD_STATUS.CMD_UNIMPLEMENTED), | |
88 | 95 | |
89 | 96 | # - Error case 4 - CMD_EXPIRED |
90 | 97 | # This command has a validity of 0s and thus should be tagged as "expired" |
91 | - ("self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), | |
98 | + (COMMIT_ONLY, "self set_mode ATTENTIVE", 0, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXPIRED), | |
92 | 99 | |
93 | 100 | # - Error case 5 - CMD_SKIPPED |
94 | 101 | # a) In mode ROUTINE, SPECIFIC commands should be skipped as the agent is not ATTENTIVE |
95 | - ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
96 | - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), | |
102 | + (COMMIT_ONLY, "self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
103 | + (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, None, Agent.CMD_STATUS.CMD_SKIPPED), | |
97 | 104 | # b) Back to mode ATTENTIVE, SPECIFIC commands should be executed |
98 | - ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
99 | - ("self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), | |
105 | + (COMMIT_ONLY, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
106 | + (COMMIT_ONLY, "self do_specific10 2 2 3.5 titi (3,'titi',5) [1,3,5,7,9]", 200, '16.5', Agent.CMD_STATUS.CMD_EXECUTED), | |
107 | + | |
108 | + # ---------------------------------------------------- | |
109 | + # ------ B - ERROR CASES - from RUNNING status ------- | |
110 | + # ---------------------------------------------------- | |
111 | + | |
112 | + (True, "self cmd_raising_error_exec", 200, "EXCEPTION on command cmd_raising_error_exec: Error during Execution", Agent.CMD_STATUS.CMD_EXEC_ERROR), | |
100 | 113 | |
101 | 114 | # ------------------------------ |
102 | - # ------ B - NORMAL CASES ------- | |
115 | + # ------ C - NORMAL CASES ------- | |
103 | 116 | # ------------------------------ |
104 | 117 | |
105 | 118 | # do_restart => #iteration should restart at 1 (so at least it should be <= 4) |
... | ... | @@ -129,13 +142,13 @@ class AgentBasic(Agent): |
129 | 142 | # ------------------------------- |
130 | 143 | |
131 | 144 | # Agent general command |
132 | - ("self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
133 | - ("self get_mode", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
134 | - ("self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
135 | - ("self get_mode", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
145 | + (COMMIT_ONLY, "self set_mode ROUTINE", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
146 | + (COMMIT_ONLY, "self get_mode", 200, "MODE is ROUTINE", Agent.CMD_STATUS.CMD_EXECUTED), | |
147 | + (COMMIT_ONLY, "self set_mode ATTENTIVE", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
148 | + (COMMIT_ONLY, "self get_mode", 200, "MODE is ATTENTIVE", Agent.CMD_STATUS.CMD_EXECUTED), | |
136 | 149 | |
137 | 150 | # End test |
138 | - ("self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), | |
151 | + (True, "self do_stop", 200, 'STOPPING asap', Agent.CMD_STATUS.CMD_EXECUTED), | |
139 | 152 | |
140 | 153 | ] |
141 | 154 | |
... | ... | @@ -324,6 +337,9 @@ class AgentBasic(Agent): |
324 | 337 | #def do_specific1(self, arg1:int, arg2:int=2, arg3:int=3) -> int: |
325 | 338 | #def do_specific1(self, arg1:int, arg2:int=2, arg3:float=3.1, arg4:list=[1,2,3]) -> float: |
326 | 339 | |
340 | + def cmd_raising_error_exec(self): | |
341 | + raise CmdExceptionExecError(self.CURRENT_CMD) | |
342 | + | |
327 | 343 | def do_specific10(self, |
328 | 344 | arg1:int, |
329 | 345 | arg2:int, | ... | ... |
src/core/pyros_django/common/models.py
... | ... | @@ -12,6 +12,9 @@ from dateutil.relativedelta import relativedelta |
12 | 12 | import os |
13 | 13 | import sys |
14 | 14 | from typing import Any, List, Tuple |
15 | +import re | |
16 | + | |
17 | +# Django imports | |
15 | 18 | from django.core.validators import MaxValueValidator, MinValueValidator |
16 | 19 | |
17 | 20 | # DJANGO imports |
... | ... | @@ -575,8 +578,10 @@ class AgentCmd(models.Model): |
575 | 578 | # GET commands |
576 | 579 | # ------------ |
577 | 580 | |
578 | - # - Get agent current STATE (IN_MAIN_LOOP, ...) | |
581 | + # - Get agent current STATUS or STEP (IN_MAIN_LOOP, ...) | |
582 | + "get_status", | |
579 | 583 | ##"get_current_state", |
584 | + # @deprecated | |
580 | 585 | "get_state", |
581 | 586 | |
582 | 587 | # - Get agent current MODE (idle, routine, attentive) |
... | ... | @@ -644,6 +649,7 @@ class AgentCmd(models.Model): |
644 | 649 | # Priority commands, executed as soon as in the received commands list (BEFORE any other pending command) |
645 | 650 | # NB : must be a subset of _AGENT_GENERAL_COMMANDS |
646 | 651 | _AGENT_GENERAL_PRIORITY_COMMANDS = [ |
652 | + "get_specific_cmds", | |
647 | 653 | #"do_exit", |
648 | 654 | "do_flush_commands", |
649 | 655 | "do_exec_commands" |
... | ... | @@ -666,7 +672,10 @@ class AgentCmd(models.Model): |
666 | 672 | if '.' in agent_to: |
667 | 673 | agent_to, component_name = agent_to.split('.') |
668 | 674 | cmd_name = component_name+'.'+cmd_name |
675 | + # remove all excessive spaces | |
676 | + print(cmd_args) | |
669 | 677 | if cmd_args: |
678 | + cmd_args = re.sub(r"\s+", " ", cmd_args).strip() | |
670 | 679 | cmd_name += ' ' + cmd_args |
671 | 680 | # cls._device_command=DeviceCommand(cmd_name) |
672 | 681 | if cmd_validity is None: cmd_validity = cls.DEFAULT_VALIDITY_DURATION |
... | ... | @@ -1091,13 +1100,15 @@ class AgentCmd(models.Model): |
1091 | 1100 | if result: |
1092 | 1101 | self.set_result(result, False) |
1093 | 1102 | |
1103 | + ''' | |
1094 | 1104 | # - Changing state to PENDING (from None) |
1095 | 1105 | if status_new == self.CMD_STATUS_CODES.CMD_PENDING: |
1096 | 1106 | self.s_deposit_time = now_time |
1107 | + ''' | |
1097 | 1108 | |
1098 | 1109 | # - Changing state from PENDING |
1099 | 1110 | #if status_new in (self.CMD_STATUS_CODES.CMD_RUNNING, self.CMD_STATUS_CODES.CMD_SKIPPED, self.CMD_STATUS_CODES.CMD_EXPIRED): |
1100 | - elif status_new in ( | |
1111 | + if status_new in ( | |
1101 | 1112 | # Errors cases |
1102 | 1113 | self.CMD_STATUS_CODES.CMD_INVALID, |
1103 | 1114 | self.CMD_STATUS_CODES.CMD_UNIMPLEMENTED, |
... | ... | @@ -1119,7 +1130,7 @@ class AgentCmd(models.Model): |
1119 | 1130 | |
1120 | 1131 | # - Changing state from RUNNING (CMD_EXECUTED, CMD_EXEC_...) |
1121 | 1132 | #elif status_new in (self.CMD_STATUS_CODES.CMD_EXECUTED, self.CMD_STATUS_CODES.CMD_EXEC_KILLED): |
1122 | - else: | |
1133 | + elif status_new != self.CMD_STATUS_CODES.CMD_PENDING: | |
1123 | 1134 | assert self.is_running() |
1124 | 1135 | self.r_end_time = now_time |
1125 | 1136 | if status_new == self.CMD_STATUS_CODES.CMD_EXEC_KILLED: | ... | ... |