fsfw/tests/src/fsfw_tests/internal/osal/testSemaphore.cpp
Robin Mueller ade15ad16d
tests can now be built as part of FSFW
This PR refactores the tests so they are built as part of the FSFW.
This is done by adding Catch2 with the FetchContent directive.

A future implementation might also use a system installation of Catch2
by first checking whether Catch2 can already be found as a package

The custom configuration folder testcfg was moved from the user folder
to the actual unittest folder.

The tests can be built by setting the CMake FSFW_BUILD_UNITTESTS option
to TRUE/ON. They are built with the static library and dropped inside
the build folders fsfw directory.
2021-10-07 13:24:46 +02:00

166 lines
4.6 KiB
C++

#include "fsfw/FSFW.h"
#include "testSemaphore.h"
#include "fsfw_tests/internal/UnittDefinitions.h"
#include "fsfw/tasks/SemaphoreFactory.h"
#include "fsfw/serviceinterface/ServiceInterface.h"
#include "fsfw/timemanager/Stopwatch.h"
#include <cstdlib>
void testsemaph::testBinSemaph() {
std::string id = "[BinSemaphore]";
SemaphoreIF* binSemaph =
SemaphoreFactory::instance()->createBinarySemaphore();
if(binSemaph == nullptr) {
return;
}
testBinSemaphoreImplementation(binSemaph, id);
SemaphoreFactory::instance()->deleteSemaphore(binSemaph);
#if defined FSFW_OSAL_FREERTOS
SemaphoreIF* binSemaphUsingTask =
SemaphoreFactory::instance()->createBinarySemaphore(1);
testBinSemaphoreImplementation(binSemaphUsingTask, id);
SemaphoreFactory::instance()->deleteSemaphore(binSemaphUsingTask);
#endif
}
void testsemaph::testCountingSemaph() {
std::string id = "[CountingSemaph]";
{
// First test: create a binary semaphore by using a counting semaphore.
SemaphoreIF* countingSemaph = SemaphoreFactory::instance()->
createCountingSemaphore(1,1);
if(countingSemaph == nullptr) {
return;
}
testBinSemaphoreImplementation(countingSemaph, id);
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
#if defined FSFW_OSAL_FREERTOS
countingSemaph = SemaphoreFactory::instance()->
createCountingSemaphore(1, 1, 1);
testBinSemaphoreImplementation(countingSemaph, id);
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
#endif
}
{
// Second test: counting semaphore with count 3 and init count of 3.
SemaphoreIF* countingSemaph = SemaphoreFactory::instance()->
createCountingSemaphore(3,3);
testCountingSemaphImplementation(countingSemaph, id);
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
#if defined FSFW_OSAL_FREERTOS
countingSemaph = SemaphoreFactory::instance()->
createCountingSemaphore(3, 0, 1);
uint8_t semaphCount = countingSemaph->getSemaphoreCounter();
if(semaphCount != 0) {
unitt::put_error(id);
}
// release 3 times in a row
for(int i = 0; i < 3; i++) {
auto result = countingSemaph->release();
if(result != HasReturnvaluesIF::RETURN_OK) {
unitt::put_error(id);
}
}
testCountingSemaphImplementation(countingSemaph, id);
SemaphoreFactory::instance()->deleteSemaphore(countingSemaph);
#endif
}
}
void testsemaph::testBinSemaphoreImplementation(SemaphoreIF* binSemaph,
std::string id) {
uint8_t semaphCount = binSemaph->getSemaphoreCounter();
if(semaphCount != 1) {
unitt::put_error(id);
}
ReturnValue_t result = binSemaph->release();
if(result != SemaphoreIF::SEMAPHORE_NOT_OWNED) {
unitt::put_error(id);
}
result = binSemaph->acquire(SemaphoreIF::BLOCKING);
if(result != HasReturnvaluesIF::RETURN_OK) {
unitt::put_error(id);
}
// There is not really a point in testing time related, the task
// might get interrupted..
{
//Stopwatch stopwatch(false);
result = binSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 10);
//dur_millis_t time = stopwatch.stop();
// if(abs(time - 10) > 2) {
#if FSFW_CPP_OSTREAM_ENABLED == 1
// sif::error << "UnitTester: Semaphore timeout measured incorrect."
// << std::endl;
#endif
// unitt::put_error(id);
// }
}
if(result != SemaphoreIF::SEMAPHORE_TIMEOUT) {
unitt::put_error(id);
}
semaphCount = binSemaph->getSemaphoreCounter();
if(semaphCount != 0) {
unitt::put_error(id);
}
result = binSemaph->release();
if(result != HasReturnvaluesIF::RETURN_OK) {
unitt::put_error(id);
}
}
void testsemaph::testCountingSemaphImplementation(SemaphoreIF* countingSemaph,
std::string id) {
// check count getter function
uint8_t semaphCount = countingSemaph->getSemaphoreCounter();
if(semaphCount != 3) {
unitt::put_error(id);
}
ReturnValue_t result = countingSemaph->release();
if(result != SemaphoreIF::SEMAPHORE_NOT_OWNED) {
unitt::put_error(id);
}
// acquire 3 times in a row
for(int i = 0; i < 3; i++) {
result = countingSemaph->acquire(SemaphoreIF::BLOCKING);
if(result != HasReturnvaluesIF::RETURN_OK) {
unitt::put_error(id);
}
}
{
Stopwatch stopwatch(false);
// attempt to take when count is 0, measure time
result = countingSemaph->acquire(SemaphoreIF::TimeoutType::WAITING, 10);
dur_millis_t time = stopwatch.stop();
if(std::abs(static_cast<int32_t>(time - 10)) > 1) {
unitt::put_error(id);
}
}
if(result != SemaphoreIF::SEMAPHORE_TIMEOUT) {
unitt::put_error(id);
}
// release 3 times in a row
for(int i = 0; i < 3; i++) {
result = countingSemaph->release();
if(result != HasReturnvaluesIF::RETURN_OK) {
unitt::put_error(id);
}
}
// assert correct full count
if(countingSemaph->getSemaphoreCounter() != 3) {
unitt::put_error(id);
}
}