From 0aff71bfdef5fbbf30572932bdbb858267c562d6 Mon Sep 17 00:00:00 2001 From: kpetridis <petridkon@gmail.com> Date: Sun, 27 Mar 2022 02:05:20 +0200 Subject: [PATCH] Unit tests addition --- inc/ErrorHandler.hpp | 8 +- inc/Helpers/ForwardControlConfiguration.hpp | 1 + .../RealTimeForwardingControlService.hpp | 6 + .../RealTimeForwardingControlService.cpp | 33 ++- test/Services/RealTimeForwardingControl.cpp | 255 +++++++++++++++++- 5 files changed, 280 insertions(+), 23 deletions(-) diff --git a/inc/ErrorHandler.hpp b/inc/ErrorHandler.hpp index ea4e8266..feab4ebe 100644 --- a/inc/ErrorHandler.hpp +++ b/inc/ErrorHandler.hpp @@ -204,17 +204,17 @@ public: * Attempt to add a new report type, when the addition of all report types is already enabled in the * Application Process configuration (ST[14]) */ - AdditionOfAllReportTypesAlreadyEnabled = 22, + AllReportTypesAlreadyAllowed = 22, /** * Attempt to add a new service type, when the addition of all service types is already enabled in the * Application Process configuration (ST[14]) */ - AdditionOfAllServiceTypesAlreadyEnabled = 23, + AllServiceTypesAlreadyAllowed = 23, /** * Attempt to add a new report type, when the max number of reports types allowed per service type * definition in the Application Process configuration is already reached (ST[14]) */ - MaxReportTypeDefinitionsReached = 24, + MaxReportTypesReached = 24, /** * Attempt to add a new service type, when the max number of service types allowed per application process * definition in the Application Process configuration is already reached (ST[14]) @@ -224,7 +224,7 @@ public: * Attempt to add a report/event definition/housekeeping report type, when the specified application process * ID is not controlled by the Service (ST[14]) */ - ApplicationNotControlled = 26, + NotControlledApplication = 26, }; /** diff --git a/inc/Helpers/ForwardControlConfiguration.hpp b/inc/Helpers/ForwardControlConfiguration.hpp index c965601d..353a481b 100644 --- a/inc/Helpers/ForwardControlConfiguration.hpp +++ b/inc/Helpers/ForwardControlConfiguration.hpp @@ -31,6 +31,7 @@ public: * Indicates the meaning of a service type being empty of report types. It specifies whether the 'empty' means that * it has not been filled yet (so we proceed to add new report types) or it is empty because we accept every * report type for the service. + * TODO: rename to 'allServicesAllowed' */ etl::map<uint8_t, reportsAreNotEmpty, ECSSMaxControlledApplications> serviceNotEmpty; diff --git a/inc/Services/RealTimeForwardingControlService.hpp b/inc/Services/RealTimeForwardingControlService.hpp index 9be63b97..fa88121b 100644 --- a/inc/Services/RealTimeForwardingControlService.hpp +++ b/inc/Services/RealTimeForwardingControlService.hpp @@ -106,6 +106,12 @@ private: */ bool maxReportTypesReached(Message& request, uint8_t applicationID, uint8_t serviceType); + /** + * Checks if the maximum number of message types that can be contained inside a service type definition, is + * already reached. + */ + bool checkMessage1(Message& request, uint8_t applicationID, uint8_t serviceType, uint8_t messageType); + public: /** * TC[14,1] 'Add report types to the application process forward control configuration'. diff --git a/src/Services/RealTimeForwardingControlService.cpp b/src/Services/RealTimeForwardingControlService.cpp index 62e24a32..38f528ac 100644 --- a/src/Services/RealTimeForwardingControlService.cpp +++ b/src/Services/RealTimeForwardingControlService.cpp @@ -4,7 +4,7 @@ bool RealTimeForwardingControlService::appIsControlled(Message& request, uint8_t applicationId) { if (std::find(controlledApplications.begin(), controlledApplications.end(), applicationId) == controlledApplications.end()) { - ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::ApplicationNotControlled); + ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::NotControlledApplication); return false; } return true; @@ -12,8 +12,7 @@ bool RealTimeForwardingControlService::appIsControlled(Message& request, uint8_t bool RealTimeForwardingControlService::checkApplication1(Message& request, uint8_t applicationID, uint8_t numOfServices) { - if (not appIsControlled(request, applicationID) or allServiceTypesAllowed(request, applicationID) or - maxServiceTypesReached(request, applicationID)) { + if (not appIsControlled(request, applicationID) or allServiceTypesAllowed(request, applicationID)) { for (uint8_t l = 0; l < numOfServices; l++) { request.skipBytes(1); uint8_t numOfMessages = request.readUint8(); @@ -27,8 +26,7 @@ bool RealTimeForwardingControlService::checkApplication1(Message& request, uint8 bool RealTimeForwardingControlService::allServiceTypesAllowed(Message& request, uint8_t applicationID) { if (applicationProcessConfiguration.definitions[applicationID].empty() and not applicationProcessConfiguration.serviceNotEmpty[applicationID].empty()) { - ErrorHandler::reportError(request, - ErrorHandler::ExecutionStartErrorType::AdditionOfAllServiceTypesAlreadyEnabled); + ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AllServiceTypesAlreadyAllowed); return true; } return false; @@ -44,8 +42,7 @@ bool RealTimeForwardingControlService::maxServiceTypesReached(Message& request, bool RealTimeForwardingControlService::checkService1(Message& request, uint8_t applicationID, uint8_t serviceType, uint8_t numOfMessages) { - if (allReportTypesAllowed(request, applicationID, serviceType) or - maxReportTypesReached(request, applicationID, serviceType)) { + if (maxServiceTypesReached(request, applicationID) or allReportTypesAllowed(request, applicationID, serviceType)) { request.skipBytes(numOfMessages); return false; } @@ -56,8 +53,7 @@ bool RealTimeForwardingControlService::allReportTypesAllowed(Message& request, u uint8_t serviceType) { if (applicationProcessConfiguration.definitions[applicationID][serviceType].empty() and applicationProcessConfiguration.serviceNotEmpty[applicationID][serviceType]) { - ErrorHandler::reportError(request, - ErrorHandler::ExecutionStartErrorType::AdditionOfAllReportTypesAlreadyEnabled); + ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::AllReportTypesAlreadyAllowed); return true; } return false; @@ -67,12 +63,22 @@ bool RealTimeForwardingControlService::maxReportTypesReached(Message& request, u uint8_t serviceType) { if (applicationProcessConfiguration.definitions[applicationID][serviceType].size() >= ECSSMaxReportTypeDefinitions) { - ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::MaxReportTypeDefinitionsReached); + ErrorHandler::reportError(request, ErrorHandler::ExecutionStartErrorType::MaxReportTypesReached); return true; } return false; } +bool RealTimeForwardingControlService::checkMessage1(Message& request, uint8_t applicationID, uint8_t serviceType, + uint8_t messageType) { + if (maxReportTypesReached(request, applicationID, serviceType) or + reportExistsInAppProcessConfiguration(messageType, applicationID, serviceType)) { + // request.skipBytes(1); + return false; + } + return true; +} + bool RealTimeForwardingControlService::reportExistsInAppProcessConfiguration(uint8_t target, uint8_t applicationID, uint8_t serviceType) { return std::find(applicationProcessConfiguration.definitions[applicationID][serviceType].begin(), @@ -105,7 +111,6 @@ void RealTimeForwardingControlService::addReportTypesToAppProcessConfiguration(M if (not checkService1(request, applicationID, serviceType, numOfMessages)) { continue; } - // if (numOfMessages == 0) { // // todo: add all report types of the service type to the configuration. // continue; @@ -113,10 +118,12 @@ void RealTimeForwardingControlService::addReportTypesToAppProcessConfiguration(M for (uint8_t k = 0; k < numOfMessages; k++) { uint8_t messageType = request.readUint8(); - // todo: check if message type is valid. - if (reportExistsInAppProcessConfiguration(messageType, applicationID, serviceType)) { + + if (not checkMessage1(request, applicationID, serviceType, messageType)) { continue; } + + // todo: check if message type is valid. applicationProcessConfiguration.definitions[applicationID][serviceType].push_back(messageType); applicationProcessConfiguration.serviceNotEmpty[applicationID][serviceType] = true; } diff --git a/test/Services/RealTimeForwardingControl.cpp b/test/Services/RealTimeForwardingControl.cpp index 75dd95e6..39a4dfa4 100644 --- a/test/Services/RealTimeForwardingControl.cpp +++ b/test/Services/RealTimeForwardingControl.cpp @@ -5,17 +5,19 @@ #include "ECSS_Definitions.hpp" #include "Services/RealTimeForwardingControlService.hpp" +RealTimeForwardingControlService& realTimeForwarding = Services.realTimeForwarding; + uint8_t applications[] = {1}; uint8_t services[] = {3, 5}; +uint8_t allServices[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}; +uint8_t redundantServices[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17}; uint8_t messages1[] = {HousekeepingService::MessageType::HousekeepingPeriodicPropertiesReport, HousekeepingService::MessageType::DisablePeriodicHousekeepingParametersReport}; uint8_t messages2[] = {EventReportService::MessageType::InformativeEventReport, EventReportService::MessageType::DisabledListEventReport}; -RealTimeForwardingControlService& realTimeForwarding = Services.realTimeForwarding; - -void initialize(Message& request) { +void initializeValid(Message& request) { uint8_t numOfApplications = 1; uint8_t numOfServicesPerApp = 2; uint8_t numOfMessagesPerService = 2; @@ -52,20 +54,59 @@ void initialize(Message& request) { request.resetRead(); } +void initializeCombined(Message& request) { + uint8_t numOfApplications = 3; + uint8_t numOfMessagesPerService = 2; + + uint8_t applications2[] = {1, 2, 3}; + request.appendUint8(numOfApplications); + + for (uint8_t i = 0; i < numOfApplications; i++) { + request.appendUint8(applications2[i]); + uint8_t numOfServicesPerApp = (i == 0) ? 17 : 2; + uint8_t* servicesToPick = (i == 0) ? redundantServices : services; + request.appendUint8(numOfServicesPerApp); + + for (uint8_t j = 0; j < numOfServicesPerApp; j++) { + uint8_t serviceType = servicesToPick[j]; + request.appendUint8(serviceType); + request.appendUint8(numOfMessagesPerService); + uint8_t* messages = (j == 0) ? messages1 : messages2; + + for (uint8_t k = 0; k < numOfMessagesPerService; k++) { + request.appendUint8(messages[k]); + } + } + } + + // REQUIRE(request.readUint8() == 3); + // REQUIRE(request.readUint8() == 1); + // REQUIRE(request.readUint8() == 17); + // REQUIRE(request.readUint8() == 1); + // REQUIRE(request.readUint8() == 2); + // REQUIRE(request.readUint8() == HousekeepingService::MessageType::HousekeepingPeriodicPropertiesReport); + // REQUIRE(request.readUint8() == HousekeepingService::MessageType::DisablePeriodicHousekeepingParametersReport); + // REQUIRE(request.readUint8() == 5); + // REQUIRE(request.readUint8() == 2); + // REQUIRE(request.readUint8() == EventReportService::MessageType::InformativeEventReport); + // REQUIRE(request.readUint8() == EventReportService::MessageType::DisabledListEventReport); + // request.resetRead(); +} + void resetAppProcessConfiguration() { realTimeForwarding.applicationProcessConfiguration.definitions.clear(); REQUIRE(realTimeForwarding.applicationProcessConfiguration.definitions.empty()); } -TEST_CASE("Add report types to the application process configuration") { - SECTION("Successful addition of report types to the application process configuration") { +TEST_CASE("Add report types to the Application Process Configuration") { + SECTION("Successful addition of report types to the Application Process Configuration") { Message request(RealTimeForwardingControlService::ServiceType, RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, Message::TC, 1); uint8_t applicationID = 1; realTimeForwarding.controlledApplications.push_back(applicationID); - initialize(request); + initializeValid(request); MessageParser::execute(request); @@ -90,6 +131,208 @@ TEST_CASE("Add report types to the application process configuration") { } } } + + auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty; + REQUIRE(servicesAllowed[applicationID].size() == 2); + REQUIRE(servicesAllowed[applicationID][services[0]] == true); + REQUIRE(servicesAllowed[applicationID][services[1]] == true); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + + SECTION("Requested Application Process is not controlled by the service") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID = 1; + initializeValid(request); + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 1); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::NotControlledApplication) == 1); + REQUIRE(realTimeForwarding.applicationProcessConfiguration.definitions.empty()); + REQUIRE(realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID].empty()); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + + SECTION("All service types already allowed") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID = 1; + realTimeForwarding.controlledApplications.push_back(applicationID); + initializeValid(request); + + realTimeForwarding.applicationProcessConfiguration.definitions[applicationID].clear(); + CHECK(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID].empty()); + realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID][services[0]] = true; + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 1); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::AllServiceTypesAlreadyAllowed) == + 1); + REQUIRE(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID].empty()); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + + SECTION("Max service types already reached") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID = 1; + realTimeForwarding.controlledApplications.push_back(applicationID); + initializeValid(request); + + auto& applicationProcessConfig = realTimeForwarding.applicationProcessConfiguration; + + for (auto service : allServices) { + applicationProcessConfig.definitions[applicationID][service].clear(); + applicationProcessConfig.serviceNotEmpty[applicationID][service] = true; + } + REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 15); + REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 15); + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 2); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::MaxServiceTypesReached) == 2); + REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 15); + REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 15); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + + SECTION("All report types already allowed") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID = 1; + uint8_t serviceType = services[0]; + realTimeForwarding.controlledApplications.push_back(applicationID); + initializeValid(request); + + realTimeForwarding.applicationProcessConfiguration.definitions[applicationID][serviceType].clear(); + CHECK(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID][serviceType].empty()); + realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID][serviceType] = true; + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 1); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::AllReportTypesAlreadyAllowed) == + 1); + REQUIRE(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID].size() == 2); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + + SECTION("Max report types already reached") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID = 1; + uint8_t serviceType = services[0]; + realTimeForwarding.controlledApplications.push_back(applicationID); + initializeValid(request); + + auto& applicationProcessConfig = realTimeForwarding.applicationProcessConfiguration; + + applicationProcessConfig.serviceNotEmpty[applicationID][serviceType] = true; + for (uint8_t i = 0; i < ECSSMaxReportTypeDefinitions; i++) { + applicationProcessConfig.definitions[applicationID][serviceType].push_back(i); + } + + REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 1); + REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 1); + REQUIRE(applicationProcessConfig.definitions[applicationID][serviceType].size() == + ECSSMaxReportTypeDefinitions); + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 2); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::MaxReportTypesReached) == 2); + REQUIRE(applicationProcessConfig.definitions[applicationID].size() == 2); + REQUIRE(applicationProcessConfig.serviceNotEmpty[applicationID].size() == 2); + REQUIRE(applicationProcessConfig.definitions[applicationID][services[1]].size() == 2); + REQUIRE(applicationProcessConfig.definitions[applicationID][serviceType].size() == + ECSSMaxReportTypeDefinitions); + + resetAppProcessConfiguration(); + ServiceTests::reset(); + Services.reset(); + } + + SECTION("Valid and invalid application-related requests combined") { + Message request(RealTimeForwardingControlService::ServiceType, + RealTimeForwardingControlService::MessageType::AddReportTypesToAppProcessConfiguration, + Message::TC, 1); + + uint8_t applicationID1 = 1; + uint8_t applicationID2 = 2; + uint8_t applicationID3 = 3; + realTimeForwarding.controlledApplications.push_back(applicationID1); + realTimeForwarding.controlledApplications.push_back(applicationID3); + initializeCombined(request); + + realTimeForwarding.applicationProcessConfiguration.definitions[applicationID3].clear(); + CHECK(realTimeForwarding.applicationProcessConfiguration.definitions[applicationID3].empty()); + realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty[applicationID3][services[0]] = true; + + MessageParser::execute(request); + + CHECK(ServiceTests::count() == 4); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::NotControlledApplication) == 1); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::MaxServiceTypesReached) == 2); + CHECK(ServiceTests::countThrownErrors(ErrorHandler::ExecutionStartErrorType::AllServiceTypesAlreadyAllowed) == + 1); + + auto& applicationProcesses = realTimeForwarding.applicationProcessConfiguration.definitions; + auto& servicesAllowed = realTimeForwarding.applicationProcessConfiguration.serviceNotEmpty; + + REQUIRE(applicationProcesses.size() == 2); + REQUIRE(applicationProcesses.find(applicationID2) == applicationProcesses.end()); + REQUIRE(applicationProcesses.find(applicationID1) != applicationProcesses.end()); + REQUIRE(applicationProcesses.find(applicationID3) != applicationProcesses.end()); + + REQUIRE(applicationProcesses[applicationID1].size() == 15); + REQUIRE(servicesAllowed[applicationID1].size() == 15); + for (auto serviceType : allServices) { + REQUIRE(servicesAllowed[applicationID1][serviceType]); + } + REQUIRE(applicationProcesses[applicationID3].empty()); + + for (auto& serviceType : applicationProcesses[applicationID1]) { + REQUIRE(std::find(std::begin(allServices), std::end(allServices), serviceType.first) != + std::end(allServices)); + REQUIRE(serviceType.second.size() == 2); + auto& messagesToCheck = (serviceType.first == 1) ? messages1 : messages2; + for (auto message : serviceType.second) { + REQUIRE(std::find(std::begin(messagesToCheck), std::end(messagesToCheck), message) != + std::end(messagesToCheck)); + } + } + + REQUIRE(servicesAllowed[applicationID3].size() == 1); + REQUIRE(servicesAllowed[applicationID3][services[0]] == true); + resetAppProcessConfiguration(); ServiceTests::reset(); Services.reset(); -- GitLab