ChimeraTK-ApplicationCore 04.06.00
Loading...
Searching...
No Matches
testVersionPropagation.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#define BOOST_TEST_MODULE testVersionpropagation
4
5#include "ApplicationModule.h"
6#include "check_timeout.h"
7#include "fixtures.h"
8
9#include <ChimeraTK/ExceptionDummyBackend.h>
10#include <ChimeraTK/RegisterPath.h>
11#include <ChimeraTK/VersionNumber.h>
12
13#include <boost/test/included/unit_test.hpp>
14
15#include <future>
16
18
19 namespace ctk = ChimeraTK;
21
22 BOOST_FIXTURE_TEST_SUITE(VersionPropagationPart1, Fixture)
23
24 /********************************************************************************************************************/
25
26 BOOST_AUTO_TEST_CASE(versionPropagation_testPolledRead) {
27 std::cout << "versionPropagation_testPolledRead" << std::endl;
28 auto moduleVersion = application.group1.pollModule.getCurrentVersionNumber();
29 [[maybe_unused]] auto pollVariableVersion = pollVariable2.getVersionNumber();
30
31 application.group1.outputModule.setCurrentVersionNumber({});
32 outputVariable2.write();
33 pollVariable2.read();
34
35 assert(pollVariable2.getVersionNumber() > pollVariableVersion);
36 BOOST_CHECK(moduleVersion == application.group1.pollModule.getCurrentVersionNumber());
37 }
38
39 /********************************************************************************************************************/
40
41 BOOST_AUTO_TEST_CASE(versionPropagation_testPolledReadNonBlocking) {
42 std::cout << "versionPropagation_testPolledReadNonBlocking" << std::endl;
43 auto moduleVersion = application.group1.pollModule.getCurrentVersionNumber();
44 [[maybe_unused]] auto pollVariableVersion = pollVariable2.getVersionNumber();
45
46 application.group1.outputModule.setCurrentVersionNumber({});
47 outputVariable2.write();
48 pollVariable2.readNonBlocking();
49
50 assert(pollVariable2.getVersionNumber() > pollVariableVersion);
51 BOOST_CHECK(moduleVersion == application.group1.pollModule.getCurrentVersionNumber());
52 }
53
54 /********************************************************************************************************************/
55
56 BOOST_AUTO_TEST_CASE(versionPropagation_testPolledReadLatest) {
57 std::cout << "versionPropagation_testPolledReadLatest" << std::endl;
58 auto moduleVersion = application.group1.pollModule.getCurrentVersionNumber();
59 [[maybe_unused]] auto pollVariableVersion = pollVariable2.getVersionNumber();
60
61 application.group1.outputModule.setCurrentVersionNumber({});
62 outputVariable2.write();
63 pollVariable2.readLatest();
64
65 assert(pollVariable2.getVersionNumber() > pollVariableVersion);
66 BOOST_CHECK(moduleVersion == application.group1.pollModule.getCurrentVersionNumber());
67 }
68
69 /********************************************************************************************************************/
70
71 BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeRead) {
72 std::cout << "versionPropagation_testPushTypeRead" << std::endl;
73 // Make sure we pop out any stray values in the pushInput before test start:
74 CHECK_TIMEOUT(pushVariable.readLatest() == false, 10000);
75
76 [[maybe_unused]] ctk::VersionNumber nextVersionNumber = {};
77 interrupt.write();
78 pushVariable.read();
79 assert(pushVariable.getVersionNumber() > nextVersionNumber);
80 BOOST_CHECK(application.group1.pushModule.getCurrentVersionNumber() == pushVariable.getVersionNumber());
81 }
82
83 /********************************************************************************************************************/
84
85 BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeReadNonBlocking) {
86 std::cout << "versionPropagation_testPushTypeReadNonBlocking" << std::endl;
87 CHECK_TIMEOUT(pushVariable.readLatest() == false, 10000);
88
89 auto pushInputVersionNumber = pushVariable.getVersionNumber();
90
91 // no version change on readNonBlocking false
92 BOOST_CHECK_EQUAL(pushVariable.readNonBlocking(), false);
93 BOOST_CHECK(pushInputVersionNumber == pushVariable.getVersionNumber());
94
95 ctk::VersionNumber nextVersionNumber = {};
96 auto moduleVersion = application.group1.pushModule.getCurrentVersionNumber();
97
98 interrupt.write();
99 CHECK_TIMEOUT(pushVariable.readNonBlocking() == true, 10000);
100 BOOST_CHECK(pushVariable.getVersionNumber() > nextVersionNumber);
101
102 // readNonBlocking will not propagete the version to the module
103 BOOST_CHECK(application.group1.pushModule.getCurrentVersionNumber() == moduleVersion);
104 }
105
106 /********************************************************************************************************************/
107
108 BOOST_AUTO_TEST_CASE(versionPropagation_testPushTypeReadLatest) {
109 std::cout << "versionPropagation_testPushTypeReadLatest" << std::endl;
110 // Make sure we pop out any stray values in the pushInput before test start:
111 CHECK_TIMEOUT(pushVariable.readLatest() == false, 10000);
112
113 auto pushInputVersionNumber = pushVariable.getVersionNumber();
114
115 // no version change on readNonBlocking false
116 BOOST_CHECK_EQUAL(pushVariable.readLatest(), false);
117 BOOST_CHECK(pushInputVersionNumber == pushVariable.getVersionNumber());
118
119 ctk::VersionNumber nextVersionNumber = {};
120 auto moduleVersion = application.group1.pushModule.getCurrentVersionNumber();
121
122 interrupt.write();
123 CHECK_TIMEOUT(pushVariable.readLatest() == true, 10000);
124 BOOST_CHECK(pushVariable.getVersionNumber() > nextVersionNumber);
125
126 // readLatest will not propagete the version to the module
127 BOOST_CHECK(application.group1.pushModule.getCurrentVersionNumber() == moduleVersion);
128 }
129
130 BOOST_AUTO_TEST_SUITE_END()
131
132 /********************************************************************************************************************/
133 /********************************************************************************************************************/
134
135 // The EmptyFixture is required, since we cannot use an ordinary BOOST_AUTO_TEST_SUITE after a
136 // BOOST_FIXTURE_TEST_SUITE when compiling with -std=c++20 or later.
137 class EmptyFixture {};
138 BOOST_FIXTURE_TEST_SUITE(VersionPropagationPart2, EmptyFixture)
139
140 struct ThePushModule : ChimeraTK::ApplicationModule {
142
143 ChimeraTK::ScalarPushInput<int> pushInput{this, "/theVariable", "", ""};
144
145 std::promise<void> p;
146 void mainLoop() override { p.set_value(); }
147 };
148
151
152 ChimeraTK::ScalarOutput<int> output{this, "/theVariable", "", ""};
153
154 void prepare() override { output.write(); }
155
156 std::promise<void> p;
157 void mainLoop() override { p.set_value(); }
158 };
159
162 explicit TheTestApplication(const std::string& name, const std::unordered_set<std::string>& pmTags = {})
163 : ChimeraTK::Application(name), pm{this, "pm", "", pmTags} {}
164
166
168 TheOutputModule om{this, "om", ""};
169 };
170
171 /********************************************************************************************************************/
172
173 BOOST_AUTO_TEST_CASE(versionPropagation_testSetAndWrite) {
174 std::cout << "versionPropagation_testSetAndWrite" << std::endl;
175 TheTestApplication app("app");
176 ChimeraTK::TestFacility test(app, false);
177 test.runApplication();
178 app.pm.p.get_future().wait();
179 app.om.p.get_future().wait();
180
181 ChimeraTK::VersionNumber theVersion;
182 app.om.setCurrentVersionNumber(theVersion);
183 app.om.output.setAndWrite(42);
184
185 app.pm.pushInput.read();
186
187 BOOST_CHECK(app.pm.getCurrentVersionNumber() == theVersion);
188 }
189
190 /********************************************************************************************************************/
191
192 BOOST_AUTO_TEST_CASE(versionPropagation_testWriteIfDifferent) {
193 std::cout << "versionPropagation_testWriteIfDifferent" << std::endl;
194 TheTestApplication app("app");
195 ChimeraTK::TestFacility test(app, false);
196 test.runApplication();
197 app.pm.p.get_future().wait();
198 app.om.p.get_future().wait();
199
200 ChimeraTK::VersionNumber theVersion;
201 app.om.setCurrentVersionNumber(theVersion);
202 app.om.output.writeIfDifferent(42);
203
204 app.pm.pushInput.read();
205
206 BOOST_CHECK(app.pm.getCurrentVersionNumber() == theVersion);
207 }
208
209 /********************************************************************************************************************/
210
211 BOOST_AUTO_TEST_CASE(versionPropagation_testDisabledVersionProp) {
212 std::cout << "versionPropagation_testDisabledVersionProp" << std::endl;
214 ChimeraTK::TestFacility test(app, false);
215 test.runApplication();
216 app.pm.p.get_future().wait();
217 app.om.p.get_future().wait();
218
219 // test that special tag disables propagation of VersionNumber to application module
220 ctk::VersionNumber vnInputBeforeWrite = app.pm.pushInput.getVersionNumber();
221 ctk::VersionNumber vnModuleBeforeWrite = app.pm.getCurrentVersionNumber();
222 app.om.setCurrentVersionNumber({});
223 app.om.output.write();
224 app.pm.pushInput.read();
225 BOOST_CHECK(app.pm.pushInput.getVersionNumber() > vnInputBeforeWrite);
226 BOOST_CHECK(app.pm.getCurrentVersionNumber() == vnModuleBeforeWrite);
227 }
228
229 /********************************************************************************************************************/
230
231 BOOST_AUTO_TEST_SUITE_END()
232
233 /********************************************************************************************************************/
234
235} // namespace Tests::testVersionpropagation
void shutdown() override
This will remove the global pointer to the instance and allows creating another instance afterwards.
ApplicationModule()=default
Default constructor: Allows late initialisation of modules (e.g.
void setCurrentVersionNumber(VersionNumber versionNumber) override
Set the current version number.
VersionNumber getCurrentVersionNumber() const override
Return the current version number which has been received with the last push-type read operation.
friend class Application
Definition ModuleGroup.h:47
bool write(ChimeraTK::VersionNumber versionNumber)=delete
void writeIfDifferent(UserType newValue, VersionNumber versionNumber, DataValidity validity)=delete
void setAndWrite(UserType newValue, VersionNumber versionNumber)=delete
Convenience class for input scalar accessors with UpdateMode::push.
Helper class to facilitate tests of applications based on ApplicationCore.
void runApplication() const
Start the application in testable mode.
InvalidityTracer application module.
constexpr auto independentVersionTag
Special tag to designate that a push-input should not propagate VersionNumber updates to its owning m...
BOOST_AUTO_TEST_CASE(versionPropagation_testPolledRead)
Convenience class for output scalar accessors (always UpdateMode::push)
void write(ChimeraTK::DummyRegisterRawAccessor &accessor, T value)
Definition fixtures.h:308
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
void prepare() override
Prepare the execution of the module.
void mainLoop() override
To be implemented by the user: function called in a separate thread executing the main loop of the mo...
TheTestApplication(const std::string &name, const std::unordered_set< std::string > &pmTags={})
#define CHECK_TIMEOUT(condition, maxMilliseconds)