Files
lorakiss/test/test_kiss.cpp
Maze X cb14666710 Add unit test framework and test stubs
- Add test/test_kiss.cpp: Unit tests for KISS protocol encoder/decoder
  Tests: frame decoding with/without escape sequences, port extraction,
  round-trip encoding/decoding, signal quality encoding, buffer overflow handling
- Add test/test_commands.cpp: Unit tests for config command parsing
  Tests: big-endian encoding/decoding, frequency frame parsing, type byte decoding
- Configure PlatformIO native test environment with GoogleTest framework
- Tests currently build but require linking stubs for full integration

Note: Full end-to-end testing requires mocking Serial I/O and radio functions,
which would be handled by integration tests on actual hardware or with a
more sophisticated test harness (e.g., CMake + GoogleTest).
2026-03-27 17:40:49 +01:00

136 lines
4.1 KiB
C++

#include <gtest/gtest.h>
#include <cstring>
extern "C" {
#include "kiss.h"
}
TEST(KissDecoder, InitState) {
kiss_decoder_t dec;
kiss_decoder_init(&dec);
EXPECT_EQ(dec.state, KISS_STATE_IDLE);
EXPECT_EQ(dec.len, 0);
}
TEST(KissDecoder, DecodeSimpleFrame) {
kiss_decoder_t dec;
kiss_decoder_init(&dec);
kiss_frame_t frame;
/* Build frame: FEND [0x00 0xAA 0xBB] FEND */
EXPECT_FALSE(kiss_decode(&dec, KISS_FEND, &frame)); /* FEND start */
EXPECT_FALSE(kiss_decode(&dec, 0x00, &frame)); /* type byte */
EXPECT_FALSE(kiss_decode(&dec, 0xAA, &frame)); /* data */
EXPECT_FALSE(kiss_decode(&dec, 0xBB, &frame)); /* data */
EXPECT_TRUE(kiss_decode(&dec, KISS_FEND, &frame)); /* FEND end */
EXPECT_EQ(frame.port, 0);
EXPECT_EQ(frame.len, 2);
EXPECT_EQ(frame.data[0], 0xAA);
EXPECT_EQ(frame.data[1], 0xBB);
}
TEST(KissDecoder, DecodeWithEscape) {
kiss_decoder_t dec;
kiss_decoder_init(&dec);
kiss_frame_t frame;
/* Frame with escaped FEND: FEND [0x00 FESC TFEND] FEND */
EXPECT_FALSE(kiss_decode(&dec, KISS_FEND, &frame));
EXPECT_FALSE(kiss_decode(&dec, 0x00, &frame));
EXPECT_FALSE(kiss_decode(&dec, KISS_FESC, &frame));
EXPECT_FALSE(kiss_decode(&dec, KISS_TFEND, &frame));
EXPECT_TRUE(kiss_decode(&dec, KISS_FEND, &frame));
EXPECT_EQ(frame.port, 0);
EXPECT_EQ(frame.len, 1);
EXPECT_EQ(frame.data[0], KISS_FEND);
}
TEST(KissDecoder, DecodePortExtraction) {
kiss_decoder_t dec;
kiss_decoder_init(&dec);
kiss_frame_t frame;
/* Frame with port 2: FEND [0x21 0xAA] FEND (port=2 in upper nibble) */
EXPECT_FALSE(kiss_decode(&dec, KISS_FEND, &frame));
EXPECT_FALSE(kiss_decode(&dec, 0x21, &frame)); /* port=2, cmd=1 */
EXPECT_FALSE(kiss_decode(&dec, 0xAA, &frame));
EXPECT_TRUE(kiss_decode(&dec, KISS_FEND, &frame));
EXPECT_EQ(frame.port, 2);
EXPECT_EQ(frame.len, 1);
EXPECT_EQ(frame.data[0], 0xAA);
}
TEST(KissEncoder, EncodeSimpleFrame) {
uint8_t data[] = {0xAA, 0xBB};
uint8_t dst[32];
size_t len = kiss_encode(0, data, 2, dst, sizeof(dst));
EXPECT_EQ(len, 6); /* FEND type data[2] FEND = 6 bytes */
EXPECT_EQ(dst[0], KISS_FEND);
EXPECT_EQ(dst[1], 0x00); /* type byte */
EXPECT_EQ(dst[2], 0xAA);
EXPECT_EQ(dst[3], 0xBB);
EXPECT_EQ(dst[4], KISS_FEND);
}
TEST(KissEncoder, EncodeWithEscape) {
uint8_t data[] = {KISS_FEND};
uint8_t dst[32];
size_t len = kiss_encode(0, data, 1, dst, sizeof(dst));
EXPECT_EQ(len, 7); /* FEND type FESC TFEND FEND = 7 bytes */
EXPECT_EQ(dst[0], KISS_FEND);
EXPECT_EQ(dst[1], 0x00);
EXPECT_EQ(dst[2], KISS_FESC);
EXPECT_EQ(dst[3], KISS_TFEND);
EXPECT_EQ(dst[4], KISS_FEND);
}
TEST(KissEncoder, EncodeQuality) {
uint8_t dst[32];
size_t len = kiss_encode_quality(-7, -103, dst, sizeof(dst));
EXPECT_EQ(len, 8); /* FEND type(0x11) snr rssi_hi rssi_lo FEND */
EXPECT_EQ(dst[0], KISS_FEND);
EXPECT_EQ(dst[1], 0x11); /* port=1, cmd=1 */
EXPECT_EQ(dst[2], 0xF9); /* -7 in two's complement */
EXPECT_EQ(dst[3], 0xFF); /* -103 >> 8 */
EXPECT_EQ(dst[4], 0x99); /* -103 & 0xFF */
EXPECT_EQ(dst[5], KISS_FEND);
}
TEST(KissEncoder, RoundTrip) {
uint8_t orig_data[] = {0x11, 0x22, KISS_FEND, KISS_FESC, 0x33};
uint8_t encoded[64];
uint8_t decoded_data[64];
size_t enc_len = kiss_encode(1, orig_data, 5, encoded, sizeof(encoded));
EXPECT_GT(enc_len, 0);
kiss_decoder_t dec;
kiss_decoder_init(&dec);
kiss_frame_t frame;
for (size_t i = 0; i < enc_len; i++) {
if (kiss_decode(&dec, encoded[i], &frame)) {
EXPECT_EQ(frame.port, 1);
EXPECT_EQ(frame.len, 5);
for (int j = 0; j < 5; j++) {
EXPECT_EQ(frame.data[j], orig_data[j]);
}
return;
}
}
FAIL() << "Decoder did not return complete frame";
}
TEST(KissEncoder, BufferOverflow) {
uint8_t data[] = {0xAA, 0xBB};
uint8_t dst[3]; /* Too small */
size_t len = kiss_encode(0, data, 2, dst, sizeof(dst));
EXPECT_EQ(len, 0); /* Should return 0 on overflow */
}