ChimeraTK-DeviceAccess  03.18.00
testSharedDummyBackendUnifiedExt.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 SharedDummyBackendUnifiedTest
6 #include "Device.h"
7 #include "ProcessManagement.h"
8 #include "sharedDummyHelpers.h"
9 #include "Utilities.h"
10 
11 #include <boost/filesystem.hpp>
12 #include <boost/interprocess/managed_shared_memory.hpp>
13 #include <boost/test/unit_test.hpp>
14 
15 #include <algorithm>
16 #include <string>
17 #include <thread>
18 #include <unistd.h>
19 
20 namespace {
21 
22  using namespace ChimeraTK;
23  using namespace boost::unit_test_framework;
24 
25  // Static variables
26  // Use hardcoded information from the dmap-file to
27  // only use public interface here
28  static std::string instanceId{"1"};
29  static std::string mapFileName{"sharedDummyUnified.map"};
30 
31  BOOST_AUTO_TEST_SUITE(SharedDummyBackendUnifiedTestSuite)
32 
33  struct TestFixture {
34  TestFixture() : argc(framework::master_test_suite().argc), argv(framework::master_test_suite().argv) {}
35 
36  int argc;
37  char** argv;
38  };
39 
40  static void mirrorArea(
42  processVarsFrom.read();
43  for(size_t i = 0; i < processVarsFrom.getNElements(); ++i) {
44  processVarsTo[i] = processVarsFrom[i];
45  }
46  processVarsTo.write();
47  }
48 
49  /********************************************************************************************************************/
50 
57  BOOST_FIXTURE_TEST_CASE(testRegisterAccessor, TestFixture) {
58  bool keepRunning = true;
59 
60  setDMapFilePath("sharedDummyUnified.dmap");
61 
62  boost::filesystem::path absPathToMapFile = boost::filesystem::absolute(mapFileName);
63  std::string shmName{createExpectedShmName(instanceId, absPathToMapFile.string(), getUserName())};
64 
65  {
66  Device dev;
67  BOOST_CHECK(!dev.isOpened());
68  dev.open("SHDMEMDEV");
69  BOOST_CHECK(dev.isOpened());
70 
71  BOOST_CHECK(shm_exists(shmName));
72 
73  ChimeraTK::OneDRegisterAccessor<int> processVarsFeature = dev.getOneDRegisterAccessor<int>("FEATURE/AREA1");
74 
75  ChimeraTK::OneDRegisterAccessor<int> processVarsMirror = dev.getOneDRegisterAccessor<int>("MIRRORED/AREA1");
76 
77  BOOST_CHECK_EQUAL(processVarsFeature.getNElements(), processVarsMirror.getNElements());
78 
79  ScalarRegisterAccessor<int> mirrorRequest_Type = dev.getScalarRegisterAccessor<int>("MIRRORREQUEST/TYPE");
80  ScalarRegisterAccessor<int> mirrorRequest_Busy = dev.getScalarRegisterAccessor<int>("MIRRORREQUEST/BUSY");
81  ScalarRegisterAccessor<int> mirrorRequest_Updated =
82  dev.getScalarRegisterAccessor<int>("MIRRORREQUEST/UPDATED/DUMMY_WRITEABLE");
83  ScalarRegisterAccessor<int> mirrorRequest_DataInterrupt =
84  dev.getScalarRegisterAccessor<int>("MIRRORREQUEST/DATA_INTERRUPT");
85  ScalarRegisterAccessor<int> mirrorRequestUpdated_Interrupt{
86  dev.getScalarRegisterAccessor<int>("DUMMY_INTERRUPT_0")};
87 
88  ScalarRegisterAccessor<int> dataInterrupt{dev.getScalarRegisterAccessor<int>("DUMMY_INTERRUPT_1")};
89 
90  do {
91  // poll Busy until it is set to true, indicating a new request
92  do {
93  mirrorRequest_Busy.readLatest();
94  // we use boost::sleep because it defines an interruption point for signals
95  boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
96  } while(mirrorRequest_Busy == 0);
97 
98  mirrorRequest_Type.readLatest();
99  switch(static_cast<MirrorRequestType>((int)mirrorRequest_Type)) {
101  mirrorArea(processVarsMirror, processVarsFeature);
102  break;
104  mirrorArea(processVarsFeature, processVarsMirror);
105  break;
107  keepRunning = false;
108  }
109  mirrorRequest_Updated.readLatest();
110  ++mirrorRequest_Updated;
111  mirrorRequest_Updated.write();
112  // also trigger interrupt for this variable
113  mirrorRequestUpdated_Interrupt = 1;
114  mirrorRequestUpdated_Interrupt.write();
115 
116  mirrorRequest_Busy = 0;
117  mirrorRequest_Busy.write();
118 
119  mirrorRequest_DataInterrupt.readLatest();
120  if(mirrorRequest_DataInterrupt == 1) {
121  dataInterrupt.write();
122  mirrorRequest_DataInterrupt = 0;
123  mirrorRequest_DataInterrupt.write();
124  }
125  } while(keepRunning);
126  dev.close();
127  }
128  }
129 
130  /********************************************************************************************************************/
131  BOOST_AUTO_TEST_SUITE_END()
132 
133 } // anonymous namespace
ChimeraTK::TransferElementAbstractor::readLatest
bool readLatest()
Read the latest value, discarding any other update since the last read if present.
Definition: TransferElementAbstractor.h:77
ChimeraTK::Device::close
void close()
Close the device.
Definition: Device.cc:66
ChimeraTK::Device::getOneDRegisterAccessor
OneDRegisterAccessor< UserType > getOneDRegisterAccessor(const RegisterPath &registerPathName, size_t numberOfWords=0, size_t wordOffsetInRegister=0, const AccessModeFlags &flags=AccessModeFlags({})) const
Get a OneDRegisterAccessor object for the given register.
Definition: Device.h:273
Utilities.h
MirrorRequestType::stop
@ stop
MirrorRequestType::from
@ from
MirrorRequestType::to
@ to
ChimeraTK::OneDRegisterAccessor::getNElements
unsigned int getNElements()
Return number of elements/samples in the register.
Definition: OneDRegisterAccessor.h:51
TestFixture::TestFixture
TestFixture(uint32_t interrupt, bool activateAsyncFirst)
Definition: testGenericMuxedInterruptDistributor.cpp:90
ChimeraTK::ScalarRegisterAccessor
Accessor class to read and write scalar registers transparently by using the accessor object like a v...
Definition: ScalarRegisterAccessor.h:24
BOOST_FIXTURE_TEST_CASE
BOOST_FIXTURE_TEST_CASE(testSlowReader, DeviceFixture)
Definition: testDoubleBuffering.cpp:240
ChimeraTK::OneDRegisterAccessor
Accessor class to read and write registers transparently by using the accessor object like a vector o...
Definition: OneDRegisterAccessor.h:20
Device.h
createExpectedShmName
std::string createExpectedShmName(std::string instanceId_, std::string mapFileName_, std::string userName)
Definition: sharedDummyHelpers.h:16
MirrorRequestType
MirrorRequestType
Definition: sharedDummyHelpers.h:13
sharedDummyHelpers.h
shm_exists
bool shm_exists(std::string shmName)
Definition: sharedDummyHelpers.h:24
ChimeraTK::Device
Class allows to read/write registers from device.
Definition: Device.h:39
ProcessManagement.h
ChimeraTK::Device::open
void open(std::string const &aliasName)
Open a device by the given alias name from the DMAP file.
Definition: Device.cc:58
ChimeraTK::Device::getScalarRegisterAccessor
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:263
ChimeraTK::Device::isOpened
bool isOpened() const
Check if the device is currently opened.
Definition: Device.cc:73
ChimeraTK::TransferElementAbstractor::write
bool write(ChimeraTK::VersionNumber versionNumber={})
Write the data to device.
Definition: TransferElementAbstractor.h:89
ChimeraTK::setDMapFilePath
void setDMapFilePath(std::string dmapFilePath)
Set the location of the dmap file.
Definition: Utilities.cpp:327
ChimeraTK
Definition: DummyBackend.h:16
ChimeraTK::TransferElementAbstractor::read
void read()
Read the data from the device.
Definition: TransferElementAbstractor.h:57
getUserName
std::string getUserName()
Definition: ProcessManagement.cpp:24