ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
testDataConsistencyGroup.cpp
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
4#define BOOST_TEST_DYN_LINK
5#define BOOST_TEST_MODULE DataConsistencyGroupTest
6#include <boost/test/unit_test.hpp>
7using namespace boost::unit_test_framework;
8
10#include "Device.h"
11#include "NDRegisterAccessor.h"
12
13using namespace ChimeraTK;
14
15BOOST_AUTO_TEST_SUITE(DataConsistencyGroupTestSuite)
16
17// notice: you cannot read from this accessor. It will block forever because there is nobody to write into the
18// _readQueue.
19template<typename UserType>
20class Accessor : public NDRegisterAccessor<UserType> {
21 public:
22 Accessor() : NDRegisterAccessor<UserType>("", {AccessMode::wait_for_new_data}) {}
23
24 ~Accessor() override {}
25
26 void doReadTransferSynchronously() override {}
27
28 bool doWriteTransfer(ChimeraTK::VersionNumber) override { return true; }
29
31
33
34 void doPreRead(TransferType) override {}
35
36 void doPostRead(TransferType, bool /*hasNewData*/) override {}
37
38 // AccessModeFlags getAccessModeFlags() const override { return {AccessMode::wait_for_new_data}; }
39 bool isReadOnly() const override { return false; }
40 bool isReadable() const override { return true; }
41 bool isWriteable() const override { return true; }
42
43 std::vector<boost::shared_ptr<TransferElement>> getHardwareAccessingElements() override {
44 return {this->shared_from_this()};
45 }
46 std::list<boost::shared_ptr<TransferElement>> getInternalElements() override { return {}; }
47
48 // VersionNumber getVersionNumber() const override { return currentVersion; }
49
50 // VersionNumber currentVersion;
51};
52
53BOOST_AUTO_TEST_CASE(testDataConsistencyGroup) {
54 boost::shared_ptr<Accessor<int>> acc_1 = boost::make_shared<Accessor<int>>();
55 boost::shared_ptr<Accessor<int>> acc_2 = boost::make_shared<Accessor<int>>();
56
57 // test the deprecated syntax without warning about it...
58#pragma GCC diagnostic push
59#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
60 DataConsistencyGroup dcgroup({acc_1, acc_2});
61#pragma GCC diagnostic pop
62
63 // until now all versions are {nullptr}
64 // prepare the version numbers in the dcgroup by writing (which set new version numbers)
65 acc_1->write();
66 acc_2->write();
67
68 BOOST_CHECK(dcgroup.update(acc_1->getId()) == false);
69
70 BOOST_CHECK(dcgroup.update(acc_2->getId()) == false);
71
72 // now update acc_1 with the newer version number from acc_2
73 acc_1->write(acc_2->getVersionNumber());
74
75 BOOST_CHECK(dcgroup.update(acc_1->getId()) == true);
76 BOOST_CHECK(dcgroup.update(acc_1->getId()) == true);
77 BOOST_CHECK(dcgroup.update(acc_2->getId()) == true);
78 BOOST_CHECK(dcgroup.update(acc_2->getId()) == true);
79 BOOST_CHECK(dcgroup.update(acc_2->getId()) == true);
80}
81
82BOOST_AUTO_TEST_CASE(testMoreDataConsistencyGroup) {
83 boost::shared_ptr<Accessor<int>> acc_1 = boost::make_shared<Accessor<int>>();
84 boost::shared_ptr<Accessor<int>> acc_2 = boost::make_shared<Accessor<int>>();
85 boost::shared_ptr<Accessor<int>> acc_3 = boost::make_shared<Accessor<int>>();
86 boost::shared_ptr<Accessor<int>> acc_4 = boost::make_shared<Accessor<int>>();
87
88 // test the deprecated syntax without warning about it...
89#pragma GCC diagnostic push
90#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
91 DataConsistencyGroup dcgroup({acc_1, acc_2, acc_3, acc_4});
92#pragma GCC diagnostic pop
93 // 4 different version numbers
94 acc_1->write();
95 acc_2->write();
96 acc_3->write();
97 acc_4->write();
98 BOOST_CHECK(dcgroup.update(acc_1->getId()) == false);
99 BOOST_CHECK(dcgroup.update(acc_2->getId()) == false);
100 BOOST_CHECK(dcgroup.update(acc_3->getId()) == false);
101 BOOST_CHECK(dcgroup.update(acc_4->getId()) == false);
102
103 // 3 different version numbers, acc_1 and acc_2 are the same
104 VersionNumber v; // a new version number
105 acc_1->write(v);
106 acc_2->write(v);
107 BOOST_CHECK(dcgroup.update(acc_1->getId()) == false);
108 BOOST_CHECK(dcgroup.update(acc_2->getId()) == false);
109 BOOST_CHECK(dcgroup.update(acc_3->getId()) == false);
110 BOOST_CHECK(dcgroup.update(acc_4->getId()) == false);
111
112 acc_3->write(v);
113 BOOST_CHECK(dcgroup.update(acc_1->getId()) == false);
114 BOOST_CHECK(dcgroup.update(acc_2->getId()) == false);
115 BOOST_CHECK(dcgroup.update(acc_3->getId()) == false);
116 BOOST_CHECK(dcgroup.update(acc_4->getId()) == false);
117
118 acc_4->write(v);
119 BOOST_CHECK(dcgroup.update(acc_1->getId()) == false);
120 BOOST_CHECK(dcgroup.update(acc_2->getId()) == false);
121 BOOST_CHECK(dcgroup.update(acc_3->getId()) == false);
122 BOOST_CHECK(dcgroup.update(acc_4->getId()) == true);
123 BOOST_CHECK(dcgroup.update(acc_2->getId()) == true);
124 BOOST_CHECK(dcgroup.update(acc_4->getId()) == true);
125 BOOST_CHECK(dcgroup.update(acc_3->getId()) == true);
126 BOOST_CHECK(dcgroup.update(acc_1->getId()) == true);
127
128 // push an accessor that does not belong to DataConsistencyGroup, should be ignored, although it hat the same version
129 // number
130 boost::shared_ptr<Accessor<int>> acc_5 = boost::make_shared<Accessor<int>>();
131 acc_5->write(v);
132 BOOST_CHECK(dcgroup.update(acc_5->getId()) == false);
133}
134
135// The same TransferElement shall be allowed to be part of multiple DataConsistencyGroups at the same time.
136BOOST_AUTO_TEST_CASE(testMultipleDataConsistencyGroup) {
137 boost::shared_ptr<Accessor<int>> acc_1 = boost::make_shared<Accessor<int>>();
138 boost::shared_ptr<Accessor<int>> acc_2 = boost::make_shared<Accessor<int>>();
139 boost::shared_ptr<Accessor<int>> acc_3 = boost::make_shared<Accessor<int>>();
140 boost::shared_ptr<Accessor<int>> acc_4 = boost::make_shared<Accessor<int>>();
141 // test the deprecated syntax without warning about it...
142#pragma GCC diagnostic push
143#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
144 DataConsistencyGroup dcgroup_1({acc_1, acc_2, acc_3});
145 DataConsistencyGroup dcgroup_2({acc_1, acc_3, acc_4});
146#pragma GCC diagnostic pop
148 acc_1->write(v);
149 acc_2->write(v);
150 acc_3->write(v);
151 acc_4->write(v);
152 BOOST_CHECK(dcgroup_1.update(acc_1->getId()) == false);
153 BOOST_CHECK(dcgroup_1.update(acc_2->getId()) == false);
154 BOOST_CHECK(dcgroup_1.update(acc_3->getId()) == true);
155 BOOST_CHECK(dcgroup_1.update(acc_4->getId()) == false); // ignored
156 BOOST_CHECK(dcgroup_2.update(acc_1->getId()) == false);
157 BOOST_CHECK(dcgroup_2.update(acc_3->getId()) == false);
158 BOOST_CHECK(dcgroup_2.update(acc_4->getId()) == true);
159 BOOST_CHECK(dcgroup_2.update(acc_2->getId()) == false); // ignored
160}
161
162BOOST_AUTO_TEST_CASE(testVersionNumberChange) {
163 VersionNumber v1{};
164 VersionNumber v2{};
165 VersionNumber v3{};
166
167 boost::shared_ptr<Accessor<int>> acc_1 = boost::make_shared<Accessor<int>>();
168 boost::shared_ptr<Accessor<int>> acc_2 = boost::make_shared<Accessor<int>>();
169
170 // test the deprecated syntax without warning about it...
171#pragma GCC diagnostic push
172#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
173 DataConsistencyGroup dcgroup_1({acc_1, acc_2});
174#pragma GCC diagnostic pop
175
176 acc_2->write(v2);
177 BOOST_CHECK_EQUAL(dcgroup_1.update(acc_2->getId()), false);
178
179 acc_1->write(v1);
180 BOOST_CHECK_EQUAL(dcgroup_1.update(acc_1->getId()), false);
181
182 acc_1->write(v2);
183 BOOST_CHECK_EQUAL(dcgroup_1.update(acc_1->getId()), true);
184
185 acc_1->write(v3);
186 acc_2->write(v3);
187 BOOST_CHECK_EQUAL(dcgroup_1.update(acc_1->getId()), false);
188 BOOST_CHECK_EQUAL(dcgroup_1.update(acc_2->getId()), true);
189}
190
191BOOST_AUTO_TEST_CASE(testException) {
192 Device dev;
193 dev.open("(dummy?map=registerAccess.map)");
194 auto acc = dev.getScalarRegisterAccessor<int>("BOARD.WORD_FIRMWARE");
195 DataConsistencyGroup dcgroup;
196 // accessors without wait_for_new_data cannot be added.
197 // test the deprecated syntax without warning about it...
198 BOOST_CHECK_THROW(dcgroup.add(acc), ChimeraTK::logic_error);
199}
200
201BOOST_AUTO_TEST_SUITE_END()
bool isReadable() const override
Check if transfer element is readable.
void doPostRead(TransferType, bool) override
Backend specific implementation of postRead().
void doPostWrite(TransferType, VersionNumber) override
Backend specific implementation of postWrite().
void doPreWrite(TransferType, VersionNumber) override
Backend specific implementation of preWrite().
std::vector< boost::shared_ptr< TransferElement > > getHardwareAccessingElements() override
Obtain the underlying TransferElements with actual hardware access.
bool doWriteTransfer(ChimeraTK::VersionNumber) override
Implementation version of writeTransfer().
void doPreRead(TransferType) override
Backend specific implementation of preRead().
std::list< boost::shared_ptr< TransferElement > > getInternalElements() override
Obtain the full list of TransferElements internally used by this TransferElement.
bool isWriteable() const override
Check if transfer element is writeable.
void doReadTransferSynchronously() override
Implementation version of readTransfer() for synchronous reads.
bool isReadOnly() const override
Check if transfer element is read only, i.e.
Group several registers (= TransferElement) which ensures data consistency across multiple variables ...
Class allows to read/write registers from device.
Definition Device.h:39
ScalarRegisterAccessor< UserType > getScalarRegisterAccessor(const RegisterPath &registerPathName, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a ScalarRegisterObject object for the given register.
Definition Device.h:266
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition Device.cc:58
N-dimensional register accessor.
Class for generating and holding version numbers without exposing a numeric representation.
Exception thrown when a logic error has occured.
Definition Exception.h:51
TransferType
Used to indicate the applicable operation on a Transferelement.
BOOST_AUTO_TEST_CASE(testDataConsistencyGroup)