Summary
GenericAnalyzer's expected matcher is non-functional: an analyzer whose only matcher is expected fails to initialise, and even alongside another matcher, expected never matches anything.
Root cause
In generic_analyzer.cpp, the expected branch of GenericAnalyzer::init only pre-seeds the base-class items_ map (via addItem()); it never populates the expected_ vector:
} else if (pname.compare("expected") == 0) {
...
for (auto exp : pvalue.as_string_array()) {
auto item = std::make_shared<StatusItem>(exp);
this->addItem(exp, item); // -> items_, never expected_
}
}
But expected_ is what the rest of the class relies on:
- the init guard —
startswith_.size() == 0 && name_.size() == 0 && contains_.size() == 0 && expected_.size() == 0 && regex_.size() == 0 — decides "was not initialized with any way of checking diagnostics";
match() — iterates expected_ (name == expected_[i]);
report() — iterates expected_ for missing-item detection.
expected_ is never written anywhere in the file, so:
- an
expected-only analyzer trips the init guard and is dropped, leaving its AnalyzerGroup empty (Group '<x>' doesn't contain any analyzers, can't match); and
- even combined with another matcher,
expected contributes nothing, since match()/report() read the empty expected_.
This is a regression from the ROS 1 implementation, which populated the vector via getParamVals(expected, expected_) before creating the pre-seeded items (noetic-devel generic_analyzer.cpp).
Reproduction
Config (aggregator_node --ros-args --params-file expected.yaml):
/**:
ros__parameters:
path: Test
loctest:
type: diagnostic_aggregator/GenericAnalyzer
path: LocTest
expected: ['some/expected/status_name']
timeout: 5.0
Actual: node logs GenericAnalyzer 'LocTest' was not initialized with any way of checking diagnostics and Group 'Test' doesn't contain any analyzers, can't match. Swapping expected for startswith/contains/regex works.
Expected: the analyzer initialises and matches statuses whose names are in expected (and reports missing expected items as stale, per the ROS 1 behaviour).
Affected versions
Present in the installed Jazzy build (diagnostic_aggregator 4.2.7) and the current ros2 (rolling) branch.
Fix
A fix (restore expected_ population) plus a regression test is proposed in #655.
Summary
GenericAnalyzer'sexpectedmatcher is non-functional: an analyzer whose only matcher isexpectedfails to initialise, and even alongside another matcher,expectednever matches anything.Root cause
In
generic_analyzer.cpp, theexpectedbranch ofGenericAnalyzer::initonly pre-seeds the base-classitems_map (viaaddItem()); it never populates theexpected_vector:But
expected_is what the rest of the class relies on:startswith_.size() == 0 && name_.size() == 0 && contains_.size() == 0 && expected_.size() == 0 && regex_.size() == 0— decides "was not initialized with any way of checking diagnostics";match()— iteratesexpected_(name == expected_[i]);report()— iteratesexpected_for missing-item detection.expected_is never written anywhere in the file, so:expected-only analyzer trips the init guard and is dropped, leaving itsAnalyzerGroupempty (Group '<x>' doesn't contain any analyzers, can't match); andexpectedcontributes nothing, sincematch()/report()read the emptyexpected_.This is a regression from the ROS 1 implementation, which populated the vector via
getParamVals(expected, expected_)before creating the pre-seeded items (noetic-develgeneric_analyzer.cpp).Reproduction
Config (
aggregator_node --ros-args --params-file expected.yaml):Actual: node logs
GenericAnalyzer 'LocTest' was not initialized with any way of checking diagnosticsandGroup 'Test' doesn't contain any analyzers, can't match. Swappingexpectedforstartswith/contains/regexworks.Expected: the analyzer initialises and matches statuses whose names are in
expected(and reports missing expected items as stale, per the ROS 1 behaviour).Affected versions
Present in the installed Jazzy build (
diagnostic_aggregator4.2.7) and the currentros2(rolling) branch.Fix
A fix (restore
expected_population) plus a regression test is proposed in #655.