unittest now contained directly

This commit is contained in:
Robin Müller 2020-10-20 17:11:23 +02:00
parent c677358343
commit 865ea3386c
78 changed files with 22684 additions and 4 deletions

3
.gitmodules vendored
View File

@ -1,3 +0,0 @@
[submodule "unittest"]
path = unittest
url = https://egit.irs.uni-stuttgart.de/fsfw/fsfw_tests.git

@ -1 +0,0 @@
Subproject commit 76cbb97ae410a7440d2b71eaecd4eea4a5cccaf3

View File

@ -0,0 +1,415 @@
#-------------------------------------------------------------------------------
# Makefile for FSFW Test
#-------------------------------------------------------------------------------
# User-modifiable options
#-------------------------------------------------------------------------------
# Fundamentals on the build process of C/C++ Software:
# https://www3.ntu.edu.sg/home/ehchua/programming/cpp/gcc_make.html
# Make documentation: https://www.gnu.org/software/make/manual/make.pdf
# Online: https://www.gnu.org/software/make/manual/make.html
# General rules: http://make.mad-scientist.net/papers/rules-of-makefiles/#rule3
SHELL = /bin/sh
# Chip & board used for compilation
# (can be overriden by adding CHIP=chip and BOARD=board to the command-line)
# Unit Test can only be run on host machine for now (Linux)
FRAMEWORK_PATH = fsfw
FILE_ROOT = $(FRAMEWORK_PATH)/unittest
BOARD = unittest
LINUX = 1
OS_FSFW = linux
CUSTOM_DEFINES += -D$(OS_FSFW)
# Copied from stackoverflow, can be used to differentiate between Windows
# and Linux
ifeq ($(OS),Windows_NT)
CUSTOM_DEFINES += -DWIN32
ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
CUSTOM_DEFINES += -DAMD64
else
ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
CUSTOM_DEFINES += -DAMD64
endif
ifeq ($(PROCESSOR_ARCHITECTURE),x86)
CUSTOM_DEFINES += -DIA32
endif
endif
else
UNAME_S := $(shell uname -s)
ifeq ($(UNAME_S),Linux)
DETECTED_OS = LINUX
CUSTOM_DEFINES += -DLINUX
endif
ifeq ($(UNAME_S),Darwin)
CUSTOM_DEFINES += -DOSX
endif
UNAME_P := $(shell uname -p)
ifeq ($(UNAME_P),x86_64)
CUSTOM_DEFINES += -DAMD64
endif
ifneq ($(filter %86,$(UNAME_P)),)
CUSTOM_DEFINES += -DIA32
endif
ifneq ($(filter arm%,$(UNAME_P)),)
CUSTOM_DEFINES += -DARM
endif
endif
UNIT_TEST = 1
# General folder paths
CONFIG_PATH = $(FILE_ROOT)/config
UNIT_TEST_PATH = $(FILE_ROOT)/tests
CORE_PATH = $(FILE_ROOT)/core
# Output file basename
BASENAME = fsfw
BINARY_NAME := $(BASENAME)-$(BOARD)
# Output files will be put in this directory inside
OUTPUT_FOLDER = $(OS)
# Optimization level. Optimized for debugging.
OPTIMIZATION = -O0
# Default debug output. Optimized for debugging.
DEBUG_LEVEL = -g3
ifdef GCOV
CUSTOM_DEFINES += -DGCOV
endif
# Output directories
BUILDPATH = _bin
DEPENDPATH = _dep
OBJECTPATH = _obj
ifeq ($(MAKECMDGOALS),mission)
BUILD_FOLDER = mission
else
BUILD_FOLDER = devel
endif
DEPENDDIR = $(DEPENDPATH)/$(OUTPUT_FOLDER)/$(BUILD_FOLDER)
OBJDIR = $(OBJECTPATH)/$(OUTPUT_FOLDER)/$(BUILD_FOLDER)
BINDIR = $(BUILDPATH)
CLEANDEP = $(DEPENDPATH)/$(OUTPUT_FOLDER)
CLEANOBJ = $(OBJECTPATH)/$(OUTPUT_FOLDER)
CLEANBIN = $(BUILDPATH)
#-------------------------------------------------------------------------------
# Tools and Includes
#-------------------------------------------------------------------------------
# Tool suffix when cross-compiling
CROSS_COMPILE =
# C Compiler
CC = $(CROSS_COMPILE)gcc
# C++ compiler
CXX = $(CROSS_COMPILE)g++
# Additional Tools
SIZE = $(CROSS_COMPILE)size
STRIP = $(CROSS_COMPILE)strip
CP = $(CROSS_COMPILE)objcopy
HEXCOPY = $(CP) -O ihex
BINCOPY = $(CP) -O binary
# files to be compiled, will be filled in by include makefiles
# := assignment is neccessary so we get all paths right
# https://www.gnu.org/software/make/manual/html_node/Flavors.html
CSRC :=
CXXSRC :=
ASRC :=
INCLUDES :=
# Directories where $(directoryname).mk files should be included from
SUBDIRS := $(FRAMEWORK_PATH) $(TEST_PATH) $(UNIT_TEST_PATH) $(CONFIG_PATH) \
$(CORE_PATH)
I_INCLUDES += $(addprefix -I, $(INCLUDES))
# This is a hack from http://make.mad-scientist.net/the-eval-function/
#
# The problem is, that included makefiles should be aware of their relative path
# but not need to guess or hardcode it. So we set $(CURRENTPATH) for them. If
# we do this globally and the included makefiles want to include other makefiles as
# well, they would overwrite $(CURRENTPATH), screwing the include after them.
#
# By using a for-loop with an eval'd macro, we can generate the code to include all
# sub-makefiles (with the correct $(CURRENTPATH) set) before actually evaluating
# (and by this possibly changing $(CURRENTPATH)) them.
#
# This works recursively, if an included makefile wants to include, it can safely set
# $(SUBDIRS) (which has already been evaluated here) and do
# "$(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))"
# $(SUBDIRS) must be relative to the project root, so to include subdir foo, set
# $(SUBDIRS) = $(CURRENTPATH)/foo.
define INCLUDE_FILE
CURRENTPATH := $S
include $(S)/$(notdir $S).mk
endef
$(foreach S,$(SUBDIRS),$(eval $(INCLUDE_FILE)))
INCLUDES += $(FILE_ROOT)
INCLUDES += $(FILE_ROOT)/catch2/
#-------------------------------------------------------------------------------
# Source Files
#-------------------------------------------------------------------------------
# All source files which are not includes by the .mk files are added here
# Please ensure that no files are included by both .mk file and here !
# if a target is not listed in the current directory,
# make searches in the directories specified with VPATH
# All C Sources included by .mk files are assigned here
# Add the objects to sources so dependency handling works
C_OBJECTS += $(CSRC:.c=.o)
# Objects built from Assembly source files
ASM_OBJECTS = $(ASRC:.S=.o)
# Objects built from C++ source files
CXX_OBJECTS += $(CXXSRC:.cpp=.o)
#-------------------------------------------------------------------------------
# Build Configuration + Output
#-------------------------------------------------------------------------------
TARGET = Debug build.
DEBUG_MESSAGE = Off
OPTIMIZATION_MESSAGE = Off
# Define Messages
MSG_INFO = Software: Hosted unittest \(Catch2\) for the FSFW.
MSG_OPTIMIZATION = Optimization: $(OPTIMIZATION), $(OPTIMIZATION_MESSAGE)
MSG_TARGET = Target Build: $(TARGET)
MSG_DEBUG = Debug level: $(DEBUG_LEVEL), FSFW Debugging: $(DEBUG_MESSAGE)
MSG_LINKING = Linking:
MSG_COMPILING = Compiling:
MSG_ASSEMBLING = Assembling:
MSG_DEPENDENCY = Collecting dependencies for:
MSG_BINARY = Generate binary:
# See https://stackoverflow.com/questions/6687630/how-to-remove-unused-c-c-symbols-with-gcc-and-ld
# Used to throw away unused code. Reduces code size significantly !
# -Wl,--gc-sections: needs to be passed to the linker to throw aways unused code
ifdef KEEP_UNUSED_CODE
PROTOTYPE_OPTIMIZATION =
UNUSED_CODE_REMOVAL =
else
PROTOTYPE_OPTIMIZATION = -ffunction-sections -fdata-sections
UNUSED_CODE_REMOVAL = -Wl,--gc-sections
# Link time optimization
# See https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html for reference
# Link time is larger and size of object files can not be retrieved
# but resulting binary is smaller. Could be used in mission/deployment build
# Requires -ffunction-section in linker call
LINK_TIME_OPTIMIZATION = -flto
OPTIMIZATION += $(PROTOTYPE_OPTIMIZATION)
endif
# Dependency Flags
# These flags tell the compiler to build dependencies
# See: https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html
# Using following guide: http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/#combine
DEPFLAGS = -MT $@ -MMD -MP -MF $(DEPENDDIR)/$*.d
# Flags for the compiler call
# - std: Which C++ version to use. Common versions: c++11, c++14 and c++17
# - Wall: enable all warnings
# - Wextra: enable extra warnings
# - g: defines debug level
# - fmessage-length: to control the formatting algorithm for diagnostic messages;
# =0 means no line-wrapping is done; each error message appears on a single line
# - fno-exceptions: stops generating extra code needed to propagate exceptions,
# which can produce significant data size overhead
CUSTOM_DEFINES += -DUNIT_TEST
WARNING_FLAGS = -Wall -Wshadow=local -Wextra -Wimplicit-fallthrough=1 \
-Wno-unused-parameter
CXXDEFINES := $(CUSTOM_DEFINES)
CFLAGS +=
CXXFLAGS += -I. $(DEBUG_LEVEL) $(WARNING_FLAGS) $(DEPFLAGS) -fmessage-length=0 $(OPTIMIZATION)\
$(I_INCLUDES) $(CXXDEFINES)
CPPFLAGS += -std=c++11
# Flags for the linker call
# LINK_INCLUDES specify the path to used libraries and the linker script
# LINK_LIBRARIES: Link real time support
LDFLAGS := $(DEBUG_LEVEL) $(UNUSED_CODE_REMOVAL) $(OPTIMIZATION) -pthread
LINK_INCLUDES :=
LINK_LIBRARIES :=
ifdef LINUX
LINK_LIBRARIES += -lrt
endif
ifeq ($(OS),Windows_NT)
LINK_LIBRARIES += -lwsock32 -lws2_32
LDFLASGS += -fuse-ld=lld
endif
# Gnu Coverage Tools Flags
ifdef GCOV
GCOV_CXXFLAGS = -fprofile-arcs -ftest-coverage --coverage -fno-inline \
-fno-inline-small-functions -fno-default-inline
CXXFLAGS += $(GCOV_CXXFLAGS)
GCOV_LINKER_LIBS = -lgcov -fprofile-arcs -ftest-coverage
LINK_LIBRARIES += $(GCOV_LINKER_LIBS)
endif
# $(info $${CXXFLAGS} is [${CXXFLAGS}])
#-------------------------------------------------------------------------------
# Rules
#-------------------------------------------------------------------------------
# the call function assigns parameters to temporary variables
# https://www.gnu.org/software/make/manual/make.html#Call-Function
# $(1) = Memory names
# Rules are called for each memory type
# Two Expansion Symbols $$ are to escape the dollar sign for eval.
# See: http://make.mad-scientist.net/the-eval-function/
default: all
# Cleans all files
hardclean:
-rm -rf $(BUILDPATH)
-rm -rf $(OBJECTPATH)
-rm -rf $(DEPENDPATH)
# Only clean files for current build
clean:
-rm -rf $(CLEANOBJ)
-rm -rf $(CLEANBIN)
-rm -rf $(CLEANDEP)
# Only clean binaries. Useful for changing the binary type when object files
# are already compiled so complete rebuild is not necessary
cleanbin:
-rm -rf $(CLEANBIN)
# In this section, the binaries are built for all selected memories
# notestfw: all
all: executable
# Build target configuration
release: OPTIMIZATION = -Os $(PROTOTYPE_OPTIMIZATION) $(LINK_TIME_OPTIMIZATION)
release: LINK_TIME_OPTIMIZATION = -flto
release: TARGET = Mission build.
release: OPTIMIZATION_MESSAGE = On with Link Time Optimization
debug: CXXDEFINES += -DDEBUG
debug: TARGET = Debug
debug: DEBUG_MESSAGE = On
ifndef KEEP_UNUSED_CODE
debug release: OPTIMIZATION_MESSAGE += , no unused code removal
endif
debug release notestfw: executable
executable: $(BINDIR)/$(BINARY_NAME).elf
@echo
@echo $(MSG_INFO)
@echo $(MSG_TARGET)
@echo $(MSG_OPTIMIZATION)
@echo $(MSG_DEBUG)
C_OBJECTS_PREFIXED = $(addprefix $(OBJDIR)/, $(C_OBJECTS))
CXX_OBJECTS_PREFIXED = $(addprefix $(OBJDIR)/, $(CXX_OBJECTS))
ASM_OBJECTS_PREFIXED = $(addprefix $(OBJDIR)/, $(ASM_OBJECTS))
ALL_OBJECTS = $(ASM_OBJECTS_PREFIXED) $(C_OBJECTS_PREFIXED) \
$(CXX_OBJECTS_PREFIXED)
# Useful for debugging the Makefile
# Also see: https://www.oreilly.com/openbook/make3/book/ch12.pdf
# $(info $${ALL_OBJECTS} is [${ALL_OBJECTS}])
# $(info $${CXXSRC} is [${CXXSRC}])
# Automatic variables are used here extensively. Some of them
# are escaped($$) to suppress immediate evaluation. The most important ones are:
# $@: Name of Target (left side of rule)
# $<: Name of the first prerequisite (right side of rule)
# @^: List of all prerequisite, omitting duplicates
# @D: Directory and file-within-directory part of $@
# Generates binary and displays all build properties
# -p with mkdir ignores error and creates directory when needed.
# SHOW_DETAILS = 1
# Link with required libraries: HAL (Hardware Abstraction Layer) and
# HCC (File System Library)
$(BINDIR)/$(BINARY_NAME).elf: $(ALL_OBJECTS)
@echo
@echo $(MSG_LINKING) Target $@
@mkdir -p $(@D)
ifdef SHOW_DETAILS
$(CXX) $(LDFLAGS) $(LINK_INCLUDES) -o $@ $^ $(LINK_LIBRARIES)
else
@$(CXX) $(LDFLAGS) $(LINK_INCLUDES) -o $@ $^ $(LINK_LIBRARIES)
endif
ifeq ($(BUILD_FOLDER), mission)
# With Link Time Optimization, section size is not available
$(SIZE) $@
else
$(SIZE) $^ $@
endif
$(BINDIR)/$(BINARY_NAME).hex: $(BINDIR)/$(BINARY_NAME).elf
@echo
@echo $(MSG_BINARY)
@mkdir -p $(@D)
$(HEXCOPY) $< $@
# Build new objects for changed dependencies.
$(OBJDIR)/%.o: %.cpp
$(OBJDIR)/%.o: %.cpp $(DEPENDDIR)/%.d | $(DEPENDDIR)
@echo
@echo $(MSG_COMPILING) $<
@mkdir -p $(@D)
ifdef SHOW_DETAILS
$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
else
@$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c -o $@ $<
endif
$(OBJDIR)/%.o: %.c
$(OBJDIR)/%.o: %.c $(DEPENDDIR)/%.d | $(DEPENDDIR)
@echo
@echo $(MSG_COMPILING) $<
@mkdir -p $(@D)
ifdef SHOW_DETAILS
$(CC) $(CXXFLAGS) $(CFLAGS) -c -o $@ $<
else
@$(CC) $(CXXFLAGS) $(CFLAGS) -c -o $@ $<
endif
#-------------------------------------------------------------------------------
# Dependency Handling
#-------------------------------------------------------------------------------
# Dependency Handling according to following guide:
# http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/
$(DEPENDDIR):
@mkdir -p $(@D)
DEPENDENCY_RELATIVE = $(CSRC:.c=.d) $(CXXSRC:.cpp=.d)
# This is the list of all dependencies
DEPFILES = $(addprefix $(DEPENDDIR)/, $(DEPENDENCY_RELATIVE))
# Create subdirectories for dependencies
$(DEPFILES):
@mkdir -p $(@D)
# Include all dependencies
include $(wildcard $(DEPFILES))
# .PHONY tells make that these targets aren't files
.PHONY: clean release debug all hardclean cleanbin

121
unittest/README.md Normal file
View File

@ -0,0 +1,121 @@
## FSFW Testing
This repository contains testing and unit testing components.
[Catch2](https://github.com/catchorg/Catch2) has been used as a framework,
and these unit tests can only be run on a linux host machine.
The makefile with default settings creates the unit test binary which can be
run in the terminal or in eclipse.
### Instructions
Basic steps:
1. Clone this branch
```sh
git clone https://egit.irs.uni-stuttgart.de/fsfw/fsfw_tests.git
```
2. Inititate the framework submodule (need to only be done once)
```sh
git submodule init
git submodule sync
git submodule update
```
2. Run the makefile With
```sh
make all -j<Number Of Processors>
```
This will build the debug version of the unit tests.
The release version can be built with the target `release`
4. Run the binary located in the \_bin folder in the terminal or in eclipse.
```sh
_bin/<binaryName>.elf [--success]
```
The success parameter is optional. Leaving it out ommits the success messages.
5. To clear the binary, object and dependency folder, run
```sh
make clean
```
Please note that on most UNIX environments (e.g. Ubuntu), the real time functionalities used by the UNIX pthread module are restricted, which will lead to permission errors when creating these tasks.
To solve this issues, try following steps:
1. Edit the /etc/security/limits.conf
file and add following lines at the end (worked on Ubuntu 19.10):
```sh
<username> hard rtprio 99
<username> soft rtprio 99
```
Then restart the computer. <br>
The soft limit can also be set in the console with `ulimit -Sr` if the hard
limit has been increased,
but it is recommended to add it to the file as well for convenience.
If adding the second line is not desired for security reasons,
the soft limit needs to be set for each session. If using an IDE like eclipse
in that case, the IDE needs to be started from the console after setting
the soft limit higher there.
2. Run the shell script inside the linux folder (worked on Ubuntu 18.04)
```sh
./unlockRealtime
```
This script executes the `setcap` command on bash and on the binaries.
It also increases the soft real time limit of the current shell instance
to the maximum. If running the script before executing the binary does
not help, try the following step.
### Eclipse CDT settings
The default eclipse terminal has issues displaying the colors used
when running the unit test binary by catch2. To fix this issue,
install the ANSI Escape In Console package from the eclipse marketplace.
### GCOV integration
GCOV has been integrated as a code coverage tool.
It can be enabled by adding `GCOV=1` to the build process as an additional argument.
Coverage data will be provided in form of .gcno and .gcda files.
These can be displayed in eclipse by looking
for a .gcno or .gcda file in the \_obj folder, double-clicking it
and picking the right source-binary. This will generate
information about which lines of a file have run, provided it is open in
eclipse.
### LCOV integration
The files generated by GCOV can also be processed by the tool LCOV.
On ubuntu, the tool can be installed with the following command:
```sh
sudo apt-get install lcov
````
After that, the tool can be run by building the unit tests with `GCOV=1`,
running them at least one time and then executing the `lcov.sh` script.
### Adding unit tests
The catch unit tests are located in unittest/testfw. To add new unit tests,
add them to the UnitTestCatch.cpp file or add a new source file which
includes catch.hpp.
For writing basics tests, the [assertion documentation](https://github.com/catchorg/Catch2/blob/master/docs/assertions.md#top)
or the existing examples are a good guideliens.
For more advanced tests, refer to the [catch2 documentation](https://github.com/catchorg/Catch2/blob/master/docs/Readme.md#top).
### Compile without test framework
Alternatively, the unit tests can also be run internally without
a framework. This can be used to perform unit tests on the real hardware.
To do this, run
```sh
make -j<Number Of Processors> notestfw
```
This will instruct the makefile to exclude the test framework main.cpp
and include our own. This will also create a binary which can be used
outside the host machine (a Makefile adaptions might be neccessary
if another OS than linux is required)

View File

@ -0,0 +1,23 @@
Boost Software License - Version 1.0 - August 17th, 2003
Permission is hereby granted, free of charge, to any person or organization
obtaining a copy of the software and accompanying documentation covered by
this license (the "Software") to use, reproduce, display, distribute,
execute, and transmit the Software, and to prepare derivative works of the
Software, and to permit third-parties to whom the Software is furnished to
do so, all subject to the following:
The copyright notices in the Software and this entire statement, including
the above license grant, this restriction and the following disclaimer,
must be included in all copies of the Software, in whole or in part, and
all derivative works of the Software, unless such copies or derivative
works are solely in the form of machine-executable object code generated by
a source language processor.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.

17618
unittest/catch2/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,62 @@
/*
* Created by Justin R. Wilson on 2/19/2017.
* Copyright 2017 Justin R. Wilson. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED
// Don't #include any Catch headers here - we can assume they are already
// included before this header.
// This is not good practice in general but is necessary in this case so this
// file can be distributed as a single header that works with the main
// Catch single header.
namespace Catch {
struct AutomakeReporter : StreamingReporterBase<AutomakeReporter> {
AutomakeReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config )
{}
~AutomakeReporter() override;
static std::string getDescription() {
return "Reports test results in the format of Automake .trs files";
}
void assertionStarting( AssertionInfo const& ) override {}
bool assertionEnded( AssertionStats const& /*_assertionStats*/ ) override { return true; }
void testCaseEnded( TestCaseStats const& _testCaseStats ) override {
// Possible values to emit are PASS, XFAIL, SKIP, FAIL, XPASS and ERROR.
stream << ":test-result: ";
if (_testCaseStats.totals.assertions.allPassed()) {
stream << "PASS";
} else if (_testCaseStats.totals.assertions.allOk()) {
stream << "XFAIL";
} else {
stream << "FAIL";
}
stream << ' ' << _testCaseStats.testInfo.name << '\n';
StreamingReporterBase::testCaseEnded( _testCaseStats );
}
void skipTest( TestCaseInfo const& testInfo ) override {
stream << ":test-result: SKIP " << testInfo.name << '\n';
}
};
#ifdef CATCH_IMPL
AutomakeReporter::~AutomakeReporter() {}
#endif
CATCH_REGISTER_REPORTER( "automake", AutomakeReporter)
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_AUTOMAKE_HPP_INCLUDED

View File

@ -0,0 +1,181 @@
/*
* Created by Daniel Garcia on 2018-12-04.
* Copyright Social Point SL. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
#define CATCH_REPORTER_SONARQUBE_HPP_INCLUDED
// Don't #include any Catch headers here - we can assume they are already
// included before this header.
// This is not good practice in general but is necessary in this case so this
// file can be distributed as a single header that works with the main
// Catch single header.
#include <map>
namespace Catch {
struct SonarQubeReporter : CumulativeReporterBase<SonarQubeReporter> {
SonarQubeReporter(ReporterConfig const& config)
: CumulativeReporterBase(config)
, xml(config.stream()) {
m_reporterPrefs.shouldRedirectStdOut = true;
m_reporterPrefs.shouldReportAllAssertions = true;
}
~SonarQubeReporter() override;
static std::string getDescription() {
return "Reports test results in the Generic Test Data SonarQube XML format";
}
static std::set<Verbosity> getSupportedVerbosities() {
return { Verbosity::Normal };
}
void noMatchingTestCases(std::string const& /*spec*/) override {}
void testRunStarting(TestRunInfo const& testRunInfo) override {
CumulativeReporterBase::testRunStarting(testRunInfo);
xml.startElement("testExecutions");
xml.writeAttribute("version", "1");
}
void testGroupEnded(TestGroupStats const& testGroupStats) override {
CumulativeReporterBase::testGroupEnded(testGroupStats);
writeGroup(*m_testGroups.back());
}
void testRunEndedCumulative() override {
xml.endElement();
}
void writeGroup(TestGroupNode const& groupNode) {
std::map<std::string, TestGroupNode::ChildNodes> testsPerFile;
for(auto const& child : groupNode.children)
testsPerFile[child->value.testInfo.lineInfo.file].push_back(child);
for(auto const& kv : testsPerFile)
writeTestFile(kv.first.c_str(), kv.second);
}
void writeTestFile(const char* filename, TestGroupNode::ChildNodes const& testCaseNodes) {
XmlWriter::ScopedElement e = xml.scopedElement("file");
xml.writeAttribute("path", filename);
for(auto const& child : testCaseNodes)
writeTestCase(*child);
}
void writeTestCase(TestCaseNode const& testCaseNode) {
// All test cases have exactly one section - which represents the
// test case itself. That section may have 0-n nested sections
assert(testCaseNode.children.size() == 1);
SectionNode const& rootSection = *testCaseNode.children.front();
writeSection("", rootSection, testCaseNode.value.testInfo.okToFail());
}
void writeSection(std::string const& rootName, SectionNode const& sectionNode, bool okToFail) {
std::string name = trim(sectionNode.stats.sectionInfo.name);
if(!rootName.empty())
name = rootName + '/' + name;
if(!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) {
XmlWriter::ScopedElement e = xml.scopedElement("testCase");
xml.writeAttribute("name", name);
xml.writeAttribute("duration", static_cast<long>(sectionNode.stats.durationInSeconds * 1000));
writeAssertions(sectionNode, okToFail);
}
for(auto const& childNode : sectionNode.childSections)
writeSection(name, *childNode, okToFail);
}
void writeAssertions(SectionNode const& sectionNode, bool okToFail) {
for(auto const& assertion : sectionNode.assertions)
writeAssertion( assertion, okToFail);
}
void writeAssertion(AssertionStats const& stats, bool okToFail) {
AssertionResult const& result = stats.assertionResult;
if(!result.isOk()) {
std::string elementName;
if(okToFail) {
elementName = "skipped";
}
else {
switch(result.getResultType()) {
case ResultWas::ThrewException:
case ResultWas::FatalErrorCondition:
elementName = "error";
break;
case ResultWas::ExplicitFailure:
elementName = "failure";
break;
case ResultWas::ExpressionFailed:
elementName = "failure";
break;
case ResultWas::DidntThrowException:
elementName = "failure";
break;
// We should never see these here:
case ResultWas::Info:
case ResultWas::Warning:
case ResultWas::Ok:
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
elementName = "internalError";
break;
}
}
XmlWriter::ScopedElement e = xml.scopedElement(elementName);
ReusableStringStream messageRss;
messageRss << result.getTestMacroName() << "(" << result.getExpression() << ")";
xml.writeAttribute("message", messageRss.str());
ReusableStringStream textRss;
if (stats.totals.assertions.total() > 0) {
textRss << "FAILED:\n";
if (result.hasExpression()) {
textRss << "\t" << result.getExpressionInMacro() << "\n";
}
if (result.hasExpandedExpression()) {
textRss << "with expansion:\n\t" << result.getExpandedExpression() << "\n";
}
}
if(!result.getMessage().empty())
textRss << result.getMessage() << "\n";
for(auto const& msg : stats.infoMessages)
if(msg.type == ResultWas::Info)
textRss << msg.message << "\n";
textRss << "at " << result.getSourceInfo();
xml.writeText(textRss.str(), XmlFormatting::Newline);
}
}
private:
XmlWriter xml;
};
#ifdef CATCH_IMPL
SonarQubeReporter::~SonarQubeReporter() {}
#endif
CATCH_REGISTER_REPORTER( "sonarqube", SonarQubeReporter )
} // end namespace Catch
#endif // CATCH_REPORTER_SONARQUBE_HPP_INCLUDED

View File

@ -0,0 +1,253 @@
/*
* Created by Colton Wolkins on 2015-08-15.
* Copyright 2015 Martin Moene. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED
// Don't #include any Catch headers here - we can assume they are already
// included before this header.
// This is not good practice in general but is necessary in this case so this
// file can be distributed as a single header that works with the main
// Catch single header.
#include <algorithm>
namespace Catch {
struct TAPReporter : StreamingReporterBase<TAPReporter> {
using StreamingReporterBase::StreamingReporterBase;
~TAPReporter() override;
static std::string getDescription() {
return "Reports test results in TAP format, suitable for test harnesses";
}
ReporterPreferences getPreferences() const override {
return m_reporterPrefs;
}
void noMatchingTestCases( std::string const& spec ) override {
stream << "# No test cases matched '" << spec << "'" << std::endl;
}
void assertionStarting( AssertionInfo const& ) override {}
bool assertionEnded( AssertionStats const& _assertionStats ) override {
++counter;
stream << "# " << currentTestCaseInfo->name << std::endl;
AssertionPrinter printer( stream, _assertionStats, counter );
printer.print();
stream << std::endl;
return true;
}
void testRunEnded( TestRunStats const& _testRunStats ) override {
printTotals( _testRunStats.totals );
stream << "\n" << std::endl;
StreamingReporterBase::testRunEnded( _testRunStats );
}
private:
std::size_t counter = 0;
class AssertionPrinter {
public:
AssertionPrinter& operator= ( AssertionPrinter const& ) = delete;
AssertionPrinter( AssertionPrinter const& ) = delete;
AssertionPrinter( std::ostream& _stream, AssertionStats const& _stats, std::size_t _counter )
: stream( _stream )
, result( _stats.assertionResult )
, messages( _stats.infoMessages )
, itMessage( _stats.infoMessages.begin() )
, printInfoMessages( true )
, counter(_counter)
{}
void print() {
itMessage = messages.begin();
switch( result.getResultType() ) {
case ResultWas::Ok:
printResultType( passedString() );
printOriginalExpression();
printReconstructedExpression();
if ( ! result.hasExpression() )
printRemainingMessages( Colour::None );
else
printRemainingMessages();
break;
case ResultWas::ExpressionFailed:
if (result.isOk()) {
printResultType(passedString());
} else {
printResultType(failedString());
}
printOriginalExpression();
printReconstructedExpression();
if (result.isOk()) {
printIssue(" # TODO");
}
printRemainingMessages();
break;
case ResultWas::ThrewException:
printResultType( failedString() );
printIssue( "unexpected exception with message:" );
printMessage();
printExpressionWas();
printRemainingMessages();
break;
case ResultWas::FatalErrorCondition:
printResultType( failedString() );
printIssue( "fatal error condition with message:" );
printMessage();
printExpressionWas();
printRemainingMessages();
break;
case ResultWas::DidntThrowException:
printResultType( failedString() );
printIssue( "expected exception, got none" );
printExpressionWas();
printRemainingMessages();
break;
case ResultWas::Info:
printResultType( "info" );
printMessage();
printRemainingMessages();
break;
case ResultWas::Warning:
printResultType( "warning" );
printMessage();
printRemainingMessages();
break;
case ResultWas::ExplicitFailure:
printResultType( failedString() );
printIssue( "explicitly" );
printRemainingMessages( Colour::None );
break;
// These cases are here to prevent compiler warnings
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
printResultType( "** internal error **" );
break;
}
}
private:
static Colour::Code dimColour() { return Colour::FileName; }
static const char* failedString() { return "not ok"; }
static const char* passedString() { return "ok"; }
void printSourceInfo() const {
Colour colourGuard( dimColour() );
stream << result.getSourceInfo() << ":";
}
void printResultType( std::string const& passOrFail ) const {
if( !passOrFail.empty() ) {
stream << passOrFail << ' ' << counter << " -";
}
}
void printIssue( std::string const& issue ) const {
stream << " " << issue;
}
void printExpressionWas() {
if( result.hasExpression() ) {
stream << ";";
{
Colour colour( dimColour() );
stream << " expression was:";
}
printOriginalExpression();
}
}
void printOriginalExpression() const {
if( result.hasExpression() ) {
stream << " " << result.getExpression();
}
}
void printReconstructedExpression() const {
if( result.hasExpandedExpression() ) {
{
Colour colour( dimColour() );
stream << " for: ";
}
std::string expr = result.getExpandedExpression();
std::replace( expr.begin(), expr.end(), '\n', ' ');
stream << expr;
}
}
void printMessage() {
if ( itMessage != messages.end() ) {
stream << " '" << itMessage->message << "'";
++itMessage;
}
}
void printRemainingMessages( Colour::Code colour = dimColour() ) {
if (itMessage == messages.end()) {
return;
}
// using messages.end() directly (or auto) yields compilation error:
std::vector<MessageInfo>::const_iterator itEnd = messages.end();
const std::size_t N = static_cast<std::size_t>( std::distance( itMessage, itEnd ) );
{
Colour colourGuard( colour );
stream << " with " << pluralise( N, "message" ) << ":";
}
for(; itMessage != itEnd; ) {
// If this assertion is a warning ignore any INFO messages
if( printInfoMessages || itMessage->type != ResultWas::Info ) {
stream << " '" << itMessage->message << "'";
if ( ++itMessage != itEnd ) {
Colour colourGuard( dimColour() );
stream << " and";
}
}
}
}
private:
std::ostream& stream;
AssertionResult const& result;
std::vector<MessageInfo> messages;
std::vector<MessageInfo>::const_iterator itMessage;
bool printInfoMessages;
std::size_t counter;
};
void printTotals( const Totals& totals ) const {
if( totals.testCases.total() == 0 ) {
stream << "1..0 # Skipped: No tests ran.";
} else {
stream << "1.." << counter;
}
}
};
#ifdef CATCH_IMPL
TAPReporter::~TAPReporter() {}
#endif
CATCH_REGISTER_REPORTER( "tap", TAPReporter )
} // end namespace Catch
#endif // TWOBLUECUBES_CATCH_REPORTER_TAP_HPP_INCLUDED

View File

@ -0,0 +1,219 @@
/*
* Created by Phil Nash on 19th December 2014
* Copyright 2014 Two Blue Cubes Ltd. All rights reserved.
*
* Distributed under the Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
*/
#ifndef TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
#define TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED
// Don't #include any Catch headers here - we can assume they are already
// included before this header.
// This is not good practice in general but is necessary in this case so this
// file can be distributed as a single header that works with the main
// Catch single header.
#include <cstring>
#ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wpadded"
#endif
namespace Catch {
struct TeamCityReporter : StreamingReporterBase<TeamCityReporter> {
TeamCityReporter( ReporterConfig const& _config )
: StreamingReporterBase( _config )
{
m_reporterPrefs.shouldRedirectStdOut = true;
}
static std::string escape( std::string const& str ) {
std::string escaped = str;
replaceInPlace( escaped, "|", "||" );
replaceInPlace( escaped, "'", "|'" );
replaceInPlace( escaped, "\n", "|n" );
replaceInPlace( escaped, "\r", "|r" );
replaceInPlace( escaped, "[", "|[" );
replaceInPlace( escaped, "]", "|]" );
return escaped;
}
~TeamCityReporter() override;
static std::string getDescription() {
return "Reports test results as TeamCity service messages";
}
void skipTest( TestCaseInfo const& /* testInfo */ ) override {
}
void noMatchingTestCases( std::string const& /* spec */ ) override {}
void testGroupStarting( GroupInfo const& groupInfo ) override {
StreamingReporterBase::testGroupStarting( groupInfo );
stream << "##teamcity[testSuiteStarted name='"
<< escape( groupInfo.name ) << "']\n";
}
void testGroupEnded( TestGroupStats const& testGroupStats ) override {
StreamingReporterBase::testGroupEnded( testGroupStats );
stream << "##teamcity[testSuiteFinished name='"
<< escape( testGroupStats.groupInfo.name ) << "']\n";
}
void assertionStarting( AssertionInfo const& ) override {}
bool assertionEnded( AssertionStats const& assertionStats ) override {
AssertionResult const& result = assertionStats.assertionResult;
if( !result.isOk() ) {
ReusableStringStream msg;
if( !m_headerPrintedForThisSection )
printSectionHeader( msg.get() );
m_headerPrintedForThisSection = true;
msg << result.getSourceInfo() << "\n";
switch( result.getResultType() ) {
case ResultWas::ExpressionFailed:
msg << "expression failed";
break;
case ResultWas::ThrewException:
msg << "unexpected exception";
break;
case ResultWas::FatalErrorCondition:
msg << "fatal error condition";
break;
case ResultWas::DidntThrowException:
msg << "no exception was thrown where one was expected";
break;
case ResultWas::ExplicitFailure:
msg << "explicit failure";
break;
// We shouldn't get here because of the isOk() test
case ResultWas::Ok:
case ResultWas::Info:
case ResultWas::Warning:
CATCH_ERROR( "Internal error in TeamCity reporter" );
// These cases are here to prevent compiler warnings
case ResultWas::Unknown:
case ResultWas::FailureBit:
case ResultWas::Exception:
CATCH_ERROR( "Not implemented" );
}
if( assertionStats.infoMessages.size() == 1 )
msg << " with message:";
if( assertionStats.infoMessages.size() > 1 )
msg << " with messages:";
for( auto const& messageInfo : assertionStats.infoMessages )
msg << "\n \"" << messageInfo.message << "\"";
if( result.hasExpression() ) {
msg <<
"\n " << result.getExpressionInMacro() << "\n"
"with expansion:\n" <<
" " << result.getExpandedExpression() << "\n";
}
if( currentTestCaseInfo->okToFail() ) {
msg << "- failure ignore as test marked as 'ok to fail'\n";
stream << "##teamcity[testIgnored"
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
<< " message='" << escape( msg.str() ) << "'"
<< "]\n";
}
else {
stream << "##teamcity[testFailed"
<< " name='" << escape( currentTestCaseInfo->name )<< "'"
<< " message='" << escape( msg.str() ) << "'"
<< "]\n";
}
}
stream.flush();
return true;
}
void sectionStarting( SectionInfo const& sectionInfo ) override {
m_headerPrintedForThisSection = false;
StreamingReporterBase::sectionStarting( sectionInfo );
}
void testCaseStarting( TestCaseInfo const& testInfo ) override {
m_testTimer.start();
StreamingReporterBase::testCaseStarting( testInfo );
stream << "##teamcity[testStarted name='"
<< escape( testInfo.name ) << "']\n";
stream.flush();
}
void testCaseEnded( TestCaseStats const& testCaseStats ) override {
StreamingReporterBase::testCaseEnded( testCaseStats );
if( !testCaseStats.stdOut.empty() )
stream << "##teamcity[testStdOut name='"
<< escape( testCaseStats.testInfo.name )
<< "' out='" << escape( testCaseStats.stdOut ) << "']\n";
if( !testCaseStats.stdErr.empty() )
stream << "##teamcity[testStdErr name='"
<< escape( testCaseStats.testInfo.name )
<< "' out='" << escape( testCaseStats.stdErr ) << "']\n";
stream << "##teamcity[testFinished name='"
<< escape( testCaseStats.testInfo.name ) << "' duration='"
<< m_testTimer.getElapsedMilliseconds() << "']\n";
stream.flush();
}
private:
void printSectionHeader( std::ostream& os ) {
assert( !m_sectionStack.empty() );
if( m_sectionStack.size() > 1 ) {
os << getLineOfChars<'-'>() << "\n";
std::vector<SectionInfo>::const_iterator
it = m_sectionStack.begin()+1, // Skip first section (test case)
itEnd = m_sectionStack.end();
for( ; it != itEnd; ++it )
printHeaderString( os, it->name );
os << getLineOfChars<'-'>() << "\n";
}
SourceLineInfo lineInfo = m_sectionStack.front().lineInfo;
os << lineInfo << "\n";
os << getLineOfChars<'.'>() << "\n\n";
}
// if string has a : in first line will set indent to follow it on
// subsequent lines
static void printHeaderString( std::ostream& os, std::string const& _string, std::size_t indent = 0 ) {
std::size_t i = _string.find( ": " );
if( i != std::string::npos )
i+=2;
else
i = 0;
os << Column( _string )
.indent( indent+i)
.initialIndent( indent ) << "\n";
}
private:
bool m_headerPrintedForThisSection = false;
Timer m_testTimer;
};
#ifdef CATCH_IMPL
TeamCityReporter::~TeamCityReporter() {}
#endif
CATCH_REGISTER_REPORTER( "teamcity", TeamCityReporter )
} // end namespace Catch
#ifdef __clang__
# pragma clang diagnostic pop
#endif
#endif // TWOBLUECUBES_CATCH_REPORTER_TEAMCITY_HPP_INCLUDED

View File

@ -0,0 +1,32 @@
#ifndef CONFIG_FSFWCONFIG_H_
#define CONFIG_FSFWCONFIG_H_
#include <fsfw/unittest/config/version.h>
//! Used to determine whether C++ ostreams are used
//! Those can lead to code bloat.
#define FSFW_CPP_OSTREAM_ENABLED 1
//! Reduced printout to further decrese code size
//! Be careful, this also turns off most diagnostic prinouts!
#define FSFW_REDUCED_PRINTOUT 0
//! If -DDEBUG is supplied in the build defines, there will be
//! additional output which requires the translation files translateObjects
//! and translateEvents (and their compiles source files)
#ifdef DEBUG
#define FSFW_DEBUG_OUTPUT 1
//! Specify whether info events are printed too.
#define FSFW_DEBUG_INFO 1
#include <translateObjects.h>
#include <translateEvents.h>
#else
#define FSFW_DEBUG_OUTPUT 0
#endif
//! When using the newlib nano library, C99 support for stdio facilities
//! will not be provided. This define should be set to 1 if this is the case.
#define FSFW_NEWLIB_NANO_NO_C99_IO 1
#endif /* CONFIG_FSFWCONFIG_H_ */

View File

@ -0,0 +1,8 @@
#ifndef FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_
#define FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_
#endif /* FSFW_UNITTEST_CONFIG_TESTSCONFIG_H_ */

View File

@ -0,0 +1,48 @@
#include <fsfw/unittest/config/cdatapool/dataPoolInit.h>
void datapool::dataPoolInit(std::map<uint32_t, PoolEntryIF*> * poolMap) {
uint8_t UINT8T_INIT[1] = {0};
uint16_t UINT16T_INIT[1] = {0};
uint32_t UINT32T_INIT[1] = {0};
float FLOAT_INIT[2] = {0.0, 0.0};
/* FSFW */
poolMap->emplace(datapool::INTERNAL_ERROR_STORE_FULL,
new PoolEntry<uint32_t>(UINT32T_INIT,1));
poolMap->emplace(datapool::INTERNAL_ERROR_MISSED_LIVE_TM,
new PoolEntry<uint32_t>(UINT32T_INIT,1));
poolMap->emplace(datapool::INTERNAL_ERROR_FULL_MSG_QUEUES,
new PoolEntry<uint32_t>(UINT32T_INIT,1));
/* TEST */
poolMap->emplace(datapool::TEST_UINT8,
new PoolEntry<uint8_t>(UINT8T_INIT,1));
poolMap->emplace(datapool::TEST_UINT16,
new PoolEntry<uint16_t>(UINT16T_INIT,1));
poolMap->emplace(datapool::TEST_UINT32,
new PoolEntry<uint32_t>(UINT32T_INIT,1));
poolMap->emplace(datapool::TEST_FLOAT_VECTOR,
new PoolEntry<float>(FLOAT_INIT,2));
// With new initializer list feature and boolean entries.
// /* FSFW */
// poolMap->emplace(datapool::INTERNAL_ERROR_STORE_FULL,
// new PoolEntry<uint32_t>({0},1));
// poolMap->emplace(datapool::INTERNAL_ERROR_MISSED_LIVE_TM,
// new PoolEntry<uint32_t>({0},1));
// poolMap->emplace(datapool::INTERNAL_ERROR_FULL_MSG_QUEUES,
// new PoolEntry<uint32_t>({0},1));
//
// /* TEST */
// poolMap->emplace(datapool::TEST_BOOLEAN,
// new PoolEntry<bool>({0},1));
// poolMap->emplace(datapool::TEST_UINT8,
// new PoolEntry<uint8_t>({0},1));
// poolMap->emplace(datapool::TEST_UINT16,
// new PoolEntry<uint16_t>({0},1));
// poolMap->emplace(datapool::TEST_UINT32,
// new PoolEntry<uint32_t>({0},1));
// poolMap->emplace(datapool::TEST_FLOAT_VECTOR,
// new PoolEntry<float>({0, 0},2));
}

View File

@ -0,0 +1,29 @@
#ifndef HOSTED_CONFIG_CDATAPOOL_DATAPOOLINIT_H_
#define HOSTED_CONFIG_CDATAPOOL_DATAPOOLINIT_H_
#include <fsfw/datapool/DataPool.h>
#include <fsfw/datapool/PoolEntryIF.h>
#include <map>
#include <cstdint>
namespace datapool {
void dataPoolInit(std::map<uint32_t, PoolEntryIF*> * poolMap);
enum datapoolvariables {
NO_PARAMETER = 0,
/** [EXPORT] : [GROUP] FSFW */
INTERNAL_ERROR_STORE_FULL = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Store Entry [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
INTERNAL_ERROR_MISSED_LIVE_TM = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Missed Live Tm [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
INTERNAL_ERROR_FULL_MSG_QUEUES = 0xEE000001, //!< [EXPORT] : [NAME] Internal Error Full Msg Queue [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
/** [EXPORT] : [GROUP] TEST */
TEST_BOOLEAN = 0x01010102, //!< [EXPORT] : [NAME] Test Boolean [UNIT] (-) [SIZE] 1 [TYPE] bool
TEST_UINT8 = 0x02020204, //!< [EXPORT] : [NAME] Test Byte [UNIT] (-) [SIZE] 1 [TYPE] uint8_t
TEST_UINT16 = 0x03030306, //!< [EXPORT] : [NAME] Test UINT16 [UNIT] (-) [SIZE] 1 [TYPE] uint16_t
TEST_UINT32 = 0x04040408, //!< [EXPORT] : [NAME] Test UINT32 [UNIT] (-) [SIZE] 1 [TYPE] uint32_t
TEST_FLOAT_VECTOR = 0x05050510, //!< [EXPORT] : [NAME] Test Float [UNIT] (-) [SIZE] 2 [TYPE] float
};
}
#endif /* CONFIG_CDATAPOOL_DATAPOOLINIT_H_ */

15
unittest/config/config.mk Normal file
View File

@ -0,0 +1,15 @@
CXXSRC += $(wildcard $(CURRENTPATH)/cdatapool/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/ipc/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/objects/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/pollingsequence/*.cpp)
CXXSRC += $(wildcard $(CURRENTPATH)/events/*.cpp)
INCLUDES += $(CURRENTPATH)
INCLUDES += $(CURRENTPATH)/objects
INCLUDES += $(CURRENTPATH)/ipc
INCLUDES += $(CURRENTPATH)/pollingsequence
INCLUDES += $(CURRENTPATH)/returnvalues
INCLUDES += $(CURRENTPATH)/tmtc
INCLUDES += $(CURRENTPATH)/events
INCLUDES += $(CURRENTPATH)/devices
INCLUDES += $(CURRENTPATH)/cdatapool

View File

@ -0,0 +1,11 @@
/**
* \file logicalAddresses.cpp
*
* \date 06.11.2019
*/
#include <fsfw/unittest/config/devices/logicalAddresses.h>

View File

@ -0,0 +1,15 @@
#ifndef CONFIG_DEVICES_LOGICALADDRESSES_H_
#define CONFIG_DEVICES_LOGICALADDRESSES_H_
#include <fsfw/devicehandlers/CookieIF.h>
#include <fsfw/unittest/config/objects/systemObjectList.h>
#include <cstdint>
namespace addresses {
/* Logical addresses have uint32_t datatype */
enum logicalAddresses: address_t {
};
}
#endif /* CONFIG_DEVICES_LOGICALADDRESSES_H_ */

View File

@ -0,0 +1,10 @@
/**
* @file switcherList.cpp
*
* @date 28.11.2019
*/
#include <fsfw/unittest/config/devices/powerSwitcherList.h>

View File

@ -0,0 +1,22 @@
/**
* @file switcherList.h
*
* @date 28.11.2019
*/
#ifndef CONFIG_DEVICES_POWERSWITCHERLIST_H_
#define CONFIG_DEVICES_POWERSWITCHERLIST_H_
namespace switches {
/* Switches are uint8_t datatype and go from 0 to 255 */
enum switcherList {
PCDU,
GPS0,
GPS1,
DUMMY = 129
};
}
#endif /* CONFIG_DEVICES_POWERSWITCHERLIST_H_ */

View File

@ -0,0 +1,20 @@
/**
* @brief Auto-generated event translation file. Contains 80 translations.
* Generated on: 2020-05-02 20:13:41
*/
#include <fsfw/unittest/config/events/translateEvents.h>
const char *TEST_EVENT_SERVICE_1_STRING = "TEST_EVENT_SERVICE_1";
const char *TEST2_STRING = "TEST2";
const char * translateEvents(Event event){
switch((event&0xFFFF)){
case 8000:
return TEST_EVENT_SERVICE_1_STRING;
case 9100:
return TEST2_STRING;
default:
return "UNKNOWN_EVENT";
}
return 0;
}

View File

@ -0,0 +1,16 @@
/*
* translateEvent.h
*
* Created on: 28 May 2019
* Author: Robin
*/
#ifndef CONFIG_EVENTS_TRANSLATEEVENTS_H_
#define CONFIG_EVENTS_TRANSLATEEVENTS_H_
#include <fsfw/events/Event.h>
const char * translateEvents(Event event);