[modbus] Add unit tests for U_WORD_S and S_WORD_S (#17831)

This commit is contained in:
Marek Pilch
2026-08-04 12:17:27 -04:00
committed by GitHub
parent 5abd100b53
commit 8bd9f213e5
5 changed files with 83 additions and 1 deletions
@@ -331,6 +331,7 @@ TEST(ModbusCreateClientPdu, WriteCoilsUseTheCoilLimitNotTheRegisterLimit) {
EXPECT_TRUE(create_client_pdu(FC::WRITE_MULTIPLE_COILS, 0x0000, 1969, big.data(), big.size()).empty());
}
// --- payload_to_number -----------------------------------------------------
TEST(ModbusHelpersTest, PayloadToNumberRejectsOffsetAtEndOfBuffer) {
const std::vector<uint8_t> data{0x12, 0x34};
EXPECT_FALSE(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD, 2, 0xFFFFFFFF).has_value());
@@ -346,6 +347,28 @@ TEST(ModbusHelpersTest, PayloadToNumberDecodesValidWord) {
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD, 0, 0xFFFFFFFF), 0x1234);
}
TEST(ModbusHelpersTest, PayloadToNumberDecodesSwappedUnsignedWord) {
const std::vector<uint8_t> data{0x34, 0x12};
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD_S, 0, 0xFFFFFFFF), 0x1234);
}
TEST(ModbusHelpersTest, PayloadToNumberDecodesSwappedSignedWord) {
const std::vector<uint8_t> data{0xFE, 0xFF};
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::S_WORD_S, 0, 0xFFFFFFFF), -2);
}
TEST(ModbusHelpersTest, PayloadToNumberAppliesBitmaskAfterSwap) {
// Bytes {0x34,0x12} decode as U_WORD_S to 0x1234; mask 0xFF00 then right-shift by bit 8 -> 0x12
const std::vector<uint8_t> data{0x34, 0x12};
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::U_WORD_S, 0, 0xFF00), 0x12);
}
TEST(ModbusHelpersTest, PayloadToNumberAppliesBitmaskAfterSwapSigned) {
// Bytes {0x34,0xFE} decode as S_WORD_S to 0xFE34 (negative); mask 0x00F0 then right-shift by bit 4 -> 0x3
const std::vector<uint8_t> data{0x34, 0xFE};
EXPECT_EQ(payload_to_number(std::span<const uint8_t>(data), SensorValueType::S_WORD_S, 0, 0x00F0), 0x3);
}
// --- registers_to_number ---------------------------------------------------
// Register words are host byte order; results must match the byte-based payload_to_number.
@@ -354,6 +377,16 @@ TEST(ModbusHelpersTest, RegistersToNumberDecodesWord) {
EXPECT_EQ(registers_to_number(registers, 1, SensorValueType::U_WORD), 0x1234);
}
TEST(ModbusHelpersTest, RegistersToNumberDecodesSwappedUnsignedWord) {
const uint16_t registers[] = {0x3412};
EXPECT_EQ(registers_to_number(registers, 1, SensorValueType::U_WORD_S), 0x1234);
}
TEST(ModbusHelpersTest, RegistersToNumberDecodesSwappedSignedWord) {
const uint16_t registers[] = {0xFEFF};
EXPECT_EQ(registers_to_number(registers, 1, SensorValueType::S_WORD_S), -2);
}
TEST(ModbusHelpersTest, RegistersToNumberDecodesDwordHighWordFirst) {
const uint16_t registers[] = {0x1234, 0x5678};
EXPECT_EQ(registers_to_number(registers, 2, SensorValueType::U_DWORD), 0x12345678);
@@ -434,6 +467,24 @@ TEST(ModbusTypedBuilders, FloatToPayloadAppendsToExistingContent) {
EXPECT_EQ(data[1], 0x0001);
}
// --- number_to_payload -----------------------------------------------------
TEST(ModbusHelpersTest, NumberToPayloadRoundTripsSwappedUnsignedWord) {
std::vector<uint16_t> regs;
number_to_payload(regs, 0x1234, SensorValueType::U_WORD_S);
ASSERT_EQ(regs.size(), 1u);
EXPECT_EQ(regs[0], 0x3412);
EXPECT_EQ(registers_to_number(regs.data(), regs.size(), SensorValueType::U_WORD_S), 0x1234);
}
TEST(ModbusHelpersTest, NumberToPayloadRoundTripsSwappedSignedWord) {
std::vector<uint16_t> regs;
number_to_payload(regs, -2, SensorValueType::S_WORD_S);
ASSERT_EQ(regs.size(), 1u);
EXPECT_EQ(regs[0], 0xFEFF);
EXPECT_EQ(registers_to_number(regs.data(), regs.size(), SensorValueType::S_WORD_S), -2);
}
TEST(ModbusCreateClientPdu, ExceptionFlaggedWriteCodesRejected) {
// is_function_code_write() masks the exception bit; the builder must not.
const uint8_t values[] = {0x00, 0x0B, 0x00, 0x16};
@@ -41,6 +41,13 @@ number:
return x * 2.0;
write_lambda: |-
return x / 2.0;
# Covers Python value-type maps + read/write path for byte-swapped words
- platform: modbus_controller
modbus_controller_id: modbus_controller1
id: modbus_number3
name: Test Number Swapped Word
address: 0x9003
value_type: U_WORD_S
output:
- platform: modbus_controller