8#include "../../../tests/testXWC.hpp"
12#include "../stateRuleEngine.hpp"
31 void addRule(
const std::string &name,
indiCompRule *rule )
33 m_ruleMaps.rules[name] = rule;
35 pcf::IndiProperty *
property = ruleStateProperty( rule->
priority() );
36 if( property ==
nullptr )
41 if( property->getType() != pcf::IndiProperty::Switch )
43 *
property = pcf::IndiProperty( pcf::IndiProperty::Switch );
46 if( !property->find( name ) )
48 property->add( pcf::IndiElement( name, pcf::IndiElement::Off ) );
53 void setPublishedRuleState(
const rulePriority &priority,
54 const std::string &name,
55 pcf::IndiElement::SwitchStateType state )
57 pcf::IndiProperty *
property = ruleStateProperty( priority );
58 if( property ==
nullptr )
60 throw std::runtime_error(
"published rule property is not available" );
63 if( property->getType() != pcf::IndiProperty::Switch )
65 *
property = pcf::IndiProperty( pcf::IndiProperty::Switch );
68 if( !property->find( name ) )
70 property->add( pcf::IndiElement( name, pcf::IndiElement::Off ) );
73 ( *property )[name].setSwitchState( state );
77 const std::vector<std::string> ¬ifications()
const
79 return m_notifications;
83 void clearNotifications()
85 m_notifications.clear();
90 int sendNotification(
const std::string &message )
override
92 m_notifications.push_back( message );
97 std::vector<std::string> m_notifications;
105 fixedRule(
bool value =
false ) : m_value( value )
110 void value(
bool value )
116 boolorerr_t valid()
override
122 bool value()
override
129 bool m_value{
false };
148namespace stateRuleEngineTest
155TEST_CASE(
"stateRuleEngine placeholder harness instantiates the app",
"[stateRuleEngine]" )
158 #ifdef STATERULEENGINE_TEST_DOXYGEN_REF
163 SECTION(
"default construction succeeds" )
175TEST_CASE(
"stateRuleEngine notification helpers format active and clear messages",
"[stateRuleEngine]" )
178 rule.message( std::string(
"camera combo mismatch" ) );
181 #ifdef STATERULEENGINE_TEST_DOXYGEN_REF
187 SECTION(
"active notifications use the rule priority label" )
190 REQUIRE( stateRuleEngine_test::notificationMessage(
192 "WARNING: camera combo mismatch" );
195 SECTION(
"clear notifications prefix the configured rule message" )
197 REQUIRE( stateRuleEngine_test::notificationMessage(
198 "combo-mismatch", rule, stateRuleEngine_test::notificationLabel(
rulePriority::info ),
true ) ==
199 "INFO: Cleared: camera combo mismatch" );
202 SECTION(
"clear notifications fall back to the rule name when message is empty" )
204 rule.message( std::string() );
206 REQUIRE( stateRuleEngine_test::notificationMessage(
207 "combo-mismatch", rule, stateRuleEngine_test::notificationLabel(
rulePriority::info ),
true ) ==
208 "INFO: Cleared: combo-mismatch" );
216TEST_CASE(
"stateRuleEngine published-state helpers select properties and detect On state",
"[stateRuleEngine]" )
218 stateRuleEngine_test app;
221 #ifdef STATERULEENGINE_TEST_DOXYGEN_REF
227 app.m_indiP_info = pcf::IndiProperty( pcf::IndiProperty::Switch );
228 app.m_indiP_caution = pcf::IndiProperty( pcf::IndiProperty::Switch );
229 app.m_indiP_warning = pcf::IndiProperty( pcf::IndiProperty::Switch );
230 app.m_indiP_alert = pcf::IndiProperty( pcf::IndiProperty::Switch );
238 app.m_indiP_warning.add( pcf::IndiElement(
"combo-mismatch", pcf::IndiElement::Off ) );
240 REQUIRE( stateRuleEngine_test::ruleIsOn( app.m_indiP_warning,
"combo-mismatch" ) ==
false );
242 app.m_indiP_warning[
"combo-mismatch"].setSwitchState( pcf::IndiElement::On );
243 REQUIRE( stateRuleEngine_test::ruleIsOn( app.m_indiP_warning,
"combo-mismatch" ) ==
true );
245 REQUIRE( stateRuleEngine_test::ruleIsOn( app.m_indiP_warning,
"missing-rule" ) ==
false );
252TEST_CASE(
"stateRuleEngine appLogic reports one clear notification per observed On-to-Off transition",
253 "[stateRuleEngine]" )
255 stateRuleEngine_test app;
256 auto *rule =
new fixedRule(
false );
259 rule->
message( std::string(
"camera combo mismatch" ) );
261 app.addRule(
"combo-mismatch", rule );
264 #ifdef STATERULEENGINE_TEST_DOXYGEN_REF
269 SECTION(
"configured rule message is used for the clear notification" )
273 REQUIRE( app.appLogic() == 0 );
274 REQUIRE( app.notifications().size() == 1 );
275 REQUIRE( app.notifications().front() ==
"INFO: Cleared: camera combo mismatch" );
278 app.clearNotifications();
281 REQUIRE( app.appLogic() == 0 );
282 REQUIRE( app.notifications().empty() );
285 SECTION(
"rule name is used when no explicit message is configured" )
287 rule->
message( std::string() );
290 REQUIRE( app.appLogic() == 0 );
291 REQUIRE( app.notifications().size() == 1 );
292 REQUIRE( app.notifications().front() ==
"INFO: Cleared: combo-mismatch" );
The MagAO-X stateRuleEngine.
static bool ruleIsOn(pcf::IndiProperty &property, const std::string &ruleName)
Report whether a published rule element is currently On.
static std::string notificationMessage(const std::string &ruleName, indiCompRule &rule, const std::string &label, bool cleared=false, bool settime=false)
Format a notification message for a rule.
static std::string notificationLabel(const rulePriority &priority)
Get the notification label for a reporting priority.
pcf::IndiProperty * ruleStateProperty(const rulePriority &priority)
Get the published rule-state property for a reporting priority.
virtual int appLogic()
Implementation of the FSM for stateRuleEngine.
TEST_CASE("stateRuleEngine placeholder harness instantiates the app", "[stateRuleEngine]")
Verify the placeholder stateRuleEngine test harness instantiates the app cleanly.
rulePriority
Reporting priorities for rules.
@ caution
Caution – make sure you know what you're doing.
@ warning
Warning – something is probably wrong, you should check.
@ alert
Alert – something is definitely wrong, you should take action.
@ info
For information only.
Namespace for all libXWC tests.
Virtual base-class for all rules.
void messageCount(int mc)
Set the message count.
void priority(const rulePriority &p, double delay=-1)
Set priority of this rule.
void message(const std::string &m)
Set the message.