API
 
Loading...
Searching...
No Matches
observerCtrl_test.cpp
Go to the documentation of this file.
1/** \file observerCtrl_test.cpp
2 * \brief Catch2 tests for the observerCtrl app.
3 * \author Jared R. Males (jaredmales@gmail.com)
4 *
5 * \ingroup observerCtrl_files
6 */
7
8#include "../../../tests/testXWC.hpp"
9#include "../../../tests/testMacrosINDI.hpp"
10
11#include "../observerCtrl.hpp"
12
13using namespace MagAOX::app;
14
15namespace libXWCTest
16{
17
18/** \defgroup observerCtrl_unit_test observerCtrl Unit Tests
19 * \brief Unit tests for the observerCtrl application.
20 *
21 * \ingroup application_unit_test
22 */
23
24/// Namespace for `observerCtrl` unit tests.
25/** \ingroup observerCtrl_unit_test
26 */
27namespace observerCtrlTest
28{
29
30/// \cond DOXYGEN_SUPPRESS_TEST_HARNESS
31class observerCtrl_test : public observerCtrl
32{
33 public:
34 observerCtrl_test( const std::string &device )
35 {
36 m_configName = device;
37
38 XWCTEST_SETUP_INDI_NEW_PROP( observers );
40 XWCTEST_SETUP_INDI_NEW_PROP( observing );
42 }
43
44 void configureStreamWriters( const std::vector<std::string> &writers,
45 const std::vector<std::string> &defWriters = std::vector<std::string>() )
46 {
47 m_streamWriters = writers;
48 m_defStreamWriters = defWriters;
49
50 m_indiP_sws = pcf::IndiProperty( pcf::IndiProperty::Switch );
51 m_indiP_sws.setDevice( m_configName );
52 m_indiP_sws.setName( "writers" );
53 m_indiP_sws.setPerm( pcf::IndiProperty::ReadWrite );
54 m_indiP_sws.setState( pcf::IndiProperty::Idle );
55 m_indiP_sws.setRule( pcf::IndiProperty::AnyOfMany );
56
57 m_indiP_streamWriterWriting.clear();
58 m_streamWriterSelectable.clear();
59 m_streamWriterDevices.clear();
60 m_streamWriterWriting.clear();
61 m_streamWriterWritingKnown.clear();
62 m_streamWriterStartedByObserver.clear();
63 m_indiSetCallBacks.clear();
64
65 for( const auto &writer : writers )
66 {
67 m_indiP_sws.add( pcf::IndiElement( writer, pcf::IndiElement::Off ) );
68 REQUIRE( registerStreamWriter( writer, true ) == 0 );
69 }
70
71 for( const auto &writer : defWriters )
72 {
73 REQUIRE( registerStreamWriter( writer, false ) == 0 );
74 }
75 }
76
77 void setWriterSelected( const std::string &writerName, pcf::IndiElement::SwitchStateType state )
78 {
79 m_indiP_sws[writerName].setSwitchState( state );
80 }
81
82 int setWriterWritingState( const std::string &writerName, pcf::IndiElement::SwitchStateType state )
83 {
84 pcf::IndiProperty ip( pcf::IndiProperty::Switch );
85
86 ip.setDevice( streamWriterDeviceName( writerName ) );
87 ip.setName( "writing" );
88 ip.add( pcf::IndiElement( "toggle" ) );
89 ip["toggle"].setSwitchState( state );
90
91 return setCallBack_streamWriterWriting( ip );
92 }
93
94 bool beginWriter( const std::string &writerName )
95 {
96 return beginObservationStreamWriter( writerName );
97 }
98
99 bool endWriter( const std::string &writerName )
100 {
101 return endObservationStreamWriter( writerName );
102 }
103
104 bool writerWritingKnown( const std::string &writerName ) const
105 {
106 return m_streamWriterWritingKnown.at( writerName );
107 }
108
109 bool writerWriting( const std::string &writerName ) const
110 {
111 return m_streamWriterWriting.at( writerName );
112 }
113
114 bool writerExposed( const std::string &writerName ) const
115 {
116 return m_indiP_sws.find( writerName );
117 }
118};
119/// \endcond
120
121/// Verify the observerCtrl INDI callback validators accept only the expected properties.
122/**
123 * \ingroup observerCtrl_unit_test
124 */
125TEST_CASE( "observerCtrl INDI callbacks validate device and property names", "[observerCtrl]" )
126{
127 // clang-format off
128 #ifdef OBSERVERCTRL_TEST_DOXYGEN_REF
129 observerCtrl::newCallBack_m_indiP_observers( pcf::IndiProperty() );
130 observerCtrl::newCallBack_m_indiP_obsName( pcf::IndiProperty() );
131 observerCtrl::newCallBack_m_indiP_observing( pcf::IndiProperty() );
132 observerCtrl::newCallBack_m_indiP_sws( pcf::IndiProperty() );
133 #endif
134 // clang-format on
135
140}
141
142/// Verify observerCtrl tracks remote stream writer writing state updates.
143/**
144 * \ingroup observerCtrl_unit_test
145 */
146TEST_CASE( "observerCtrl tracks remote stream writer writing state", "[observerCtrl]" )
147{
148 // clang-format off
149 #ifdef OBSERVERCTRL_TEST_DOXYGEN_REF
151 #endif
152 // clang-format on
153
154 observerCtrl_test app( "observerCtrl_test" );
155 app.configureStreamWriters( { "camwfs" } );
156
157 REQUIRE_FALSE( app.writerWritingKnown( "camwfs" ) );
158
159 REQUIRE( app.setWriterWritingState( "camwfs", pcf::IndiElement::On ) == 0 );
160 REQUIRE( app.writerWritingKnown( "camwfs" ) );
161 REQUIRE( app.writerWriting( "camwfs" ) );
162
163 REQUIRE( app.setWriterWritingState( "camwfs", pcf::IndiElement::Off ) == 0 );
164 REQUIRE_FALSE( app.writerWriting( "camwfs" ) );
165}
166
167/// Verify observerCtrl only stops stream writers it started for the current observation.
168/**
169 * \ingroup observerCtrl_unit_test
170 */
171TEST_CASE( "observerCtrl only stops stream writers it started", "[observerCtrl]" )
172{
173 // clang-format off
174 #ifdef OBSERVERCTRL_TEST_DOXYGEN_REF
177 #endif
178 // clang-format on
179
180 observerCtrl_test app( "observerCtrl_test" );
181 app.configureStreamWriters( { "camsci1", "camwfs" } );
182
183 app.setWriterSelected( "camsci1", pcf::IndiElement::On );
184 app.setWriterSelected( "camwfs", pcf::IndiElement::On );
185
186 REQUIRE( app.setWriterWritingState( "camsci1", pcf::IndiElement::On ) == 0 );
187 REQUIRE( app.setWriterWritingState( "camwfs", pcf::IndiElement::Off ) == 0 );
188
189 REQUIRE_FALSE( app.beginWriter( "camsci1" ) );
190 REQUIRE( app.beginWriter( "camwfs" ) );
191
192 REQUIRE_FALSE( app.endWriter( "camsci1" ) );
193 REQUIRE( app.endWriter( "camwfs" ) );
194 REQUIRE_FALSE( app.endWriter( "camwfs" ) );
195}
196
197/// Verify observerCtrl always manages configured default writers without exposing them in INDI.
198/**
199 * \ingroup observerCtrl_unit_test
200 */
201TEST_CASE( "observerCtrl default stream writers are managed but not selectable", "[observerCtrl]" )
202{
203 observerCtrl_test app( "observerCtrl_test" );
204 app.configureStreamWriters( { "camsci1" }, { "camlowfs" } );
205
206 REQUIRE( app.writerExposed( "camsci1" ) );
207 REQUIRE_FALSE( app.writerExposed( "camlowfs" ) );
208
209 REQUIRE( app.setWriterWritingState( "camlowfs", pcf::IndiElement::Off ) == 0 );
210 REQUIRE( app.beginWriter( "camlowfs" ) );
211 REQUIRE( app.endWriter( "camlowfs" ) );
212}
213
214/// Verify observerCtrl does not claim ownership when a writer state has not been received yet.
215/**
216 * \ingroup observerCtrl_unit_test
217 */
218TEST_CASE( "observerCtrl does not stop writers with unknown initial state", "[observerCtrl]" )
219{
220 observerCtrl_test app( "observerCtrl_test" );
221 app.configureStreamWriters( {}, { "camlowfs" } );
222
223 REQUIRE( app.beginWriter( "camlowfs" ) );
224 REQUIRE_FALSE( app.endWriter( "camlowfs" ) );
225}
226
227} // namespace observerCtrlTest
228
229} // namespace libXWCTest
The MagAO-X Observer Controller.
int setCallBack_streamWriterWriting(const pcf::IndiProperty &ipRecv)
Handle remote stream writer writing property updates.
bool endObservationStreamWriter(const std::string &writerName)
Determine whether observerCtrl should stop a stream writer when an observation ends.
bool beginObservationStreamWriter(const std::string &writerName)
Determine whether observerCtrl should start a stream writer for a new observation.
TEST_CASE("observerCtrl INDI callbacks validate device and property names", "[observerCtrl]")
Verify the observerCtrl INDI callback validators accept only the expected properties.
#define XWCTEST_INDI_NEW_CALLBACK(testclass, propname)
Catch-2 tests for whether a NEW callback properly validates the input property properly.
Namespace for all libXWC tests.
#define XWCTEST_SETUP_INDI_NEW_PROP(propname)