14 #define BOOST_TEST_MODULE testUnifiedBackendTest
16 #include <doocs-server-test-helper/doocsServerTestHelper.h>
17 #include <doocs-server-test-helper/ThreadedDoocsServer.h>
18 #include <doocs/EqCall.h>
20 #include <ChimeraTK/Device.h>
21 #include <ChimeraTK/TransferGroup.h>
22 #include <ChimeraTK/UnifiedBackendTest.h>
24 #include <boost/filesystem.hpp>
25 #include <boost/test/included/unit_test.hpp>
29 using namespace boost::unit_test_framework;
34 static std::atomic<bool> zmqStartup_gotData{
false};
39 : ThreadedDoocsServer(
"testUnifiedBackendTest.conf", boost::unit_test::framework::master_test_suite().argc,
40 boost::unit_test::framework::master_test_suite().argv,
eq_dummy::createServer()) {
43 DoocsServer =
"doocs:doocs://localhost:" + rpcNo() +
"/F/D";
48 doocs::EqData src, dst;
49 ea.adr(
"doocs://localhost:" + rpcNo() +
"/F/D/MYDUMMY/SOME_ZMQINT");
50 while(eq.get(&ea, &src, &dst)) usleep(100000);
55 std::cout <<
"ZeroMQ Subscribe" << std::endl;
56 [[maybe_unused]]
int err = dmsg_attach(
58 [](
void*, doocs::EqData* data, dmsg_info_t*) {
59 if(!data->error()) zmqStartup_gotData =
true;
63 std::cout <<
"ZeroMQ wait" << std::endl;
64 [[maybe_unused]]
auto location =
dynamic_cast<eq_dummy*
>(find_device(
"MYDUMMY"));
65 assert(location !=
nullptr);
66 while(!zmqStartup_gotData) {
68 DoocsServerTestHelper::runUpdate();
70 std::cout <<
"OK!" << std::endl;
71 dmsg_detach(&ea,
nullptr);
74 static std::string rpc_no;
83 static size_t mpn = 10000;
84 static size_t seconds = 0;
85 static size_t microseconds = 0;
91 template<
typename DERIVED>
93 DERIVED* derived{
static_cast<DERIVED*
>(
this)};
103 static constexpr
auto capabilities = TestCapabilities<>()
104 .disableForceDataLossWrite()
105 .disableAsyncReadInconsistency()
106 .disableSwitchReadOnly()
107 .disableSwitchWriteOnly();
120 microseconds += 100000;
121 if(microseconds > 1000000) {
122 microseconds -= 1000000;
125 derived->prop.set_tmstmp(seconds, microseconds);
126 derived->prop.set_mpnum(mpn);
132 template<
typename DERIVED>
138 template<
typename UserType>
140 return {{ChimeraTK::numericToUserType<UserType>(
static_cast<typename DERIVED::minimumUserType
>(
141 derived->template getRemoteValue<typename DERIVED::minimumUserType>()[0][0] + derived->increment))}};
144 template<
typename UserType>
146 std::lock_guard<EqFct> lk(*location);
147 auto v = ChimeraTK::numericToUserType<UserType>(derived->prop.value());
152 auto v = derived->template generateValue<typename DERIVED::minimumUserType>()[0][0];
153 std::lock_guard<EqFct> lk(*location);
154 derived->prop.set_value(v);
161 template<
typename DERIVED>
166 template<
typename UserType>
168 auto curval = derived->template getRemoteValue<typename DERIVED::minimumUserType>()[0];
169 std::vector<UserType> val;
170 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
171 val.push_back(ChimeraTK::numericToUserType<UserType>(curval[i] + (i + 1) * derived->increment));
176 template<
typename UserType>
178 std::vector<UserType> val;
179 std::lock_guard<EqFct> lk(*location);
180 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
181 val.push_back(ChimeraTK::numericToUserType<UserType>(derived->prop.value(i)));
187 auto val = derived->template generateValue<typename DERIVED::minimumUserType>()[0];
188 std::lock_guard<EqFct> lk(*location);
189 for(
size_t i = 0; i < derived->nElementsPerChannel(); ++i) {
190 derived->prop.set_value(val[i], i);
199 std::string
path() {
return "MYDUMMY/SOME_INT"; }
202 int32_t increment{3};
208 prop.set_ro_access();
211 prop.set_rw_access();
220 std::string
path() {
return "MYDUMMY/SOME_RO_INT"; }
223 int32_t increment{7};
232 std::string
path() {
return "MYDUMMY/SOME_ZMQINT"; }
235 int32_t increment{51};
242 std::lock_guard<EqFct> lk(*location);
244 memset(&info, 0,
sizeof(info));
246 info.usec = microseconds;
261 std::string
path() {
return "MYDUMMY/SOME_FLOAT"; }
264 float increment{std::exp(1.F)};
270 std::string
path() {
return "MYDUMMY/SOME_DOUBLE"; }
273 double increment{std::exp(1.5)};
279 std::string
path() {
return "MYDUMMY/SOME_STRING"; }
283 template<
typename UserType>
288 template<
typename UserType>
290 std::vector<UserType> val;
291 std::lock_guard<EqFct> lk(*location);
292 val.push_back(prop.value());
296 size_t someValue{42};
300 std::vector<std::vector<std::string>> RegSomeString::generateValue<std::string>() {
302 return {{
"This is a string: " + std::to_string(someValue)}};
308 std::string
path() {
return "MYDUMMY/SOME_STATUS"; }
311 uint16_t increment{32000};
317 std::string
path() {
return "MYDUMMY/SOME_BIT"; }
320 uint8_t increment{0};
322 template<
typename UserType>
324 return {{!this->getRemoteValue<minimumUserType>()[0][0]}};
331 std::string
path() {
return "MYDUMMY/SOME_INT_ARRAY"; }
335 int32_t increment{11};
341 std::string
path() {
return "MYDUMMY/SOME_SHORT_ARRAY"; }
345 int16_t increment{17};
351 std::string
path() {
return "MYDUMMY/SOME_LONG_ARRAY"; }
355 int64_t increment{23};
361 std::string
path() {
return "MYDUMMY/SOME_FLOAT_ARRAY"; }
365 float increment{std::exp(5.F)};
371 std::string
path() {
return "MYDUMMY/SOME_DOUBLE_ARRAY"; }
375 double increment{std::exp(7.)};
381 std::string
path() {
return "MYDUMMY/SOME_SPECTRUM"; }
385 float increment{std::exp(11.F)};
388 auto val = generateValue<minimumUserType>()[0];
389 std::lock_guard<EqFct> lk(*location);
390 prop.current_buffer(0);
391 for(
size_t i = 0; i < nElementsPerChannel(); ++i) {
392 prop.fill_spectrum(i, val[i]);
397 template<
typename UserType>
399 std::vector<UserType> val;
400 std::lock_guard<EqFct> lk(*location);
401 for(
size_t i = 0; i < nElementsPerChannel(); ++i) {
402 val.push_back(prop.read_spectrum(i));
409 microseconds += 100000;
410 if(microseconds > 1000000) {
411 microseconds -= 100000;
414 derived->prop.set_tmstmp(seconds, microseconds, 0);
415 derived->prop.set_mpnum(mpn);
422 std::string
path() {
return "MYDUMMY/SOME_IIII"; }
426 int32_t increment{13};
429 auto val = generateValue<minimumUserType>()[0];
430 std::lock_guard<EqFct> lk(*location);
431 prop.set_value(val[0], val[1], val[2], val[3]);
435 template<
typename UserType>
437 std::lock_guard<EqFct> lk(*location);
438 auto val = prop.value();
439 return {{ChimeraTK::numericToUserType<UserType>(val->i1_data), ChimeraTK::numericToUserType<UserType>(val->i2_data),
440 ChimeraTK::numericToUserType<UserType>(val->i3_data), ChimeraTK::numericToUserType<UserType>(val->i4_data)}};
447 std::string
path() {
return "MYDUMMY/SOME_IFFF/I"; }
450 int32_t increment{23};
453 auto v = generateValue<minimumUserType>()[0][0];
454 std::lock_guard<EqFct> lk(*location);
455 auto curval = prop.value();
456 prop.set_value(v, curval->f1_data, curval->f2_data, curval->f3_data);
460 template<
typename UserType>
462 std::lock_guard<EqFct> lk(*location);
463 return {{ChimeraTK::numericToUserType<UserType>(prop.value()->i1_data)}};
470 std::string
path() {
return "MYDUMMY/SOME_IFFF/F1"; }
473 float increment{std::exp(3.14F)};
476 auto v = generateValue<minimumUserType>()[0][0];
477 std::lock_guard<EqFct> lk(*location);
478 auto curval = prop.value();
479 prop.set_value(curval->i1_data, v, curval->f2_data, curval->f3_data);
483 template<
typename UserType>
485 std::lock_guard<EqFct> lk(*location);
486 return {{ChimeraTK::numericToUserType<UserType>(prop.value()->f1_data)}};
493 std::string
path() {
return "MYDUMMY/SOME_IFFF/F2"; }
496 float increment{std::exp(1.23F)};
499 auto v = generateValue<minimumUserType>()[0][0];
500 std::lock_guard<EqFct> lk(*location);
501 auto curval = prop.value();
502 prop.set_value(curval->i1_data, curval->f1_data, v, curval->f3_data);
506 template<
typename UserType>
508 std::lock_guard<EqFct> lk(*location);
509 return {{ChimeraTK::numericToUserType<UserType>(prop.value()->f2_data)}};
516 std::string
path() {
return "MYDUMMY/SOME_IFFF/F3"; }
519 float increment{std::exp(2.34F)};
522 auto v = generateValue<minimumUserType>()[0][0];
523 std::lock_guard<EqFct> lk(*location);
524 auto curval = prop.value();
525 prop.set_value(curval->i1_data, curval->f1_data, curval->f2_data, v);
529 template<
typename UserType>
531 std::lock_guard<EqFct> lk(*location);
532 return {{ChimeraTK::numericToUserType<UserType>(prop.value()->f3_data)}};
539 location =
dynamic_cast<eq_dummy*
>(find_device(
"MYDUMMY"));
540 assert(location !=
nullptr);
542 doocs::Timestamp timestamp = get_global_timestamp();
543 auto sinceEpoch = timestamp.get_seconds_and_microseconds_since_epoch();
544 seconds = sinceEpoch.seconds + 1;
546 doocs::zmq_set_subscription_timeout(10);
548 auto ubt = ChimeraTK::UnifiedBackendTest<>()
550 .addRegister<RegSomeRoInt>()
552 .addRegister<RegSomeFloat>()
554 .addRegister<RegSomeString>()
556 .addRegister<RegSomeBit>()
558 .addRegister<RegSomeShortArray>()
560 .addRegister<RegSomeFloatArray>()
562 .addRegister<RegSomeSpectrum>()
564 .addRegister<RegSomeIfff_I>()
566 .addRegister<RegSomeIfff_F2>()