added tests for python
Some checks failed
Build on RHEL8 / build (push) Failing after 1m18s
Build on RHEL9 / build (push) Failing after 3m30s

This commit is contained in:
2025-11-20 12:22:43 +01:00
parent f4c1395319
commit 1ad2628311
7 changed files with 237 additions and 13 deletions

View File

@@ -155,15 +155,24 @@ def make_path(arg):
def _make(arg, transform):
"""Helper function for make_mac and make_ip special cases for
"""Helper function for make_mac, make_ip and other special cases for
dict, list and tuple. Otherwise just calls transform"""
if isinstance(arg, dict):
return {key: transform(value) for key, value in arg.items()}
return {key: _make(value, transform) for key, value in arg.items()}
elif isinstance(arg, list):
return [transform(a) for a in arg]
return [_make(a, transform) for a in arg]
elif isinstance(arg, tuple):
return tuple(transform(a) for a in arg)
# special case for BitPosition
if transform is _slsdet.BitPosition:
addr, bit = arg
if isinstance(addr, int):
addr = _slsdet.RegisterAddress(addr)
return transform(addr, bit)
else:
# general case: recursively transform each element
return tuple(_make(a, transform) for a in arg)
else:
# single element
return transform(arg)

View File

@@ -8,7 +8,7 @@ Testing functions from utils.py
import pytest
from slsdet.utils import *
from slsdet import IpAddr, MacAddr, DurationWrapper
from slsdet import IpAddr, MacAddr, DurationWrapper, RegisterAddress, RegisterValue, BitPosition
import datetime as dt
import pathlib
from pathlib import Path
@@ -198,6 +198,80 @@ def test_make_mac_from_tuple():
assert make_mac(arg) == (MacAddr("84:a9:aa:24:32:88"),
MacAddr("84:a9:3e:24:32:aa"))
def test_make_reg_addr_from_dict():
arg = {0: 0, 1: 0x305}
res = make_register_address(arg)
assert res == {0: RegisterAddress(0x0), 1: RegisterAddress(0x305)}
assert res[0].str() == "0x0"
assert res[1].str() == "0x305"
def test_make_reg_addr_from_str():
reg_addr = "0x305"
assert make_register_address(reg_addr).str() == reg_addr
def test_make_reg_addr_from_list():
arg = [0x305, "0x1fff1fff", 0xc34a]
assert make_register_address(arg) == [RegisterAddress(a) for a in arg]
def test_make_reg_addr_from_tuple():
arg = ("0x340")
assert make_register_address(arg) == (RegisterAddress(arg))
def test_make_reg_val_from_dict():
arg = {0: 0, 1: 0x305}
res = make_register_value(arg)
assert res == {0: RegisterValue(0x0), 1: RegisterValue(0x305)}
assert res[0].str() == "0x0"
assert res[1].str() == "0x305"
def test_make_reg_val_from_str():
reg_val = "0x305"
assert make_register_value(reg_val).str() == reg_val
def test_make_reg_val_from_list():
arg = [0x305, "0x1fff1fff", 0xc34a]
assert make_register_value(arg) == [RegisterValue(a) for a in arg]
def test_make_reg_val_from_tuple():
arg = ("0x340")
assert make_register_value(arg) == (RegisterValue(arg))
def test_make_bit_pos_from_dict():
arg = {
0: (RegisterAddress(0), 2),
1: (RegisterAddress(0x305), 23)
}
res = make_bit_position(arg)
assert res == {
0: BitPosition(RegisterAddress("0x0"), 2),
1: BitPosition(RegisterAddress("0x305"), 23)
}
assert res[0].str() == "[0x0, 2]"
assert res[1].str() == "[0x305, 23]"
def test_make_bit_pos_from_list():
arg = [
(RegisterAddress(0), 2),
(RegisterAddress(0x305), 23)
]
expected = [BitPosition(*a) for a in arg]
assert make_bit_position(arg) == expected
def test_make_bit_pos_from_tuple():
arg = (RegisterAddress(0x305), 23)
expected = BitPosition(*arg)
assert make_bit_position(arg) == expected
def test_make_path_from_str():
assert make_path("/") == Path("/")

View File

@@ -1502,7 +1502,7 @@ std::string Caller::define(int action) {
WrongNumberOfParameters(2);
}
// get name from address
if (is_hex_or_dec_int(args[1])) {
if (is_hex_or_dec_uint(args[1])) {
auto addr = RegisterAddress(args[1]);
auto t = det->getRegisterDefinition(addr);
os << t << '\n';
@@ -1546,7 +1546,7 @@ std::string Caller::define(int action) {
std::string err_str = e.what();
if (err_str.find("No bit definition found") !=
std::string::npos &&
!is_hex_or_dec_int(args[1])) {
!is_hex_or_dec_uint(args[1])) {
err_str += " and addr = " + args[1];
throw RuntimeError(err_str);
}
@@ -1738,7 +1738,7 @@ std::string Caller::bitoperations(int action) {
}
RegisterAddress Caller::parseAddress(const std::string &saddr) const {
if (is_hex_or_dec_int(saddr)) {
if (is_hex_or_dec_uint(saddr)) {
return RegisterAddress(saddr);
}
auto det_type = det->getDetectorType().squash();
@@ -1821,7 +1821,7 @@ Caller::parseRegAddressAndValue(const bool validate) const {
if (argsSize == 2) {
std::string saddr = args[0];
std::string sval = args[1];
if (!is_hex_or_dec_int(sval)) {
if (!is_hex_or_dec_uint(sval)) {
throw RuntimeError(
"If " + sval +
" is a bit name, use only one argument to specify it.");

View File

@@ -89,7 +89,7 @@ std::string RemoveUnit(std::string &str);
bool is_int(const std::string &s);
/** '0x200' is also an int here */
bool is_hex_or_dec_int(const std::string &s);
bool is_hex_or_dec_uint(const std::string &s);
bool replace_first(std::string *s, const std::string &substr,
const std::string &repl);

View File

@@ -7,7 +7,7 @@
namespace sls {
RegisterAddress::RegisterAddress(const std::string &address) {
if (!is_hex_or_dec_int(address)) {
if (!is_hex_or_dec_uint(address)) {
throw RuntimeError("Address must be an integer value.");
}
uint32_t addr = StringTo<uint32_t>(address);
@@ -30,6 +30,9 @@ std::string BitPosition::str() const {
}
RegisterValue::RegisterValue(const std::string &value) {
if (!is_hex_or_dec_uint(value)) {
throw RuntimeError("Value must be an integer value.");
}
uint32_t val = StringTo<uint32_t>(value);
value_ = val;
}

View File

@@ -43,9 +43,9 @@ bool is_int(const std::string &s) {
}) == s.end();
}
bool is_hex_or_dec_int(const std::string &s) {
bool is_hex_or_dec_uint(const std::string &s) {
try {
StringTo<int>(s);
StringTo<uint32_t>(s);
return true;
} catch (...) {
}

View File

@@ -3,6 +3,7 @@
#include "catch.hpp"
#include "sls/bit_utils.h"
#include <vector>
#include <sstream>
namespace sls {
@@ -42,4 +43,141 @@ TEST_CASE("Get set bits from 523") {
REQUIRE(vec == std::vector<int>{0, 1, 3, 9});
}
TEST_CASE("Convert RegisterAddress using classes ", "[support][bit_utils]") {
std::vector<uint32_t> vec_addr{0x305, 0xffffffff, 0x0, 0x34550987, 0x1fff1fff};
std::vector<std::string> vec_ans{"0x305", "0xffffffff", "0x0", "0x34550987", "0x1fff1fff"};
for (size_t i = 0; i != vec_addr.size(); ++i) {
auto reg0 = RegisterAddress(vec_addr[i]);
auto reg1 = RegisterAddress(vec_ans[i]);
auto reg2 = RegisterAddress(vec_addr[0]);
CHECK(reg0 == reg1);
if (i != 0)
CHECK(reg2 != reg1);
CHECK(reg0 == vec_addr[i]);
CHECK(reg1 == vec_addr[i]);
CHECK(reg0.str() == vec_ans[i]);
CHECK(reg1.str() == vec_ans[i]);
CHECK(static_cast<uint32_t>(reg0) == vec_addr[i]);
CHECK(static_cast<uint32_t>(reg1) == vec_addr[i]);
}
}
TEST_CASE("Convert RegisterValue using classes ", "[support][bit_utils]") {
std::vector<uint32_t> vec_addr{0x305, 0xffffffff, 0x0, 500254562, 0x1fff1fff};
std::vector<std::string> vec_ans{"0x305", "0xffffffff", "0x0", "0x1dd14762", "0x1fff1fff"};
for (size_t i = 0; i != vec_addr.size(); ++i) {
auto reg0 = RegisterValue(vec_addr[i]);
auto reg1 = RegisterValue(vec_ans[i]);
auto reg2 = RegisterValue(vec_addr[0]);
CHECK(reg0 == reg1);
if (i != 0)
CHECK(reg2 != reg1);
CHECK(reg0 == vec_addr[i]);
CHECK(reg1 == vec_addr[i]);
CHECK(reg0.str() == vec_ans[i]);
CHECK(reg1.str() == vec_ans[i]);
CHECK(static_cast<uint32_t>(reg0) == vec_addr[i]);
CHECK(static_cast<uint32_t>(reg1) == vec_addr[i]);
CHECK((reg0 | 0xffffffffu) == 0xffffffffu);
CHECK((reg0 | 0x0) == reg0);
}
}
TEST_CASE("Convert BitPosition using classes ", "[support][bit_utils]") {
std::vector<RegisterAddress> vec_addr{
RegisterAddress(0x305),
RegisterAddress(0xffffffffu),
RegisterAddress(0x0),
RegisterAddress(0x34550987),
RegisterAddress(0x1fff1fff)
};
std::vector<int> vec_bitpos{0, 15, 31, 7, 23};
std::vector<std::string> vec_ans{
"[0x305, 0]",
"[0xffffffff, 15]",
"[0x0, 31]",
"[0x34550987, 7]",
"[0x1fff1fff, 23]",
};
for (size_t i = 0; i != vec_addr.size(); ++i) {
auto reg0 = BitPosition(vec_addr[i], vec_bitpos[i]);
BitPosition reg1;
reg1.setAddress(vec_addr[i]);
reg1.setBitPosition(vec_bitpos[i]);
auto reg2 = BitPosition(vec_addr[0], vec_bitpos[0]);
CHECK(reg0 == reg1);
if (i != 0)
CHECK(reg2 != reg1);
CHECK(reg0.address() == vec_addr[i]);
CHECK(reg1.address() == vec_addr[i]);
CHECK(reg0.bitPosition() == vec_bitpos[i]);
CHECK(reg1.bitPosition() == vec_bitpos[i]);
CHECK(reg0.str() == vec_ans[i]);
CHECK(reg1.str() == vec_ans[i]);
}
}
TEST_CASE("Output operator gives same result as string", "[support][bit_utils]") {
{
RegisterAddress addr{"0x3456af"};
std::ostringstream os;
os << addr;
CHECK(os.str() == "0x3456af");
CHECK(os.str() == addr.str());
}
{
RegisterValue addr{"0x3456af"};
std::ostringstream os;
os << addr;
CHECK(os.str() == "0x3456af");
CHECK(os.str() == addr.str());
}
}
TEST_CASE("Strange input throws", "[support][bit_utils]") {
REQUIRE_THROWS(RegisterAddress("hej"));
// ensure correct exception message
try {
RegisterAddress("hej");
} catch (const std::exception &e) {
REQUIRE(std::string(e.what()) == "Address must be an integer value.");
}
REQUIRE_THROWS(RegisterValue("hej"));
// ensure correct exception message
try {
RegisterValue("hej");
} catch (const std::exception &e) {
REQUIRE(std::string(e.what()) == "Value must be an integer value.");
}
REQUIRE_THROWS(BitPosition(RegisterAddress(0x305), 32));
// ensure correct exception message
try {
BitPosition(RegisterAddress(0x305), 32);
} catch (const std::exception &e) {
REQUIRE(std::string(e.what()) == "Bit position must be between 0 and 31.");
}
}
TEST_CASE("Implicitly convert to uint for sending over network", "[support][bit_utils]") {
RegisterAddress addr{0x305};
uint64_t a = addr;
CHECK(a == 0x305);
RegisterValue addr1{0x305};
uint64_t a1 = addr1;
CHECK(a1 == 0x305);
}
} // namespace sls