Skip to content
Snippets Groups Projects
Commit 5a1a0d3b authored by Benny Baumann's avatar Benny Baumann
Browse files

add: Implement "make test" target to run unit tests from test/ directory

parent e7936bda
No related branches found
No related tags found
1 merge request!1First unit tests
......@@ -60,6 +60,7 @@ test:bsd:
dependencies:
- build:bsd
script:
- make test
- echo Successfully tested.
test:deb:
......@@ -68,4 +69,5 @@ test:deb:
- build:deb
script:
- make lintian
- make test
- echo Successfully tested.
......@@ -5,6 +5,7 @@ DEPFLAGS = -MT $@ -MMD -MP -MF $(patsubst ${OBJDIR}/%.o,${DEPDIR}/%.d,$@)
CFLAGS_DEBUG = -g -Og
CFLAGS_RELEASE = -O3 -msse2 -mavx
# TODO: introduce configure script
CFLAGS += ${CFLAGS_DEBUG}
PODOMAIN ?= rmrf
......@@ -54,6 +55,10 @@ POTDIR ?= po/tpl
PODIR ?= po/lang
MODIR ?= po/bin
TESTDIR ?= test
TESTBINDIR ?= bin/test
TESTOBJDIR ?= obj/test
rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))
SOURCES := $(call rwildcard,${SRCDIR},*.cpp *.c)
......@@ -65,6 +70,10 @@ OBJECTS := $(filter-out $(patsubst ${SRCDIR}/%,${OBJDIR}/%,${APPDIR})/%,${SRCOBJ
TARGETS := $(patsubst $(patsubst ${SRCDIR}/%,${OBJDIR}/%,${APPDIR})/%.o,${BINDIR}/%,${APPOBJS})
TEST_SOURCES := $(call rwildcard,${TESTDIR},*.cpp *.c)
TEST_SRCOBJS := $(patsubst ${TESTDIR}/%.c,${TESTOBJDIR}/%.o,$(patsubst ${TESTDIR}/%.cpp,${TESTOBJDIR}/%.o,${TEST_SOURCES}))
TEST_TARGETS := $(patsubst ${TESTOBJDIR}/%.o,${TESTBINDIR}/%,${TEST_SRCOBJS})
POTSRCS := ${SOURCES} $(call rwildcard,${SRCDIR},*.hpp *.h)
POTOBJS := ${POTDIR}/${PODOMAIN}.pot
POOBJS := $(foreach POLANG,${POLANGS},$(patsubst ${POTDIR}/%.pot,${PODIR}/${POLANG}/%.po,${POTOBJS}))
......@@ -77,8 +86,12 @@ MAKEFLAGS += --no-builtin-rules
.PRECIOUS: ${DEPDIR}/%.d ${OBJDIR}/%.o ${POTOBJS} ${POOBJS}
.PHONY: all clean install lintian style translation
all: ${TARGETS} translation
.PHONY: all build clean install lintian style test translation
all: build translation
echo "Test targets:"
echo ${TEST_TARGETS}
build: ${TARGETS}
${BINDIR}/%: $(patsubst ${SRCDIR}/%,${OBJDIR}/%,${APPDIR})/%.o ${OBJECTS} Makefile ${APPDIR}/%.ldflags
${MKDIR} ${@D} && ${CXX} ${CXXFLAGS} ${LFLAGS} -o $@ $< ${OBJECTS} $(shell [ -r $(patsubst ${OBJDIR}/%.o,${SRCDIR}/%.ldflags,$<) ] && cat $(patsubst ${OBJDIR}/%.o,${SRCDIR}/%.ldflags,$<) ) && touch $@
......@@ -89,6 +102,18 @@ ${OBJDIR}/%.o: ${SRCDIR}/%.cpp ${DEPDIR}/%.d Makefile
${OBJDIR}/%.o: ${SRCDIR}/%.c ${DEPDIR}/%.d Makefile
${MKDIR} ${@D} && ${MKDIR} $(patsubst ${OBJDIR}/%,${DEPDIR}/%,${@D}) && ${CC} -std=c11 -std=c17 ${CFLAGS} ${DEPFLAGS} ${LFLAGS} -o $@ -c $< && touch $@
${TESTDIR}/%.ldflags:
touch $@
${TESTBINDIR}/%: ${TESTOBJDIR}/%.o ${OBJECTS} Makefile ${TESTDIR}/%.ldflags
${MKDIR} ${@D} && ${MKDIR} $(patsubst ${TESTOBJDIR}/%,${DEPDIR}/%,${@D}) && ${CXX} ${CXXFLAGS} ${LFLAGS} -Itest -o $@ $< ${OBJECTS} $(shell [ -r $(patsubst ${TESTOBJDIR}/%.o,${TESTDIR}/%.ldflags,$<) ] && cat $(patsubst ${TESTOBJDIR}/%.o,${TESTDIR}/%.ldflags,$<) ) && touch $@
${TESTOBJDIR}/%.o: ${TESTDIR}/%.cpp ${DEPDIR}/%.d ${DEPDIR}/test Makefile
${MKDIR} ${@D} && ${MKDIR} $(patsubst ${TESTOBJDIR}/%,${DEPDIR}/%,${@D}) && ${CXX} -I${TESTDIR} ${CXXFLAGS} ${DEPFLAGS} ${LFLAGS} -o $@ -c $< && touch $@
${TESTOBJDIR}/%.o: ${TESTDIR}/%.c ${DEPDIR}/%.d ${DEPDIR}/test Makefile
${MKDIR} ${@D} && ${MKDIR} $(patsubst ${TESTOBJDIR}/%,${DEPDIR}/%,${@D}) && ${CC} -I${TESTDIR} -std=c11 -std=c17 ${CFLAGS} ${DEPFLAGS} ${LFLAGS} -o $@ -c $< && touch $@
${POTDIR}/${PODOMAIN}.pot: ${POTSRCS}
${MKDIR} ${@D} && ${XGETTEXT} ${XGETTEXT_FLAGS} $( [ -r $@ ] && echo -- -j ) -o $@ $^ && \
${SED} --expression='s/charset=CHARSET/charset=UTF-8/g' --in-place $@
......@@ -106,6 +131,9 @@ ${APPDIR}/%.ldflags: ;
${DEPDIR}/%.d: ;
${DEPDIR}/test:
${MKDIR} ${DEPDIR}/test
include $(wildcard $(patsubst ${OBJDIR}/%.o,${DEPDIR}/%.d,${SRCOBJS}))
translation: ${MOOBJS}
......@@ -126,6 +154,12 @@ lintian:
lintian --pedantic --profile debian --verbose --display-experimental --show-overrides
@if lintian --pedantic --profile debian --verbose --display-experimental --show-overrides 2>&1 | grep -q '^W:'; then false; fi
test: ${TEST_TARGETS}
for a in ${TEST_TARGETS}; do \
echo $$a; \
$$a; \
done
install:
${INSTALL} -D -o root -g root -m 700 -t ${DESTDIR}${prefix}/bin ${TARGETS}
for POLANG in ${POLANGS}; do \
......
/*
* loopback_connection_client.cpp
*
* Created on: 05.01.2021
* Author: doralitze
*/
#include "test/loopback_connection_client.hpp"
#include <string.h>
namespace rmrf::test {
loopback_connection_client::loopback_connection_client(
rmrf::net::connection_client::incomming_data_cb mut_send_data_cb_
) :
rmrf::net::connection_client{},
mut_send_data_cb(mut_send_data_cb_),
send_data_archive{}
{
// Does nothing special
}
loopback_connection_client::~loopback_connection_client() {
// Also doesn't do anything fancy.
}
void loopback_connection_client::write_data(const std::string &data) {
// TODO fixme
this->send_data_archive.push_back(data);
if (this->mut_send_data_cb != nullptr) {
this->mut_send_data_cb(data);
}
}
void loopback_connection_client::send_data_to_incomming_data_cb(const std::string &data) {
if (this->in_data_cb != nullptr) {
this->in_data_cb(data);
}
}
std::vector<std::string> loopback_connection_client::get_send_data() {
return this->send_data_archive;
}
}
/*
* loopback_connection_client.hpp
*
* Created on: 05.01.2021
* Author: doralitze
*/
#pragma once
#include <vector>
#include "net/connection_client.hpp"
namespace rmrf::test {
/**
* Use this class to mock a connection client.
*/
class loopback_connection_client : public rmrf::net::connection_client {
private:
const rmrf::net::connection_client::incomming_data_cb mut_send_data_cb;
std::vector<std::string> send_data_archive;
public:
/**
* This constructor uses the given callback to notify the test suite that the module under test
* send data.
*/
loopback_connection_client(rmrf::net::connection_client::incomming_data_cb mut_send_data_cb_);
/**
* Just the mandatory virtual destructor.
*/
virtual ~loopback_connection_client();
/**
* This method gets called by the module under test as it simulates the behavior of a normal connection client.
* @param data The data the module wants to send.
*/
virtual void write_data(const std::string& data);
/**
* This method sends data to the connections incoming data callback.
* Use it to mimic a remote client sending data.
*
* @param data The data to send.
*/
void send_data_to_incomming_data_cb(const std::string& data);
/**
* Use this method in order to get all data the module under test has send.
*/
std::vector<std::string> get_send_data();
};
}
#pragma once
#include <vector>
#include "net/connection_client.hpp"
namespace rmrf::test {
/**
* Use this class to mock a connection client.
*/
class loopback_connection_client : public rmrf::net::connection_client {
private:
const rmrf::net::connection_client::incomming_data_cb send_data_cb;
std::vector<std::string> data_archive;
public:
/**
* This constructor uses the given callback to notify the test suite that the module under test
* send data.
*/
loopback_connection_client(
rmrf::net::connection_client::incomming_data_cb send_data_cb_
) :
rmrf::net::connection_client{},
send_data_cb(send_data_cb_),
data_archive{}
{
// Does nothing special
}
/**
* Just the mandatory virtual destructor.
*/
virtual ~loopback_connection_client() {
// Also doesn't do anything fancy.
}
/**
* This method gets called by the module under test as it simulates the behavior of a normal connection client.
* @param data The data the module wants to send.
*/
virtual void write_data(const std::string& data) {
// TODO fixme
this->data_archive.push_back(data);
if (this->send_data_cb) {
this->send_data_cb(data);
}
}
/**
* This method sends data to the connections incoming data callback.
* Use it to mimic a remote client sending data.
*
* @param data The data to send.
*/
void send_data_to_incomming_data_cb(const std::string& data) {
if (this->in_data_cb) {
this->in_data_cb(data);
}
}
/**
* Use this method in order to get all data the module under test has send.
*/
std::vector<std::string> get_send_data() {
return this->data_archive;
}
};
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment