Handling exceptions when applications do not report errors but time out in stateful transitions - #868
Handling exceptions when applications do not report errors but time out in stateful transitions#868PawelPlesniak wants to merge 102 commits into
Conversation
…to agreement with SWIT as to where to host these configs)
…M timeouts and death on FSM, REQUIRES TESTING
|
…to be propagated down to the actual failing app level
|
Co-authored-by: Emir Muhammad <49058518+emmuhamm@users.noreply.github.com>
…ithub.com:DUNE-DAQ/drunc into PawelPlesniak/IncompleteStatefulCommandTransition
|
I will rerun the integration tests tomorrow in both |
|
All new All previous |
…g another issue with this PR
|
Unit tests now pass Integration tests passed on |
|
@emmuhamm please review the unresolved comment replies, the rest has been addressed |
| # Children nodes (ignore exclusion). | ||
| child_list = self.address_target_path( | ||
| request.target, | ||
| request.execute_on_all_subsequent_children_in_path, | ||
| include_excluded_nodes=False, | ||
| ) |
There was a problem hiding this comment.
Just saw this flash past my screen. NB with include_excluded_nodes=False, you're actually not including excluded nodes, contrary to the comment.
ED: I realise now my (ignore exclusion) comment is kind of ambiguous. Just checking intent.
There was a problem hiding this comment.
Thanks James! Either way, we want to include excluded nodes, as the log_on_server command is not stateful
emmuhamm
left a comment
There was a problem hiding this comment.
Thanks for addressing my comments, these look great to me! Theres a thread that I've pinged you on since you explicitly asked to leave that unresolved, and another minor comment about updating the code comments, but none of them should block this going in.
Theres also this request you mentioned:
Note to self - requested from MRiganSUSX , list the application that did not complete in time, and tell the user to look at the logs of that specific one
Has this been done? (I haven't dug in the code yet, and might be easier to ask you to confirm >.<)
Aside from that, the only thing I'll ask for is:
- a minor conflict that needs to be resolved
- pytest (done!)
- drunc integtest (done!)
- full daqsystemtest (done!)
so after the conflict I'd be happy with evidence that both the pytest, local drunc integtest, and msqt passes and we can get this in!
| _PS_COLUMNS = ["session", "friendly_name", "user", "host", "uuid", "alive", "exit_code"] | ||
| _STATUS_COLUMNS = [ | ||
| "name", | ||
| "info", | ||
| "state", | ||
| "substate", | ||
| "in_error", | ||
| "included", | ||
| "endpoint", | ||
| ] | ||
| _EXEC_REPORT_COLUMNS = ["name", "command_execution", "fsm_transition"] |
There was a problem hiding this comment.
Yeah thats fair. The comment was mainly focused on how I'm not a fan of my own design choices, primarily having to hardcode status columns in actual tests.
Eg. we shouldn't ever do table['state'] when writing the tests themselves, since this is prone to error (eg if the name 'state' changes in the future or whatever).
Personally it would be better if when we grab the table we can do a table.state when writing the tests, and abstract away the implementation to the testing utils.
Now obviously this is something far beyond the scope of this PR, but this is something to think about.
| pytestmark = pytest.mark.skipif( | ||
| drunc_missing, | ||
| reason="drunc is not present in DUNEDAQ_DB_PATH, skipping drunc integration tests", | ||
| ) |
There was a problem hiding this comment.
@PawelPlesniak pinging you on this again since you explicitly asked to leave this unresolved. Is this thread fine now?
| # successful and we can return, otherwise, we will log the error and place the | ||
| # session in an error state if required. | ||
| in_error_state = obj.get_driver("controller").status().status.in_error | ||
| if not in_error_state and not put_in_error_state: |
There was a problem hiding this comment.
Thanks for adding the comments! A slight request on the comments:
# Determine whether the session should be placed into an error state. See usage for examples on why such a session _should_ be placed into the error state.
Its a lot of handholding but I think this is important, at least it'll tell a developer what the variables does and tells them to read the code for a few examples of why put_in_error_state needs to be used.
Thanks
Yep
Also done ;) Other comments will be addressed in the relevant threads now Thanks! |
|
At this stage, I think we're coming to a close, the last topic is the discussion on the |
emmuhamm
left a comment
There was a problem hiding this comment.
At this stage, I think we're coming to a close, the last topic is the discussion on the in_error_state flag
Agree! Thats why I'm going to approve this right now so you can merge it whenever this is resolved but so it isn't blocked on my availability.
In any case I've seen all the code already and whatever's gonna change is just a comment. So as long as the aformentioned checks are done this can go in.
Thanks for this nice work my guy!
Description
Fixes #803
Fixes #869
Fixes #911
Fixes #687
If a segment does not reach the target state, it is marked as in error, and the timeout is logged in the relevant server.
Also defines a set of configurations constructed to fail, and defines a set of unit tests to demonstrate this behaviour.
Error recovery with the supervisor will address what happens if an application completes this outside of the designated window. This is defined in #840
Type of change
List of required branches from other repositories
Requires DUNE-DAQ/druncschema#87
Change log
Addressed issues
Now when an application does not complete its transition in the allocated timeout, the session is put into an error state.
Defines a new click command
log(implemented in code asdef log_on_serverto prevent naming conflicts withlogging.Loggersdefined aslog) that allows the user to send a message to the relevant controller or process manager to put into their log file with a selectable severity level.Other new features
When running in batch mode, the user can start the run with
--no-stop-error-batch-mode. Should an error state be encountered, the session is not terminated, and commands can continue to be executed. This is primarily intended for use with integration tests, such that we can inspect thepsandstatustables.Integration tests for failure modes
Defines a set of intentionally failing configurations in
config/tests/failure-testing.data.xml, which contain configurations with a set offake-daq-apps that fail at configurable points in the session lifecycle. These configurations areft-death-on-boot-nest-app- this kills a nested application (2 segments deep) onboot.ft-death-on-boot-top-app- this kills the top application onboot.ft-death-post-boot-nest-app- this kills a nested application (2 segments deep) afterboot, before applications are marked as ready.ft-death-post-boot-top-app- this kills the top application afterboot, before applications are marked as ready.ft-fsm-cmd-timeout-nest-app- this times out an FSM transition on a nested application.ft-fsm-cmd-timeout-top-app- this times out an FSM transition on the top application.ft-fsm-cmd-death-nest-app- this kills a nested fake daq app during a FSM transition.ft-fsm-cmd-death-top-app- this kills the top fake daq app during a FSM transition.The differences between the
on-bootandpost-bootare useful to see, as thepost-bootconfigs allow the applications that die to register themselves on the connectivity service before dying, hence there is different behaviour.The differences between the
nest-appandtop-appallow the user to visualize the effect of a nested hierarchy on the control tree, and how the releveant children applications register themselves to the segment parents. The user shoudl expect to see the majority of the apps in the status table onbootwhen using anestconfig, and only the top two apps when using thetopconfig.Note that these configurations use the
FSMconfiguration_noActionstate machine, and will not behave fulliy in the standard way. An example includes not being able to reach the running state as there is no run number allocated, which will be reported as a genericgRPCerror.These tests have been integrated into the unit test framework, which can be executed as (from the local
druncroot)It is recommended for the tester to use
--integtest-verbosity 5to see what is happening during the process, and if more details are wanted from thepytestside, the user can run the tests aspytest -sto show what would be printed.Suggested manual testing checklist
Run each of the integration tests as defined above.
Developer checklist
Prior to marking this as "Ready for Review"
Tests ran on:
np04-srv-029from releaseNFD_DEV_260709_A9.Unit tests - some tests can't be ran on the CI. This is documented. If this PR checks a feature that can't be tested with CI, this has been marked appropriately.
Integration tests - the
daqsystemtest_integtest_bundlerequires a lot of resources, and connections to the EHN1 infrastructure. Check the cross referenced list if you can't run these. The developer needs to run at least the .pytest --marker) passeddaqsystemtest_integtest_bundle.sh -k minimal_system_quick_test.pydaqsystemtest_integtest_bundle.shFinal checklist prior to marking this as "Ready for Review"
Reviewer checklist
druncare in the log filesdruncfailure appears:Once the features are validated and both the unit and integration tests pass, the PRs is ready to be merged.
Choose one of the following an complete all substepsPrior to merging
Once completed, the reviewer can merge the PR.
Notification message for a Slack channel
Note - this should be to #dunedaq-integration for general workflow that isn't during a release candidate period, and to #daq-release-prep otherwise.
For an single merge that changes the user workflow
For co-ordinated merge