Skip to content

fault_manager: document which debounce lever fits which reporter, and test it - #643

Draft
bburda wants to merge 1 commit into
mainfrom
test/debounce-and-healing
Draft

fault_manager: document which debounce lever fits which reporter, and test it#643
bburda wants to merge 1 commit into
mainfrom
test/debounce-and-healing

Conversation

@bburda

@bburda bburda commented Aug 27, 2026

Copy link
Copy Markdown
Collaborator

Pull Request

Summary

The debounce docs told everyone to use confirmation_threshold: -3 with healing_threshold: 3.
That works only for a reporter that keeps sending FAILED while a condition is still there. For a
reporter that sends one FAILED per raise and one clear per de-assert, the second event never
arrives, so the fault stays PREFAILED and never confirms. The default ListFaults filter returns
CONFIRMED only, so such a fault is never seen at all. Healing breaks the same way in the other
direction: it needs healing_threshold - confirmation_threshold consecutive PASSED events and only
one is ever sent, so a confirmed fault stays CONFIRMED until someone calls ~/clear_fault.

auto_confirm_after_sec is the right lever for that kind of reporter and it already works, but
nothing said so. This PR documents which lever fits which reporter, and adds the integration test
that was missing on that path.

No production code changed. All four parameters already behave correctly and both storage backends
agree on the arithmetic.


Issue


Type

  • Bug fix
  • New feature or tests
  • Breaking change
  • Documentation only

Testing

New integration test test_debounce_and_healing.test.py drives the real node over the real
services with SQLite storage, and sends the event counts a one-event-per-transition reporter really
sends: one FAILED per raise, one PASSED per clear. It pins five things:

  • one FAILED does not confirm
  • an unconfirmed fault is not in the default fault list
  • a condition that stays confirms after auto_confirm_after_sec with nobody acting
  • a condition that clears inside that window never confirms
  • one PASSED heals a confirmed fault with nobody acting

The fourth case is the one that keeps the setting honest. Without it a config could pass by only
delaying a false alarm instead of filtering it.

The test was written first and run against the parameter defaults, where 4 of the 5 cases fail:

test_01: AssertionError: 'CONFIRMED' == 'CONFIRMED'
         : a single failed read confirmed the fault immediately
test_02: 'PLC_HIDDEN_WHILE_PENDING' unexpectedly found in ['PLC_SINGLE_READ', ...]
         : an unconfirmed fault is already visible in the default fault list
test_04: AssertionError: 'CONFIRMED' == 'CONFIRMED'
         : a transient that already cleared was confirmed by the timer
test_05: AssertionError: 'CONFIRMED' != 'HEALED'
         : a de-asserted alarm did not heal on its single clear, it is CONFIRMED
Ran 5 tests in 6.374s
FAILED (failures=4)

Case 3 passes on the defaults, which is intended. It is the guard that stops anyone from "fixing"
the other four by making faults invisible.

With the settings under test it is 5/5 green.

To run it:

colcon test --packages-select ros2_medkit_fault_manager \
  --ctest-args -R test_debounce_and_healing --parallel-workers 1

Checklist

  • Breaking changes are clearly described (and announced in docs / changelog if needed)
  • Tests were added or updated if needed
  • Docs were updated if behavior or public API changed

… test it

The debounce counter only moves when an event arrives, so confirmation_threshold
and healing_threshold only work for a reporter that keeps sending FAILED while a
condition is still there. The docs recommended confirmation_threshold: -3 with
healing_threshold: 3 to everyone.

For a reporter that sends one FAILED per raise and one clear per de-assert the
second event never comes. The fault stops at PREFAILED and never confirms, and
ListFaults with an empty status filter returns CONFIRMED only, so nobody sees
it. Healing breaks the same way: it needs healing_threshold minus
confirmation_threshold consecutive PASSED events and only one is sent, so a
confirmed fault stays CONFIRMED until someone calls ~/clear_fault.

auto_confirm_after_sec is the lever for that kind of reporter and already works.
It holds the first FAILED in PREFAILED and confirms it only if it is still there
when the window closes, so a condition that recovers never reaches an operator.
The docs listed the parameter but never said what it is for.

Add an integration test driving the real node over the real services with the
event counts such a reporter sends: one FAILED per raise, one PASSED per clear.
It also pins the case where a condition clears inside the window, which is what
stops a config from passing by only delaying a false alarm.

No production code change.
Copilot AI lite review requested due to automatic review settings August 27, 2026 13:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR clarifies fault-manager debounce/healing parameter guidance for edge-triggered (one-event-per-transition) reporters and adds an integration test that exercises the auto_confirm_after_sec + healing_threshold: 0 path end-to-end (SQLite backend), without changing production code.

Changes:

  • Document when count-based thresholds work vs when time-based auto-confirm is required (README + Sphinx docs).
  • Add a launch-based integration test that drives report/list services with edge-triggered event patterns.
  • Register the new integration test in ros2_medkit_fault_manager’s CMake.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
src/ros2_medkit_fault_manager/test/integration/test_debounce_and_healing.test.py New launch integration test covering edge-triggered debounce + timer confirm + healing behavior.
src/ros2_medkit_fault_manager/README.md Adds guidance on selecting debounce/healing levers based on reporter behavior.
src/ros2_medkit_fault_manager/CMakeLists.txt Registers the new launch test with an appropriate timeout.
docs/config/fault-manager.rst Adds an “important” note explaining edge-triggered reporter implications and recommended settings.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +246 to +249
def test_exit_code(self, proc_info, fault_manager_node):
launch_testing.asserts.assertExitCodes(
proc_info, allowable_exit_codes=[0, -2, -15], process=fault_manager_node
)
@bburda bburda self-assigned this Aug 27, 2026
@bburda
bburda marked this pull request as draft August 27, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Debounce docs recommend a setting that silently disables faults for one-event-per-transition reporters

2 participants