// // Unit tests for the CoPrtCnv module: central telegram, radio telegram // (header fields, payload access, fragmentation) and the string helpers. // #include #include #include #include #include #include #include #include #include #include #include class coprtcnv_unit_test : public QObject { Q_OBJECT private slots: void initTestCase(); void centralTelegramFromId(); void centralTelegramDataRoundtrip(); void centralTelegramCounter(); void radioTelegramSourceIssi(); void radioTelegramDestIssi(); void radioTelegramIdentity(); void radioTelegramCounter(); void radioTelegramPayloadBytes(); void radioTelegramLengthChecks(); void radioTelegramFragmentationRoundtrip(); void radioTelegramLoginVsNormal(); void telegramIdToString(); void wirkfeldTypToString(); }; void coprtcnv_unit_test::initTestCase() { NGL::NGLLoggerBootstrap::createNGLRootLogger("log4cxx.props", false); } void coprtcnv_unit_test::centralTelegramFromId() { N_CoPrtCnv::CoPrtCnvCentralTelegram tele(TrainingAreaBase::TetraIcd::BESTAETIGUNG); QCOMPARE(tele.telegramId(), TrainingAreaBase::TetraIcd::BESTAETIGUNG); } void coprtcnv_unit_test::centralTelegramDataRoundtrip() { N_CoPrtCnv::CoPrtCnvCentralTelegram tele(TrainingAreaBase::TetraIcd::BESTAETIGUNG); const QByteArray data(QByteArrayLiteral("central-telegram-payload")); tele.setData(data); QCOMPARE(tele.data(), data); } void coprtcnv_unit_test::centralTelegramCounter() { N_CoPrtCnv::CoPrtCnvCentralTelegram tele(TrainingAreaBase::TetraIcd::BESTAETIGUNG); tele.setCounter(42); QCOMPARE(tele.counter(), 42); } void coprtcnv_unit_test::radioTelegramSourceIssi() { N_CoPrtCnv::CoPrtCnvRadioTelegram tele(0x12345678); QCOMPARE(tele.getSrcISSI(), 0x12345678u); } void coprtcnv_unit_test::radioTelegramDestIssi() { N_CoPrtCnv::CoPrtCnvRadioTelegram tele(0x00000001); tele.setDestISSI(0x87654321); QCOMPARE(tele.getDestISSI(), 0x87654321u); } void coprtcnv_unit_test::radioTelegramIdentity() { // Identity is only a field of the DataIndReq payload (the (id, size, identity) constructor); other PDU types have no identity area. N_CoPrtCnv::CoPrtCnvRadioTelegram tele(GEF_BESTAETIGUNG, 32, 0xBEEF); QCOMPARE(tele.getIdentity(), 0xBEEF); } void coprtcnv_unit_test::radioTelegramCounter() { N_CoPrtCnv::CoPrtCnvRadioTelegram tele(0x00000003); tele.setZaehler(7); QCOMPARE(tele.zaehler(), 7); } void coprtcnv_unit_test::radioTelegramPayloadBytes() { N_CoPrtCnv::CoPrtCnvRadioTelegram tele(GEF_BESTAETIGUNG, 32, 0x3333); QCOMPARE(tele.getPayloadSize(), 32); const uint8_t pattern[4] = {0xDE, 0xAD, 0xBE, 0xEF}; tele.setPayloadData(pattern, 4); QCOMPARE(tele.getPayloadDataUInt8(3), 0xDE); QCOMPARE(tele.getPayloadDataUInt8(4), 0xAD); QCOMPARE(tele.getPayloadDataUInt8(5), 0xBE); QCOMPARE(tele.getPayloadDataUInt8(6), 0xEF); // getPayloadDataUInt32 assembles the bytes big endian QCOMPARE(tele.getPayloadDataUInt32(3, 4), 0xDEADBEEFu); } void coprtcnv_unit_test::radioTelegramLengthChecks() { // isTelegramLengthOk: length <= MAX_RADIO_TELEGRAM_PAYLOAD_LENGTH // + DATA_IND_REQ_HEADER_LENGTH - sizeof(GwHeader) - PAYLOAD_STATUS_LENGTH // = 249 + 27 - 4 - 1 = 271 QVERIFY(N_CoPrtCnv::CoPrtCnvRadioTelegram::isTelegramLengthOk(271)); QVERIFY(!N_CoPrtCnv::CoPrtCnvRadioTelegram::isTelegramLengthOk(272)); QVERIFY(!N_CoPrtCnv::CoPrtCnvRadioTelegram::isTelegramLengthOk(1000)); } void coprtcnv_unit_test::radioTelegramFragmentationRoundtrip() { // Build a big telegram whose payload must be fragmented, reassemble the // fragments and compare the payload area against the original data. const uint16_t payloadSize = 300; std::shared_ptr bigPtr(new N_CoPrtCnv::CoPrtCnvRadioTelegram(GEF_BESTAETIGUNG, payloadSize, 0x1111)); 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((payloadPart - 1) / maxFragPayload); QVERIFY(nbrFragments >= 1); std::vector > frags; std::multimap fragList; for (uint8_t i = 0; i <= nbrFragments; ++i) { bool error = true; auto frag = std::make_shared(bigPtr, i, error); QVERIFY2(!error, "fragment creation failed"); frags.push_back(frag); fragList.insert(std::make_pair(frag->getFragmentCounter(), frag.get())); } QCOMPARE(static_cast(fragList.size()), static_cast(nbrFragments) + 1); const QByteArray unfragmented = N_CoPrtCnv::CoPrtCnvRadioTelegram::getUnfragmentedData(fragList); QVERIFY(!unfragmented.isEmpty()); 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)); } void coprtcnv_unit_test::radioTelegramLoginVsNormal() { N_CoPrtCnv::CoPrtCnvRadioTelegram login(N_CoPrtCnv::CoPrtCnvRadioTelegram::e_LoginRequest, 0x2222, 0x00000005); QVERIFY(login.isLoginTelegram()); QVERIFY(!login.isNormalTelegram()); } void coprtcnv_unit_test::telegramIdToString() { // telegramId2String / wirkfeldTyp2Str are declared in global scope const QByteArray known = telegramId2String(GEF_BESTAETIGUNG); QVERIFY(!known.isEmpty()); } void coprtcnv_unit_test::wirkfeldTypToString() { const QString text = wirkfeldTyp2Str(TrainingAreaBase::TetraIcd::AreaEffectSimulationType::BeStillWarning); QVERIFY(!text.isEmpty()); } QTEST_MAIN(coprtcnv_unit_test) #include "coprtcnv_unit_test.moc"