Files
slsDetectorPackage/slsDetectorSoftware/tests/Caller/test-Caller-rx.cpp
T
maliakal_d 8529c8b232
Build and Deploy on local RHEL9 / build (push) Successful in 2m3s
Build on RHEL8 docker image / build (push) Successful in 5m10s
Build on RHEL9 docker image / build (push) Successful in 5m15s
Build and Deploy on local RHEL8 / build (push) Successful in 5m0s
Run Simulator Tests on local RHEL9 / build (push) Successful in 20m8s
Run Simulator Tests on local RHEL8 / build (push) Successful in 23m29s
Dev/test rx roi refactor 2 (#1532)
* missed the call, typo

* wip, phase2 refactor

* compiles

* fixed tests
2026-08-19 14:38:29 +02:00

1384 lines
45 KiB
C++

// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "Caller.h"
#include "sls/Detector.h"
#include "sls/Version.h"
#include "sls/versionAPI.h"
#include "test-Caller-global.h"
#include "tests/globals.h"
#include "acquire/Acquire.h"
#include "acquire/FileState.h"
#include "catch.hpp"
namespace sls {
namespace acq = sls::test::acquire;
using test::GET;
using test::PUT;
/*
This file should contain receiver specific tests use
python/scripts/list_tested_cmd.py to check if all commands are covered
*/
/* configuration */
TEST_CASE("rx_version", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
std::ostringstream oss;
caller.call("rx_version", {}, -1, GET, oss);
sls::Version v(APIRECEIVER);
std::ostringstream vs;
vs << "rx_version " << v.concise() << '\n';
REQUIRE(oss.str() == vs.str());
REQUIRE_THROWS(caller.call("rx_version", {"0"}, -1, PUT));
}
/* acquisition */
TEST_CASE("rx_start", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
det.setFileWrite(false); // avoid writing or error on file creation
// PUT only command
REQUIRE_THROWS(caller.call("rx_start", {}, -1, GET));
{
std::ostringstream oss;
caller.call("rx_start", {}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_start successful\n");
}
{
std::ostringstream oss;
caller.call("rx_status", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_status running\n");
}
}
TEST_CASE("rx_stop", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
// PUT only command
REQUIRE_THROWS(caller.call("rx_stop", {}, -1, GET));
{
std::ostringstream oss;
caller.call("rx_stop", {}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_stop successful\n");
}
{
std::ostringstream oss;
caller.call("rx_status", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_status idle\n");
}
}
TEST_CASE("rx_status", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
det.setFileWrite(false); // avoid writing or error on file creation
det.startReceiver();
{
std::ostringstream oss;
caller.call("rx_status", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_status running\n");
}
det.stopReceiver();
{
std::ostringstream oss;
caller.call("rx_status", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_status idle\n");
}
}
TEST_CASE("rx_framescaught", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
// This ensures 0 caught frames
auto prev_val = det.getFileWrite();
det.setFileWrite(false); // avoid writing or error on file creation
det.startReceiver();
det.stopReceiver();
{
std::ostringstream oss;
caller.call("rx_framescaught", {}, -1, GET, oss);
if (det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces") == 1) {
REQUIRE(oss.str() == "rx_framescaught [0]\n");
} else {
REQUIRE(oss.str() == "rx_framescaught [0, 0]\n");
}
}
// Currently disabled may activate if we have a stable env
// Now take one frame and see that we caught it
// det.setNumberOfFrames(1);
// det.acquire();
// {
// std::ostringstream oss;
// caller.call("rx_framescaught", {}, -1, GET, oss);
// REQUIRE(oss.str() == "rx_framescaught 1\n");
// }
for (int i = 0; i != det.size(); ++i) {
det.setFileWrite(prev_val[i], {i});
}
}
TEST_CASE("rx_missingpackets",
"[.detectorintegration][.disable_check_data_file]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFileWrite();
det.setFileWrite(false); // avoid writing or error on file creation
auto prev_frames =
det.getNumberOfFrames().tsquash("inconsistent #frames in test");
det.setNumberOfFrames(100);
{
// some missing packets
det.startReceiver();
det.stopReceiver();
std::ostringstream oss;
caller.call("rx_missingpackets", {}, -1, GET, oss);
if (det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces") == 1) {
REQUIRE(oss.str() != "rx_missingpackets [0]\n");
} else {
REQUIRE(oss.str() != "rx_missingpackets [0, 0]\n");
}
}
auto det_type = det.getDetectorType().squash();
if (det_type != defs::CHIPTESTBOARD &&
det_type != defs::XILINX_CHIPTESTBOARD) {
// 0 missing packets (takes into account that acquisition is
// stopped)
det.startReceiver();
det.startDetector();
det.stopDetector();
det.stopReceiver();
std::ostringstream oss;
caller.call("rx_missingpackets", {}, -1, GET, oss);
if (det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces") == 1) {
REQUIRE(oss.str() == "rx_missingpackets [0]\n");
} else {
REQUIRE(oss.str() == "rx_missingpackets [0, 0]\n");
}
}
for (int i = 0; i != det.size(); ++i) {
det.setFileWrite(prev_val[i], {i});
}
det.setNumberOfFrames(prev_frames);
}
TEST_CASE("rx_frameindex", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
caller.call("rx_frameindex", {}, -1, GET);
// This is a get only command
REQUIRE_THROWS(caller.call("rx_frameindex", {"2"}, -1, PUT));
}
/* Network Configuration (Detector<->Receiver) */
TEST_CASE("rx_printconfig", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
REQUIRE_NOTHROW(caller.call("rx_printconfig", {}, -1, GET));
}
/* Receiver Config */
TEST_CASE("rx_hostname", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxHostname();
// Cannot set rx_hostname (will reset parameters in rxr and no shm
// variables to update)
// {
// // disable receiver
// std::ostringstream oss;
// caller.call("rx_hostname", {"none"}, -1, PUT, oss);
// REQUIRE(oss.str() == "rx_hostname [none]\n");
// }
// {
// std::ostringstream oss;
// caller.call("rx_hostname", {}, -1, GET, oss);
// REQUIRE(oss.str() == "rx_hostname none\n");
// // receiver should be disabled
// REQUIRE(det.getUseReceiverFlag().tsquash(
// "different values of flag in test") == false);
// }
// put back old values (not necessary when we dont set it to none)
// for (int i = 0; i != det.size(); ++i) {
// det.setRxHostname(prev_val[i], {i});
// }
{
std::ostringstream oss;
caller.call("rx_hostname", {}, 0, GET, oss);
REQUIRE(oss.str() == "rx_hostname " + prev_val[0] + "\n");
}
}
TEST_CASE("rx_tcpport", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxPort();
uint16_t port = 3500;
caller.call("rx_tcpport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
caller.call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
}
port = 5754;
caller.call("rx_tcpport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
caller.call("rx_tcpport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_tcpport " + std::to_string(port + i) + '\n');
}
test_valid_port_caller("rx_tcpport", {}, -1, PUT);
test_valid_port_caller("rx_tcpport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
REQUIRE_THROWS(caller.call("rx_tcpport", {"65535"}, -1, PUT));
auto rxHostname = det.getRxHostname().squash("none");
if (rxHostname != "none") {
std::ostringstream oss;
for (int i = 0; i != det.size(); ++i) {
oss << rxHostname << ":" << 65536 + i << "+";
}
REQUIRE_THROWS(caller.call("rx_hostname", {oss.str()}, -1, PUT));
}
}
for (int i = 0; i != det.size(); ++i) {
det.setRxPort(prev_val[i], i);
}
}
TEST_CASE("rx_fifodepth", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxFifoDepth();
{
std::ostringstream oss;
caller.call("rx_fifodepth", {"10"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_fifodepth 10\n");
}
{
std::ostringstream oss;
caller.call("rx_fifodepth", {"100"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_fifodepth 100\n");
}
{
std::ostringstream oss;
caller.call("rx_fifodepth", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_fifodepth 100\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxFifoDepth(prev_val[i], {i});
}
}
TEST_CASE("rx_silent", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxSilentMode();
{
std::ostringstream oss;
caller.call("rx_silent", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_silent 1\n");
}
{
std::ostringstream oss;
caller.call("rx_silent", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_silent 1\n");
}
{
std::ostringstream oss;
caller.call("rx_silent", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_silent 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxSilentMode(prev_val[i], {i});
}
}
TEST_CASE("rx_discardpolicy", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxFrameDiscardPolicy();
{
std::ostringstream oss;
caller.call("rx_discardpolicy", {"discardempty"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_discardpolicy discardempty\n");
}
{
std::ostringstream oss;
caller.call("rx_discardpolicy", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_discardpolicy discardempty\n");
}
{
std::ostringstream oss;
caller.call("rx_discardpolicy", {"discardpartial"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_discardpolicy discardpartial\n");
}
{
std::ostringstream oss;
caller.call("rx_discardpolicy", {"nodiscard"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_discardpolicy nodiscard\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxFrameDiscardPolicy(prev_val[i], {i});
}
}
TEST_CASE("rx_padding", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getPartialFramesPadding();
{
std::ostringstream oss;
caller.call("rx_padding", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_padding 0\n");
}
{
std::ostringstream oss;
caller.call("rx_padding", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_padding 0\n");
}
{
std::ostringstream oss;
caller.call("rx_padding", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_padding 1\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setPartialFramesPadding(prev_val[i], {i});
}
}
TEST_CASE("rx_udpsocksize", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
int64_t prev_val = det.getRxUDPSocketBufferSize().tsquash(
"Need same udp socket buffer size to test");
std::string s_new_val = std::to_string(prev_val);
/*std::string s_new_val = std::to_string(prev_val - 1000);
{ Need permissions
std::ostringstream oss;
caller.call("rx_udpsocksize", {s_new_val}, -1, PUT, oss);
REQUIRE(oss.str() >= "rx_udpsocksize " + s_new_val + "\n");
}*/
{
std::ostringstream oss;
caller.call("rx_udpsocksize", {}, -1, GET, oss);
REQUIRE(oss.str() >= "rx_udpsocksize " + s_new_val + "\n");
}
det.setRxUDPSocketBufferSize(prev_val);
}
TEST_CASE("rx_realudpsocksize", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
uint64_t val = 0;
{
std::ostringstream oss;
caller.call("rx_udpsocksize", {}, -1, GET, oss);
std::string s = (oss.str()).erase(0, strlen("rx_udpsocksize "));
val = std::stol(s);
}
{
std::ostringstream oss;
caller.call("rx_realudpsocksize", {}, -1, GET, oss);
std::string s = (oss.str()).erase(0, strlen("rx_realudpsocksize "));
uint64_t rval = std::stol(s);
REQUIRE(rval >= val * 2);
}
}
TEST_CASE("rx_lock", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxLock();
{
std::ostringstream oss;
caller.call("rx_lock", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_lock 1\n");
}
{
std::ostringstream oss;
caller.call("rx_lock", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_lock 1\n");
}
{
std::ostringstream oss;
caller.call("rx_lock", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_lock 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxLock(prev_val[i], {i});
}
}
TEST_CASE("rx_lastclient", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_lastclient", {}, -1, GET, oss));
if (test::my_ip != "undefined") {
REQUIRE(oss.str() == "rx_lastclient " + test::my_ip + "\n");
}
}
TEST_CASE("rx_threads", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_threads", {}, -1, GET, oss));
}
TEST_CASE("rx_arping", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxArping();
if (det.getDestinationUDPIP()[0].str() != "127.0.0.1") {
{
std::ostringstream oss;
caller.call("rx_arping", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_arping 1\n");
}
{
std::ostringstream oss;
caller.call("rx_arping", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_arping 1\n");
}
{
std::ostringstream oss;
caller.call("rx_arping", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_arping 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxArping(prev_val[i], {i});
}
}
}
void test_rx_roi_2d_multi_horizontal_ports(Detector &det, Caller &caller) {
auto det_type = det.getDetectorType().squash();
auto portSize = det.getPortSize()[0];
int delta = 50;
auto two_ports = (det_type == defs::EIGER);
// setting roi at boundary of 2nd port
{
std::string min = std::to_string(portSize.x);
std::string max = std::to_string(portSize.x + 1);
std::string arg_port1 = "[5, 10, 20, 30]";
std::string arg_port2 = "[" + min + ", " + max + ", 20, 30]";
std::string res = "rx_roi [" + arg_port1 + ", " + arg_port2 + "]\n";
// separated by space is allowed
REQUIRE_NOTHROW(caller.call("rx_roi", {arg_port1, arg_port2}, -1, PUT));
// separated by semicolon with quotes is allowed (skips cmdParser)
std::ostringstream oss;
REQUIRE_NOTHROW(
caller.call("rx_roi", {arg_port1 + ";" + arg_port2}, -1, PUT, oss));
REQUIRE(oss.str() == res);
}
// setting to only one port and verify individual roi
{
std::string arg = "[5, 10, 20, 30]";
std::string no_roi = "[0, 0, 0, 0]";
std::string res_mod0 = "rx_roi [" + arg + "]\n";
std::string res_mod1 = "rx_roi [" + no_roi + "]\n";
if (two_ports) {
res_mod0 = "rx_roi [" + arg + ", " + no_roi + "]\n";
res_mod1 = "rx_roi [" + no_roi + ", " + no_roi + "]\n";
}
REQUIRE_NOTHROW(caller.call("rx_roi", {arg}, -1, PUT));
// single or first module
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss));
REQUIRE(oss.str() == res_mod0);
// second module
if (det.size() > 1) {
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 1, GET, oss));
REQUIRE(oss.str() == res_mod1);
}
}
// setting multiple port roi and verify individual roi
{
std::string min = std::to_string(portSize.x - delta);
std::string max = std::to_string(portSize.x + delta);
std::string arg = "[" + min + ", " + max + ", 20, 30]";
// for each port
std::string max_port1 = std::to_string(portSize.x - 1);
std::string arg_port1 = "[" + min + ", " + max_port1 + ", 20, 30]";
std::string max_port2 = std::to_string(delta);
std::string arg_port2 = "[0, " + max_port2 + ", 20, 30]";
std::string res_all = "rx_roi [" + arg + "]\n";
std::string res_mod0 = "rx_roi [" + arg_port1 + "]\n";
if (two_ports) {
res_mod0 = "rx_roi [" + arg_port1 + ", " + arg_port2 + "]\n";
}
REQUIRE_NOTHROW(caller.call("rx_roi", {arg}, -1, PUT));
// verify multi roi
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, -1, GET, oss));
REQUIRE(oss.str() == res_all);
// verify 1st module
std::ostringstream oss1;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss1));
REQUIRE(oss1.str() == res_mod0);
}
}
void test_rx_roi_2d_multi_vertical_ports(Detector &det, Caller &caller) {
auto det_type = det.getDetectorType().squash();
auto portSize = det.getPortSize()[0];
int delta = 50;
int numinterfaces = det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces");
auto two_ports =
((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) &&
(numinterfaces == 2)) ||
(det_type == defs::EIGER);
// setting roi at boundary of 2nd port
{
std::string min = std::to_string(portSize.y);
std::string max = std::to_string(portSize.y + 1);
std::string arg_port1 = "[5, 10, 20, 30]";
std::string arg_port2 = "[25, 28, " + min + ", " + max + "]";
std::string res = "rx_roi [" + arg_port1 + ", " + arg_port2 + "]\n";
// separated by space is allowed
REQUIRE_NOTHROW(caller.call("rx_roi", {arg_port1, arg_port2}, -1, PUT));
// separated by semicolon is allowed with quotes (skips cmdParser)
std::ostringstream oss;
REQUIRE_NOTHROW(
caller.call("rx_roi", {arg_port1 + ";" + arg_port2}, -1, PUT, oss));
REQUIRE(oss.str() == res);
}
// setting to only one port roi and verify individual roi
{
std::string arg = "[5, 10, 20, 30]";
std::string no_roi = "[0, 0, 0, 0]";
std::string res_mod0 = "rx_roi [" + arg + "]\n";
std::string res_mod1 = "rx_roi [" + no_roi + "]\n";
if (two_ports) {
res_mod0 = "rx_roi [" + arg + ", " + no_roi + "]\n";
res_mod1 = "rx_roi [" + no_roi + ", " + no_roi + "]\n";
}
REQUIRE_NOTHROW(caller.call("rx_roi", {arg}, -1, PUT));
// single or first module
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss));
REQUIRE(oss.str() == res_mod0);
// second module
if (det.size() > 1) {
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 1, GET, oss));
REQUIRE(oss.str() == res_mod1);
}
}
// setting multiple ports and verify individual roi
{
std::string min = std::to_string(portSize.y - delta);
std::string max = std::to_string(portSize.y + delta);
std::string arg = "[20, 30, " + min + ", " + max + "]";
// for each port
std::string max_port1 = std::to_string(portSize.y - 1);
std::string arg_port1 = "[20, 30, " + min + ", " + max_port1 + "]";
std::string max_port2 = std::to_string(delta);
std::string arg_port2 = "[20, 30, 0, " + max_port2 + "]";
std::string res_all = "rx_roi [" + arg + "]\n";
std::string res_mod0 = "rx_roi [" + arg_port1 + "]\n";
if (two_ports) {
res_mod0 = "rx_roi [" + arg_port1 + ", " + arg_port2 + "]\n";
}
REQUIRE_NOTHROW(caller.call("rx_roi", {arg}, -1, PUT));
// verify multi roi
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, -1, GET, oss));
REQUIRE(oss.str() == res_all);
// verify both ports of 1st module
std::ostringstream oss1;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss1));
REQUIRE(oss1.str() == res_mod0);
}
}
void test_rx_roi_1d(Detector &det, Caller &caller) {
defs::xy detsize = det.getDetectorSize();
int delta = 50;
{
std::ostringstream oss;
caller.call("rx_roi", {"5", "10"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [[5, 10]]\n");
}
{
std::ostringstream oss;
caller.call("rx_roi", {"10", "15"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [[10, 15]]\n");
}
REQUIRE_THROWS(caller.call("rx_roi", {"0", "0"}, -1, PUT));
REQUIRE_THROWS(caller.call("rx_roi", {"-1", "-1"}, -1, PUT));
// xmin > xmax
REQUIRE_THROWS(caller.call("rx_roi", {"[12, 8, -1, -1]"}, -1, PUT));
// outside detector bounds
REQUIRE_THROWS(caller.call(
"rx_roi", {"[95," + std::to_string(detsize.x + 5) + ", -1, -1]"}, -1,
PUT));
// module level not allowed
REQUIRE_THROWS(caller.call("rx_roi", {"[5, 10, -1, -1]"}, 0, PUT));
// vector of rois
// square brackets missing
REQUIRE_THROWS(
caller.call("rx_roi", {"[5, 20, -1, -1]; 25, 30, -1, -1]"}, -1, PUT));
REQUIRE_THROWS(
caller.call("rx_roi", {"[5, 20, -1, -1]; [25, 30, -1, -1"}, -1, PUT));
// invalid roi, 4 parts expected
REQUIRE_THROWS(
caller.call("rx_roi", {"[5, 20, -1] [25, 30, -1, -1]"}, -1, PUT));
// overlapping rois
REQUIRE_THROWS(
caller.call("rx_roi", {"[0, 10,-1, -1] [5, 15, -1, -1]"}, -1, PUT));
auto moduleSize = det.getModuleSize()[0];
// setting roi at boundary of 2nd module
if (det.size() == 2) {
std::string min = std::to_string(moduleSize.x);
std::string max = std::to_string(moduleSize.x + 1);
std::string arg_mod1 = "[5, 10]";
std::string arg_mod2 = "[" + min + ", " + max + "]";
std::string res = "rx_roi [" + arg_mod1 + ", " + arg_mod2 + "]\n";
// separated by space is allowed
REQUIRE_NOTHROW(caller.call("rx_roi", {arg_mod1, arg_mod2}, -1, PUT));
std::ostringstream oss;
// separated by semicolon with quotes is allowed (skips cmdParser)
REQUIRE_NOTHROW(
caller.call("rx_roi", {arg_mod1 + ";" + arg_mod2}, -1, PUT, oss));
REQUIRE(oss.str() == res);
}
// setting to only one module and verify individual roi
{
std::string arg = "[5, 10]";
std::string no_roi = "[0, 0]";
std::string res_mod0 = "rx_roi [" + arg + "]\n";
std::string res_mod1 = "rx_roi [" + no_roi + "]\n";
REQUIRE_NOTHROW(caller.call("rx_roi", {arg}, -1, PUT));
// first module
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss));
REQUIRE(oss.str() == res_mod0);
// second module
if (det.size() > 1) {
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 1, GET, oss));
REQUIRE(oss.str() == res_mod1);
}
}
// setting multiple module roi and verify individual roi
if (det.size() == 2) {
std::string min = std::to_string(moduleSize.x - delta);
std::string max = std::to_string(moduleSize.x + delta);
std::string arg = "[" + min + ", " + max + "]";
// for each module
std::string max_mod0 = std::to_string(moduleSize.x - 1);
std::string arg_mod0 = "[" + min + ", " + max_mod0 + "]";
std::string max_mod1 = std::to_string(delta);
std::string arg_mod1 = "[0, " + max_mod1 + "]";
std::string res_all = "rx_roi [" + arg + "]\n";
std::string res_mod0 = "rx_roi [" + arg_mod0 + "]\n";
std::string res_mod1 = "rx_roi [" + arg_mod1 + "]\n";
REQUIRE_NOTHROW(caller.call("rx_roi", {arg}, -1, PUT));
// verify multi roi
std::ostringstream oss;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, -1, GET, oss));
REQUIRE(oss.str() == res_all);
// verify 1st module
std::ostringstream oss1;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 0, GET, oss1));
REQUIRE(oss1.str() == res_mod0);
// verify 1st module
std::ostringstream oss2;
REQUIRE_NOTHROW(caller.call("rx_roi", {}, 1, GET, oss2));
REQUIRE(oss2.str() == res_mod1);
}
}
void test_rx_roi_2d(Detector &det, Caller &caller) {
auto det_type = det.getDetectorType().squash();
defs::xy detsize = det.getDetectorSize();
int numinterfaces = det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces");
std::string maxx = std::to_string(detsize.x - 5);
std::string maxy = std::to_string(detsize.y - 5);
{
std::ostringstream oss;
caller.call("rx_roi", {"10", "15", "1", "5"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [[10, 15, 1, 5]]\n");
}
{
std::ostringstream oss;
caller.call("rx_roi", {"10", "22", "18", "19"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_roi [[10, 22, 18, 19]]\n");
}
{
std::ostringstream oss;
caller.call("rx_roi", {"1", maxx, "1", maxy}, -1, PUT, oss);
auto res = "rx_roi [[1, " + maxx + ", 1, " + maxy + "]]\n";
REQUIRE(oss.str() == res);
}
REQUIRE_THROWS(caller.call("rx_roi", {"0", "0", "0", "0"}, -1, PUT));
REQUIRE_THROWS(caller.call("rx_roi", {"-1", "-1", "-1", "-1"}, -1, PUT));
// xmin > xmax
REQUIRE_THROWS(caller.call("rx_roi", {"[12, 8, 0, 10]"}, -1, PUT));
// ymin > ymax
REQUIRE_THROWS(caller.call("rx_roi", {"[0, 10, 20, 5]"}, -1, PUT));
// outside detector bounds
REQUIRE_THROWS(caller.call(
"rx_roi", {"[95," + std::to_string(detsize.x + 5) + ", 0, 10]"}, -1,
PUT));
REQUIRE_THROWS(caller.call(
"rx_roi", {"[95, 100, 0, " + std::to_string(detsize.y + 5) + "]"}, -1,
PUT));
// module level not allowed
REQUIRE_THROWS(caller.call("rx_roi", {"[5, 10, 20, 30]"}, 0, PUT));
// vector of rois
// square brackets missing
REQUIRE_THROWS(
caller.call("rx_roi", {"[5, 20, 20, 30]; 25, 30, 14, 15]"}, -1, PUT));
REQUIRE_THROWS(
caller.call("rx_roi", {"[5, 20, 20, 30]; [25, 30, 14, 15"}, -1, PUT));
// invalid roi, 4 parts expected
REQUIRE_THROWS(
caller.call("rx_roi", {"[5, 20, 20] [25, 30, 14, 15]"}, -1, PUT));
// overlapping rois
REQUIRE_THROWS(
caller.call("rx_roi", {"[0, 10, 0, 10] [5, 15, 0, 10]"}, -1, PUT));
REQUIRE_THROWS(
caller.call("rx_roi", {"[0, 10, 0, 10] [0, 10, 9, 11]"}, -1, PUT));
bool multiple_ports_horizontally =
(det_type == defs::EIGER ||
(det.size() > 1 && det.getModuleGeometry().x > 1));
bool multiple_ports_vertically =
(((det_type == defs::JUNGFRAU || det_type == defs::MOENCH) &&
(numinterfaces == 2)) ||
(det.size() > 1 && det.getModuleGeometry().y > 1));
if (multiple_ports_horizontally) {
test_rx_roi_2d_multi_horizontal_ports(det, caller);
} else if (multiple_ports_vertically) {
test_rx_roi_2d_multi_vertical_ports(det, caller);
} else {
// valid roi before acquiring
REQUIRE_NOTHROW(caller.call("rx_roi", {"1", maxx, "1", maxy}, -1, PUT));
}
}
TEST_CASE("rx_roi", "[.detectorintegration][.disable_check_data_file]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(caller.call("rx_roi", {"5", "10"}, -1, PUT));
} else {
auto prev_val = det.getRxROI();
bool oneD = (det_type == defs::GOTTHARD2 || det_type == defs::MYTHEN3);
// 2d = Jungfrau, moench, eiger
if (oneD)
test_rx_roi_1d(det, caller);
else
test_rx_roi_2d(det, caller);
// check master file creation
// TODO: check roi in master file
{
int numinterfaces = det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of interfaces");
auto acq_state = acq::default_acquisition_state();
auto file_state = acq::default_file_state();
file_state.file_format = defs::BINARY;
acq::run(det, acq_state, file_state);
std::string fname = acq::get_master_file_name(file_state);
REQUIRE(std::filesystem::exists(fname));
#ifdef HDF5C
file_state.file_format = defs::HDF5;
acq::run(det, acq_state, file_state);
fname = acq::get_master_file_name(file_state);
REQUIRE(std::filesystem::exists(fname));
if (det.size() > 1 || numinterfaces > 1) {
fname = acq::get_virtual_file_name(file_state);
REQUIRE(std::filesystem::exists(fname));
}
#endif
}
for (int i = 0; i != det.size(); ++i) {
if (prev_val.size() == 1 && prev_val[0].completeRoi()) {
det.clearRxROI();
} else
det.setRxROI(prev_val);
}
}
}
TEST_CASE("rx_clearroi", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
REQUIRE_THROWS(caller.call("rx_clearroi", {}, -1, PUT));
} else {
auto prev_val = det.getRxROI();
{
std::ostringstream oss;
caller.call("rx_clearroi", {}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_clearroi successful\n");
}
for (int i = 0; i != det.size(); ++i) {
if (prev_val.size() == 1 && prev_val[0].completeRoi()) {
det.clearRxROI();
} else {
det.setRxROI(prev_val);
}
}
}
}
/* File */
TEST_CASE("fformat", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFileFormat();
{
std::ostringstream oss;
caller.call("fformat", {"binary"}, -1, PUT, oss);
REQUIRE(oss.str() == "fformat binary\n");
}
{
std::ostringstream oss;
caller.call("fformat", {}, -1, GET, oss);
REQUIRE(oss.str() == "fformat binary\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setFileFormat(prev_val[i], {i});
}
}
TEST_CASE("fpath", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFilePath();
{
std::ostringstream oss;
caller.call("fpath", {"/tmp"}, -1, PUT, oss);
REQUIRE(oss.str() == "fpath /tmp\n");
}
{
std::ostringstream oss;
caller.call("fpath", {}, -1, GET, oss);
REQUIRE(oss.str() == "fpath /tmp\n");
}
for (int i = 0; i != det.size(); ++i) {
if (prev_val[i].empty()) {
continue;
}
det.setFilePath(prev_val[i], {i});
}
}
TEST_CASE("fname", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFileNamePrefix();
{
std::ostringstream oss;
caller.call("fname", {"somename"}, -1, PUT, oss);
REQUIRE(oss.str() == "fname somename\n");
}
{
std::ostringstream oss;
caller.call("fname", {}, -1, GET, oss);
REQUIRE(oss.str() == "fname somename\n");
}
{
std::ostringstream oss;
caller.call("fname", {"run"}, -1, PUT, oss);
REQUIRE(oss.str() == "fname run\n");
}
REQUIRE_THROWS(caller.call("fname", {"fdf/dfd"}, -1, PUT));
REQUIRE_THROWS(caller.call("fname", {"fdf dfd"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setFileNamePrefix(prev_val[i], {i});
}
}
TEST_CASE("findex", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getAcquisitionIndex();
{
std::ostringstream oss;
caller.call("findex", {"57"}, -1, PUT, oss);
REQUIRE(oss.str() == "findex 57\n");
}
{
std::ostringstream oss;
caller.call("findex", {}, -1, GET, oss);
REQUIRE(oss.str() == "findex 57\n");
}
{
std::ostringstream oss;
caller.call("findex", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "findex 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setAcquisitionIndex(prev_val[i], {i});
}
}
TEST_CASE("fwrite", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFileWrite();
{
std::ostringstream oss;
caller.call("fwrite", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "fwrite 1\n");
}
{
std::ostringstream oss;
caller.call("fwrite", {}, -1, GET, oss);
REQUIRE(oss.str() == "fwrite 1\n");
}
{
std::ostringstream oss;
caller.call("fwrite", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "fwrite 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setFileWrite(prev_val[i], {i});
}
}
TEST_CASE("fmaster", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getMasterFileWrite();
{
std::ostringstream oss;
caller.call("fmaster", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "fmaster 0\n");
}
{
std::ostringstream oss;
caller.call("fmaster", {}, -1, GET, oss);
REQUIRE(oss.str() == "fmaster 0\n");
}
{
std::ostringstream oss;
caller.call("fmaster", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "fmaster 1\n");
}
det.setMasterFileWrite(prev_val);
}
TEST_CASE("foverwrite", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFileOverWrite();
{
std::ostringstream oss;
caller.call("foverwrite", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "foverwrite 1\n");
}
{
std::ostringstream oss;
caller.call("foverwrite", {}, -1, GET, oss);
REQUIRE(oss.str() == "foverwrite 1\n");
}
{
std::ostringstream oss;
caller.call("foverwrite", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "foverwrite 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setFileOverWrite(prev_val[i], {i});
}
}
TEST_CASE("rx_framesperfile", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getFramesPerFile();
{
std::ostringstream oss;
caller.call("rx_framesperfile", {"50"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_framesperfile 50\n");
}
{
std::ostringstream oss;
caller.call("rx_framesperfile", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_framesperfile 50\n");
}
{
std::ostringstream oss;
caller.call("rx_framesperfile", {"10000"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_framesperfile 10000\n");
}
{
std::ostringstream oss;
caller.call("rx_framesperfile", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_framesperfile 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setFramesPerFile(prev_val[i], {i});
}
}
/* ZMQ Streaming Parameters (Receiver<->Client) */
TEST_CASE("rx_zmqstream", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxZmqDataStream();
{
std::ostringstream oss;
caller.call("rx_zmqstream", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqstream 1\n");
REQUIRE(det.getRxZmqDataStream().squash() == true);
}
{
std::ostringstream oss;
caller.call("rx_zmqstream", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_zmqstream 1\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqstream", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqstream 0\n");
REQUIRE(det.getRxZmqDataStream().squash() == false);
}
for (int i = 0; i != det.size(); ++i) {
det.setRxZmqDataStream(prev_val[i], {i});
}
}
TEST_CASE("rx_zmqfreq", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxZmqFrequency();
{
std::ostringstream oss;
caller.call("rx_zmqfreq", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqfreq 1\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqfreq", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_zmqfreq 1\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqfreq", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqfreq 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxZmqFrequency(prev_val[i], {i});
}
}
TEST_CASE("rx_zmqstartfnum", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getRxZmqStartingFrame();
{
std::ostringstream oss;
caller.call("rx_zmqstartfnum", {"5"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqstartfnum 5\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqstartfnum", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_zmqstartfnum 5\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqstartfnum", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqstartfnum 0\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxZmqStartingFrame(prev_val[i], {i});
}
}
TEST_CASE("rx_zmqport", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val_zmqport = det.getRxZmqPort();
auto prev_val_numinterfaces = det.getNumberofUDPInterfaces().tsquash(
"inconsistent number of udp interfaces to test");
int socketsperdetector = 1;
auto det_type = det.getDetectorType().squash();
if (det_type == defs::EIGER) {
socketsperdetector *= 2;
} else if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH) {
caller.call("numinterfaces", {"2"}, -1, PUT);
socketsperdetector *= 2;
}
uint16_t port = 3500;
caller.call("rx_zmqport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
caller.call("rx_zmqport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_zmqport " +
std::to_string(port + i * socketsperdetector) +
'\n');
}
port = 30001;
caller.call("rx_zmqport", {std::to_string(port)}, -1, PUT);
for (int i = 0; i != det.size(); ++i) {
std::ostringstream oss;
caller.call("rx_zmqport", {}, i, GET, oss);
REQUIRE(oss.str() == "rx_zmqport " +
std::to_string(port + i * socketsperdetector) +
'\n');
}
test_valid_port_caller("rx_zmqport", {}, -1, PUT);
test_valid_port_caller("rx_zmqport", {}, 0, PUT);
// should fail for the second module
if (det.size() > 1) {
REQUIRE_THROWS(caller.call("rx_zmqport", {"65535"}, -1, PUT));
}
for (int i = 0; i != det.size(); ++i) {
det.setRxZmqPort(prev_val_zmqport[i], i);
}
if (det_type == defs::JUNGFRAU || det_type == defs::MOENCH) {
det.setNumberofUDPInterfaces(prev_val_numinterfaces);
}
}
TEST_CASE("rx_zmqhwm", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val =
det.getRxZmqHwm().tsquash("Inconsistent values for rx_zmqhwm to test");
{
std::ostringstream oss;
caller.call("rx_zmqhwm", {"50"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqhwm 50\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqhwm", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_zmqhwm 50\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqhwm", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqhwm 0\n");
}
{
std::ostringstream oss;
caller.call("rx_zmqhwm", {"-1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_zmqhwm -1\n");
}
det.setRxZmqHwm(prev_val);
}
/* CTB Specific */
TEST_CASE("rx_dbitlist", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
auto prev_val = det.getRxDbitList();
{
std::ostringstream oss;
caller.call("rx_dbitlist",
{"0", "4", "5", "8", "9", "10", "52", "63"}, -1, PUT,
oss);
REQUIRE(oss.str() == "rx_dbitlist [0, 4, 5, 8, 9, 10, 52, 63]\n");
}
{
std::ostringstream oss;
caller.call("rx_dbitlist", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_dbitlist [0, 4, 5, 8, 9, 10, 52, 63]\n");
}
REQUIRE_THROWS(caller.call("rx_dbitlist", {"67"}, -1, PUT));
REQUIRE_THROWS(caller.call("rx_dbitlist", {"-1"}, -1, PUT));
REQUIRE_NOTHROW(caller.call("rx_dbitlist", {"all"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setRxDbitList(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(caller.call("rx_dbitlist", {}, -1, GET));
}
}
TEST_CASE("rx_dbitoffset", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
auto prev_val = det.getRxDbitOffset();
{
std::ostringstream oss;
caller.call("rx_dbitoffset", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_dbitoffset 1\n");
}
{
std::ostringstream oss;
caller.call("rx_dbitoffset", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_dbitoffset 0\n");
}
{
std::ostringstream oss;
caller.call("rx_dbitoffset", {"15"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_dbitoffset 15\n");
}
{
std::ostringstream oss;
caller.call("rx_dbitoffset", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_dbitoffset 15\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setRxDbitOffset(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(caller.call("rx_dbitoffset", {}, -1, GET));
}
}
TEST_CASE("rx_dbitreorder", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto det_type = det.getDetectorType().squash();
if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
auto prev_val = det.getRxDbitReorder();
{
std::ostringstream oss;
caller.call("rx_dbitreorder", {"0"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_dbitreorder 0\n");
}
{
std::ostringstream oss;
caller.call("rx_dbitreorder", {"1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_dbitreorder 1\n");
}
{
std::ostringstream oss;
caller.call("rx_dbitreorder", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_dbitreorder 1\n");
}
REQUIRE_THROWS(caller.call("rx_dbitreorder", {"15"}, -1, PUT));
for (int i = 0; i != det.size(); ++i) {
det.setRxDbitReorder(prev_val[i], {i});
}
} else {
REQUIRE_THROWS(caller.call("rx_dbitreorder", {}, -1, GET));
}
}
TEST_CASE("rx_jsonaddheader", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getAdditionalJsonHeader();
{
std::ostringstream oss;
caller.call("rx_jsonaddheader", {"key1", "value1", "key2", "value2"},
-1, PUT, oss);
REQUIRE(oss.str() == "rx_jsonaddheader {key1: value1, key2: value2}\n");
}
{
std::ostringstream oss;
caller.call("rx_jsonaddheader", {}, -1, GET, oss);
REQUIRE(oss.str() == "rx_jsonaddheader {key1: value1, key2: value2}\n");
}
{
std::ostringstream oss;
caller.call("rx_jsonaddheader", {}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_jsonaddheader {}\n");
}
for (int i = 0; i != det.size(); ++i) {
det.setAdditionalJsonHeader(prev_val[i], {i});
}
}
TEST_CASE("rx_jsonpara", "[.detectorintegration]") {
Detector det;
Caller caller(&det);
auto prev_val = det.getAdditionalJsonHeader();
{
std::ostringstream oss;
caller.call("rx_jsonpara", {"key1", "value1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_jsonpara {key1: value1}\n");
}
{
std::ostringstream oss;
caller.call("rx_jsonpara", {"key1", "value2"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_jsonpara {key1: value2}\n");
}
{
std::ostringstream oss;
caller.call("rx_jsonpara", {"key1"}, -1, GET, oss);
REQUIRE(oss.str() == "rx_jsonpara value2\n");
}
{
std::ostringstream oss;
caller.call("rx_jsonpara", {"key1"}, -1, PUT, oss);
REQUIRE(oss.str() == "rx_jsonpara key1 deleted\n");
}
REQUIRE_THROWS(caller.call("rx_jsonpara", {"key1"}, -1, GET));
for (int i = 0; i != det.size(); ++i) {
det.setAdditionalJsonHeader(prev_val[i], {i});
}
}
/* Insignificant */
} // namespace sls