API
 
Loading...
Searching...
No Matches
fsmNode_test.cpp
Go to the documentation of this file.
1/** \file fsmNode_test.cpp
2 * \brief Catch2 tests for the xInstGraph `fsmNode` helper.
3 * \author Jared R. Males (jaredmales@gmail.com)
4 *
5 * \ingroup xInstGraph_files
6 */
7
8#include "../../../../tests/testXWC.hpp"
9
10#include <fstream>
11
12#include "../../../../libMagAOX/libMagAOX.hpp"
13
14#define XWC_XIGNODE_TEST
15#include "../fsmNode.hpp"
16
17namespace libXWCTest
18{
19
20/** \addtogroup xInstGraph_unit_test
21 * \brief Additional unit tests for the xInstGraph application.
22 *
23 * \ingroup application_unit_test
24 */
25
26/// Namespace for `xInstGraph` node unit tests.
27/** \ingroup xInstGraph_unit_test
28 */
29namespace xInstGraphTest
30{
31
32void writeXML()
33{
34 std::ofstream fout( "/tmp/xigNode_test.xml" );
35 fout << "<mxfile host=\"test\">\n";
36 fout << " <diagram id=\"test\" name=\"test\">\n";
37 fout << " <mxGraphModel>\n";
38 fout << " <root>\n";
39 fout << " <mxCell id=\"0\"/>\n";
40 fout << " <mxCell id=\"1\" parent=\"0\"/>\n";
41 fout << " <mxCell id=\"node:ttmpupil\">\n";
42 fout << "</mxCell>\n";
43 fout << " </root>\n";
44 fout << " </mxGraphModel>\n";
45 fout << " </diagram>\n";
46 fout << "</mxfile>\n";
47 fout.close();
48}
49
50SCENARIO( "Creating and configuring an fsmNode", "[instGraph::fsmNode]" )
51{
52 // clang-format off
53 #ifdef XINSTGRAPH_TEST_DOXYGEN_REF
54 fsmNode::loadConfig( *(mx::app::appConfigurator *)nullptr );
56 #endif
57 // clang-format on
58
59 GIVEN( "a valid XML file, a valid config file" )
60 {
61 WHEN( "node is in file, default config" )
62 {
63 ingr::instGraphXML parentGraph;
64 writeXML();
65 mx::app::writeConfigFile( "/tmp/fsmNode_test.conf", { "ttmpupil" }, { "type" }, { "fsm" } );
66 mx::app::appConfigurator config;
67 config.readConfig( "/tmp/fsmNode_test.conf" );
68
69 std::string emsg;
70
71 int rv = parentGraph.loadXMLFile( emsg, "/tmp/xigNode_test.xml" );
72
73 REQUIRE( rv == 0 );
74 REQUIRE( emsg == "" );
75
76 fsmNode *tsn = nullptr;
77 bool pass = false;
78 try
79 {
80 tsn = new fsmNode( "ttmpupil", &parentGraph );
81 pass = true;
82 }
83 catch( const std::exception &e )
84 {
85 std::cerr << e.what() << "\n";
86 }
87
88 REQUIRE( pass == true );
89 REQUIRE( tsn != nullptr );
90
91 REQUIRE( tsn->name() == "ttmpupil" );
92 REQUIRE( tsn->node()->name() == "ttmpupil" );
93
94 pass = false;
95 try
96 {
97 tsn->loadConfig( config );
98 pass = true;
99 }
100 catch( const std::exception &e )
101 {
102 std::cerr << e.what() << "\n";
103 }
104
105 REQUIRE( pass == true );
106
107 // check config-ed values
108 REQUIRE( tsn->device() == "ttmpupil" );
109 REQUIRE( tsn->fsmKey() == "ttmpupil.fsm" );
110 REQUIRE( tsn->fsmAction() == fsmNodeActionT::passive );
111 REQUIRE( tsn->targetStates().size() == 0 );
112 }
113 WHEN( "node is in file, setting action to threshOff for two states" )
114 {
115 ingr::instGraphXML parentGraph;
116 writeXML();
117 mx::app::writeConfigFile( "/tmp/fsmNode_test.conf",
118 { "ttmpupil", "ttmpupil", "ttmpupil" },
119 { "type", "fsmAction", "targetStates" },
120 { "fsm", "threshOff", "READY,OPERATING" } );
121 mx::app::appConfigurator config;
122 config.readConfig( "/tmp/fsmNode_test.conf" );
123
124 std::string emsg;
125
126 int rv = parentGraph.loadXMLFile( emsg, "/tmp/xigNode_test.xml" );
127
128 REQUIRE( rv == 0 );
129 REQUIRE( emsg == "" );
130
131 fsmNode *tsn = nullptr;
132 bool pass = false;
133 try
134 {
135 tsn = new fsmNode( "ttmpupil", &parentGraph );
136 pass = true;
137 }
138 catch( const std::exception &e )
139 {
140 std::cerr << e.what() << "\n";
141 }
142
143 REQUIRE( pass == true );
144 REQUIRE( tsn != nullptr );
145
146 REQUIRE( tsn->name() == "ttmpupil" );
147 REQUIRE( tsn->node()->name() == "ttmpupil" );
148
149 pass = false;
150 try
151 {
152 tsn->loadConfig( config );
153 pass = true;
154 }
155 catch( const std::exception &e )
156 {
157 std::cerr << e.what() << "\n";
158 }
159
160 REQUIRE( pass == true );
161
162 // check config-ed values
163 REQUIRE( tsn->device() == "ttmpupil" );
164 REQUIRE( tsn->fsmKey() == "ttmpupil.fsm" );
165 REQUIRE( tsn->fsmAction() == fsmNodeActionT::threshOff );
166 REQUIRE( tsn->targetStates().size() == 2 );
167 REQUIRE( tsn->targetStates()[0] == MagAOX::app::stateCodes::READY );
168 REQUIRE( tsn->targetStates()[1] == MagAOX::app::stateCodes::OPERATING );
169 }
170 WHEN( "node is in file, setting action to active for one state" )
171 {
172 ingr::instGraphXML parentGraph;
173 writeXML();
174 mx::app::writeConfigFile( "/tmp/fsmNode_test.conf",
175 { "ttmpupil", "ttmpupil", "ttmpupil" },
176 { "type", "fsmAction", "targetStates" },
177 { "fsm", "active", "OPERATING" } );
178 mx::app::appConfigurator config;
179 config.readConfig( "/tmp/fsmNode_test.conf" );
180
181 std::string emsg;
182
183 int rv = parentGraph.loadXMLFile( emsg, "/tmp/xigNode_test.xml" );
184
185 REQUIRE( rv == 0 );
186 REQUIRE( emsg == "" );
187
188 fsmNode *tsn = nullptr;
189 bool pass = false;
190 try
191 {
192 tsn = new fsmNode( "ttmpupil", &parentGraph );
193 pass = true;
194 }
195 catch( const std::exception &e )
196 {
197 std::cerr << e.what() << "\n";
198 }
199
200 REQUIRE( pass == true );
201 REQUIRE( tsn != nullptr );
202
203 REQUIRE( tsn->name() == "ttmpupil" );
204 REQUIRE( tsn->node()->name() == "ttmpupil" );
205
206 pass = false;
207 try
208 {
209 tsn->loadConfig( config );
210 pass = true;
211 }
212 catch( const std::exception &e )
213 {
214 std::cerr << e.what() << "\n";
215 }
216
217 REQUIRE( pass == true );
218
219 // check config-ed values
220 REQUIRE( tsn->device() == "ttmpupil" );
221 REQUIRE( tsn->fsmKey() == "ttmpupil.fsm" );
222 REQUIRE( tsn->fsmAction() == fsmNodeActionT::active );
223 REQUIRE( tsn->targetStates().size() == 1 );
224 REQUIRE( tsn->targetStates()[0] == MagAOX::app::stateCodes::OPERATING );
225 }
226 }
227}
228
229} // namespace xInstGraphTest
230
231} // namespace libXWCTest
Implementation of an instGraph node interface for a MagAO-X Finite State Machine (FSM)
Definition fsmNode.hpp:69
const std::vector< stateCodeT > & targetStates() const
Get the target states.
Definition fsmNode.hpp:305
virtual void device(const std::string &dev)
Set the device name.
Definition fsmNode.hpp:201
fsmNodeActionT fsmAction() const
Get the action.
Definition fsmNode.hpp:295
void loadConfig(mx::app::appConfigurator &config)
Load this specific node's settings from an application configuration.
Definition fsmNode.hpp:310
const std::string & fsmKey() const
Get the FSM unique key.
Definition fsmNode.hpp:290
ingr::instNode * node()
Get the pointer to the underlying node.
Definition xigNode.hpp:121
std::string name()
Get the name of this node.
Definition xigNode.hpp:106
SCENARIO("Creating and configuring an fsmNode", "[instGraph::fsmNode]")
void writeXML()
Write a minimal draw.io graph containing one of each supported node type.
Namespace for all libXWC tests.
@ OPERATING
The device is operating, other than homing.
@ READY
The device is ready for operation, but is not operating.