API
outletController_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 #define OUTLET_CTRL_TEST_NOINDI
7 #define OUTLET_CTRL_TEST_NOLOG
8 #include "../outletController.hpp"
9 
11 {
12 
13 struct outletControllerTest : public MagAOX::app::dev::outletController<outletControllerTest>
14 {
15  std::vector<double> m_timestamps;
16 
18  {
20  m_timestamps.resize(4,0);
21  turnOutletOff(0);
22  turnOutletOff(1);
23  turnOutletOff(2);
24  turnOutletOff(3);
25  }
26 
27  virtual int updateOutletState( int outletNum )
28  {
29  return m_outletStates[outletNum];
30  }
31 
32 
33  virtual int turnOutletOn( int outletNum )
34  {
35  m_outletStates[outletNum] = 2;
37  m_timestamps[outletNum] = mx::sys::get_curr_time();
38 
39  return 0;
40  }
41 
42  virtual int turnOutletOff( int outletNum )
43  {
44  m_outletStates[outletNum] = 0;
46  m_timestamps[outletNum] = mx::sys::get_curr_time();
47 
48  return 0;
49  }
50 
51 };
52 
53 
54 SCENARIO( "outletController Configuration", "[outletController]" )
55 {
56  GIVEN("a config file with 4 channels for 4 outlets")
57  {
58  WHEN("using outlet keyword, only outlet specified")
59  {
60  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel2", "channel3", "channel4"},
61  {"outlet", "outlet", "outlet", "outlet"},
62  {"0", "1", "2", "3"} );
63 
64  mx::app::appConfigurator config;
65  config.readConfig("/tmp/outletController_test.conf");
66 
68  int rv;
69  rv = pdt.setupConfig(config);
70  REQUIRE( rv == 0);
71 
72  rv = pdt.loadConfig(config);
73  REQUIRE( rv == 0);
74  REQUIRE( pdt.numChannels() == 4);
75 
76  std::vector<size_t> outlets, onOrder, offOrder;
77  std::vector<unsigned> onDelays, offDelays;
78  outlets = pdt.channelOutlets("channel1");
79  REQUIRE( outlets.size() == 1);
80  REQUIRE( outlets[0] == 0 );
81 
82  onOrder = pdt.channelOnOrder("channel1");
83  REQUIRE( onOrder.size() == 0);
84  offOrder = pdt.channelOffOrder("channel1");
85  REQUIRE( offOrder.size() == 0);
86  onDelays = pdt.channelOnDelays("channel1");
87  REQUIRE( onDelays.size() == 0);
88  offDelays = pdt.channelOffDelays("channel1");
89  REQUIRE( offDelays.size() == 0);
90 
91  outlets = pdt.channelOutlets("channel2");
92  REQUIRE( outlets.size() == 1);
93  REQUIRE( outlets[0] == 1 );
94 
95  onOrder = pdt.channelOnOrder("channel2");
96  REQUIRE( onOrder.size() == 0);
97  offOrder = pdt.channelOffOrder("channel2");
98  REQUIRE( offOrder.size() == 0);
99  onDelays = pdt.channelOnDelays("channel2");
100  REQUIRE( onDelays.size() == 0);
101  offDelays = pdt.channelOffDelays("channel2");
102  REQUIRE( offDelays.size() == 0);
103 
104  outlets = pdt.channelOutlets("channel3");
105  REQUIRE( outlets.size() == 1);
106  REQUIRE( outlets[0] == 2 );
107 
108  onOrder = pdt.channelOnOrder("channel3");
109  REQUIRE( onOrder.size() == 0);
110  offOrder = pdt.channelOffOrder("channel3");
111  REQUIRE( offOrder.size() == 0);
112  onDelays = pdt.channelOnDelays("channel3");
113  REQUIRE( onDelays.size() == 0);
114  offDelays = pdt.channelOffDelays("channel3");
115  REQUIRE( offDelays.size() == 0);
116 
117  outlets = pdt.channelOutlets("channel4");
118  REQUIRE( outlets.size() == 1);
119  REQUIRE( outlets[0] == 3 );
120 
121  onOrder = pdt.channelOnOrder("channel4");
122  REQUIRE( onOrder.size() == 0);
123  offOrder = pdt.channelOffOrder("channel4");
124  REQUIRE( offOrder.size() == 0);
125  onDelays = pdt.channelOnDelays("channel4");
126  REQUIRE( onDelays.size() == 0);
127  offDelays = pdt.channelOffDelays("channel4");
128  REQUIRE( offDelays.size() == 0);
129 
130  }
131 
132  WHEN("using outlet keyword, all specified")
133  {
134  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel1", "channel1", "channel1", "channel2", "channel2", "channel2", "channel2", "channel2", "channel3", "channel3", "channel3", "channel3", "channel3", "channel4", "channel4", "channel4", "channel4", "channel4" },
135  {"outlet", "onOrder", "offOrder", "onDelays", "offDelays", "outlet", "onOrder", "offOrder", "onDelays", "offDelays", "outlet", "onOrder", "offOrder", "onDelays", "offDelays", "outlet", "onOrder", "offOrder", "onDelays", "offDelays" },
136  {"0", "0", "0", "100", "120", "1", "0", "0", "105", "130", "2", "0", "0", "107", "132", "3", "0", "0", "108", "133"});
137 
138  mx::app::appConfigurator config;
139  config.readConfig("/tmp/outletController_test.conf");
140 
142  int rv;
143  rv = pdt.setupConfig(config);
144  REQUIRE( rv == 0);
145 
146  rv = pdt.loadConfig(config);
147  REQUIRE( rv == 0);
148  REQUIRE( pdt.numChannels() == 4);
149 
150  std::vector<size_t> outlets, onOrder, offOrder;
151  std::vector<unsigned> onDelays, offDelays;
152 
153  outlets = pdt.channelOutlets("channel1");
154  REQUIRE( outlets.size() == 1);
155  REQUIRE( outlets[0] == 0 );
156 
157  onOrder = pdt.channelOnOrder("channel1");
158  REQUIRE( onOrder.size() == 1);
159  REQUIRE( onOrder[0] == 0);
160  offOrder = pdt.channelOffOrder("channel1");
161  REQUIRE( offOrder.size() == 1);
162  REQUIRE( offOrder[0] == 0);
163  onDelays = pdt.channelOnDelays("channel1");
164  REQUIRE( onDelays.size() == 1);
165  REQUIRE( onDelays[0] == 100);
166  offDelays = pdt.channelOffDelays("channel1");
167  REQUIRE( offDelays.size() == 1);
168  REQUIRE( offDelays[0] == 120);
169 
170  outlets = pdt.channelOutlets("channel2");
171  REQUIRE( outlets.size() == 1);
172  REQUIRE( outlets[0] == 1 );
173 
174  onOrder = pdt.channelOnOrder("channel2");
175  REQUIRE( onOrder.size() == 1);
176  REQUIRE( onOrder[0] == 0);
177  offOrder = pdt.channelOffOrder("channel2");
178  REQUIRE( offOrder.size() == 1);
179  REQUIRE( offOrder[0] == 0);
180  onDelays = pdt.channelOnDelays("channel2");
181  REQUIRE( onDelays.size() == 1);
182  REQUIRE( onDelays[0] == 105);
183  offDelays = pdt.channelOffDelays("channel2");
184  REQUIRE( offDelays.size() == 1);
185  REQUIRE( offDelays[0] == 130);
186 
187  outlets = pdt.channelOutlets("channel3");
188  REQUIRE( outlets.size() == 1);
189  REQUIRE( outlets[0] == 2 );
190 
191  onOrder = pdt.channelOnOrder("channel3");
192  REQUIRE( onOrder.size() == 1);
193  REQUIRE( onOrder[0] == 0);
194  offOrder = pdt.channelOffOrder("channel3");
195  REQUIRE( offOrder.size() == 1);
196  REQUIRE( offOrder[0] == 0);
197  onDelays = pdt.channelOnDelays("channel3");
198  REQUIRE( onDelays.size() == 1);
199  REQUIRE( onDelays[0] == 107);
200  offDelays = pdt.channelOffDelays("channel3");
201  REQUIRE( offDelays.size() == 1);
202  REQUIRE( offDelays[0] == 132);
203 
204  outlets = pdt.channelOutlets("channel4");
205  REQUIRE( outlets.size() == 1);
206  REQUIRE( outlets[0] == 3 );
207 
208  onOrder = pdt.channelOnOrder("channel4");
209  REQUIRE( onOrder.size() == 1);
210  REQUIRE( onOrder[0] == 0);
211  offOrder = pdt.channelOffOrder("channel4");
212  REQUIRE( offOrder.size() == 1);
213  REQUIRE( offOrder[0] == 0);
214  onDelays = pdt.channelOnDelays("channel4");
215  REQUIRE( onDelays.size() == 1);
216  REQUIRE( onDelays[0] == 108);
217  offDelays = pdt.channelOffDelays("channel4");
218  REQUIRE( offDelays.size() == 1);
219  REQUIRE( offDelays[0] == 133);
220  }
221 
222  WHEN("using outlets keyword, only outlet specified")
223  {
224  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel2", "channel3", "channel4"},
225  {"outlets", "outlets", "outlets", "outlets"},
226  {"0", "1", "2", "3"} );
227 
228  mx::app::appConfigurator config;
229  config.readConfig("/tmp/outletController_test.conf");
230 
232  int rv;
233  rv = pdt.setupConfig(config);
234  REQUIRE( rv == 0);
235 
236  rv = pdt.loadConfig(config);
237  REQUIRE( rv == 0);
238  REQUIRE( pdt.numChannels() == 4);
239 
240  std::vector<size_t> outlets, onOrder, offOrder;
241  std::vector<unsigned> onDelays, offDelays;
242  outlets = pdt.channelOutlets("channel1");
243  REQUIRE( outlets.size() == 1);
244  REQUIRE( outlets[0] == 0 );
245 
246  onOrder = pdt.channelOnOrder("channel1");
247  REQUIRE( onOrder.size() == 0);
248  offOrder = pdt.channelOffOrder("channel1");
249  REQUIRE( offOrder.size() == 0);
250  onDelays = pdt.channelOnDelays("channel1");
251  REQUIRE( onDelays.size() == 0);
252  offDelays = pdt.channelOffDelays("channel1");
253  REQUIRE( offDelays.size() == 0);
254 
255  outlets = pdt.channelOutlets("channel2");
256  REQUIRE( outlets.size() == 1);
257  REQUIRE( outlets[0] == 1 );
258 
259  onOrder = pdt.channelOnOrder("channel2");
260  REQUIRE( onOrder.size() == 0);
261  offOrder = pdt.channelOffOrder("channel2");
262  REQUIRE( offOrder.size() == 0);
263  onDelays = pdt.channelOnDelays("channel2");
264  REQUIRE( onDelays.size() == 0);
265  offDelays = pdt.channelOffDelays("channel2");
266  REQUIRE( offDelays.size() == 0);
267 
268  outlets = pdt.channelOutlets("channel3");
269  REQUIRE( outlets.size() == 1);
270  REQUIRE( outlets[0] == 2 );
271 
272  onOrder = pdt.channelOnOrder("channel3");
273  REQUIRE( onOrder.size() == 0);
274  offOrder = pdt.channelOffOrder("channel3");
275  REQUIRE( offOrder.size() == 0);
276  onDelays = pdt.channelOnDelays("channel3");
277  REQUIRE( onDelays.size() == 0);
278  offDelays = pdt.channelOffDelays("channel3");
279  REQUIRE( offDelays.size() == 0);
280 
281  outlets = pdt.channelOutlets("channel4");
282  REQUIRE( outlets.size() == 1);
283  REQUIRE( outlets[0] == 3 );
284 
285  onOrder = pdt.channelOnOrder("channel4");
286  REQUIRE( onOrder.size() == 0);
287  offOrder = pdt.channelOffOrder("channel4");
288  REQUIRE( offOrder.size() == 0);
289  onDelays = pdt.channelOnDelays("channel4");
290  REQUIRE( onDelays.size() == 0);
291  offDelays = pdt.channelOffDelays("channel4");
292  REQUIRE( offDelays.size() == 0);
293  }
294 
295  WHEN("using outlets keyword, all specified")
296  {
297  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel1", "channel1", "channel1", "channel2", "channel2", "channel2", "channel2", "channel2", "channel3", "channel3", "channel3", "channel3", "channel3", "channel4", "channel4", "channel4", "channel4", "channel4" },
298  {"outlets", "onOrder", "offOrder", "onDelays", "offDelays", "outlets", "onOrder", "offOrder", "onDelays", "offDelays", "outlets", "onOrder", "offOrder", "onDelays", "offDelays", "outlets", "onOrder", "offOrder", "onDelays", "offDelays" },
299  {"0", "0", "0", "100", "120", "1", "0", "0", "105", "130", "2", "0", "0", "107", "132", "3", "0", "0", "108", "133"});
300 
301  mx::app::appConfigurator config;
302  config.readConfig("/tmp/outletController_test.conf");
303 
305  int rv;
306  rv = pdt.setupConfig(config);
307  REQUIRE( rv == 0);
308 
309  rv = pdt.loadConfig(config);
310  REQUIRE( rv == 0);
311  REQUIRE( pdt.numChannels() == 4);
312 
313  std::vector<size_t> outlets, onOrder, offOrder;
314  std::vector<unsigned> onDelays, offDelays;
315 
316  outlets = pdt.channelOutlets("channel1");
317  REQUIRE( outlets.size() == 1);
318  REQUIRE( outlets[0] == 0 );
319 
320  onOrder = pdt.channelOnOrder("channel1");
321  REQUIRE( onOrder.size() == 1);
322  REQUIRE( onOrder[0] == 0);
323  offOrder = pdt.channelOffOrder("channel1");
324  REQUIRE( offOrder.size() == 1);
325  REQUIRE( offOrder[0] == 0);
326  onDelays = pdt.channelOnDelays("channel1");
327  REQUIRE( onDelays.size() == 1);
328  REQUIRE( onDelays[0] == 100);
329  offDelays = pdt.channelOffDelays("channel1");
330  REQUIRE( offDelays.size() == 1);
331  REQUIRE( offDelays[0] == 120);
332 
333  outlets = pdt.channelOutlets("channel2");
334  REQUIRE( outlets.size() == 1);
335  REQUIRE( outlets[0] == 1 );
336 
337  onOrder = pdt.channelOnOrder("channel2");
338  REQUIRE( onOrder.size() == 1);
339  REQUIRE( onOrder[0] == 0);
340  offOrder = pdt.channelOffOrder("channel2");
341  REQUIRE( offOrder.size() == 1);
342  REQUIRE( offOrder[0] == 0);
343  onDelays = pdt.channelOnDelays("channel2");
344  REQUIRE( onDelays.size() == 1);
345  REQUIRE( onDelays[0] == 105);
346  offDelays = pdt.channelOffDelays("channel2");
347  REQUIRE( offDelays.size() == 1);
348  REQUIRE( offDelays[0] == 130);
349 
350  outlets = pdt.channelOutlets("channel3");
351  REQUIRE( outlets.size() == 1);
352  REQUIRE( outlets[0] == 2 );
353 
354  onOrder = pdt.channelOnOrder("channel3");
355  REQUIRE( onOrder.size() == 1);
356  REQUIRE( onOrder[0] == 0);
357  offOrder = pdt.channelOffOrder("channel3");
358  REQUIRE( offOrder.size() == 1);
359  REQUIRE( offOrder[0] == 0);
360  onDelays = pdt.channelOnDelays("channel3");
361  REQUIRE( onDelays.size() == 1);
362  REQUIRE( onDelays[0] == 107);
363  offDelays = pdt.channelOffDelays("channel3");
364  REQUIRE( offDelays.size() == 1);
365  REQUIRE( offDelays[0] == 132);
366 
367  outlets = pdt.channelOutlets("channel4");
368  REQUIRE( outlets.size() == 1);
369  REQUIRE( outlets[0] == 3 );
370 
371  onOrder = pdt.channelOnOrder("channel4");
372  REQUIRE( onOrder.size() == 1);
373  REQUIRE( onOrder[0] == 0);
374  offOrder = pdt.channelOffOrder("channel4");
375  REQUIRE( offOrder.size() == 1);
376  REQUIRE( offOrder[0] == 0);
377  onDelays = pdt.channelOnDelays("channel4");
378  REQUIRE( onDelays.size() == 1);
379  REQUIRE( onDelays[0] == 108);
380  offDelays = pdt.channelOffDelays("channel4");
381  REQUIRE( offDelays.size() == 1);
382  REQUIRE( offDelays[0] == 133);
383  }
384  }
385 
386  GIVEN("a config file with 2 channels for 4 outlets")
387  {
388  WHEN("using outlet keyword, only outlet specified")
389  {
390  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel2" },
391  {"outlet", "outlet" },
392  {"0,1", "2,3" } );
393 
394  mx::app::appConfigurator config;
395  config.readConfig("/tmp/outletController_test.conf");
396 
398  int rv;
399  rv = pdt.setupConfig(config);
400  REQUIRE( rv == 0);
401 
402  rv = pdt.loadConfig(config);
403  REQUIRE( rv == 0);
404  REQUIRE( pdt.numChannels() == 2);
405 
406  std::vector<size_t> outlets, onOrder, offOrder;
407  std::vector<unsigned> onDelays, offDelays;
408  outlets = pdt.channelOutlets("channel1");
409  REQUIRE( outlets.size() == 2);
410  REQUIRE( outlets[0] == 0 );
411  REQUIRE( outlets[1] == 1 );
412 
413  onOrder = pdt.channelOnOrder("channel1");
414  REQUIRE( onOrder.size() == 0);
415  offOrder = pdt.channelOffOrder("channel1");
416  REQUIRE( offOrder.size() == 0);
417  onDelays = pdt.channelOnDelays("channel1");
418  REQUIRE( onDelays.size() == 0);
419  offDelays = pdt.channelOffDelays("channel1");
420  REQUIRE( offDelays.size() == 0);
421 
422  outlets = pdt.channelOutlets("channel2");
423  REQUIRE( outlets.size() == 2);
424  REQUIRE( outlets[0] == 2 );
425  REQUIRE( outlets[1] == 3 );
426 
427  onOrder = pdt.channelOnOrder("channel2");
428  REQUIRE( onOrder.size() == 0);
429  offOrder = pdt.channelOffOrder("channel2");
430  REQUIRE( offOrder.size() == 0);
431  onDelays = pdt.channelOnDelays("channel2");
432  REQUIRE( onDelays.size() == 0);
433  offDelays = pdt.channelOffDelays("channel2");
434  REQUIRE( offDelays.size() == 0);
435 
436 
437  }
438 
439  WHEN("using outlet keyword, all specified")
440  {
441  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1","channel1", "channel1", "channel1", "channel1", "channel2", "channel2", "channel2", "channel2", "channel2" },
442  {"outlet", "onOrder", "offOrder", "onDelays", "offDelays", "outlet", "onOrder", "offOrder", "onDelays", "offDelays" },
443  {"0,1", "0,1", "1,0", "0,105", "0,107", "2,3", "1,0", "0,1", "0,106", "0,108" } );
444 
445  mx::app::appConfigurator config;
446  config.readConfig("/tmp/outletController_test.conf");
447 
449  int rv;
450  rv = pdt.setupConfig(config);
451  REQUIRE( rv == 0);
452 
453  rv = pdt.loadConfig(config);
454  REQUIRE( rv == 0);
455  REQUIRE( pdt.numChannels() == 2);
456 
457  std::vector<size_t> outlets, onOrder, offOrder;
458  std::vector<unsigned> onDelays, offDelays;
459  outlets = pdt.channelOutlets("channel1");
460  REQUIRE( outlets.size() == 2);
461  REQUIRE( outlets[0] == 0 );
462  REQUIRE( outlets[1] == 1 );
463 
464  onOrder = pdt.channelOnOrder("channel1");
465  REQUIRE( onOrder.size() == 2);
466  REQUIRE( onOrder[0] == 0 );
467  REQUIRE( onOrder[1] == 1 );
468  offOrder = pdt.channelOffOrder("channel1");
469  REQUIRE( offOrder.size() == 2);
470  REQUIRE( offOrder[0] == 1 );
471  REQUIRE( offOrder[1] == 0 );
472  onDelays = pdt.channelOnDelays("channel1");
473  REQUIRE( onDelays.size() == 2);
474  REQUIRE( onDelays[0] == 0 );
475  REQUIRE( onDelays[1] == 105 );
476  offDelays = pdt.channelOffDelays("channel1");
477  REQUIRE( offDelays.size() == 2);
478  REQUIRE( offDelays[0] == 0 );
479  REQUIRE( offDelays[1] == 107 );
480 
481  outlets = pdt.channelOutlets("channel2");
482  REQUIRE( outlets.size() == 2);
483  REQUIRE( outlets[0] == 2 );
484  REQUIRE( outlets[1] == 3 );
485 
486  onOrder = pdt.channelOnOrder("channel2");
487  REQUIRE( onOrder.size() == 2);
488  REQUIRE( onOrder[0] == 1 );
489  REQUIRE( onOrder[1] == 0 );
490  offOrder = pdt.channelOffOrder("channel2");
491  REQUIRE( offOrder.size() == 2);
492  REQUIRE( offOrder[0] == 0 );
493  REQUIRE( offOrder[1] == 1 );
494  onDelays = pdt.channelOnDelays("channel2");
495  REQUIRE( onDelays.size() == 2);
496  REQUIRE( onDelays[0] == 0 );
497  REQUIRE( onDelays[1] == 106 );
498  offDelays = pdt.channelOffDelays("channel2");
499  REQUIRE( offDelays.size() == 2);
500  REQUIRE( offDelays[0] == 0 );
501  REQUIRE( offDelays[1] == 108 );
502  }
503 
504  WHEN("using outlets keyword, only outlet specified")
505  {
506  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel2" },
507  {"outlets", "outlets" },
508  {"0,1", "2,3" } );
509 
510  mx::app::appConfigurator config;
511  config.readConfig("/tmp/outletController_test.conf");
512 
514  int rv;
515  rv = pdt.setupConfig(config);
516  REQUIRE( rv == 0);
517 
518  rv = pdt.loadConfig(config);
519  REQUIRE( rv == 0);
520  REQUIRE( pdt.numChannels() == 2);
521 
522  std::vector<size_t> outlets, onOrder, offOrder;
523  std::vector<unsigned> onDelays, offDelays;
524  outlets = pdt.channelOutlets("channel1");
525  REQUIRE( outlets.size() == 2);
526  REQUIRE( outlets[0] == 0 );
527  REQUIRE( outlets[1] == 1 );
528 
529  onOrder = pdt.channelOnOrder("channel1");
530  REQUIRE( onOrder.size() == 0);
531  offOrder = pdt.channelOffOrder("channel1");
532  REQUIRE( offOrder.size() == 0);
533  onDelays = pdt.channelOnDelays("channel1");
534  REQUIRE( onDelays.size() == 0);
535  offDelays = pdt.channelOffDelays("channel1");
536  REQUIRE( offDelays.size() == 0);
537 
538 
539  outlets = pdt.channelOutlets("channel2");
540  REQUIRE( outlets.size() == 2);
541  REQUIRE( outlets[0] == 2 );
542  REQUIRE( outlets[1] == 3 );
543 
544  onOrder = pdt.channelOnOrder("channel2");
545  REQUIRE( onOrder.size() == 0);
546  offOrder = pdt.channelOffOrder("channel2");
547  REQUIRE( offOrder.size() == 0);
548  onDelays = pdt.channelOnDelays("channel2");
549  REQUIRE( onDelays.size() == 0);
550  offDelays = pdt.channelOffDelays("channel2");
551  REQUIRE( offDelays.size() == 0);
552  }
553 
554  WHEN("using outlets keyword, all specified")
555  {
556  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1","channel1", "channel1", "channel1", "channel1", "channel2", "channel2", "channel2", "channel2", "channel2" },
557  {"outlets", "onOrder", "offOrder", "onDelays", "offDelays", "outlets", "onOrder", "offOrder", "onDelays", "offDelays" },
558  {"0,2", "0,1", "1,0", "0,105", "0,107", "1,3", "1,0", "0,1", "0,106", "0,108" } );
559 
560  mx::app::appConfigurator config;
561  config.readConfig("/tmp/outletController_test.conf");
562 
564  int rv;
565  rv = pdt.setupConfig(config);
566  REQUIRE( rv == 0);
567 
568  rv = pdt.loadConfig(config);
569  REQUIRE( rv == 0);
570  REQUIRE( pdt.numChannels() == 2);
571 
572  std::vector<size_t> outlets, onOrder, offOrder;
573  std::vector<unsigned> onDelays, offDelays;
574  outlets = pdt.channelOutlets("channel1");
575  REQUIRE( outlets.size() == 2);
576  REQUIRE( outlets[0] == 0 );
577  REQUIRE( outlets[1] == 2 );
578 
579  onOrder = pdt.channelOnOrder("channel1");
580  REQUIRE( onOrder.size() == 2);
581  REQUIRE( onOrder[0] == 0 );
582  REQUIRE( onOrder[1] == 1 );
583  offOrder = pdt.channelOffOrder("channel1");
584  REQUIRE( offOrder.size() == 2);
585  REQUIRE( offOrder[0] == 1 );
586  REQUIRE( offOrder[1] == 0 );
587  onDelays = pdt.channelOnDelays("channel1");
588  REQUIRE( onDelays.size() == 2);
589  REQUIRE( onDelays[0] == 0 );
590  REQUIRE( onDelays[1] == 105 );
591  offDelays = pdt.channelOffDelays("channel1");
592  REQUIRE( offDelays.size() == 2);
593  REQUIRE( offDelays[0] == 0 );
594  REQUIRE( offDelays[1] == 107 );
595 
596  outlets = pdt.channelOutlets("channel2");
597  REQUIRE( outlets.size() == 2);
598  REQUIRE( outlets[0] == 1 );
599  REQUIRE( outlets[1] == 3 );
600 
601  onOrder = pdt.channelOnOrder("channel2");
602  REQUIRE( onOrder.size() == 2);
603  REQUIRE( onOrder[0] == 1 );
604  REQUIRE( onOrder[1] == 0 );
605  offOrder = pdt.channelOffOrder("channel2");
606  REQUIRE( offOrder.size() == 2);
607  REQUIRE( offOrder[0] == 0 );
608  REQUIRE( offOrder[1] == 1 );
609  onDelays = pdt.channelOnDelays("channel2");
610  REQUIRE( onDelays.size() == 2);
611  REQUIRE( onDelays[0] == 0 );
612  REQUIRE( onDelays[1] == 106 );
613  offDelays = pdt.channelOffDelays("channel2");
614  REQUIRE( offDelays.size() == 2);
615  REQUIRE( offDelays[0] == 0 );
616  REQUIRE( offDelays[1] == 108 );
617  }
618  }
619 }
620 
621 SCENARIO( "outletController Operation", "[outletController]" )
622 {
623  GIVEN("a config file with 4 channels for 4 outlets, only outlet specified")
624  {
625  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel2", "channel3", "channel4"},
626  {"outlet", "outlet", "outlet", "outlet"},
627  {"0", "1", "2", "3"} );
628 
629  mx::app::appConfigurator config;
630  config.readConfig("/tmp/outletController_test.conf");
631 
633  pdt.setupConfig(config);
634  pdt.loadConfig(config);
635 
636  WHEN("test device startup outlet states")
637  {
638  //Verify outlet startup state
639  REQUIRE( pdt.outletState(0) == 0 );
640  REQUIRE( pdt.outletState(1) == 0 );
641  REQUIRE( pdt.outletState(2) == 0 );
642  REQUIRE( pdt.outletState(3) == 0 );
643 
644  //Verify channel state at startup
645  REQUIRE( pdt.channelState("channel1") == 0 );
646  REQUIRE( pdt.channelState("channel2") == 0 );
647  REQUIRE( pdt.channelState("channel3") == 0 );
648  REQUIRE( pdt.channelState("channel4") == 0 );
649  }
650  WHEN("operating a single channel")
651  {
652  //Turn on channel1
653  pdt.turnChannelOn("channel1");
654 
655  //Verify outlet state
656  REQUIRE( pdt.outletState(0) == 2 );
657  REQUIRE( pdt.outletState(1) == 0 );
658  REQUIRE( pdt.outletState(2) == 0 );
659  REQUIRE( pdt.outletState(3) == 0 );
660 
661  //Verify channel state
662  REQUIRE( pdt.channelState("channel1") == 2 );
663  REQUIRE( pdt.channelState("channel2") == 0 );
664  REQUIRE( pdt.channelState("channel3") == 0 );
665  REQUIRE( pdt.channelState("channel4") == 0 );
666 
667  //Turn off channel1
668  pdt.turnChannelOff("channel1");
669 
670  //Verify outlet state
671  REQUIRE( pdt.outletState(0) == 0 );
672  REQUIRE( pdt.outletState(1) == 0 );
673  REQUIRE( pdt.outletState(2) == 0 );
674  REQUIRE( pdt.outletState(3) == 0 );
675 
676  //Verify channel state
677  REQUIRE( pdt.channelState("channel1") == 0 );
678  REQUIRE( pdt.channelState("channel2") == 0 );
679  REQUIRE( pdt.channelState("channel3") == 0 );
680  REQUIRE( pdt.channelState("channel4") == 0 );
681 
682  //Turn on channel2
683  pdt.turnChannelOn("channel2");
684 
685  //Verify outlet state
686  REQUIRE( pdt.outletState(0) == 0 );
687  REQUIRE( pdt.outletState(1) == 2 );
688  REQUIRE( pdt.outletState(2) == 0 );
689  REQUIRE( pdt.outletState(3) == 0 );
690 
691  //Verify channel state
692  REQUIRE( pdt.channelState("channel1") == 0 );
693  REQUIRE( pdt.channelState("channel2") == 2 );
694  REQUIRE( pdt.channelState("channel3") == 0 );
695  REQUIRE( pdt.channelState("channel4") == 0 );
696 
697  //Turn off channel1
698  pdt.turnChannelOff("channel2");
699 
700  //Verify outlet state
701  REQUIRE( pdt.outletState(0) == 0 );
702  REQUIRE( pdt.outletState(1) == 0 );
703  REQUIRE( pdt.outletState(2) == 0 );
704  REQUIRE( pdt.outletState(3) == 0 );
705 
706  //Verify channel state
707  REQUIRE( pdt.channelState("channel1") == 0 );
708  REQUIRE( pdt.channelState("channel2") == 0 );
709  REQUIRE( pdt.channelState("channel3") == 0 );
710  REQUIRE( pdt.channelState("channel4") == 0 );
711 
712  //Turn on channel3
713  pdt.turnChannelOn("channel3");
714 
715  //Verify outlet state
716  REQUIRE( pdt.outletState(0) == 0 );
717  REQUIRE( pdt.outletState(1) == 0 );
718  REQUIRE( pdt.outletState(2) == 2 );
719  REQUIRE( pdt.outletState(3) == 0 );
720 
721  //Verify channel state
722  REQUIRE( pdt.channelState("channel1") == 0 );
723  REQUIRE( pdt.channelState("channel2") == 0 );
724  REQUIRE( pdt.channelState("channel3") == 2 );
725  REQUIRE( pdt.channelState("channel4") == 0 );
726 
727  //Turn off channel1
728  pdt.turnChannelOff("channel3");
729 
730  //Verify outlet state
731  REQUIRE( pdt.outletState(0) == 0 );
732  REQUIRE( pdt.outletState(1) == 0 );
733  REQUIRE( pdt.outletState(2) == 0 );
734  REQUIRE( pdt.outletState(3) == 0 );
735 
736  //Verify channel state
737  REQUIRE( pdt.channelState("channel1") == 0 );
738  REQUIRE( pdt.channelState("channel2") == 0 );
739  REQUIRE( pdt.channelState("channel3") == 0 );
740  REQUIRE( pdt.channelState("channel4") == 0 );
741 
742  //Turn on channel4
743  pdt.turnChannelOn("channel4");
744 
745  //Verify outlet state
746  REQUIRE( pdt.outletState(0) == 0 );
747  REQUIRE( pdt.outletState(1) == 0 );
748  REQUIRE( pdt.outletState(2) == 0 );
749  REQUIRE( pdt.outletState(3) == 2 );
750 
751  //Verify channel state
752  REQUIRE( pdt.channelState("channel1") == 0 );
753  REQUIRE( pdt.channelState("channel2") == 0 );
754  REQUIRE( pdt.channelState("channel3") == 0 );
755  REQUIRE( pdt.channelState("channel4") == 2 );
756 
757  //Turn off channel1
758  pdt.turnChannelOff("channel4");
759 
760  //Verify outlet startup state
761  REQUIRE( pdt.outletState(0) == 0 );
762  REQUIRE( pdt.outletState(1) == 0 );
763  REQUIRE( pdt.outletState(2) == 0 );
764  REQUIRE( pdt.outletState(3) == 0 );
765 
766  //Verify channel state at startup
767  REQUIRE( pdt.channelState("channel1") == 0 );
768  REQUIRE( pdt.channelState("channel2") == 0 );
769  REQUIRE( pdt.channelState("channel3") == 0 );
770  REQUIRE( pdt.channelState("channel4") == 0 );
771  }
772  WHEN("operating multiple channels")
773  {
774  //Turn on channel1&2
775  pdt.turnChannelOn("channel1");
776  pdt.turnChannelOn("channel2");
777 
778  //Verify outlet state
779  REQUIRE( pdt.outletState(0) == 2 );
780  REQUIRE( pdt.outletState(1) == 2 );
781  REQUIRE( pdt.outletState(2) == 0 );
782  REQUIRE( pdt.outletState(3) == 0 );
783 
784  //Verify channel state
785  REQUIRE( pdt.channelState("channel1") == 2 );
786  REQUIRE( pdt.channelState("channel2") == 2 );
787  REQUIRE( pdt.channelState("channel3") == 0 );
788  REQUIRE( pdt.channelState("channel4") == 0 );
789 
790  //Turn off channel1&2
791  pdt.turnChannelOff("channel1");
792  pdt.turnChannelOff("channel2");
793 
794  //Verify outlet state
795  REQUIRE( pdt.outletState(0) == 0 );
796  REQUIRE( pdt.outletState(1) == 0 );
797  REQUIRE( pdt.outletState(2) == 0 );
798  REQUIRE( pdt.outletState(3) == 0 );
799 
800  //Verify channel state
801  REQUIRE( pdt.channelState("channel1") == 0 );
802  REQUIRE( pdt.channelState("channel2") == 0 );
803  REQUIRE( pdt.channelState("channel3") == 0 );
804  REQUIRE( pdt.channelState("channel4") == 0 );
805 
806  //Turn on channel3&4
807  pdt.turnChannelOn("channel3");
808  pdt.turnChannelOn("channel4");
809 
810  //Verify outlet state
811  REQUIRE( pdt.outletState(0) == 0 );
812  REQUIRE( pdt.outletState(1) == 0 );
813  REQUIRE( pdt.outletState(2) == 2 );
814  REQUIRE( pdt.outletState(3) == 2 );
815 
816  //Verify channel state
817  REQUIRE( pdt.channelState("channel1") == 0 );
818  REQUIRE( pdt.channelState("channel2") == 0 );
819  REQUIRE( pdt.channelState("channel3") == 2 );
820  REQUIRE( pdt.channelState("channel4") == 2 );
821 
822  //Turn off channel2&4
823  pdt.turnChannelOff("channel3");
824  pdt.turnChannelOff("channel4");
825 
826  //Verify outlet state
827  REQUIRE( pdt.outletState(0) == 0 );
828  REQUIRE( pdt.outletState(1) == 0 );
829  REQUIRE( pdt.outletState(2) == 0 );
830  REQUIRE( pdt.outletState(3) == 0 );
831 
832  //Verify channel state
833  REQUIRE( pdt.channelState("channel1") == 0 );
834  REQUIRE( pdt.channelState("channel2") == 0 );
835  REQUIRE( pdt.channelState("channel3") == 0 );
836  REQUIRE( pdt.channelState("channel4") == 0 );
837 
838  //Turn on channel1&3
839  pdt.turnChannelOn("channel1");
840  pdt.turnChannelOn("channel3");
841 
842  //Verify outlet state
843  REQUIRE( pdt.outletState(0) == 2 );
844  REQUIRE( pdt.outletState(1) == 0 );
845  REQUIRE( pdt.outletState(2) == 2 );
846  REQUIRE( pdt.outletState(3) == 0 );
847 
848  //Verify channel state
849  REQUIRE( pdt.channelState("channel1") == 2 );
850  REQUIRE( pdt.channelState("channel2") == 0 );
851  REQUIRE( pdt.channelState("channel3") == 2 );
852  REQUIRE( pdt.channelState("channel4") == 0 );
853 
854  //Turn off channel1&3
855  pdt.turnChannelOff("channel1");
856  pdt.turnChannelOff("channel3");
857 
858  //Verify outlet state
859  REQUIRE( pdt.outletState(0) == 0 );
860  REQUIRE( pdt.outletState(1) == 0 );
861  REQUIRE( pdt.outletState(2) == 0 );
862  REQUIRE( pdt.outletState(3) == 0 );
863 
864  //Verify channel state
865  REQUIRE( pdt.channelState("channel1") == 0 );
866  REQUIRE( pdt.channelState("channel2") == 0 );
867  REQUIRE( pdt.channelState("channel3") == 0 );
868  REQUIRE( pdt.channelState("channel4") == 0 );
869 
870  //Turn on channel2&4
871  pdt.turnChannelOn("channel2");
872  pdt.turnChannelOn("channel4");
873 
874  //Verify outlet state
875  REQUIRE( pdt.outletState(0) == 0 );
876  REQUIRE( pdt.outletState(1) == 2 );
877  REQUIRE( pdt.outletState(2) == 0 );
878  REQUIRE( pdt.outletState(3) == 2 );
879 
880  //Verify channel state
881  REQUIRE( pdt.channelState("channel1") == 0 );
882  REQUIRE( pdt.channelState("channel2") == 2 );
883  REQUIRE( pdt.channelState("channel3") == 0 );
884  REQUIRE( pdt.channelState("channel4") == 2 );
885 
886  //Turn off channel2&4
887  pdt.turnChannelOff("channel2");
888  pdt.turnChannelOff("channel4");
889 
890  //Verify outlet startup state
891  REQUIRE( pdt.outletState(0) == 0 );
892  REQUIRE( pdt.outletState(1) == 0 );
893  REQUIRE( pdt.outletState(2) == 0 );
894  REQUIRE( pdt.outletState(3) == 0 );
895 
896  //Verify channel state at startup
897  REQUIRE( pdt.channelState("channel1") == 0 );
898  REQUIRE( pdt.channelState("channel2") == 0 );
899  REQUIRE( pdt.channelState("channel3") == 0 );
900  REQUIRE( pdt.channelState("channel4") == 0 );
901  }
902  WHEN("outlets intermediate")
903  {
904  pdt.m_outletStates[0] = 1;
905 
906  //Verify outlet state
907  REQUIRE( pdt.outletState(0) == 1 );
908  REQUIRE( pdt.outletState(1) == 0 );
909  REQUIRE( pdt.outletState(2) == 0 );
910  REQUIRE( pdt.outletState(3) == 0 );
911 
912  //Verify channel state
913  REQUIRE( pdt.channelState("channel1") == 1 );
914  REQUIRE( pdt.channelState("channel2") == 0 );
915  REQUIRE( pdt.channelState("channel3") == 0 );
916  REQUIRE( pdt.channelState("channel4") == 0 );
917 
918  pdt.m_outletStates[0] = 0;
919 
920  pdt.m_outletStates[1] = 1;
921 
922  //Verify outlet state
923  REQUIRE( pdt.outletState(0) == 0 );
924  REQUIRE( pdt.outletState(1) == 1 );
925  REQUIRE( pdt.outletState(2) == 0 );
926  REQUIRE( pdt.outletState(3) == 0 );
927 
928  //Verify channel state
929  REQUIRE( pdt.channelState("channel1") == 0 );
930  REQUIRE( pdt.channelState("channel2") == 1 );
931  REQUIRE( pdt.channelState("channel3") == 0 );
932  REQUIRE( pdt.channelState("channel4") == 0 );
933 
934  pdt.m_outletStates[1] = 0;
935 
936  pdt.m_outletStates[2] = 1;
937 
938  //Verify outlet state
939  REQUIRE( pdt.outletState(0) == 0 );
940  REQUIRE( pdt.outletState(1) == 0 );
941  REQUIRE( pdt.outletState(2) == 1 );
942  REQUIRE( pdt.outletState(3) == 0 );
943 
944  //Verify channel state
945  REQUIRE( pdt.channelState("channel1") == 0 );
946  REQUIRE( pdt.channelState("channel2") == 0 );
947  REQUIRE( pdt.channelState("channel3") == 1 );
948  REQUIRE( pdt.channelState("channel4") == 0 );
949 
950  pdt.m_outletStates[2] = 0;
951 
952  pdt.m_outletStates[3] = 1;
953 
954  //Verify outlet state
955  REQUIRE( pdt.outletState(0) == 0 );
956  REQUIRE( pdt.outletState(1) == 0 );
957  REQUIRE( pdt.outletState(2) == 0 );
958  REQUIRE( pdt.outletState(3) == 1 );
959 
960  //Verify channel state
961  REQUIRE( pdt.channelState("channel1") == 0 );
962  REQUIRE( pdt.channelState("channel2") == 0 );
963  REQUIRE( pdt.channelState("channel3") == 0 );
964  REQUIRE( pdt.channelState("channel4") == 1 );
965 
966  pdt.m_outletStates[3] = 0;
967  }
968 
969  }
970 
971  GIVEN("a config file with 2 channels for 4 outlets, only outlet specified")
972  {
973  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel2" },
974  {"outlet", "outlet" },
975  {"0,1", "2,3" } );
976 
977  mx::app::appConfigurator config;
978  config.readConfig("/tmp/outletController_test.conf");
979 
981  pdt.setupConfig(config);
982  pdt.loadConfig(config);
983 
984  WHEN("test device startup outlet states")
985  {
986  //Verify outlet startup state
987  REQUIRE( pdt.outletState(0) == 0 );
988  REQUIRE( pdt.outletState(1) == 0 );
989  REQUIRE( pdt.outletState(2) == 0 );
990  REQUIRE( pdt.outletState(3) == 0 );
991 
992  //Verify channel state at startup
993  REQUIRE( pdt.channelState("channel1") == 0 );
994  REQUIRE( pdt.channelState("channel2") == 0 );
995  }
996  WHEN("operating a single channel")
997  {
998  //Turn on channel1
999  pdt.turnChannelOn("channel1");
1000 
1001  //Verify outlet state
1002  REQUIRE( pdt.outletState(0) == 2 );
1003  REQUIRE( pdt.outletState(1) == 2 );
1004  REQUIRE( pdt.outletState(2) == 0 );
1005  REQUIRE( pdt.outletState(3) == 0 );
1006 
1007  //verify outlet order
1008  REQUIRE( pdt.m_timestamps[1] > pdt.m_timestamps[0]);
1009 
1010  //Verify channel state
1011  REQUIRE( pdt.channelState("channel1") == 2 );
1012  REQUIRE( pdt.channelState("channel2") == 0 );
1013 
1014  //Turn off channel1
1015  pdt.turnChannelOff("channel1");
1016 
1017  //Verify outlet state
1018  REQUIRE( pdt.outletState(0) == 0 );
1019  REQUIRE( pdt.outletState(1) == 0 );
1020  REQUIRE( pdt.outletState(2) == 0 );
1021  REQUIRE( pdt.outletState(3) == 0 );
1022 
1023  //Verify channel state
1024  REQUIRE( pdt.channelState("channel1") == 0 );
1025  REQUIRE( pdt.channelState("channel2") == 0 );
1026 
1027  //Turn on channel2
1028  pdt.turnChannelOn("channel2");
1029 
1030  //Verify outlet state
1031  REQUIRE( pdt.outletState(0) == 0 );
1032  REQUIRE( pdt.outletState(1) == 0 );
1033  REQUIRE( pdt.outletState(2) == 2 );
1034  REQUIRE( pdt.outletState(3) == 2 );
1035 
1036  //verify outlet order
1037  REQUIRE( pdt.m_timestamps[3] > pdt.m_timestamps[2]);
1038 
1039  //Verify channel state
1040  REQUIRE( pdt.channelState("channel1") == 0 );
1041  REQUIRE( pdt.channelState("channel2") == 2 );
1042 
1043  //Turn off channel2
1044  pdt.turnChannelOff("channel2");
1045 
1046  //Verify outlet state
1047  REQUIRE( pdt.outletState(0) == 0 );
1048  REQUIRE( pdt.outletState(1) == 0 );
1049  REQUIRE( pdt.outletState(2) == 0 );
1050  REQUIRE( pdt.outletState(3) == 0 );
1051 
1052  //Verify channel state
1053  REQUIRE( pdt.channelState("channel1") == 0 );
1054  REQUIRE( pdt.channelState("channel2") == 0 );
1055  }
1056  WHEN("operating two channels")
1057  {
1058  //Turn on channels
1059  pdt.turnChannelOn("channel1");
1060  pdt.turnChannelOn("channel2");
1061 
1062  //Verify outlet state
1063  REQUIRE( pdt.outletState(0) == 2 );
1064  REQUIRE( pdt.outletState(1) == 2 );
1065  REQUIRE( pdt.outletState(2) == 2 );
1066  REQUIRE( pdt.outletState(3) == 2 );
1067 
1068  //Verify channel state
1069  REQUIRE( pdt.channelState("channel1") == 2 );
1070  REQUIRE( pdt.channelState("channel2") == 2 );
1071 
1072  //Turn off channel1&2
1073  pdt.turnChannelOff("channel1");
1074  pdt.turnChannelOff("channel2");
1075 
1076  //Verify outlet state
1077  REQUIRE( pdt.outletState(0) == 0 );
1078  REQUIRE( pdt.outletState(1) == 0 );
1079  REQUIRE( pdt.outletState(2) == 0 );
1080  REQUIRE( pdt.outletState(3) == 0 );
1081 
1082  //Verify channel state
1083  REQUIRE( pdt.channelState("channel1") == 0 );
1084  REQUIRE( pdt.channelState("channel2") == 0 );
1085 
1086  }
1087  WHEN("outlets intermediate")
1088  {
1089  pdt.m_outletStates[0] = 2;
1090 
1091  //Verify outlet state
1092  REQUIRE( pdt.outletState(0) == 2 );
1093  REQUIRE( pdt.outletState(1) == 0 );
1094  REQUIRE( pdt.outletState(2) == 0 );
1095  REQUIRE( pdt.outletState(3) == 0 );
1096 
1097  REQUIRE( pdt.channelState("channel1") == 1);
1098  REQUIRE( pdt.channelState("channel2") == 0);
1099 
1100  pdt.turnChannelOn("channel2");
1101 
1102  //Verify outlet state
1103  REQUIRE( pdt.outletState(0) == 2 );
1104  REQUIRE( pdt.outletState(1) == 0 );
1105  REQUIRE( pdt.outletState(2) == 2 );
1106  REQUIRE( pdt.outletState(3) == 2 );
1107 
1108  REQUIRE( pdt.channelState("channel1") == 1);
1109  REQUIRE( pdt.channelState("channel2") == 2);
1110 
1111  pdt.m_outletStates[0] = 0;
1112 
1113  REQUIRE( pdt.channelState("channel1") == 0);
1114  REQUIRE( pdt.channelState("channel2") == 2);
1115 
1116  pdt.turnChannelOff("channel2");
1117 
1118  //Verify outlet state
1119  REQUIRE( pdt.outletState(0) == 0 );
1120  REQUIRE( pdt.outletState(1) == 0 );
1121  REQUIRE( pdt.outletState(2) == 0 );
1122  REQUIRE( pdt.outletState(3) == 0 );
1123 
1124  REQUIRE( pdt.channelState("channel1") == 0);
1125  REQUIRE( pdt.channelState("channel2") == 0);
1126 
1127 
1128  pdt.m_outletStates[2] = 1;
1129 
1130  //Verify outlet state
1131  REQUIRE( pdt.outletState(0) == 0 );
1132  REQUIRE( pdt.outletState(1) == 0 );
1133  REQUIRE( pdt.outletState(2) == 1 );
1134  REQUIRE( pdt.outletState(3) == 0 );
1135 
1136  REQUIRE( pdt.channelState("channel1") == 0);
1137  REQUIRE( pdt.channelState("channel2") == 1);
1138 
1139  pdt.turnChannelOn("channel1");
1140 
1141  //Verify outlet state
1142  REQUIRE( pdt.outletState(0) == 2 );
1143  REQUIRE( pdt.outletState(1) == 2 );
1144  REQUIRE( pdt.outletState(2) == 1 );
1145  REQUIRE( pdt.outletState(3) == 0 );
1146 
1147  REQUIRE( pdt.channelState("channel1") == 2);
1148  REQUIRE( pdt.channelState("channel2") == 1);
1149 
1150  pdt.m_outletStates[2] = 0;
1151 
1152  REQUIRE( pdt.channelState("channel1") == 2);
1153  REQUIRE( pdt.channelState("channel2") == 0);
1154 
1155  pdt.turnChannelOff("channel1");
1156 
1157  //Verify outlet state
1158  REQUIRE( pdt.outletState(0) == 0 );
1159  REQUIRE( pdt.outletState(1) == 0 );
1160  REQUIRE( pdt.outletState(2) == 0 );
1161  REQUIRE( pdt.outletState(3) == 0 );
1162 
1163  REQUIRE( pdt.channelState("channel1") == 0);
1164  REQUIRE( pdt.channelState("channel2") == 0);
1165  }
1166  }
1167  GIVEN("a config file with 2 channels for 4 outlets, onOrder specified")
1168  {
1169  //Here we are just testing order, so we don't need to verify outlet state anymore
1170 
1171  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel2", "channel2" },
1172  {"outlet", "onOrder", "outlet", "onOrder" },
1173  {"0,1", "0,1", "2,3", "0,1" } );
1174 
1175  mx::app::appConfigurator config;
1176  config.readConfig("/tmp/outletController_test.conf");
1177 
1179  pdt.setupConfig(config);
1180  pdt.loadConfig(config);
1181 
1182  WHEN("test device startup channel states")
1183  {
1184  //Verify channel state at startup
1185  REQUIRE( pdt.channelState("channel1") == 0 );
1186  REQUIRE( pdt.channelState("channel2") == 0 );
1187  }
1188  WHEN("operating a single channel")
1189  {
1190  //Turn on channel1
1191  pdt.turnChannelOn("channel1");
1192 
1193  //verify outlet order
1194  REQUIRE( pdt.m_timestamps[1] > pdt.m_timestamps[0]);
1195 
1196  //Verify channel state
1197  REQUIRE( pdt.channelState("channel1") == 2 );
1198  REQUIRE( pdt.channelState("channel2") == 0 );
1199 
1200  //Turn off channel1
1201  pdt.turnChannelOff("channel1");
1202 
1203  //Verify channel state
1204  REQUIRE( pdt.channelState("channel1") == 0 );
1205  REQUIRE( pdt.channelState("channel2") == 0 );
1206 
1207  //Turn on channel2
1208  pdt.turnChannelOn("channel2");
1209 
1210  //verify outlet order
1211  REQUIRE( pdt.m_timestamps[3] > pdt.m_timestamps[2]);
1212 
1213  //Verify channel state
1214  REQUIRE( pdt.channelState("channel1") == 0 );
1215  REQUIRE( pdt.channelState("channel2") == 2 );
1216 
1217  //Turn off channel2
1218  pdt.turnChannelOff("channel2");
1219 
1220  //Verify channel state
1221  REQUIRE( pdt.channelState("channel1") == 0 );
1222  REQUIRE( pdt.channelState("channel2") == 0 );
1223  }
1224  }
1225  GIVEN("a config file with 2 channels for 4 outlets, onOrder reversed")
1226  {
1227  //Here we are just testing order, so we don't need to verify outlet state anymore
1228 
1229  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel2", "channel2" },
1230  {"outlet", "onOrder", "outlet", "onOrder" },
1231  {"0,1", "1,0", "2,3", "1,0" } );
1232 
1233  mx::app::appConfigurator config;
1234  config.readConfig("/tmp/outletController_test.conf");
1235 
1237  pdt.setupConfig(config);
1238  pdt.loadConfig(config);
1239 
1240  WHEN("test device startup channel states")
1241  {
1242  //Verify channel state at startup
1243  REQUIRE( pdt.channelState("channel1") == 0 );
1244  REQUIRE( pdt.channelState("channel2") == 0 );
1245  }
1246  WHEN("operating a single channel")
1247  {
1248  //Turn on channel1
1249  pdt.turnChannelOn("channel1");
1250 
1251  //verify outlet order
1252  REQUIRE( pdt.m_timestamps[0] > pdt.m_timestamps[1]);
1253 
1254  //Verify channel state
1255  REQUIRE( pdt.channelState("channel1") == 2 );
1256  REQUIRE( pdt.channelState("channel2") == 0 );
1257 
1258  //Turn off channel1
1259  pdt.turnChannelOff("channel1");
1260 
1261  //Verify channel state
1262  REQUIRE( pdt.channelState("channel1") == 0 );
1263  REQUIRE( pdt.channelState("channel2") == 0 );
1264 
1265  //Turn on channel2
1266  pdt.turnChannelOn("channel2");
1267 
1268  //verify outlet order
1269  REQUIRE( pdt.m_timestamps[2] > pdt.m_timestamps[3]);
1270 
1271  //Verify channel state
1272  REQUIRE( pdt.channelState("channel1") == 0 );
1273  REQUIRE( pdt.channelState("channel2") == 2 );
1274 
1275  //Turn off channel2
1276  pdt.turnChannelOff("channel2");
1277 
1278  //Verify channel state
1279  REQUIRE( pdt.channelState("channel1") == 0 );
1280  REQUIRE( pdt.channelState("channel2") == 0 );
1281  }
1282  }
1283  GIVEN("a config file with 2 channels for 4 outlets, onOrder and offOrder specified, the same")
1284  {
1285  //Here we are just testing order, so we don't need to verify outlet state anymore
1286 
1287  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel1", "channel2", "channel2", "channel2" },
1288  {"outlet", "onOrder", "offOrder", "outlet", "onOrder", "offOrder" },
1289  {"0,1", "0,1", "0,1", "2,3", "0,1" , "0,1" } );
1290 
1291  mx::app::appConfigurator config;
1292  config.readConfig("/tmp/outletController_test.conf");
1293 
1295  pdt.setupConfig(config);
1296  pdt.loadConfig(config);
1297 
1298  WHEN("test device startup channel states")
1299  {
1300  //Verify channel state at startup
1301  REQUIRE( pdt.channelState("channel1") == 0 );
1302  REQUIRE( pdt.channelState("channel2") == 0 );
1303  }
1304  WHEN("operating a single channel")
1305  {
1306  //Turn on channel1
1307  pdt.turnChannelOn("channel1");
1308 
1309  //verify outlet order
1310  REQUIRE( pdt.m_timestamps[1] > pdt.m_timestamps[0]);
1311 
1312  //Verify channel state
1313  REQUIRE( pdt.channelState("channel1") == 2 );
1314  REQUIRE( pdt.channelState("channel2") == 0 );
1315 
1316  //Turn off channel1
1317  pdt.turnChannelOff("channel1");
1318 
1319  //verify outlet order
1320  REQUIRE( pdt.m_timestamps[1] > pdt.m_timestamps[0]);
1321 
1322  //Verify channel state
1323  REQUIRE( pdt.channelState("channel1") == 0 );
1324  REQUIRE( pdt.channelState("channel2") == 0 );
1325 
1326  //Turn on channel2
1327  pdt.turnChannelOn("channel2");
1328 
1329  //verify outlet order
1330  REQUIRE( pdt.m_timestamps[3] > pdt.m_timestamps[2]);
1331 
1332  //Verify channel state
1333  REQUIRE( pdt.channelState("channel1") == 0 );
1334  REQUIRE( pdt.channelState("channel2") == 2 );
1335 
1336  //Turn off channel2
1337  pdt.turnChannelOff("channel2");
1338 
1339  REQUIRE( pdt.m_timestamps[3] >= pdt.m_timestamps[2]);
1340 
1341  //Verify channel state
1342  REQUIRE( pdt.channelState("channel1") == 0 );
1343  REQUIRE( pdt.channelState("channel2") == 0 );
1344  }
1345  }
1346  GIVEN("a config file with 2 channels for 4 outlets, onOrder and offOrder specified, different")
1347  {
1348  //Here we are just testing order, so we don't need to verify outlet state anymore
1349 
1350  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel1", "channel2", "channel2", "channel2" },
1351  {"outlet", "onOrder", "offOrder", "outlet", "onOrder", "offOrder" },
1352  {"0,1", "0,1", "1,0", "2,3", "0,1" , "1,0" } );
1353 
1354  mx::app::appConfigurator config;
1355  config.readConfig("/tmp/outletController_test.conf");
1356 
1358  pdt.setupConfig(config);
1359  pdt.loadConfig(config);
1360 
1361  WHEN("test device startup channel states")
1362  {
1363  //Verify channel state at startup
1364  REQUIRE( pdt.channelState("channel1") == 0 );
1365  REQUIRE( pdt.channelState("channel2") == 0 );
1366  }
1367  WHEN("operating a single channel")
1368  {
1369  //Turn on channel1
1370  pdt.turnChannelOn("channel1");
1371 
1372  //verify outlet order
1373  REQUIRE( pdt.m_timestamps[1] > pdt.m_timestamps[0]);
1374 
1375  //Verify channel state
1376  REQUIRE( pdt.channelState("channel1") == 2 );
1377  REQUIRE( pdt.channelState("channel2") == 0 );
1378 
1379 
1380  //Turn off channel1
1381  pdt.turnChannelOff("channel1");
1382 
1383  //verify outlet order
1384  REQUIRE( pdt.m_timestamps[0] > pdt.m_timestamps[1]);
1385 
1386  //Verify channel state
1387  REQUIRE( pdt.channelState("channel1") == 0 );
1388  REQUIRE( pdt.channelState("channel2") == 0 );
1389 
1390  //Turn on channel2
1391  pdt.turnChannelOn("channel2");
1392 
1393 
1394  //verify outlet order
1395  REQUIRE( pdt.m_timestamps[3] > pdt.m_timestamps[2]);
1396 
1397  //Verify channel state
1398  REQUIRE( pdt.channelState("channel1") == 0 );
1399  REQUIRE( pdt.channelState("channel2") == 2 );
1400 
1401  //Turn off channel2
1402  pdt.turnChannelOff("channel2");
1403 
1404  //verify outlet order
1405  REQUIRE( pdt.m_timestamps[2] > pdt.m_timestamps[3]);
1406 
1407  //Verify channel state
1408  REQUIRE( pdt.channelState("channel1") == 0 );
1409  REQUIRE( pdt.channelState("channel2") == 0 );
1410  }
1411  }
1412  GIVEN("a config file with 2 channels for 4 outlets, onOrder and offOrder specified, different, reversed")
1413  {
1414  //Here we are just testing order, so we don't need to verify outlet state anymore
1415 
1416  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel1", "channel2", "channel2", "channel2" },
1417  {"outlet", "onOrder", "offOrder", "outlet", "onOrder", "offOrder" },
1418  {"0,1", "1,0", "0,1", "2,3", "1,0" , "0,1" } );
1419 
1420  mx::app::appConfigurator config;
1421  config.readConfig("/tmp/outletController_test.conf");
1422 
1424  pdt.setupConfig(config);
1425  pdt.loadConfig(config);
1426 
1427  WHEN("test device startup channel states")
1428  {
1429  //Verify channel state at startup
1430  REQUIRE( pdt.channelState("channel1") == 0 );
1431  REQUIRE( pdt.channelState("channel2") == 0 );
1432  }
1433  WHEN("operating a single channel")
1434  {
1435  //Turn on channel1
1436  pdt.turnChannelOn("channel1");
1437 
1438  //verify outlet order
1439  REQUIRE( pdt.m_timestamps[0] > pdt.m_timestamps[1]);
1440 
1441  //Verify channel state
1442  REQUIRE( pdt.channelState("channel1") == 2 );
1443  REQUIRE( pdt.channelState("channel2") == 0 );
1444 
1445 
1446  //Turn off channel1
1447  pdt.turnChannelOff("channel1");
1448 
1449  //verify outlet order
1450  REQUIRE( pdt.m_timestamps[1] > pdt.m_timestamps[0]);
1451 
1452  //Verify channel state
1453  REQUIRE( pdt.channelState("channel1") == 0 );
1454  REQUIRE( pdt.channelState("channel2") == 0 );
1455 
1456  //Turn on channel2
1457  pdt.turnChannelOn("channel2");
1458 
1459 
1460  //verify outlet order
1461  REQUIRE( pdt.m_timestamps[2] > pdt.m_timestamps[3]);
1462 
1463  //Verify channel state
1464  REQUIRE( pdt.channelState("channel1") == 0 );
1465  REQUIRE( pdt.channelState("channel2") == 2 );
1466 
1467  //Turn off channel2
1468  pdt.turnChannelOff("channel2");
1469 
1470  //verify outlet order
1471  REQUIRE( pdt.m_timestamps[3] > pdt.m_timestamps[2]);
1472 
1473  //Verify channel state
1474  REQUIRE( pdt.channelState("channel1") == 0 );
1475  REQUIRE( pdt.channelState("channel2") == 0 );
1476  }
1477  }
1478 }
1479 
1480 SCENARIO( "outletController Operation with delays", "[outletController]" )
1481 {
1482  std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1483  std::cout << "[outletController] Testing delays ... \n";
1484  GIVEN("a config file with 2 channels for 4 outlets, onDelays specified")
1485  {
1486  //Here we are just testing delays, so we don't need to verify outlet state anymore
1487 
1488  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel2", "channel2" },
1489  {"outlet", "onDelays", "outlet", "onDelays" },
1490  {"0,1", "0,350", "2,3", "0,150" } );
1491 
1492  mx::app::appConfigurator config;
1493  config.readConfig("/tmp/outletController_test.conf");
1494 
1496  pdt.setupConfig(config);
1497  pdt.loadConfig(config);
1498 
1499  WHEN("operating a single channel")
1500  {
1501  //Turn on channel1
1502  pdt.turnChannelOn("channel1");
1503 
1504  //verify outlet delay
1505  REQUIRE( pdt.m_timestamps[1] >= Approx(pdt.m_timestamps[0]+0.350));
1506  std::cout << "Ch1 On Delay was " << (pdt.m_timestamps[1] - pdt.m_timestamps[0])*1000 << " msec, expected 350.\n";
1507 
1508  //Verify channel state
1509  REQUIRE( pdt.channelState("channel1") == 2 );
1510  REQUIRE( pdt.channelState("channel2") == 0 );
1511 
1512  //Turn off channel1
1513  pdt.turnChannelOff("channel1");
1514  std::cout << "Ch1 Off Delay was " << (pdt.m_timestamps[1] - pdt.m_timestamps[0])*1000 << " msec, expected ~0.\n";
1515 
1516  //Verify channel state
1517  REQUIRE( pdt.channelState("channel1") == 0 );
1518  REQUIRE( pdt.channelState("channel2") == 0 );
1519 
1520  //Turn on channel2
1521  pdt.turnChannelOn("channel2");
1522 
1523 
1524  //verify outlet delay
1525  REQUIRE( pdt.m_timestamps[3] >= Approx(pdt.m_timestamps[2]+0.150));
1526  std::cout << "Ch2 On Delay was " << (pdt.m_timestamps[3] - pdt.m_timestamps[2])*1000 << " msec, expected 150.\n";
1527 
1528  //Verify channel state
1529  REQUIRE( pdt.channelState("channel1") == 0 );
1530  REQUIRE( pdt.channelState("channel2") == 2 );
1531 
1532  //Turn off channel2
1533  pdt.turnChannelOff("channel2");
1534  std::cout << "Ch2 Off Delay was " << (pdt.m_timestamps[3] - pdt.m_timestamps[2])*1000 << " msec, expected ~0.\n";
1535 
1536  //Verify channel state
1537  REQUIRE( pdt.channelState("channel1") == 0 );
1538  REQUIRE( pdt.channelState("channel2") == 0 );
1539  }
1540  }
1541  GIVEN("a config file with 2 channels for 4 outlets, offDelays specified")
1542  {
1543  //Here we are just testing delays, so we don't need to verify outlet state anymore
1544 
1545  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel2", "channel2" },
1546  {"outlet", "offDelays", "outlet", "offDelays" },
1547  {"0,1", "0,550", "2,3", "0,750" } );
1548 
1549  mx::app::appConfigurator config;
1550  config.readConfig("/tmp/outletController_test.conf");
1551 
1553  pdt.setupConfig(config);
1554  pdt.loadConfig(config);
1555 
1556  WHEN("operating a single channel")
1557  {
1558  //Turn on channel1
1559  pdt.turnChannelOn("channel1");
1560 
1561  std::cout << "Ch1 On Delay was " << (pdt.m_timestamps[1] - pdt.m_timestamps[0])*1000 << " msec, expected ~0.\n";
1562 
1563  //Verify channel state
1564  REQUIRE( pdt.channelState("channel1") == 2 );
1565  REQUIRE( pdt.channelState("channel2") == 0 );
1566 
1567  //Turn off channel1
1568  pdt.turnChannelOff("channel1");
1569 
1570  REQUIRE( pdt.m_timestamps[1] >= Approx(pdt.m_timestamps[0]+0.550));
1571  std::cout << "Ch1 Off Delay was " << (pdt.m_timestamps[1] - pdt.m_timestamps[0])*1000 << " msec, expected 550.\n";
1572 
1573 
1574  //Verify channel state
1575  REQUIRE( pdt.channelState("channel1") == 0 );
1576  REQUIRE( pdt.channelState("channel2") == 0 );
1577 
1578  //Turn on channel2
1579  pdt.turnChannelOn("channel2");
1580 
1581 
1582  //verify outlet delay
1583  std::cout << "Ch1 On Delay was " << (pdt.m_timestamps[3] - pdt.m_timestamps[2])*1000 << " msec, expected ~0.\n";
1584 
1585  //Verify channel state
1586  REQUIRE( pdt.channelState("channel1") == 0 );
1587  REQUIRE( pdt.channelState("channel2") == 2 );
1588 
1589  //Turn off channel2
1590  pdt.turnChannelOff("channel2");
1591  REQUIRE( pdt.m_timestamps[3] >= Approx(pdt.m_timestamps[2]+0.750));
1592  std::cout << "Ch1 On Delay was " << (pdt.m_timestamps[3] - pdt.m_timestamps[2])*1000 << " msec, expected 750.\n";
1593 
1594  //Verify channel state
1595  REQUIRE( pdt.channelState("channel1") == 0 );
1596  REQUIRE( pdt.channelState("channel2") == 0 );
1597  }
1598  }
1599  GIVEN("a config file with 2 channels for 4 outlets, onDelays and offDelays specified, off order reversed")
1600  {
1601  //Here we are just testing delays, so we don't need to verify outlet state anymore
1602 
1603  mx::app::writeConfigFile( "/tmp/outletController_test.conf", {"channel1", "channel1", "channel1", "channel1", "channel1", "channel2", "channel2", "channel2", "channel2", "channel2" },
1604  {"outlet", "onOrder", "onDelays", "offOrder", "offDelays", "outlet", "onOrder", "onDelays", "offOrder", "offDelays" },
1605  {"0,1", "0,1", "0,350", "1,0", "0,450", "2,3", "0,1", "0,150", "1,0", "0,75" } );
1606 
1607  mx::app::appConfigurator config;
1608  config.readConfig("/tmp/outletController_test.conf");
1609 
1611  pdt.setupConfig(config);
1612  pdt.loadConfig(config);
1613 
1614  WHEN("operating a single channel")
1615  {
1616  //Turn on channel1
1617  pdt.turnChannelOn("channel1");
1618 
1619  //verify outlet delay
1620  REQUIRE( pdt.m_timestamps[1] >= Approx(pdt.m_timestamps[0]+0.350));
1621  std::cout << "Ch1 On Delay was " << (pdt.m_timestamps[1] - pdt.m_timestamps[0])*1000 << " msec, expected 350.\n";
1622 
1623  //Verify channel state
1624  REQUIRE( pdt.channelState("channel1") == 2 );
1625  REQUIRE( pdt.channelState("channel2") == 0 );
1626 
1627  //Turn off channel1
1628  pdt.turnChannelOff("channel1");
1629  REQUIRE( pdt.m_timestamps[0] >= Approx(pdt.m_timestamps[1]+0.450));
1630  std::cout << "Ch1 Off Delay was " << (pdt.m_timestamps[0] - pdt.m_timestamps[1])*1000 << " msec, expected 450.\n";
1631 
1632  //Verify channel state
1633  REQUIRE( pdt.channelState("channel1") == 0 );
1634  REQUIRE( pdt.channelState("channel2") == 0 );
1635 
1636  //Turn on channel2
1637  pdt.turnChannelOn("channel2");
1638 
1639 
1640  //verify outlet delay
1641  REQUIRE( pdt.m_timestamps[3] >= Approx(pdt.m_timestamps[2]+0.150));
1642  std::cout << "Ch2 On Delay was " << (pdt.m_timestamps[3] - pdt.m_timestamps[2])*1000 << " msec, expected 150.\n";
1643 
1644  //Verify channel state
1645  REQUIRE( pdt.channelState("channel1") == 0 );
1646  REQUIRE( pdt.channelState("channel2") == 2 );
1647 
1648  //Turn off channel2
1649  pdt.turnChannelOff("channel2");
1650  REQUIRE( pdt.m_timestamps[2] >= Approx(pdt.m_timestamps[3]+0.075));
1651  std::cout << "Ch2 Off Delay was " << (pdt.m_timestamps[2] - pdt.m_timestamps[3])*1000 << " msec, expected 75.\n";
1652 
1653  //Verify channel state
1654  REQUIRE( pdt.channelState("channel1") == 0 );
1655  REQUIRE( pdt.channelState("channel2") == 0 );
1656  }
1657  }
1658  std::cout << "+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
1659 }
1660 
1661 } //namespace outletController_tests
#define GIVEN(desc)
Definition: catch.hpp:17763
#define WHEN(desc)
Definition: catch.hpp:17765
#define REQUIRE(...)
Definition: catch.hpp:17676
std::ostream & cout()
void nanoSleep(unsigned long nsec)
SCENARIO("outletController Configuration", "[outletController]")
A generic outlet controller.
int outletState(int outletNum)
Get the currently stored outlet state, without updating from device.
std::vector< unsigned > channelOffDelays(const std::string &channel)
Get the vector of outlet off delays for a channel.
int turnChannelOn(const std::string &channel)
Turn a channel on.
int channelState(const std::string &channel)
Get the state of a channel.
int loadConfig(mx::app::appConfigurator &config)
Load the [channel] sections from an application configurator.
size_t numChannels()
Get the number of channels.
std::vector< size_t > channelOnOrder(const std::string &channel)
Get the vector of outlet on orders for a channel.
int setupConfig(mx::app::appConfigurator &config)
Setup an application configurator for an outletController.
int turnChannelOff(const std::string &channel)
Turn a channel off.
std::vector< size_t > channelOutlets(const std::string &channel)
Get the vector of outlet indices for a channel.
int setNumberOfOutlets(int numOuts)
Sets the number of outlets. This should be called by the derived class constructor.
std::vector< unsigned > channelOnDelays(const std::string &channel)
Get the vector of outlet on delays for a channel.
std::vector< size_t > channelOffOrder(const std::string &channel)
Get the vector of outlet off orders for a channel.
std::vector< int > m_outletStates
The current states of each outlet. These MUST be updated by derived classes in the overridden updated...
virtual int turnOutletOff(int outletNum)
Turn an outlet off.
virtual int updateOutletState(int outletNum)
Get the state of the outlet from the device.
virtual int turnOutletOn(int outletNum)
Turn an outlet on.