15#define BOOST_TEST_MODULE testUnifiedBackendTest
18#include <ChimeraTK/Device.h>
19#include <ChimeraTK/TransferGroup.h>
20#include <ChimeraTK/UnifiedBackendTest.h>
22#include <doocs-server-test-helper/doocsServerTestHelper.h>
23#include <doocs-server-test-helper/ThreadedDoocsServer.h>
24#include <doocs/EqCall.h>
26#include <boost/filesystem.hpp>
27#include <boost/test/included/unit_test.hpp>
31using namespace boost::unit_test_framework;
36static std::atomic<bool> zmqStartup_gotData{
false};
41 : ThreadedDoocsServer(
"testUnifiedBackendTest.conf", boost::unit_test::framework::master_test_suite().argc,
42 boost::unit_test::framework::master_test_suite().argv,
eq_dummy::createServer()) {
45 DoocsServer =
"doocs:doocs://localhost:" + rpcNo() +
"/F/D";
50 doocs::EqData src, dst;
51 ea.adr(
"doocs://localhost:" + rpcNo() +
"/F/D/MYDUMMY/SOME_ZMQINT");
52 while(eq.get(&ea, &src, &dst)) usleep(100000);
57 std::cout <<
"ZeroMQ Subscribe" << std::endl;
58 [[maybe_unused]]
int err = dmsg_attach(
60 [](
void*, doocs::EqData* data, dmsg_info_t*) {
61 if(!data->error()) zmqStartup_gotData =
true;
65 std::cout <<
"ZeroMQ wait" << std::endl;
66 [[maybe_unused]]
auto location =
dynamic_cast<eq_dummy*
>(find_device(
"MYDUMMY"));
67 assert(location !=
nullptr);
68 while(!zmqStartup_gotData) {
70 DoocsServerTestHelper::runUpdate();
72 std::cout <<
"OK!" << std::endl;
73 dmsg_detach(&ea,
nullptr);
85static size_t mpn = 10000;
86static size_t seconds = 0;
87static size_t microseconds = 0;
93template<
typename DERIVED>
95 DERIVED*
derived{
static_cast<DERIVED*
>(
this)};
106 .disableForceDataLossWrite()
107 .disableAsyncReadInconsistency()
108 .disableSwitchReadOnly()
109 .disableSwitchWriteOnly();
122 microseconds += 100000;
123 if(microseconds > 1000000) {
124 microseconds -= 1000000;
127 derived->prop.set_tmstmp(seconds, microseconds);
134template<
typename DERIVED>
140 template<
typename UserType>
142 return {{ChimeraTK::numericToUserType<UserType>(
static_cast<typename DERIVED::minimumUserType
>(
143 derived->template getRemoteValue<typename DERIVED::minimumUserType>()[0][0] +
derived->increment))}};
146 template<
typename UserType>
148 std::lock_guard<EqFct> lk(*location);
149 auto v = ChimeraTK::numericToUserType<UserType>(
derived->prop.value());
154 auto v =
derived->template generateValue<typename DERIVED::minimumUserType>()[0][0];
155 std::lock_guard<EqFct> lk(*location);
163template<
typename DERIVED>
168 template<
typename UserType>
170 auto curval =
derived->template getRemoteValue<typename DERIVED::minimumUserType>()[0];
171 std::vector<UserType> val;
172 for(
size_t i = 0; i <
derived->nElementsPerChannel(); ++i) {
173 val.push_back(ChimeraTK::numericToUserType<UserType>(curval[i] + (i + 1) *
derived->increment));
178 template<
typename UserType>
180 std::vector<UserType> val;
181 std::lock_guard<EqFct> lk(*location);
182 for(
size_t i = 0; i <
derived->nElementsPerChannel(); ++i) {
183 val.push_back(ChimeraTK::numericToUserType<UserType>(
derived->prop.value(i)));
189 auto val =
derived->template generateValue<typename DERIVED::minimumUserType>()[0];
190 std::lock_guard<EqFct> lk(*location);
191 for(
size_t i = 0; i <
derived->nElementsPerChannel(); ++i) {
192 derived->prop.set_value(val[i], i);
201 std::string
path() {
return "MYDUMMY/SOME_INT"; }
210 prop.set_ro_access();
213 prop.set_rw_access();
222 std::string
path() {
return "MYDUMMY/SOME_RO_INT"; }
234 std::string
path() {
return "MYDUMMY/SOME_ZMQINT"; }
244 std::lock_guard<EqFct> lk(*location);
246 memset(&info, 0,
sizeof(info));
248 info.usec = microseconds;
263 std::string
path() {
return "MYDUMMY/SOME_FLOAT"; }
272 std::string
path() {
return "MYDUMMY/SOME_DOUBLE"; }
281 std::string
path() {
return "MYDUMMY/SOME_STRING"; }
285 template<
typename UserType>
290 template<
typename UserType>
292 std::vector<UserType> val;
293 std::lock_guard<EqFct> lk(*location);
294 val.push_back(
prop.value());
302std::vector<std::vector<std::string>> RegSomeString::generateValue<std::string>() {
304 return {{
"This is a string: " + std::to_string(someValue)}};
308 std::string
path() {
return "MYDUMMY/SOME_BIT"; }
313 template<
typename UserType>
315 return {{!this->getRemoteValue<minimumUserType>()[0][0]}};
322 std::string
path() {
return "MYDUMMY/SOME_INT_ARRAY"; }
332 std::string
path() {
return "MYDUMMY/SOME_SHORT_ARRAY"; }
342 std::string
path() {
return "MYDUMMY/SOME_LONG_ARRAY"; }
352 std::string
path() {
return "MYDUMMY/SOME_FLOAT_ARRAY"; }
362 std::string
path() {
return "MYDUMMY/SOME_DOUBLE_ARRAY"; }
372 std::string
path() {
return "MYDUMMY/SOME_SPECTRUM"; }
379 auto val = generateValue<minimumUserType>()[0];
380 std::lock_guard<EqFct> lk(*location);
381 prop.current_buffer(0);
383 prop.fill_spectrum(i, val[i]);
388 template<
typename UserType>
390 std::vector<UserType> val;
391 std::lock_guard<EqFct> lk(*location);
393 val.push_back(
prop.read_spectrum(i));
400 microseconds += 100000;
401 if(microseconds > 1000000) {
402 microseconds -= 100000;
405 derived->prop.set_tmstmp(seconds, microseconds, 0);
413 std::string
path() {
return "MYDUMMY/SOME_IIII"; }
420 auto val = generateValue<minimumUserType>()[0];
421 std::lock_guard<EqFct> lk(*location);
422 prop.set_value(val[0], val[1], val[2], val[3]);
426 template<
typename UserType>
428 std::lock_guard<EqFct> lk(*location);
429 auto val =
prop.value();
430 return {{ChimeraTK::numericToUserType<UserType>(val->i1_data), ChimeraTK::numericToUserType<UserType>(val->i2_data),
431 ChimeraTK::numericToUserType<UserType>(val->i3_data), ChimeraTK::numericToUserType<UserType>(val->i4_data)}};
438 std::string
path() {
return "MYDUMMY/SOME_IFFF/I"; }
444 auto v = generateValue<minimumUserType>()[0][0];
445 std::lock_guard<EqFct> lk(*location);
446 auto curval =
prop.value();
447 prop.set_value(v, curval->f1_data, curval->f2_data, curval->f3_data);
451 template<
typename UserType>
453 std::lock_guard<EqFct> lk(*location);
454 return {{ChimeraTK::numericToUserType<UserType>(
prop.value()->i1_data)}};
461 std::string
path() {
return "MYDUMMY/SOME_IFFF/F1"; }
467 auto v = generateValue<minimumUserType>()[0][0];
468 std::lock_guard<EqFct> lk(*location);
469 auto curval =
prop.value();
470 prop.set_value(curval->i1_data, v, curval->f2_data, curval->f3_data);
474 template<
typename UserType>
476 std::lock_guard<EqFct> lk(*location);
477 return {{ChimeraTK::numericToUserType<UserType>(
prop.value()->f1_data)}};
484 std::string
path() {
return "MYDUMMY/SOME_IFFF/F2"; }
490 auto v = generateValue<minimumUserType>()[0][0];
491 std::lock_guard<EqFct> lk(*location);
492 auto curval =
prop.value();
493 prop.set_value(curval->i1_data, curval->f1_data, v, curval->f3_data);
497 template<
typename UserType>
499 std::lock_guard<EqFct> lk(*location);
500 return {{ChimeraTK::numericToUserType<UserType>(
prop.value()->f2_data)}};
507 std::string
path() {
return "MYDUMMY/SOME_IFFF/F3"; }
513 auto v = generateValue<minimumUserType>()[0][0];
514 std::lock_guard<EqFct> lk(*location);
515 auto curval =
prop.value();
516 prop.set_value(curval->i1_data, curval->f1_data, curval->f2_data, v);
520 template<
typename UserType>
522 std::lock_guard<EqFct> lk(*location);
523 return {{ChimeraTK::numericToUserType<UserType>(
prop.value()->f3_data)}};
530 location =
dynamic_cast<eq_dummy*
>(find_device(
"MYDUMMY"));
531 assert(location !=
nullptr);
533 doocs::Timestamp timestamp = get_global_timestamp();
534 auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
535 seconds = sinceEpoch.seconds + 1;
537 doocs::zmq_set_subscription_timeout(10);
539 auto ubt = ChimeraTK::UnifiedBackendTest<>()
541 .addRegister<RegSomeRoInt>()
543 .addRegister<RegSomeFloat>()
545 .addRegister<RegSomeString>()
547 .addRegister<RegSomeIntArray>()
549 .addRegister<RegSomeLongArray>()
551 .addRegister<RegSomeDoubleArray>()
553 .addRegister<RegSomeIiii>()
555 .addRegister<RegSomeIfff_F1>()
557 .addRegister<RegSomeIfff_F3>();
static std::string DoocsServer
static std::string rpc_no
D_floatarray prop_someFloatArray
D_longarray prop_someLongArray
D_doublearray prop_someDoubleArray
D_spectrum prop_someSpectrum
D_shortarray prop_someShortArray
D_intarray prop_someIntArray
D_int prop_someReadonlyInt
static constexpr auto capabilities
void setForceRuntimeError(bool enable, size_t)
ChimeraTK::AccessModeFlags supportedFlags()
std::nullptr_t rawUserType
size_t nRuntimeErrorCases()
size_t writeQueueLength()
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > generateValue()
std::vector< std::vector< UserType > > generateValue()
ChimeraTK::Boolean minimumUserType
size_t nElementsPerChannel()
size_t nElementsPerChannel()
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > getRemoteValue()
size_t nElementsPerChannel()
size_t nElementsPerChannel()
void switchReadOnly(bool enable)
static constexpr auto capabilities
size_t nElementsPerChannel()
static constexpr auto capabilities
size_t nElementsPerChannel()
size_t nElementsPerChannel()
std::vector< std::vector< UserType > > getRemoteValue()
std::string minimumUserType
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > generateValue()
void forceAsyncReadInconsistency()
AccessModeFlags supportedFlags()
static constexpr auto capabilities
std::vector< std::vector< UserType > > getRemoteValue()
std::vector< std::vector< UserType > > generateValue()
size_t nElementsPerChannel()
BOOST_GLOBAL_FIXTURE(DoocsLauncher)
BOOST_AUTO_TEST_CASE(unifiedBackendTest)