ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
testStatusMonitor.cc
Go to the documentation of this file.
1// SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2// SPDX-License-Identifier: LGPL-3.0-or-later
3#include <ChimeraTK/SystemTags.h>
4
5#include <future>
6
7#define BOOST_TEST_MODULE testStatusMonitor
8
9#include "Application.h"
10#include "ScalarAccessor.h"
11#include "StatusMonitor.h"
12#include "TestFacility.h"
13
14#include <boost/mpl/list.hpp>
15#include <boost/test/included/unit_test.hpp>
16
18
19 using namespace boost::unit_test_framework;
20 namespace ctk = ChimeraTK;
21
22 /********************************************************************************************************************/
23 /* Test dummy application for the Monitors ************************************************************************/
24 /********************************************************************************************************************/
25
26 template<typename T>
28 TestApplication() : Application("testSuite") {}
29 ~TestApplication() override { shutdown(); }
30
31 T monitor{this, "/input/path", "/output/path", "/parameters", "Now this is a nice monitor...",
32 ctk::TAGS{"MON_OUTPUT"}, ctk::TAGS{"MON_PARAMS"}};
33 };
34
35 /********************************************************************************************************************/
36 /* Test generic functionality of the Monitors ************************************************************************/
37 /********************************************************************************************************************/
38
39 BOOST_AUTO_TEST_CASE(testMaxMonitor) {
40 std::cout << "testMaxMonitor" << std::endl;
42
43 // check that the reserved StatusOutput tag is present at the output, required for StatusAggregator integration
44 auto tags = ctk::VariableNetworkNode(app.monitor.status).getTags();
45 BOOST_CHECK(tags.find(ctk::SystemTags::statusOutput) != tags.end());
46
47 ctk::TestFacility test(app);
48 test.runApplication();
49 // app.cs.dump();
50
51 auto warning = test.getScalar<double_t>(std::string("/parameters/upperWarningThreshold"));
52 warning = 50.0;
53 warning.write();
54 test.stepApplication();
55
56 auto fault = test.getScalar<double_t>(std::string("/parameters/upperFaultThreshold"));
57 fault = 60.0;
58 fault.write();
59 test.stepApplication();
60
61 auto watch = test.getScalar<double_t>(std::string("/input/path"));
62 watch = 40.0;
63 watch.write();
64 test.stepApplication();
65
66 auto status = test.getScalar<int32_t>(std::string("/output/path"));
67 status.readLatest();
68
69 // should be in OK state.
70 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
71
72 // //just below the warning level
73 watch = 49.99;
74 watch.write();
75 test.stepApplication();
76 status.readLatest();
77 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
78
79 // drop in a disable test.
80 auto disable = test.getScalar<ChimeraTK::Boolean>("/parameters/disable");
81 disable = true;
82 disable.write();
83 test.stepApplication();
84 status.readLatest();
85 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
86
87 disable = false;
88 disable.write();
89 test.stepApplication();
90 status.readLatest();
91 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
92
93 // slightly above at the upper warning threshold (exact is not good due to rounding errors in floats/doubles)
94 watch = 50.01;
95 watch.write();
96 test.stepApplication();
97 status.readLatest();
98 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
99
100 // drop in a disable test.
101 disable = true;
102 disable.write();
103 test.stepApplication();
104 status.readLatest();
105 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
106
107 disable = false;
108 disable.write();
109 test.stepApplication();
110 status.readLatest();
111 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
112
113 // just below the fault threshold,. still warning
114 watch = 59.99;
115 watch.write();
116 test.stepApplication();
117 status.readLatest();
118 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
119
120 // slightly above at the upper fault threshold (exact is not good due to rounding errors in floats/doubles)
121 watch = 60.01;
122 watch.write();
123 test.stepApplication();
124 status.readLatest();
125 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
126
127 // drop in a disable test.
128 disable = true;
129 disable.write();
130 test.stepApplication();
131 status.readLatest();
132 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
133
134 disable = false;
135 disable.write();
136 test.stepApplication();
137 status.readLatest();
138 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
139
140 // increase well above the upper fault level
141 watch = 65;
142 watch.write();
143 test.stepApplication();
144 status.readLatest();
145 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
146
147 // now check that changing the status is updated correctly if we change the limits
148
149 // increase fault value greater than watch
150 fault = 68;
151 fault.write();
152 test.stepApplication();
153 status.readLatest();
154 // should be in WARNING state.
155 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
156
157 // increase warning value greater than watch
158 warning = 66;
159 warning.write();
160 test.stepApplication();
161 status.readLatest();
162 // should be in OK state.
163 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
164
165 // Set the upper fault limit below the upper warning limit and below the current temperature. The warning is not
166 // active, but the fault. Although this is not a reasonable configuration the fault limit must superseed the warning
167 // and the status has to be fault.
168 fault = 60;
169 fault.write();
170 test.stepApplication();
171 status.readLatest();
172 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
173
174 // check that the tags are applied correctly
175 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("upperFaultThreshold") == app.monitor.faultThreshold);
176 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("upperWarningThreshold") == app.monitor.warningThreshold);
177 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("disable") == app.monitor.disable);
178 // BOOST_CHECK(app.findTag("MON_OUTPUT")["output"]("path") == app.monitor.status);
179 }
180
181 /********************************************************************************************************************/
182
183 BOOST_AUTO_TEST_CASE(testMinMonitor) {
184 std::cout << "testMinMonitor" << std::endl;
185
187
188 // check that the reserved StatusOutput tag is present at the output, required for StatusAggregator integration
189 auto tags = ctk::VariableNetworkNode(app.monitor.status).getTags();
190 BOOST_CHECK(tags.find(ctk::SystemTags::statusOutput) != tags.end());
191
192 ctk::TestFacility test(app);
193 test.runApplication();
194 // app.dumpConnections();
195
196 auto warning = test.getScalar<uint>(std::string("/parameters/lowerWarningThreshold"));
197 warning = 40;
198 warning.write();
199 test.stepApplication();
200
201 auto fault = test.getScalar<uint>(std::string("/parameters/lowerFaultThreshold"));
202 fault = 30;
203 fault.write();
204 test.stepApplication();
205
206 auto watch = test.getScalar<uint>(std::string("/input/path"));
207 watch = 45;
208 watch.write();
209 test.stepApplication();
210
211 auto status = test.getScalar<int32_t>(std::string("/output/path"));
212 status.readLatest();
213
214 // should be in OK state.
215 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
216
217 // just abow the lower warning limit
218 watch = 41;
219 watch.write();
220 test.stepApplication();
221 status.readLatest();
222 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
223
224 // drop in a disable test.
225 auto disable = test.getScalar<ChimeraTK::Boolean>("/parameters/disable");
226 disable = true;
227 disable.write();
228 test.stepApplication();
229 status.readLatest();
230 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
231
232 disable = false;
233 disable.write();
234 test.stepApplication();
235 status.readLatest();
236 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
237
238 // exactly at the lower warning limit
239 watch = 40;
240 watch.write();
241 test.stepApplication();
242 status.readLatest();
243 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
244
245 // drop in a disable test.
246 disable = true;
247 disable.write();
248 test.stepApplication();
249 status.readLatest();
250 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
251
252 disable = false;
253 disable.write();
254 test.stepApplication();
255 status.readLatest();
256 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
257
258 // just above the lower fault limit
259 watch = 31;
260 watch.write();
261 test.stepApplication();
262 status.readLatest();
263 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
264
265 // exactly at the lower fault limit (only well defined for int)
266 watch = 30;
267 watch.write();
268 test.stepApplication();
269 status.readLatest();
270 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
271
272 // drop in a disable test.
273 disable = true;
274 disable.write();
275 test.stepApplication();
276 status.readLatest();
277 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
278
279 disable = false;
280 disable.write();
281 test.stepApplication();
282 status.readLatest();
283 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
284
285 // way bellow the lower fault limit
286 watch = 12;
287 watch.write();
288 test.stepApplication();
289 status.readLatest();
290 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
291
292 // move the temperature back to the good range and check that the status updates correctly when changing the limits
293 watch = 41;
294 watch.write();
295 test.stepApplication();
296 status.readLatest();
297 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
298
299 // change upper warning limit
300 warning = 42;
301 warning.write();
302 test.stepApplication();
303 status.readLatest();
304 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
305
306 // rise the temperature above the lower warning limit
307 watch = 43;
308 watch.write();
309 test.stepApplication();
310 status.readLatest();
311 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
312
313 // Set the lower fault limit above the lower warning limit. The warning is not active, but the fault.
314 // Although this is not a reasonable configuration the fault limit must superseed the warning and the status has to be fault.
315 fault = 44;
316 fault.write();
317 test.stepApplication();
318 status.readLatest();
319 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
320
321 // check that the tags are applied correctly
322 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("lowerFaultThreshold") == app.monitor.faultThreshold);
323 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("lowerWarningThreshold") == app.monitor.warningThreshold);
324 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("disable") == app.monitor.disable);
325 // BOOST_CHECK(app.findTag("MON_OUTPUT")["output"]("path") == app.monitor.status);
326 }
327
328 /********************************************************************************************************************/
329
330 BOOST_AUTO_TEST_CASE(testRangeMonitor) {
331 std::cout << "testRangeMonitor" << std::endl;
333
334 // check that the reserved StatusOutput tag is present at the output, required for StatusAggregator integration
335 auto tags = ctk::VariableNetworkNode(app.monitor.status).getTags();
336 BOOST_CHECK(tags.find(ctk::SystemTags::statusOutput) != tags.end());
337
338 ctk::TestFacility test(app);
339 test.runApplication();
340 // app.dumpConnections();
341
342 auto warningUpperLimit = test.getScalar<int>(std::string("/parameters/upperWarningThreshold"));
343 warningUpperLimit = 50;
344 warningUpperLimit.write();
345 test.stepApplication();
346
347 auto warningLowerLimit = test.getScalar<int>(std::string("/parameters/lowerWarningThreshold"));
348 warningLowerLimit = 40;
349 warningLowerLimit.write();
350 test.stepApplication();
351
352 auto faultUpperLimit = test.getScalar<int>(std::string("/parameters/upperFaultThreshold"));
353 faultUpperLimit = 60;
354 faultUpperLimit.write();
355 test.stepApplication();
356
357 auto faultLowerLimit = test.getScalar<int>(std::string("/parameters/lowerFaultThreshold"));
358 faultLowerLimit = 30;
359 faultLowerLimit.write();
360 test.stepApplication();
361
362 // start with a good value
363 auto watch = test.getScalar<int>(std::string("/input/path"));
364 watch = 45;
365 watch.write();
366 test.stepApplication();
367
368 auto status = test.getScalar<int32_t>(std::string("/output/path"));
369 status.readLatest();
370
371 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
372
373 // just below the warning level
374 watch = 49;
375 watch.write();
376 test.stepApplication();
377 status.readLatest();
378 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
379
380 // drop in a disable test.
381 auto disable = test.getScalar<ChimeraTK::Boolean>("/parameters/disable");
382 disable = true;
383 disable.write();
384 test.stepApplication();
385 status.readLatest();
386 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
387
388 disable = false;
389 disable.write();
390 test.stepApplication();
391 status.readLatest();
392 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
393
394 // exactly at the upper warning threshold (only well defined for int)
395 watch = 50;
396 watch.write();
397 test.stepApplication();
398 status.readLatest();
399 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
400
401 // drop in a disable test.
402 disable = true;
403 disable.write();
404 test.stepApplication();
405 status.readLatest();
406 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
407
408 disable = false;
409 disable.write();
410 test.stepApplication();
411 status.readLatest();
412 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
413
414 // just below the fault threshold,. still warning
415 watch = 59;
416 watch.write();
417 test.stepApplication();
418 status.readLatest();
419 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
420
421 // exactly at the upper warning threshold (only well defined for int)
422 watch = 60;
423 watch.write();
424 test.stepApplication();
425 status.readLatest();
426 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
427
428 // drop in a disable test.
429 disable = true;
430 disable.write();
431 test.stepApplication();
432 status.readLatest();
433 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
434
435 disable = false;
436 disable.write();
437 test.stepApplication();
438 status.readLatest();
439 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
440
441 // increase well above the upper fault level
442 watch = 65;
443 watch.write();
444 test.stepApplication();
445 status.readLatest();
446 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
447
448 // back to ok, just abow the lower warning limit
449 watch = 41;
450 watch.write();
451 test.stepApplication();
452 status.readLatest();
453 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
454
455 // exactly at the lower warning limit
456 watch = 40;
457 watch.write();
458 test.stepApplication();
459 status.readLatest();
460 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
461
462 // just above the lower fault limit
463 watch = 31;
464 watch.write();
465 test.stepApplication();
466 status.readLatest();
467 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
468
469 // exactly at the lower fault limit (only well defined for int)
470 watch = 30;
471 watch.write();
472 test.stepApplication();
473 status.readLatest();
474 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
475
476 // way bellow the lower fault limit
477 watch = 12;
478 watch.write();
479 test.stepApplication();
480 status.readLatest();
481 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
482
483 // Put the value back to the good range, then check that chaning the threshold also updated the status
484 watch = 49;
485 watch.write();
486 test.stepApplication();
487 status.readLatest();
488 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
489
490 // change upper warning limit
491 warningUpperLimit = 48;
492 warningUpperLimit.write();
493 test.stepApplication();
494 status.readLatest();
495 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
496
497 // lower the temperature below the upper warning limit
498 watch = 47;
499 watch.write();
500 test.stepApplication();
501 status.readLatest();
502 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
503
504 // Set the upper fault limit below the upper warning limit. The warning is not active, but the fault.
505 // Although this is not a reasonable configuration the fault limit must superseed the warning and the status has to be fault.
506 faultUpperLimit = 46;
507 faultUpperLimit.write();
508 test.stepApplication();
509 status.readLatest();
510 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
511
512 // move the temperature back to the good range and repeat for the lower limits
513 watch = 41;
514 watch.write();
515 test.stepApplication();
516 status.readLatest();
517 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
518
519 // change upper warning limit
520 warningLowerLimit = 42;
521 warningLowerLimit.write();
522 test.stepApplication();
523 status.readLatest();
524 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
525
526 // rise the temperature above the lower warning limit
527 watch = 43;
528 watch.write();
529 test.stepApplication();
530 status.readLatest();
531 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
532
533 // Set the lower fault limit above the lower warning limit. The warning is not active, but the fault.
534 // Although this is not a reasonable configuration the fault limit must superseed the warning and the status has to be fault.
535 faultLowerLimit = 44;
536 faultLowerLimit.write();
537 test.stepApplication();
538 status.readLatest();
539 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
540
541 // check that the tags are applied correctly
542 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("lowerFaultThreshold") == app.monitor.faultLowerThreshold);
543 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("lowerWarningThreshold") ==
544 // app.monitor.warningLowerThreshold);
545 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("upperFaultThreshold") == app.monitor.faultUpperThreshold);
546 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("upperWarningThreshold") ==
547 // app.monitor.warningUpperThreshold);
548 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("disable") == app.monitor.disable);
549 // BOOST_CHECK(app.findTag("MON_OUTPUT")["output"]("path") == app.monitor.status);
550 }
551
552 /********************************************************************************************************************/
553
554 BOOST_AUTO_TEST_CASE(testExactMonitor) {
555 std::cout << "testExactMonitor" << std::endl;
557
558 // check that the reserved StatusOutput tag is present at the output, required for StatusAggregator integration
559 auto tags = ctk::VariableNetworkNode(app.monitor.status).getTags();
560 BOOST_CHECK(tags.find(ctk::SystemTags::statusOutput) != tags.end());
561
562 ctk::TestFacility test(app);
563 test.runApplication();
564 // app.dumpConnections();
565
566 auto requiredValue = test.getScalar<int64_t>(std::string("/parameters/requiredValue"));
567 requiredValue = 409;
568 requiredValue.write();
569 test.stepApplication();
570
571 auto watch = test.getScalar<int64_t>(std::string("/input/path"));
572 watch = 409;
573 watch.write();
574 test.stepApplication();
575
576 auto status = test.getScalar<int32_t>(std::string("/output/path"));
577 status.readLatest();
578
579 // should be in OK state.
580 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
581
582 // drop in a disable test.
583 auto disable = test.getScalar<ChimeraTK::Boolean>("/parameters/disable");
584 disable = true;
585 disable.write();
586 test.stepApplication();
587 status.readLatest();
588 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
589
590 disable = false;
591 disable.write();
592 test.stepApplication();
593 status.readLatest();
594 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
595
596 // set watch value different than required value
597 watch = 414;
598 watch.write();
599 test.stepApplication();
600 status.readLatest();
601 // should be in FAULT state.
602 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
603
604 // drop in a disable test.
605 disable = true;
606 disable.write();
607 test.stepApplication();
608 status.readLatest();
609 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
610
611 disable = false;
612 disable.write();
613 test.stepApplication();
614 status.readLatest();
615 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
616
617 watch = 409;
618 watch.write();
619 test.stepApplication();
620 status.readLatest();
621 // should be in OK state.
622 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
623
624 // set requiredValue value different than watch value
625 requiredValue = 413;
626 requiredValue.write();
627 test.stepApplication();
628 status.readLatest();
629 // should be in WARNING state.
630 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
631
632 // set requiredValue value equals to watch value
633 requiredValue = 409;
634 requiredValue.write();
635 test.stepApplication();
636 status.readLatest();
637 // should be in WARNING state.
638 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
639
640 // check that the tags are applied correctly
641 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("requiredValue") == app.monitor.requiredValue);
642 // BOOST_CHECK(app.findTag("MON_PARAMS")["parameters"]("disable") == app.monitor.disable);
643 // BOOST_CHECK(app.findTag("MON_OUTPUT")["output"]("path") == app.monitor.status);
644 }
645
646 /********************************************************************************************************************/
647 /* Test initial value propagation for the Monitors *******************************************************************/
648 /********************************************************************************************************************/
649
650 BOOST_AUTO_TEST_CASE(testMaxMonitorInitialValuePropagation) {
651 std::cout << "testMaxMonitorInitialValuePropagation" << std::endl;
652
653 {
655 ctk::TestFacility test(app);
656 test.setScalarDefault<float_t>("/parameters/upperFaultThreshold", 60.0);
657 test.setScalarDefault<float_t>("/parameters/upperWarningThreshold", 50.0);
658 test.setScalarDefault<float_t>("/input/path", 45.0);
659 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
660
661 test.runApplication();
662
663 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
664 }
665 {
667 ctk::TestFacility test(app);
668 test.setScalarDefault<float_t>("/parameters/upperFaultThreshold", 60.0);
669 test.setScalarDefault<float_t>("/parameters/upperWarningThreshold", 50.0);
670 test.setScalarDefault<float_t>("/input/path", 55.0);
671 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
672
673 test.runApplication();
674
675 BOOST_TEST(
676 test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
677 }
678 {
680 ctk::TestFacility test(app);
681 test.setScalarDefault<float_t>("/parameters/upperFaultThreshold", 60.0);
682 test.setScalarDefault<float_t>("/parameters/upperWarningThreshold", 50.0);
683 test.setScalarDefault<float_t>("/input/path", 55.0);
684 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", true);
685
686 test.runApplication();
687
688 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
689 }
690 {
692 ctk::TestFacility test(app);
693 test.setScalarDefault<double_t>("/parameters/upperFaultThreshold", 60.0);
694 test.setScalarDefault<double_t>("/parameters/upperWarningThreshold", 50.0);
695 test.setScalarDefault<double_t>("/input/path", 65.0);
696 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
697
698 test.runApplication();
699
700 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
701 }
702 }
703
704 /********************************************************************************************************************/
705
706 BOOST_AUTO_TEST_CASE(testMinMonitorInitialValuePropagation) {
707 std::cout << "testMinMonitorInitialValuePropagation" << std::endl;
708
709 {
711 ctk::TestFacility test(app);
712 test.setScalarDefault<double_t>("/parameters/lowerFaultThreshold", 50.0);
713 test.setScalarDefault<double_t>("/parameters/lowerWarningThreshold", 60.0);
714 test.setScalarDefault<double_t>("/input/path", 65.0);
715 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
716
717 test.runApplication();
718
719 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
720 }
721 {
723 ctk::TestFacility test(app);
724 test.setScalarDefault<float_t>("/parameters/lowerFaultThreshold", 50.0);
725 test.setScalarDefault<float_t>("/parameters/lowerWarningThreshold", 60.0);
726 test.setScalarDefault<float_t>("/input/path", 55.0);
727 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
728
729 test.runApplication();
730
731 BOOST_TEST(
732 test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
733 }
734 {
736 ctk::TestFacility test(app);
737 test.setScalarDefault<float_t>("/parameters/lowerFaultThreshold", 50.0);
738 test.setScalarDefault<float_t>("/parameters/lowerWarningThreshold", 60.0);
739 test.setScalarDefault<float_t>("/input/path", 55.0);
740 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", true);
741
742 test.runApplication();
743
744 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
745 }
746 {
748 ctk::TestFacility test(app);
749 test.setScalarDefault<int32_t>("/parameters/lowerFaultThreshold", 50);
750 test.setScalarDefault<int32_t>("/parameters/lowerWarningThreshold", 60);
751 test.setScalarDefault<int32_t>("/input/path", 45);
752 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
753
754 test.runApplication();
755
756 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
757 }
758 }
759
760 /********************************************************************************************************************/
761
762 BOOST_AUTO_TEST_CASE(testRangeMonitorInitialValuePropagation) {
763 std::cout << "testRangeMonitorInitialValuePropagation" << std::endl;
764 // each {} defines new application and test facility
765 {
767 ctk::TestFacility test(app);
768 test.setScalarDefault<double_t>("/parameters/upperFaultThreshold", 80.0);
769 test.setScalarDefault<double_t>("/parameters/upperWarningThreshold", 70.0);
770 test.setScalarDefault<double_t>("/parameters/lowerWarningThreshold", 60.0);
771 test.setScalarDefault<double_t>("/parameters/lowerFaultThreshold", 50.0);
772 test.setScalarDefault<double_t>("/input/path", 65.0);
773 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
774
775 test.runApplication();
776
777 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
778 }
779 {
781 ctk::TestFacility test(app);
782 test.setScalarDefault<float_t>("/parameters/upperFaultThreshold", 80.0);
783 test.setScalarDefault<float_t>("/parameters/upperWarningThreshold", 70.0);
784 test.setScalarDefault<float_t>("/parameters/lowerWarningThreshold", 60.0);
785 test.setScalarDefault<float_t>("/parameters/lowerFaultThreshold", 50.0);
786 test.setScalarDefault<float_t>("/input/path", 75.0);
787 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
788
789 test.runApplication();
790
791 BOOST_TEST(
792 test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
793 }
794 {
796 ctk::TestFacility test(app);
797 test.setScalarDefault<float_t>("/parameters/upperFaultThreshold", 80.0);
798 test.setScalarDefault<float_t>("/parameters/upperWarningThreshold", 70.0);
799 test.setScalarDefault<float_t>("/parameters/lowerWarningThreshold", 60.0);
800 test.setScalarDefault<float_t>("/parameters/lowerFaultThreshold", 50.0);
801 test.setScalarDefault<float_t>("/input/path", 55.0);
802 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
803
804 test.runApplication();
805
806 BOOST_TEST(
807 test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
808 }
809 {
811 ctk::TestFacility test(app);
812 test.setScalarDefault<float_t>("/parameters/upperFaultThreshold", 80.0);
813 test.setScalarDefault<float_t>("/parameters/upperWarningThreshold", 70.0);
814 test.setScalarDefault<float_t>("/parameters/lowerWarningThreshold", 60.0);
815 test.setScalarDefault<float_t>("/parameters/lowerFaultThreshold", 50.0);
816 test.setScalarDefault<float_t>("/input/path", 55.0);
817 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", true);
818
819 test.runApplication();
820
821 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
822 }
823 {
825 ctk::TestFacility test(app);
826 test.setScalarDefault<int32_t>("/parameters/upperFaultThreshold", 80);
827 test.setScalarDefault<int32_t>("/parameters/upperWarningThreshold", 70);
828 test.setScalarDefault<int32_t>("/parameters/lowerWarningThreshold", 60);
829 test.setScalarDefault<int32_t>("/parameters/lowerFaultThreshold", 50);
830 test.setScalarDefault<int32_t>("/input/path", 85);
831 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
832
833 test.runApplication();
834
835 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
836 }
837 {
839 ctk::TestFacility test(app);
840 test.setScalarDefault<int32_t>("/parameters/upperFaultThreshold", 80);
841 test.setScalarDefault<int32_t>("/parameters/upperWarningThreshold", 70);
842 test.setScalarDefault<int32_t>("/parameters/lowerWarningThreshold", 60);
843 test.setScalarDefault<int32_t>("/parameters/lowerFaultThreshold", 50);
844 test.setScalarDefault<int32_t>("/input/path", 45);
845 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
846
847 test.runApplication();
848
849 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
850 }
851 }
852
853 /********************************************************************************************************************/
854
855 BOOST_AUTO_TEST_CASE(testExactMonitorInitialValuePropagation) {
856 std::cout << "testExactMonitorInitialValuePropagation" << std::endl;
857
858 {
860 ctk::TestFacility test(app);
861 test.setScalarDefault<double_t>("/parameters/requiredValue", 60.0);
862 test.setScalarDefault<double_t>("/input/path", 60.0);
863 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
864
865 test.runApplication();
866
867 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
868 }
869 {
871 ctk::TestFacility test(app);
872 test.setScalarDefault<float_t>("/parameters/requiredValue", 60.0);
873 test.setScalarDefault<float_t>("/input/path", 55.0);
874 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", true);
875
876 test.runApplication();
877
878 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::OFF));
879 }
880 {
882 ctk::TestFacility test(app);
883 test.setScalarDefault<int32_t>("/parameters/requiredValue", 60);
884 test.setScalarDefault<int32_t>("/input/path", 45);
885 test.setScalarDefault<ChimeraTK::Boolean>("/parameters/disable", false);
886
887 test.runApplication();
888
889 BOOST_TEST(test.readScalar<int32_t>("/output/path") == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
890 }
891 }
892
893 /********************************************************************************************************************/
894 /* Test data validity propagation for the Monitors *******************************************************************/
895 /********************************************************************************************************************/
896
897 /*
898 * Data validity is checked in base class of all monitors (MonitorBase) in method MonitorBase::setStatus only
899 * There is no need to test all types of monitors so we gonna use MaxMonitor
900 * */
901 BOOST_AUTO_TEST_CASE(testMonitorDataValidityPropagation) {
902 std::cout << "testMonitorDataValidityPropagation" << std::endl;
903
905 ctk::TestFacility test(app);
906
907 test.runApplication();
908
909 auto fault = test.getScalar<double_t>("/parameters/upperFaultThreshold");
910 auto warning = test.getScalar<double_t>("/parameters/upperWarningThreshold");
911 auto watch = test.getScalar<double_t>("/input/path");
912 auto status = test.getScalar<int32_t>("/output/path");
913
914 fault = 60.0;
915 fault.write();
916 warning = 50.0;
917 warning.write();
918 watch = 40.0;
919 watch.write();
920 test.stepApplication();
921 status.readLatest();
922 // status is OK and data validity also
923 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
924 BOOST_CHECK(status.dataValidity() == ctk::DataValidity::ok);
925
926 watch.setDataValidity(ctk::DataValidity::faulty);
927 watch.write();
928 test.stepApplication();
929 // status is not changed as watch is the same, data validity is changed -> test condition: getDataValidity() !=
930 // lastStatusValidity
931 BOOST_CHECK(status.readLatest());
932 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::OK));
933 // StatusOutput by default does not propagate DataValidity=fault (behaviour was changed!)
934 BOOST_CHECK(status.dataValidity() == ctk::DataValidity::ok);
935
936 watch = 55.0;
937 watch.write();
938 test.stepApplication();
939 status.readLatest();
940 // status is changed, data validity is not changed -> test condition: status.value != newStatus
941 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::WARNING));
942 BOOST_CHECK(status.dataValidity() == ctk::DataValidity::ok);
943
944 watch = 70.0;
945 watch.setDataValidity(ctk::DataValidity::ok);
946 watch.write();
947 test.stepApplication();
948 status.readLatest();
949 // status is changed, data validity is changed -> test condition: status.value != newStatus
950 BOOST_CHECK(status == static_cast<int>(ChimeraTK::StatusOutput::Status::FAULT));
951 BOOST_CHECK(status.dataValidity() == ctk::DataValidity::ok);
952
953 watch = 75.0;
954 watch.setDataValidity(ctk::DataValidity::ok);
955 watch.write();
956 test.stepApplication();
957 // status is not changed, data validity is not changed -> test that there is no new value of status
958 BOOST_CHECK(status.readLatest() == false);
959 }
960
961} // namespace Tests::testStatusMonitor
void shutdown() override
This will remove the global pointer to the instance and allows creating another instance afterwards.
friend class Application
Definition ModuleGroup.h:47
Helper class to facilitate tests of applications based on ApplicationCore.
TYPE readScalar(const std::string &name)
Convenience function to read the latest value of a scalar process variable in a single call.
void stepApplication(bool waitForDeviceInitialisation=true) const
Perform a "step" of the application.
ChimeraTK::ScalarRegisterAccessor< T > getScalar(const ChimeraTK::RegisterPath &name) const
Obtain a scalar process variable from the application, which is published to the control system.
void runApplication() const
Start the application in testable mode.
void setScalarDefault(const ChimeraTK::RegisterPath &name, const T &value)
Set default value for scalar process variable.
Class describing a node of a variable network.
const std::unordered_set< std::string > & getTags() const
InvalidityTracer application module.
const std::unordered_set< std::string > TAGS
Convenience type definition which can optionally be used as a shortcut for the type which defines a l...
Definition EntityOwner.h:27
BOOST_AUTO_TEST_CASE(testMaxMonitor)