fixed ctb guard tests
Build on RHEL9 docker image / build (push) Successful in 3m48s
Build on RHEL8 docker image / build (push) Successful in 5m4s
Run Simulator Tests on local RHEL9 / build (push) Failing after 18m26s
Run Simulator Tests on local RHEL8 / build (push) Failing after 20m51s

This commit is contained in:
2026-06-10 01:27:30 +02:00
parent 8477152318
commit e106bc4e1e
6 changed files with 147 additions and 82 deletions
@@ -15,10 +15,12 @@ namespace acq = sls::test::acquire;
namespace checks = sls::test::checks;
void acquire_and_check_file_size(
Detector &det, const acq::CTBState &ctb_state = acq::default_ctb_state()) {
Detector &det, std::optional<acq::CTBState> ctb_state = std::nullopt) {
auto acq_state = acq::default_acquisition_state();
acq_state.num_frames = 2;
auto file_state = acq::default_file_state();
INFO("Acquiring " << ToString(det.getDetectorType().squash(defs::GENERIC))
<< " with num_frames = " << acq_state.num_frames);
acq::run(det, acq_state, file_state);
auto image_size = acq::get_expected_image_size(det, ctb_state);
REQUIRE_NOTHROW(
@@ -26,9 +28,8 @@ void acquire_and_check_file_size(
}
void test_ctb_binary_file_size(Detector &det) {
bool isAltera =
(det.getDetectorType().squash(defs::GENERIC) == defs::CHIPTESTBOARD);
acq::CTBState ctb_state = acq::default_ctb_state(isAltera);
auto detType = det.getDetectorType().squash(defs::GENERIC);
acq::CTBState ctb_state = acq::default_ctb_state(detType);
// default ctb state for tests
// readout mode = defs::ANALOG_AND_DIGITAL
// analog samples = 5000
@@ -42,187 +43,212 @@ void test_ctb_binary_file_size(Detector &det) {
// dbit reorder = false
// trans mask = 0x3
acq::CTBStateGuard ctb_guard(det, ctb_state);
acq::CTBStateGuard ctb_guard(det, std::make_optional(ctb_state));
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_offset = 16;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_offset = 16;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_reorder = true;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_offset = 16;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_offset = 16;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_reorder = true;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::DIGITAL_AND_TRANSCEIVER;
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_offset = 16;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_offset = 16;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_reorder = true;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::TRANSCEIVER_ONLY;
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
ctb_state.dbit_list.clear();
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
{
ctb_state = acq::default_ctb_state(isAltera);
ctb_state = acq::default_ctb_state(detType);
ctb_state.readout_mode = defs::ANALOG_ONLY;
ctb_state.dbit_offset = 16;
ctb_state.dbit_reorder = true;
acq::set_ctb_state(det, ctb_state);
REQUIRE_NOTHROW(acquire_and_check_file_size(det, ctb_state));
REQUIRE_NOTHROW(
acquire_and_check_file_size(det, std::make_optional(ctb_state)));
}
}
@@ -33,6 +33,17 @@ TEST_CASE("check_master_file_attributes",
auto acq_state = acq::default_acquisition_state();
auto file_state = acq::default_file_state();
// if ctb, set to default and restore after test
auto detType = det.getDetectorType().squash(defs::GENERIC);
std::optional<acq::CTBState> ctb_state = std::nullopt;
if (detType == defs::CHIPTESTBOARD ||
detType == defs::XILINX_CHIPTESTBOARD) {
ctb_state = std::make_optional(acq::default_ctb_state(detType));
}
acq::CTBStateGuard ctb_guard(det, ctb_state);
INFO("Checking master file attributes for " << ToString(detType));
// binary => /tmp/sls_test_master_0.json
file_state.file_format = defs::BINARY;
acq::run(det, acq_state, file_state);
@@ -42,7 +53,7 @@ TEST_CASE("check_master_file_attributes",
// get expected state of parameters and check against master file
acq::ExpectedState expected_state =
acq::build_expected_state(det, acq_state, file_state);
acq::build_expected_state(det, acq_state, file_state, ctb_state);
checks::check_metadata(checker, expected_state);
#ifdef HDF5C
@@ -56,7 +67,7 @@ TEST_CASE("check_master_file_attributes",
// get expected state of parameters and check against master file
acq::ExpectedState expected_state =
acq::build_expected_state(det, acq_state, file_state);
acq::build_expected_state(det, acq_state, file_state, ctb_state);
checks::check_metadata(checker, expected_state);
} catch (H5::Exception &e) {
LOG(logERROR) << "HDF5 error: " << e.getDetailMsg();
+17 -7
View File
@@ -6,6 +6,7 @@
#include "sls/logger.h"
#include <cstdint>
#include <optional>
#include <vector>
namespace sls::test::acquire {
@@ -25,7 +26,13 @@ struct CTBState {
};
/** an example of CTB config */
inline CTBState default_ctb_state(bool isAltera = false) {
inline CTBState
default_ctb_state(const defs::detectorType &detType = defs::GENERIC) {
if (detType == defs::GENERIC) {
throw sls::RuntimeError(
"Cannot determine default CTB state for generic detector type.");
}
auto isAltera = (detType == defs::CHIPTESTBOARD);
return {defs::ANALOG_AND_DIGITAL, 5000, 6000, 288,
isAltera ? false : true, 0xFFFFFF00, 0xFF00FFFF, 0,
{0, 12, 2, 43}, false, 0x3};
@@ -103,14 +110,18 @@ inline void print_current_ctb_state(const Detector &det) {
*/
class CTBStateGuard {
public:
explicit CTBStateGuard(Detector &det, const CTBState &new_state)
explicit CTBStateGuard(Detector &det,
std::optional<CTBState> new_state = std::nullopt)
: det(det) {
auto type = det.getDetectorType().squash(defs::GENERIC);
active =
(type == defs::CHIPTESTBOARD || type == defs::XILINX_CHIPTESTBOARD);
if (active) {
if (type == defs::CHIPTESTBOARD || type == defs::XILINX_CHIPTESTBOARD) {
active = true;
if (!new_state.has_value()) {
throw sls::RuntimeError(
"New CTB state must be provided for CTBStateGuard.");
}
saved_ = get_ctb_state(det);
set_ctb_state(det, new_state);
set_ctb_state(det, new_state.value());
}
}
~CTBStateGuard() {
@@ -121,7 +132,6 @@ class CTBStateGuard {
private:
Detector &det;
bool active{false};
bool isAltera{false};
CTBState saved_;
};
@@ -27,7 +27,8 @@ int get_dynamic_range(const Detector &det) {
return det.getDynamicRange().tsquash("Inconsistent dynamic range");
}
defs::xy get_port_shape(const Detector &det) {
defs::xy get_port_shape(const Detector &det,
std::optional<acq::CTBState> &ctb_state) {
auto det_type = get_detector_type(det);
auto portSize = det.getPortSize()[0];
@@ -41,10 +42,14 @@ defs::xy get_port_shape(const Detector &det) {
portSize.x = nchan * num_counters;
} else if (det_type == defs::CHIPTESTBOARD ||
det_type == defs::XILINX_CHIPTESTBOARD) {
acq::CTBState test_info = acq::default_ctb_state();
portSize.x = sls::calculate_ctb_image_size(
test_info, det_type == defs::XILINX_CHIPTESTBOARD)
.second;
if (!ctb_state.has_value()) {
throw sls::RuntimeError(
"CTB state must be provided to calculate expected port shape");
}
portSize.x =
sls::calculate_ctb_image_size(
ctb_state.value(), det_type == defs::XILINX_CHIPTESTBOARD)
.second;
portSize.y = 1;
}
return portSize;
@@ -150,14 +155,15 @@ std::pair<ns, ns> get_sub_exptime_and_sub_period(const Detector &det) {
return std::make_pair(ns(exptime), ns(sub_period));
}
acq::CommonExpectedState build_common_state(const Detector &det,
const acq::CTBState &ctb_state) {
acq::CommonExpectedState
build_common_state(const Detector &det,
std::optional<acq::CTBState> ctb_state) {
acq::CommonExpectedState e;
e.det_type = get_detector_type(det);
e.timing_mode = det.getTimingMode().tsquash("Inconsistent timing mode");
e.geometry = get_geometry(det);
e.image_size = acq::get_expected_image_size(det, ctb_state);
e.port_shape = get_port_shape(det);
e.port_shape = get_port_shape(det, ctb_state);
e.max_frames_per_file =
det.getFramesPerFile().tsquash("Inconsistent frames per file");
e.frame_discard_policy = det.getRxFrameDiscardPolicy().tsquash(
@@ -258,7 +264,7 @@ acq::CTBExpectedState build_ctb_specific_state(const Detector &det,
acq::DetectorSpecificState
build_detector_specific_state(const Detector &det,
const acq::CTBState &ctb_state) {
std::optional<acq::CTBState> ctb_state) {
switch (det.getDetectorType().tsquash("bad type")) {
case defs::JUNGFRAU:
return build_jungfrau_specific_state(det);
@@ -272,7 +278,11 @@ build_detector_specific_state(const Detector &det,
return build_gotthard2_specific_state(det);
case defs::CHIPTESTBOARD:
case defs::XILINX_CHIPTESTBOARD:
return build_ctb_specific_state(det, ctb_state);
if (!ctb_state.has_value()) {
throw sls::RuntimeError(
"CTB state must be provided to build expected state");
}
return build_ctb_specific_state(det, ctb_state.value());
default:
throw sls::RuntimeError("Unsupported detector type");
}
@@ -284,7 +294,7 @@ namespace sls::test::acquire {
ExpectedState build_expected_state(const Detector &det,
const AcquisitionState &acq_state,
const FileState &file_state,
const CTBState &ctb_state) {
std::optional<CTBState> ctb_state) {
ExpectedState e;
e.common_state = build_common_state(det, ctb_state);
e.file_state = file_state;
@@ -293,7 +303,8 @@ ExpectedState build_expected_state(const Detector &det,
return e;
}
int get_expected_image_size(const Detector &det, const CTBState &ctb_state) {
int get_expected_image_size(const Detector &det,
std::optional<CTBState> ctb_state) {
auto det_type = get_detector_type(det);
auto dynamic_range = get_dynamic_range(det);
int bytes_per_pixel = dynamic_range / 8;
@@ -324,11 +335,17 @@ int get_expected_image_size(const Detector &det, const CTBState &ctb_state) {
image_size = par.nChanX * par.nChipX * bytes_per_pixel;
} break;
case defs::CHIPTESTBOARD:
image_size = sls::calculate_ctb_image_size(ctb_state, false).first;
case defs::XILINX_CHIPTESTBOARD:
if (!ctb_state.has_value()) {
throw sls::RuntimeError(
"CTB state must be provided to calculate expected image size");
}
LOG(logINFORED) << ctb_state.value();
image_size =
sls::calculate_ctb_image_size(
ctb_state.value(), (det_type == defs::XILINX_CHIPTESTBOARD))
.first;
break;
case defs::XILINX_CHIPTESTBOARD: {
image_size = sls::calculate_ctb_image_size(ctb_state, true).first;
} break;
default:
throw sls::RuntimeError("Unsupported detector type for this test");
}
@@ -111,9 +111,9 @@ ExpectedState build_expected_state(
const Detector &det,
const AcquisitionState &acq_state = default_acquisition_state(),
const FileState &file_state = default_file_state(),
const CTBState &ctb_state = default_ctb_state());
std::optional<CTBState> ctb_state = std::nullopt);
int get_expected_image_size(const Detector &det,
const CTBState &ctb_state = default_ctb_state());
std::optional<CTBState> ctb_state = std::nullopt);
} // namespace sls::test::acquire
@@ -24,6 +24,7 @@ template <> class Checker<JsonContext> {
template <typename T>
void check(const std::string &name, const T &expected,
AccessType = AccessType::Dataset) const {
CAPTURE(name);
REQUIRE(ctx_.doc.HasMember(name.c_str()));
auto retval = read<JsonContext, T>(ctx_, name);
REQUIRE(retval == expected);