API
 
Loading...
Searching...
No Matches
MagAOXApp_test.cpp
Go to the documentation of this file.
1// #define CATCH_CONFIG_MAIN
2#include "../../../tests/catch2/catch.hpp"
3
4#include <mx/sys/timeUtils.hpp>
5
6#include "../MagAOXApp.hpp"
7
9{
10
12{
13 MagAOXApp_test(bool gitmod = false) : MagAOXApp( "sha1", gitmod )
14 {
15 }
16
17 virtual int appStartup()
18 {
19 return 0;
20 }
21 virtual int appLogic()
22 {
23 return 0;
24 }
25 virtual int appShutdown()
26 {
27 return 0;
28 }
29
34
39
44
45 std::string &invokedName()
46 {
48 }
49
50 bool &doHelp()
51 {
53 }
54
56 {
58 }
59
60 void setConfigName( const std::string &cn )
61 {
63
65 }
66
67 void setConfigBase( const std::string &cb )
68 {
70 }
71
72 int called_back{ 0 };
73
75 {
76 pcf::IndiProperty ip(pcf::IndiProperty::Switch);
77 ip.setDevice(configName());
78 ip.setName("fsm_clear_alert");
79 ip.add(pcf::IndiElement("request"));
80 ip["request"].setSwitchState(pcf::IndiElement::On);
81
83 }
84
85};
86
87int callback( void *app, const pcf::IndiProperty &ipRecv )
88{
89 static_cast<void>( ipRecv ); // be unused
90
91 MagAOXApp_test *appt = static_cast<MagAOXApp_test *>( app );
92
93 appt->called_back = 1;
94
95 return 0;
96}
97
98SCENARIO( "MagAOXApp INDI NewProperty", "[app::MagAOXApp]" )
99{
100 GIVEN( "a new property request" )
101 {
102 WHEN( "a wrong device name" )
103 {
104 MagAOXApp_test app;
105
106 app.setConfigName( "test" );
107
108 REQUIRE( app.configName() == "test" );
109
110 pcf::IndiProperty prop;
111 app.registerIndiPropertyNew( prop,
112 "nprop",
113 pcf::IndiProperty::Number,
114 pcf::IndiProperty::ReadWrite,
115 pcf::IndiProperty::Idle,
116 callback );
117
118 pcf::IndiProperty nprop;
119
120 // First test the right device name
121 nprop.setDevice( "test" );
122 nprop.setName( "nprop" );
123
124 app.handleNewProperty( nprop );
125
126 REQUIRE( app.called_back == 1 );
127
128 app.called_back = 0;
129
130 // Now test the wrong device name
131 nprop.setDevice( "wrong" );
132
133 app.handleNewProperty( nprop );
134
135 REQUIRE( app.called_back == 0 );
136 }
137 }
138}
139
140TEST_CASE( "Setting defaults", "[app::MagAOXApp]" )
141{
142 SECTION( "using default paths, configname is invoked name" )
143 {
144 std::vector<std::string> argvstr( { "./execname" } );
145
146 std::vector<const char *> argv( argvstr.size() + 1, NULL );
147 for( size_t index = 0; index < argvstr.size(); ++index )
148 {
149 argv[index] = argvstr[index].c_str();
150 }
151
152 MagAOXApp_test app;
153
154 app.invokedName() = argv[0];
155 app.setDefaults( argv.size() - 1, const_cast<char **>( argv.data() ) );
156
157 REQUIRE( app.basePath() == MAGAOX_path );
158 REQUIRE( app.configDir() == app.basePath() + '/' + MAGAOX_configRelPath );
159 REQUIRE( app.configPathGlobal() == app.configDir() + "/magaox.conf" );
160 REQUIRE( app.calibDir() == app.basePath() + '/' + MAGAOX_calibRelPath );
161 REQUIRE( app.m_log.logPath() == app.basePath() + '/' + MAGAOX_logRelPath );
162 REQUIRE( app.sysPath() == app.basePath() + '/' + MAGAOX_sysRelPath );
163 REQUIRE( app.secretsPath() == app.basePath() + '/' + MAGAOX_secretsRelPath );
165 REQUIRE( app.configBase() == "" );
166 REQUIRE( app.configPathUser() == "" );
167 REQUIRE( app.configName() == "execname" );
168 REQUIRE( app.configPathLocal() == app.configDir() + "/execname.conf" );
169
170 REQUIRE( app.doHelp() == true );
171 }
172
173 SECTION( "using default paths, with config-ed name" )
174 {
175 std::vector<std::string> argvstr( { "./execname", "-n", "testapp" } );
176
177 std::vector<const char *> argv( argvstr.size() + 1, NULL );
178 for( size_t index = 0; index < argvstr.size(); ++index )
179 {
180 argv[index] = argvstr[index].c_str();
181 }
182
183 MagAOXApp_test app;
184 app.invokedName() = argv[0];
185
186 app.setDefaults( argv.size() - 1, const_cast<char **>( argv.data() ) );
187
188 REQUIRE( app.basePath() == MAGAOX_path );
189 REQUIRE( app.configDir() == app.basePath() + '/' + MAGAOX_configRelPath );
190 REQUIRE( app.configPathGlobal() == app.configDir() + "/magaox.conf" );
191 REQUIRE( app.calibDir() == app.basePath() + '/' + MAGAOX_calibRelPath );
192 REQUIRE( app.m_log.logPath() == app.basePath() + '/' + MAGAOX_logRelPath );
193
194 REQUIRE( app.sysPath() == app.basePath() + '/' + MAGAOX_sysRelPath );
195 REQUIRE( app.secretsPath() == app.basePath() + '/' + MAGAOX_secretsRelPath );
197 REQUIRE( app.configBase() == "" );
198 REQUIRE( app.configPathUser() == "" );
199 REQUIRE( app.configName() == "testapp" );
200 REQUIRE( app.configPathLocal() == app.configDir() + "/testapp.conf" );
201 REQUIRE( app.doHelp() == false );
202 }
203
204 // Something goes wrong here, third time is the charm.
205 // Hangs on config.parseCommandLine
206 SECTION( "using environment paths, with config-ed name" )
207 {
208 std::vector<const char *> argv;
209 std::vector<std::string> argvstr( { "./execname", "--name", "testapp2" } );
210
211 argv.resize( argvstr.size() + 1, NULL );
212 for( size_t index = 0; index < argvstr.size(); ++index )
213 {
214 argv[index] = argvstr[index].c_str();
215 }
216
217 char ppath[1024];
218 snprintf( ppath, sizeof( ppath ), "%s=/tmp/MagAOXApp_test", MAGAOX_env_path );
219 putenv( ppath );
220
221 char cpath[1024];
222 snprintf( cpath, sizeof( cpath ), "%s=config2", MAGAOX_env_config );
223 putenv( cpath );
224
225 char cbpath[1024];
226 snprintf( cbpath, sizeof( cbpath ), "%s=calib2", MAGAOX_env_calib );
227 putenv( cbpath );
228
229 char lpath[1024];
230 snprintf( lpath, sizeof( lpath ), "%s=logs2", MAGAOX_env_log );
231 putenv( lpath );
232
233 char syspath[1024];
234 snprintf( syspath, sizeof( syspath ), "%s=sys2", MAGAOX_env_sys );
235 putenv( syspath );
236
237 char secretspath[1024];
238 snprintf( secretspath, sizeof( secretspath ), "%s=secrets2", MAGAOX_env_secrets );
239 putenv( secretspath );
240
241 char cpupath[1024];
242 snprintf( cpupath, sizeof( cpupath ), "%s=/tmp/MagAOX/cpuset", MAGAOX_env_cpuset );
243 putenv( cpupath );
244
245 MagAOXApp_test app;
246
247 app.invokedName() = argv[0];
248 app.setConfigBase( "cbase" );
249
250 app.setDefaults( argv.size() - 1, const_cast<char **>( argv.data() ) );
251
252 REQUIRE( app.basePath() == "/tmp/MagAOXApp_test" );
253 REQUIRE( app.configDir() == app.basePath() + '/' + "config2" );
254 REQUIRE( app.configPathGlobal() == app.configDir() + "/magaox.conf" );
255 REQUIRE( app.calibDir() == app.basePath() + '/' + "calib2" );
256 REQUIRE( app.m_log.logPath() == app.basePath() + '/' + "logs2" );
257 REQUIRE( app.sysPath() == app.basePath() + '/' + "sys2" );
258 REQUIRE( app.secretsPath() == app.basePath() + '/' + "secrets2" );
259 REQUIRE( app.cpusetPath() == "/tmp/MagAOX/cpuset" );
260 REQUIRE( app.configBase() == "cbase" );
261 REQUIRE( app.configPathUser() == app.configDir() + "/cbase.conf" );
262 REQUIRE( app.configName() == "testapp2" );
263 REQUIRE( app.configPathLocal() == app.configDir() + "/testapp2.conf" );
264 REQUIRE( app.doHelp() == false );
265 }
266}
267
268TEST_CASE( "Configuring MagAOXApp", "[app::MagAOXApp]" )
269{
270 SECTION( "setup basic config" )
271 {
272 MagAOXApp_test app;
273 app.setPowerMgtEnabled(true);
274
275 app.setupBasicConfig();
276
277 REQUIRE(app.shutdown() == false);
278 }
279
280 SECTION( "load basic config w all defaults w/out pwr management" )
281 {
282 MagAOXApp_test app;
283 app.setPowerMgtEnabled(false);
284
285 app.setupBasicConfig();
286
287 app.loadBasicConfig();
288
289 app.checkConfig();
290
291 REQUIRE(app.stateAlert() == false);
292 REQUIRE(app.gitAlert() == false);
293 REQUIRE(app.shutdown() == false);
294
295 }
296
297 SECTION( "load basic config w all defaults w/out pwr management, git modified" )
298 {
299 std::vector<const char *> argv;
300 std::vector<std::string> argvstr( { "./execname", "--name", "testapp" } );
301
302 argv.resize( argvstr.size() + 1, NULL );
303 for( size_t index = 0; index < argvstr.size(); ++index )
304 {
305 argv[index] = argvstr[index].c_str();
306 }
307
308 MagAOXApp_test app(true);
309 app.setPowerMgtEnabled(false);
310
311 app.setupBasicConfig();
312
313 app.setDefaults(argv.size()-1, const_cast<char**>(argv.data()));
314
315 app.loadBasicConfig();
316
317 app.checkConfig();
318
319 REQUIRE(app.stateAlert() == true);
320 REQUIRE(app.gitAlert() == true);
321 REQUIRE(app.shutdown() == false);
322
323
324 app.doFSMClearAlert();
325 REQUIRE(app.stateAlert() == false);
326 REQUIRE(app.gitAlert() == true);
327 REQUIRE(app.shutdown() == false);
328
329 }
330
331 SECTION( "load basic config w all defaults w unconfigured pwr management" )
332 {
333 MagAOXApp_test app;
334 app.setPowerMgtEnabled(true);
335
336 app.setupBasicConfig();
337
338 app.loadBasicConfig();
339
340 REQUIRE(app.shutdown() == true);
341
342 app.checkConfig();
343
344 REQUIRE(app.stateAlert() == false);
345 REQUIRE(app.gitAlert() == false);
346 REQUIRE(app.shutdown() == true);
347 }
348}
349
350} // namespace MagAOXApp_tests
#define GIVEN(desc)
Definition catch.hpp:17763
#define WHEN(desc)
Definition catch.hpp:17765
#define TEST_CASE(...)
Definition catch.hpp:17712
#define SCENARIO(...)
Definition catch.hpp:17760
#define SECTION(...)
Definition catch.hpp:17716
#define REQUIRE(...)
Definition catch.hpp:17676
The base-class for XWCTk applications.
bool gitAlert()
Get the value of the git alert flag.
std::string basePath()
Get the.
std::string m_configName
The name of the configuration file (minus .conf).
std::string configBase()
Get the config base file.
int registerIndiPropertyNew(pcf::IndiProperty &prop, int(*)(void *, const pcf::IndiProperty &))
Register an INDI property which is exposed for others to request a New Property for.
int shutdown()
Get the value of the shutdown flag.
indiDriver< MagAOXApp > * m_indiDriver
The INDI driver wrapper. Constructed and initialized by execute, which starts and stops communication...
void handleNewProperty(const pcf::IndiProperty &ipRecv)
Handler for the new INDI property request.
std::string configDir()
Get the config directory.
std::string secretsPath()
Get the secrets path.
static int st_newCallBack_clearFSMAlert(void *app, const pcf::IndiProperty &ipRecv)
The static callback function to be registered for requesting to clear the FSM alert.
static logManagerT m_log
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Make a log entry.
MagAOXApp()=delete
Default c'tor is deleted.
virtual void setDefaults(int argc, char **argv)
Set the paths for config files.
std::string cpusetPath()
Get the cpuset path.
virtual void setupBasicConfig()
The basic MagAO-X configuration setup method. Should not normally be overridden.
std::string m_configBase
The name of a base config class for this app (minus .conf).
std::string configName()
Get the config name.
virtual void checkConfig()
Check for unused and unrecognized config options and settings.
virtual void loadBasicConfig()
The basic MagAO-X configuration processing method. Should not normally be overridden.
std::string sysPath()
Get the system path.
std::string calibDir()
Get the calibration directory.
bool stateAlert()
Get the value of the state alert flag.
#define MAGAOX_calibRelPath
The relative path to the calibration files.
Definition paths.hpp:36
#define MAGAOX_configRelPath
The relative path to the configuration files.
Definition paths.hpp:29
#define MAGAOX_logRelPath
The relative path to the log directory.
Definition paths.hpp:50
#define MAGAOX_sysRelPath
The relative path to the system directory.
Definition paths.hpp:64
#define MAGAOX_path
The path to the MagAO-X system files.
Definition paths.hpp:22
#define MAGAOX_secretsRelPath
The relative path to the secrets directory. Used for storing passwords, etc.
Definition paths.hpp:71
#define MAGAOX_cpusetPath
The absolute path to the cpuset mount point.
Definition paths.hpp:99
#define MAGAOX_env_sys
Environment variable setting the relative system directory path.
#define MAGAOX_env_path
Environment variable setting the MagAO-X path.
#define MAGAOX_env_log
Environment variable setting the relative log path.
#define MAGAOX_env_calib
Environment variable setting the relative calib path.
#define MAGAOX_env_secrets
Environment variable setting the relative secrets path.
#define MAGAOX_env_config
Environment variable setting the relative config path.
#define MAGAOX_env_cpuset
Environment variable setting the cpu set path.
int callback(void *app, const pcf::IndiProperty &ipRecv)
virtual int appStartup()
Any tasks to perform prior to the main event loop go here.
virtual int appLogic()
This is where derived applications implement their main FSM logic.
void setConfigBase(const std::string &cb)
void setConfigName(const std::string &cn)
virtual int appShutdown()
Any tasks to perform after main loop exit go here.