1
0
forked from fsfw/fsfw

Merge remote-tracking branch 'origin/development' into mohr_introspection

This commit is contained in:
2023-06-01 15:08:03 +02:00
960 changed files with 18471 additions and 12457 deletions

View File

@ -0,0 +1 @@
target_sources(${FSFW_TEST_TGT} PRIVATE TestActionHelper.cpp)

View File

@ -0,0 +1,108 @@
#include "TestActionHelper.h"
#include <fsfw/action/ActionHelper.h>
#include <fsfw/ipc/CommandMessage.h>
#include <array>
#include <catch2/catch_test_macros.hpp>
#include "mocks/MessageQueueMock.h"
TEST_CASE("Action Helper", "[ActionHelper]") {
MessageQueueMockBase testMqMock;
ActionHelperOwnerMockBase testDhMock(&testMqMock);
CommandMessage actionMessage;
ActionId_t testActionId = (ActionId_t) TestActions::TEST_ACTION;
std::array<uint8_t, 3> testParams{1, 2, 3};
store_address_t paramAddress;
StorageManagerIF* ipcStore = tglob::getIpcStoreHandle();
REQUIRE(ipcStore != nullptr);
ipcStore->addData(&paramAddress, testParams.data(), 3);
REQUIRE(testDhMock.getActionHelper()->initialize() == returnvalue::OK);
SECTION("Simple tests") {
ActionMessage::setCommand(&actionMessage, testActionId, paramAddress);
CHECK(not testDhMock.executeActionCalled);
REQUIRE(testDhMock.getActionHelper()->handleActionMessage(&actionMessage) == retval::CATCH_OK);
CHECK(testDhMock.executeActionCalled);
// No message is sent if everything is alright.
CHECK(not testMqMock.wasMessageSent());
store_address_t invalidAddress;
ActionMessage::setCommand(&actionMessage, testActionId, invalidAddress);
testDhMock.getActionHelper()->handleActionMessage(&actionMessage);
CHECK(testMqMock.wasMessageSent());
const uint8_t* ptr = nullptr;
size_t size = 0;
REQUIRE(ipcStore->getData(paramAddress, &ptr, &size) ==
static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
REQUIRE(ptr == nullptr);
testDhMock.getBuffer(&ptr);
for (uint8_t i = 0; i < 3; i++) {
REQUIRE(ptr[i] == (i + 1));
}
testDhMock.clearBuffer();
}
SECTION("Handle failures") {
actionMessage.setCommand(1234);
REQUIRE(testDhMock.getActionHelper()->handleActionMessage(&actionMessage) ==
static_cast<uint32_t>(CommandMessage::UNKNOWN_COMMAND));
CHECK(not testMqMock.wasMessageSent());
uint16_t step = 5;
ReturnValue_t status = 0x1234;
testDhMock.getActionHelper()->step(step, testMqMock.getId(), testActionId, status);
step += 1;
CHECK(testMqMock.wasMessageSent());
CommandMessage testMessage;
REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK);
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
REQUIRE(testMessage.getParameter() == static_cast<uint32_t>(testActionId));
uint32_t parameter2 = ((uint32_t)step << 16) | (uint32_t)status;
REQUIRE(testMessage.getParameter2() == parameter2);
REQUIRE(ActionMessage::getStep(&testMessage) == step);
}
SECTION("Handle finish") {
CHECK(not testMqMock.wasMessageSent());
ReturnValue_t status = 0x9876;
testDhMock.getActionHelper()->finish(false, testMqMock.getId(), testActionId, status);
CHECK(testMqMock.wasMessageSent());
CommandMessage testMessage;
REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK);
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::COMPLETION_FAILED));
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
REQUIRE(ActionMessage::getReturnCode(&testMessage) == static_cast<uint32_t>(status));
}
SECTION("Handle failed") {
store_address_t toLongParamAddress = store_address_t::invalid();
std::array<uint8_t, 5> toLongData = {5, 4, 3, 2, 1};
REQUIRE(ipcStore->addData(&toLongParamAddress, toLongData.data(), 5) == returnvalue::OK);
ActionMessage::setCommand(&actionMessage, testActionId, toLongParamAddress);
CHECK(not testDhMock.executeActionCalled);
REQUIRE(testDhMock.getActionHelper()->handleActionMessage(&actionMessage) == returnvalue::OK);
REQUIRE(ipcStore->getData(toLongParamAddress).first ==
static_cast<uint32_t>(StorageManagerIF::DATA_DOES_NOT_EXIST));
CommandMessage testMessage;
REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK);
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
REQUIRE(ActionMessage::getReturnCode(&testMessage) == HasActionsIF::INVALID_PARAMETERS);
REQUIRE(ActionMessage::getStep(&testMessage) == 0);
REQUIRE(ActionMessage::getActionId(&testMessage) == testActionId);
}
SECTION("Missing IPC Data") {
ActionMessage::setCommand(&actionMessage, testActionId, store_address_t::invalid());
CHECK(not testDhMock.executeActionCalled);
REQUIRE(testDhMock.getActionHelper()->handleActionMessage(&actionMessage) == returnvalue::OK);
CommandMessage testMessage;
REQUIRE(testMqMock.getNextSentMessage(testMessage) == returnvalue::OK);
REQUIRE(testMessage.getCommand() == static_cast<uint32_t>(ActionMessage::STEP_FAILED));
REQUIRE(ActionMessage::getReturnCode(&testMessage) ==
static_cast<uint32_t>(StorageManagerIF::ILLEGAL_STORAGE_ID));
REQUIRE(ActionMessage::getStep(&testMessage) == 0);
}
SECTION("Data Reply") {}
}

View File

@ -0,0 +1,75 @@
#ifndef UNITTEST_HOSTED_TESTACTIONHELPER_H_
#define UNITTEST_HOSTED_TESTACTIONHELPER_H_
#include <fsfw/action/HasActionsIF.h>
#include <fsfw/action/Parameter.h>
#include <fsfw/action/TemplateAction.h>
#include <fsfw/introspection/Enum.h>
#include <fsfw/ipc/MessageQueueIF.h>
#include <cstring>
#include "CatchDefinitions.h"
class ActionHelperOwnerMockBase;
FSFW_ENUM(TestActions, ActionId_t, ((TEST_ACTION, "Test Action")))
class TestAction : public TemplateAction < ActionHelperOwnerMockBase, TestAction, TestActions> {
public:
TestAction(ActionHelperOwnerMockBase* owner) : TemplateAction(owner, TestActions::TEST_ACTION) {}
Parameter<uint8_t> p1 = Parameter<uint8_t>::createParameter(this, "An uint8_t");
Parameter<uint8_t> p2 = Parameter<uint8_t>::createParameter(this, "An uint8_t");
Parameter<uint8_t> p3 = Parameter<uint8_t>::createParameter(this, "An uint8_t");
};
class ActionHelperOwnerMockBase : public HasActionsIF {
public:
bool getCommandQueueCalled = false;
bool executeActionCalled = false;
static const size_t MAX_SIZE = 3;
uint8_t buffer[MAX_SIZE] = {0, 0, 0};
size_t size = 0;
ActionHelperOwnerMockBase(MessageQueueIF* useThisQueue) : actionHelper(this, useThisQueue) {}
MessageQueueId_t getCommandQueue() const override { return tconst::testQueueId; }
ActionHelper* getActionHelper() override { return &actionHelper; }
ReturnValue_t executeAction(Action* action) override {
executeActionCalled = true;
if (size > MAX_SIZE) {
return 0xAFFE;
}
this->size = size;
return action->handle();
}
ReturnValue_t handleAction(TestAction *action){
executeActionCalled = true;
buffer[0] = action->p1;
buffer[1] = action->p2;
buffer[2] = action->p3;
return returnvalue::OK;
}
void clearBuffer() {
this->size = 0;
for (size_t i = 0; i < MAX_SIZE; i++) {
buffer[i] = 0;
}
}
void getBuffer(const uint8_t** ptr) {
if (ptr != nullptr) {
*ptr = buffer;
}
}
private:
ActionHelper actionHelper;
TestAction testAction = TestAction(this);
};
#endif /* UNITTEST_TESTFW_NEWTESTS_TESTACTIONHELPER_H_ */