ChimeraTK-DeviceAccess 03.25.00
Loading...
Searching...
No Matches
testRegisterCatalogue.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
6#define BOOST_TEST_MODULE RegisterCatalogue
7#include <boost/test/unit_test.hpp>
8using namespace boost::unit_test_framework;
9
11
12using namespace ChimeraTK;
13
14/**********************************************************************************************************************/
15
17 public:
18 myRegisterInfo(std::string path, unsigned int nbOfElements, unsigned int nbOfChannels, unsigned int nbOfDimensions,
19 DataDescriptor dataDescriptor, bool readable, bool writeable, AccessModeFlags supportedFlags, bool hidden = false)
20 : _path(path), _nbOfElements(nbOfElements), _nbOfChannels(nbOfChannels), _nbOfDimensions(nbOfDimensions),
21 _dataDescriptor(dataDescriptor), _readable(readable), _writeable(writeable), _supportedFlags(supportedFlags),
22 _hidden(hidden) {}
23
24 myRegisterInfo() = default;
25
26 [[nodiscard]] RegisterPath getRegisterName() const override { return _path; }
27
28 [[nodiscard]] unsigned int getNumberOfElements() const override { return _nbOfElements; }
29
30 [[nodiscard]] unsigned int getNumberOfChannels() const override { return _nbOfChannels; }
31
32 [[nodiscard]] const DataDescriptor& getDataDescriptor() const override { return _dataDescriptor; }
33
34 [[nodiscard]] bool isReadable() const override { return _readable; }
35
36 [[nodiscard]] bool isWriteable() const override { return _writeable; }
37
38 [[nodiscard]] AccessModeFlags getSupportedAccessModes() const override { return _supportedFlags; }
39
40 [[nodiscard]] bool isHidden() const override { return _hidden; }
41
42 [[nodiscard]] std::unique_ptr<BackendRegisterInfoBase> clone() const override {
43 auto* info = new myRegisterInfo(*this);
44 return std::unique_ptr<BackendRegisterInfoBase>(info);
45 }
46
47 bool operator==(const myRegisterInfo& other) const {
48 return _path == other._path && _nbOfElements == other._nbOfElements && _nbOfChannels == other._nbOfChannels &&
51 }
52
53 protected:
59 bool _hidden;
60};
61
62/**********************************************************************************************************************/
63
65 public:
68
69 catalogue.addRegister(theInfo);
70 catalogue.addRegister(theInfo2);
71 catalogue.addRegister(theInfo3);
72 catalogue.addRegister(theInfo4);
73
74 return catalogue;
75 }
76
77 DataDescriptor dataDescriptor{DataDescriptor::FundamentalType::numeric, false, false, 8, 3, DataType::int32};
78 myRegisterInfo theInfo{"/some/register/name", 42, 3, 2, dataDescriptor, true, false, {AccessMode::raw}};
79
80 DataDescriptor dataDescriptor2{DataDescriptor::FundamentalType::numeric, true, false, 12};
82 "/some/other/name", 1, 1, 0, dataDescriptor2, true, true, {AccessMode::raw, AccessMode::wait_for_new_data}};
83
84 DataDescriptor dataDescriptor3{DataDescriptor::FundamentalType::string};
85 myRegisterInfo theInfo3{"/justAName", 1, 1, 0, dataDescriptor3, false, false, {}};
86
87 myRegisterInfo theInfo4{"/some/hidden/register", 42, 3, 2, dataDescriptor, true, false, {AccessMode::raw}, true};
88};
89
90/**********************************************************************************************************************/
91
92BOOST_AUTO_TEST_SUITE(RegisterCatalogueTestSuite)
93
94/**********************************************************************************************************************/
95
96BOOST_AUTO_TEST_CASE(testDirectAccess) {
97 CatalogueGenerator generator;
98 auto catalogue = generator.generateCatalogue();
99
100 BOOST_TEST(catalogue.getNumberOfRegisters() == 3);
101
102 auto info = catalogue.getRegister("/some/register/name");
103 // check accessor functions of RegisterInfo class
104 BOOST_TEST(info.getRegisterName() == "/some/register/name");
105 BOOST_TEST(info.getNumberOfElements() == 42);
106 BOOST_TEST(info.getNumberOfChannels() == 3);
107 BOOST_TEST(info.getNumberOfDimensions() == 2);
108 BOOST_TEST(info.getDataDescriptor().fundamentalType() == DataDescriptor::FundamentalType::numeric);
109 BOOST_TEST(info.getDataDescriptor().isSigned() == false);
110 BOOST_TEST(info.getDataDescriptor().isIntegral() == false);
111 BOOST_TEST(info.getDataDescriptor().nDigits() == 8);
112 BOOST_TEST(info.getDataDescriptor().nFractionalDigits() == 3);
113 BOOST_TEST(info.getDataDescriptor().rawDataType() == DataType::int32);
114 BOOST_TEST(info.getDataDescriptor().rawDataType().isNumeric());
115 BOOST_TEST(info.getDataDescriptor().rawDataType().isIntegral());
116 BOOST_TEST(info.getDataDescriptor().rawDataType().isSigned());
117 BOOST_TEST(info.isReadable() == true);
118 BOOST_TEST(info.isWriteable() == false);
119 BOOST_TEST(info.getSupportedAccessModes().has(AccessMode::raw) == true);
120 BOOST_TEST(info.getSupportedAccessModes().has(AccessMode::wait_for_new_data) == false);
121 // check that the RegisterInfoImpl object is a copy of the original object (different address but identical content).
122 auto& theImpl = info.getImpl();
123 auto theImpl_casted = dynamic_cast<myRegisterInfo*>(&theImpl);
124 BOOST_TEST(theImpl_casted != nullptr);
125 BOOST_TEST(theImpl_casted != &generator.theInfo);
126
127 info = catalogue.getRegister("/some/other/name");
128 BOOST_TEST(info.getRegisterName() == "/some/other/name");
129 BOOST_TEST(info.getNumberOfElements() == 1);
130 BOOST_TEST(info.getNumberOfChannels() == 1);
131 BOOST_TEST(info.getNumberOfDimensions() == 0);
132 BOOST_TEST(info.getDataDescriptor().fundamentalType() == DataDescriptor::FundamentalType::numeric);
133 BOOST_TEST(info.getDataDescriptor().isSigned() == false);
134 BOOST_TEST(info.getDataDescriptor().isIntegral() == true);
135 BOOST_TEST(info.getDataDescriptor().nDigits() == 12);
136 BOOST_TEST(info.getDataDescriptor().rawDataType() == DataType::none);
137 BOOST_TEST(info.getDataDescriptor().rawDataType().isNumeric() == false);
138 BOOST_TEST(info.getDataDescriptor().rawDataType().isIntegral() == false);
139 BOOST_TEST(info.getDataDescriptor().rawDataType().isSigned() == false);
140 BOOST_TEST(info.isReadable() == true);
141 BOOST_TEST(info.isWriteable() == true);
142 BOOST_TEST(info.getSupportedAccessModes().has(AccessMode::raw) == true);
143 BOOST_TEST(info.getSupportedAccessModes().has(AccessMode::wait_for_new_data) == true);
144
145 info = catalogue.getRegister("/justAName");
146 BOOST_TEST(info.getRegisterName() == "/justAName");
147 BOOST_TEST(info.getNumberOfElements() == 1);
148 BOOST_TEST(info.getNumberOfChannels() == 1);
149 BOOST_TEST(info.getNumberOfDimensions() == 0);
150 BOOST_TEST(info.getDataDescriptor().fundamentalType() == DataDescriptor::FundamentalType::string);
151 BOOST_TEST(info.getDataDescriptor().rawDataType() == DataType::none);
152 BOOST_TEST(info.getDataDescriptor().rawDataType().isNumeric() == false);
153 BOOST_TEST(info.getDataDescriptor().rawDataType().isIntegral() == false);
154 BOOST_TEST(info.getDataDescriptor().rawDataType().isSigned() == false);
155 BOOST_TEST(info.isReadable() == false);
156 BOOST_TEST(info.isWriteable() == false);
157 BOOST_TEST(info.getSupportedAccessModes().has(AccessMode::raw) == false);
158 BOOST_TEST(info.getSupportedAccessModes().has(AccessMode::wait_for_new_data) == false);
159}
160/**********************************************************************************************************************/
161
163 CatalogueGenerator generator;
164 auto catalogue = generator.generateCatalogue();
165
166 // create clone of the entire catalogue (must be a deep copy)
167 std::unique_ptr<BackendRegisterCatalogue<myRegisterInfo>> cat_copy(
168 dynamic_cast<BackendRegisterCatalogue<myRegisterInfo>*>(catalogue.clone().release()));
169 BOOST_TEST(cat_copy->getNumberOfRegisters() == 3);
170
171 BOOST_CHECK(
172 catalogue.getBackendRegister("/some/register/name") == cat_copy->getBackendRegister("/some/register/name"));
173 BOOST_CHECK(catalogue.getBackendRegister("/some/other/name") == cat_copy->getBackendRegister("/some/other/name"));
174 BOOST_CHECK(catalogue.getBackendRegister("/justAName") == cat_copy->getBackendRegister("/justAName"));
175
176 std::vector<myRegisterInfo> seenObjects;
177 for(auto& i : *cat_copy) {
178 seenObjects.push_back(i);
179 }
180
181 BOOST_TEST(seenObjects.size() == 3);
182 BOOST_CHECK(seenObjects[0] == generator.theInfo);
183 BOOST_CHECK(seenObjects[1] == generator.theInfo2);
184 BOOST_CHECK(seenObjects[2] == generator.theInfo3);
185}
186
187/**********************************************************************************************************************/
188
189BOOST_AUTO_TEST_CASE(testRangeBasedLoopBackend) {
190 CatalogueGenerator generator;
191 auto catalogue = generator.generateCatalogue();
192
193 std::vector<myRegisterInfo> seenObjects;
194 for(auto& elem : catalogue) {
195 seenObjects.push_back(elem);
196 }
197
198 BOOST_TEST(seenObjects.size() == 3);
199 BOOST_CHECK(seenObjects[0] == generator.theInfo);
200 BOOST_CHECK(seenObjects[1] == generator.theInfo2);
201 BOOST_CHECK(seenObjects[2] == generator.theInfo3);
202}
203
204/**********************************************************************************************************************/
205
206BOOST_AUTO_TEST_CASE(testRangeBasedLoopBackendConst) {
207 CatalogueGenerator generator;
208 const auto catalogue = generator.generateCatalogue();
209
210 std::vector<myRegisterInfo> seenObjects;
211 for(const auto& elem : catalogue) {
212 seenObjects.push_back(elem);
213 }
214
215 BOOST_TEST(seenObjects.size() == 3);
216 BOOST_CHECK(seenObjects[0] == generator.theInfo);
217 BOOST_CHECK(seenObjects[1] == generator.theInfo2);
218 BOOST_CHECK(seenObjects[2] == generator.theInfo3);
219}
220
221/**********************************************************************************************************************/
222
223BOOST_AUTO_TEST_CASE(testRangeBasedLoopFrontend) {
224 CatalogueGenerator generator;
225 auto backend_catalogue = generator.generateCatalogue();
226 RegisterCatalogue catalogue(backend_catalogue.clone());
227
228 std::vector<RegisterInfo> seenObjects;
229 for(const auto& elem : catalogue) {
230 seenObjects.emplace_back(elem.clone());
231 }
232
233 BOOST_TEST(seenObjects.size() == 3);
234 BOOST_TEST(seenObjects[0].getRegisterName() == generator.theInfo.getRegisterName());
235 BOOST_TEST(seenObjects[1].getRegisterName() == generator.theInfo2.getRegisterName());
236 BOOST_TEST(seenObjects[2].getRegisterName() == generator.theInfo3.getRegisterName());
237}
238
239/**********************************************************************************************************************/
240
241BOOST_AUTO_TEST_CASE(TestHiddenRegisters) {
242 CatalogueGenerator generator;
243 auto backend_catalogue = generator.generateCatalogue();
244 RegisterCatalogue catalogue(backend_catalogue.clone());
245
246 std::vector<RegisterInfo> seenObjects;
247 for(const auto& elem : catalogue.hiddenRegisters()) {
248 seenObjects.emplace_back(elem.clone());
249 }
250
251 BOOST_TEST(seenObjects.size() == 1);
252 BOOST_TEST(seenObjects[0].getRegisterName() == generator.theInfo4.getRegisterName());
253}
254
255/**********************************************************************************************************************/
256
257BOOST_AUTO_TEST_SUITE_END()
BackendRegisterCatalogue< myRegisterInfo > generateCatalogue()
Set of AccessMode flags with additional functionality for an easier handling.
Definition AccessMode.h:48
Interface for backends to the register catalogue.
void addRegister(const BackendRegisterInfo &registerInfo)
Add register information to the catalogue.
DeviceBackend-independent register description.
Class describing the actual payload data format of a register in an abstract manner.
@ int32
Signed 32 bit integer.
@ none
The data type/concept does not exist, e.g. there is no raw transfer (do not confuse with Void)
Catalogue of register information.
HiddenRange hiddenRegisters() const
Returns non-owning range of all hidden registers in the catalogue.
Class to store a register path name.
const DataDescriptor & getDataDescriptor() const override
Return description of the actual payload data for this register.
bool isHidden() const override
Returns whether the register is "hidden", meaning it won't be listed when iterating the catalogue.
bool isReadable() const override
Return whether the register is readable.
myRegisterInfo()=default
DataDescriptor _dataDescriptor
AccessModeFlags _supportedFlags
unsigned int getNumberOfChannels() const override
Return number of channels in register.
AccessModeFlags getSupportedAccessModes() const override
Return all supported AccessModes for this register.
bool isWriteable() const override
Return whether the register is writeable.
bool operator==(const myRegisterInfo &other) const
RegisterPath getRegisterName() const override
Return full path name of the register (including modules)
unsigned int getNumberOfElements() const override
Return number of elements per channel.
std::unique_ptr< BackendRegisterInfoBase > clone() const override
Create copy of the object.
myRegisterInfo(std::string path, unsigned int nbOfElements, unsigned int nbOfChannels, unsigned int nbOfDimensions, DataDescriptor dataDescriptor, bool readable, bool writeable, AccessModeFlags supportedFlags, bool hidden=false)
BOOST_AUTO_TEST_CASE(testDirectAccess)