New TetraIF/unit-test/ directory with one QtTest executable per TetraIF release-scope module, wired into ctest and the DEB pipeline: - coprtcnv_unit_test: central and radio telegram header fields, payload access, length checks, fragmentation/reassembly roundtrip, telegram-id string helpers - logview_unit_test: IntegerCalculator arithmetic, operator priority, parentheses, error codes and variables (compiles the LogView class source directly; the class otherwise lives in the LogView executable) - prtcnv_unit_test: PrtCnvMember state and fragmented-telegram handling (compiles the class source directly because PrtCnvLib is built with hidden visibility) TetraIF/CMakeLists.txt adds the unit-test subdirectory and new_docker_build.sh builds and ctest-runs the three new targets.
116 lines
4.0 KiB
C++
116 lines
4.0 KiB
C++
//
|
|
// Unit tests for the PrtCnv module: PrtCnvMember (member state and
|
|
// fragmented telegram handling / reassembly).
|
|
//
|
|
#include <PrtCnv/PrtCnvMember.hpp>
|
|
#include <CoPrtCnv/CoPrtCnvRadioTelegram.hpp>
|
|
#include <CoPrtCnv/tetra_telegram_ids.h>
|
|
|
|
#include <NGLLogger/NGLLoggerBootstrap.h>
|
|
|
|
#include <QtTest/QTest>
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
|
|
class prtcnv_unit_test : public QObject
|
|
{
|
|
Q_OBJECT
|
|
|
|
private slots:
|
|
void initTestCase();
|
|
|
|
void memberDefaults();
|
|
void fragmentedListEmptyInitially();
|
|
void addAndClearFragments();
|
|
void unfragmentationRoundtrip();
|
|
};
|
|
|
|
void prtcnv_unit_test::initTestCase()
|
|
{
|
|
NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false);
|
|
}
|
|
|
|
void prtcnv_unit_test::memberDefaults()
|
|
{
|
|
PrtCnv::PrtCnvMember member(7, 0x1234);
|
|
QCOMPARE(member.m_Id, 7);
|
|
QCOMPARE(member.m_ISSI, 0x1234);
|
|
QCOMPARE(member.m_ClaimCount, 0);
|
|
QCOMPARE(member.m_loggedInExerciseId, 0);
|
|
QCOMPARE(member.m_Licensed, false);
|
|
}
|
|
|
|
void prtcnv_unit_test::fragmentedListEmptyInitially()
|
|
{
|
|
PrtCnv::PrtCnvMember member(1, 0x0001);
|
|
QVERIFY(member.isFragmentedListEmpty());
|
|
QVERIFY(member.getUnfragmentedTelegramData().isEmpty());
|
|
}
|
|
|
|
void prtcnv_unit_test::addAndClearFragments()
|
|
{
|
|
const uint16_t payloadSize = 300;
|
|
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> bigPtr(new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_BESTAETIGUNG, payloadSize, 0x4321));
|
|
|
|
const int payloadPart = bigPtr->getSize() - N_CoPrtCnv::CoPrtCnvRadioTelegram::DATA_IND_REQ_HEADER_LENGTH;
|
|
const uint8_t maxFragPayload = N_CoPrtCnv::CoPrtCnvRadioTelegram::MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH
|
|
- N_CoPrtCnv::CoPrtCnvRadioTelegram::PAYLOAD_STATUS_LENGTH;
|
|
const uint8_t nbrFragments = static_cast<uint8_t>((payloadPart - 1) / maxFragPayload);
|
|
|
|
PrtCnv::PrtCnvMember member(1, 0x0001);
|
|
QVERIFY(member.isFragmentedListEmpty());
|
|
|
|
std::vector<std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> > frags;
|
|
for (uint8_t i = 0; i <= nbrFragments; ++i)
|
|
{
|
|
bool error = true;
|
|
auto frag = std::make_shared<N_CoPrtCnv::CoPrtCnvRadioTelegram>(bigPtr, i, error);
|
|
QVERIFY2(!error, "fragment creation failed");
|
|
frags.push_back(frag);
|
|
member.addFragmentedTelegram(*frag);
|
|
}
|
|
|
|
QVERIFY(!member.isFragmentedListEmpty());
|
|
QCOMPARE(member.getFragmentedTelegramId(), GEF_BESTAETIGUNG);
|
|
|
|
member.clearFragmentedList();
|
|
QVERIFY(member.isFragmentedListEmpty());
|
|
}
|
|
|
|
void prtcnv_unit_test::unfragmentationRoundtrip()
|
|
{
|
|
// A big telegram with a known payload pattern, fragmented into the member and reassembled
|
|
const uint16_t payloadSize = 300;
|
|
std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> bigPtr(new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_BESTAETIGUNG, payloadSize, 0x5678));
|
|
|
|
QByteArray pattern(payloadSize, 0);
|
|
for (int i = 0; i < payloadSize; ++i)
|
|
pattern[i] = static_cast<char>(i * 7 + 1);
|
|
bigPtr->setPayloadData(reinterpret_cast<const uint8_t *>(pattern.constData()), payloadSize);
|
|
|
|
const int payloadPart = bigPtr->getSize() - N_CoPrtCnv::CoPrtCnvRadioTelegram::DATA_IND_REQ_HEADER_LENGTH;
|
|
const uint8_t maxFragPayload = N_CoPrtCnv::CoPrtCnvRadioTelegram::MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH
|
|
- N_CoPrtCnv::CoPrtCnvRadioTelegram::PAYLOAD_STATUS_LENGTH;
|
|
const uint8_t nbrFragments = static_cast<uint8_t>((payloadPart - 1) / maxFragPayload);
|
|
|
|
PrtCnv::PrtCnvMember member(2, 0x0002);
|
|
std::vector<std::shared_ptr<N_CoPrtCnv::CoPrtCnvRadioTelegram> > frags;
|
|
for (uint8_t i = 0; i <= nbrFragments; ++i)
|
|
{
|
|
bool error = true;
|
|
auto frag = std::make_shared<N_CoPrtCnv::CoPrtCnvRadioTelegram>(bigPtr, i, error);
|
|
QVERIFY2(!error, "fragment creation failed");
|
|
frags.push_back(frag);
|
|
member.addFragmentedTelegram(*frag);
|
|
}
|
|
|
|
const QByteArray unfragmented = member.getUnfragmentedTelegramData();
|
|
QCOMPARE(unfragmented.size(), bigPtr->data().size());
|
|
QCOMPARE(unfragmented.mid(N_CoPrtCnv::CoPrtCnvRadioTelegram::DATA_IND_REQ_HEADER_LENGTH - 1),
|
|
bigPtr->data().mid(N_CoPrtCnv::CoPrtCnvRadioTelegram::DATA_IND_REQ_HEADER_LENGTH - 1));
|
|
}
|
|
|
|
QTEST_MAIN(prtcnv_unit_test)
|
|
#include "prtcnv_unit_test.moc"
|