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