Skip to content

Add scripted return status support for TestNode mocks#1125

Open
pepeRossRobotics wants to merge 4 commits into
BehaviorTree:masterfrom
pepeRossRobotics:feature/conditional_mock
Open

Add scripted return status support for TestNode mocks#1125
pepeRossRobotics wants to merge 4 commits into
BehaviorTree:masterfrom
pepeRossRobotics:feature/conditional_mock

Conversation

@pepeRossRobotics

Copy link
Copy Markdown

This adds support for computing a TestNode return status from a script, so mock behavior can depend on blackboard state without adding extra nodes to the tree.

It also updates the substitution tests and tutorial examples to cover both the observable and strict-failure mock flows.

Addresses #995

pepeRossRobotics and others added 4 commits April 2, 2026 22:52
…t-scripts

Introduces `return_status_script` to allow dynamic computation of the TestNode's completion status based on blackboard variables at runtime. This provides greater flexibility for mocking different scenarios in tests.

Refines post-execution logic by replacing a single `post_script` with distinct `success_script` and `failure_script` that execute based on the TestNode's final status. The `return_status_script` takes precedence over a statically defined `return_status`.

Adds comprehensive validation to prevent the TestNode from returning an `IDLE` status and to ensure a valid completion status mechanism is always configured.
Adjusts line wrapping and whitespace across examples, headers, source files, and tests
to enhance readability and maintain a unified code style.
@facontidavide

Copy link
Copy Markdown
Collaborator

Thanks for this contribution — the feature itself is welcome and addresses #995 well, the test coverage is good, and I verified locally that everything builds and passes.

However, there are a few things that need to be addressed before this can be merged:

1. We can not accept API changes: return_status must remain a plain NodeStatus.

Changing TestNodeConfig::return_status from NodeStatus to std::optional<NodeStatus> is a source-compatibility break for any downstream code that reads the field directly (e.g. NodeStatus s = cfg.return_status;, toStr(cfg.return_status), or a switch on it).

The optional isn't actually needed for the feature: since return_status_script takes precedence over the fixed status anyway (as your own documentation states), you can keep

NodeStatus return_status = NodeStatus::SUCCESS;

unchanged. Concretely:

  • drop the .reset() calls from the examples and tests;
  • in loadSubstitutionRuleFromJSON, use a local "was return_status present in the JSON" flag for the "must contain return_status or return_status_script" validation, instead of resetting the member.

That makes the whole PR purely additive.

2. Misleading error message for out-of-range script results.

validateTestNodeStatus() hardcodes "resolved to invalid status IDLE". A script that evaluates to e.g. 7 reports "IDLE", which would send users debugging in the wrong direction. Please include the actual offending value in the message (the raw integer is fine, since toStr can't render invalid enum values).

3. Unrelated change in tests/gtest_wakeup.cpp.

The system_clocksteady_clock switch and the relaxed assertion bound are reasonable on their own, but they are unrelated to this feature and not mentioned in the PR description. Please move them to a separate PR (or at minimum call them out explicitly in the description).

4. Please leave the existing tutorial t15_nodes_mocking.cpp untouched.

Tutorial 15 corresponds to a published page on behaviortree.dev; restructuring its tree (the added Fallback, the mock flag) makes the code diverge from the website text. Keep the original example as it is and demonstrate the scripted return status only in your new t15_nodes_mocking_strict_failure.cpp (or a dedicated new example).

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.

2 participants