Commit 2358fb2a authored by Adrien Oliva's avatar Adrien Oliva

Add autotools and utests framework

parent bfbc7f9a
Pipeline #117 failed with stages
in 1 minute and 14 seconds
# http://www.gnu.org/software/automake
Makefile.in
Makefile
# http://www.gnu.org/software/autoconf
/autom4te.cache
/autoscan.log
/autoscan-*.log
/aclocal.m4
/compile
config.h.in
/configure
/configure.scan
/config.guess
/config.log
/config.status
/config.sub
/configure.ac
libtool
ltmain.sh
/depcomp
/install-sh
/missing
/stamp-h1
/ar-lib
.deps/
.libs/
config.h
stamp-h1
*.log
*.trs
test-driver
*.m4
INSTALL
# Object files
*.o
*.ko
*.obj
*.elf
# Precompiled headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
*.x
*.xtest
# Debug files
*.dSYM/
*.su
# Coverage files
*.gcda
*.gcno
coverage-report*
# Compiled object files
*.slo
# Editor buffer
*~
*.sw?
# Distribution package archive
*.tar
*.tar
*.tar.*
# CppUTest xml report
cpputest*.xml
# Build folder
build/
# Doxygen
doc/html
doc/Doxyfile
stages:
- build
- test
- deploy
build:
stage: build
script:
- ./autogen.sh
- ./configure
- make
check:
stage: test
script:
- ./autogen.sh
- ./configure --enable-coverage
- make
- make check
- make coverage | tail -10
dependencies:
- build
distribute:
stage: deploy
script:
- ./autogen.sh
- ./configure
- make dist
artifacts:
paths:
- libbutton-*.tar.gz
expire_in: 1 week
except:
- tags
dependencies:
- build
distribute-release:
stage: deploy
script:
- ./autogen.sh
- ./configure
- make dist
artifacts:
paths:
- libbutton-*.tar.gz
only:
- tags
dependencies:
- check
2 Adrien Oliva <olivaa+gitlab@yapbreak.fr>
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright 2017 YapBreak
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
ChangeLog.md
\ No newline at end of file
# ChangeLog
ACLOCAL_AMFLAGS = -I m4
include Makefile.common
SOURCE_DIR = src
if CPPUTEST
SOURCE_DIR += utests
endif
SUBDIRS = $(SOURCE_DIR)
ALLPHONY = coverage doc
doc:
@(cd doc && $(MAKE) $@)
if COVERAGE
if LCOV
lcov-coverage-clean:
lcov --compat-libtool --directory "$(top_srcdir)/src" --zerocounters --output-file "coverage-report.info"
lcov-coverage-filter:
lcov --rc lcov_branch_coverage=1 --compat-libtool --directory "$$(readlink -f "$(top_builddir)/")" --capture --output-file "coverage-report.info"
lcov --rc lcov_branch_coverage=1 --extract "coverage-report.info" "$$(readlink -f "$(top_srcdir)")/*" --output-file "coverage-report2.info"
lcov --rc lcov_branch_coverage=1 --remove "coverage-report2.info" "*utests*" --output-file "coverage-report.info"
if GENHTML
GENHTML_EXTRA = --rc lcov_branch_coverage=1 --highlight --legend --demangle-cpp
if PERLGD
GENHTML_EXTRA += --frames
endif # PERLGD
genhtml-coverage-report:
genhtml $(GENHTML_EXTRA) --output-directory "coverage-report" --prefix "$$(readlink -f $(top_srcdir))" "coverage-report.info"
else # GENHTML
genhtml-coverage-report:
@(echo "Lcov suite is not completely installed. Please be sure to have genhtml to get beautiful coverage report")
endif # GENHTML
else # LCOV
lcov-coverage-clean:
lcov-coverage-filter:
genhtml-coverage-report:
endif # LCOV
if GCOVR
gcovr-coverage-report:
gcovr -r . --exclude-unreachable-branches --exclude-directories="utests" --xml -o "coverage-report.xml"
else # GCOVR
gcovr-coverage-report:
endif # GCOVR
coverage-clean: lcov-coverage-clean
coverage-report: lcov-coverage-filter genhtml-coverage-report gcovr-coverage-report
coverage: coverage-clean check coverage-report
ALLPHONY += coverage-clean
ALLPHONY += coverage-report
ALLPHONY += lcov-coverage-clean
ALLPHONY += lcov-coverage-filter
ALLPHONY += genhtml-coverage-report
ALLPHONY += gcovr-coverage-report
else # COVERAGE
coverage:
@(echo "Coverage support is disabled. Re-run configure with --enable-coverage switch.")
endif # COVERAGE
CLEANFILES = "coverage-report.info" "coverage-report2.info" "coverage-report" "coverage-report.xml"
clean-local:
@rm -rf $(CLEANFILES)
.PHONY: $(ALLPHONY)
AM_CFLAGS = -std=c11 -Wall -Wextra ${extra_CFLAGS}
AM_CXXFLAGS = -std=c++11 -Wall -Wextra ${extra_CXXFLAGS}
AM_LDFLAGS = ${extra_LDFLAGS}
AM_CFLAGS += -I$(top_srcdir)/src
AM_CFLAGS += -I$(top_builddir)/src
AM_CFLAGS += -I$(top_builddir)/utests
AM_CFLAGS += -I$(top_srcdir)/utests/fixtures
AM_CFLAGS += -include $(top_builddir)/src/config.h
AM_CXXFLAGS += -I$(top_srcdir)/src
AM_CXXFLAGS += -I$(top_builddir)/src
AM_CXXFLAGS += -I$(top_builddir)/utests
AM_CXXFLAGS += -I$(top_srcdir)/utests/fixtures
AM_CXXFLAGS += -include $(top_builddir)/src/config.h
AM_LDFLAGS += -L$(top_builddir)
NEWS.md
\ No newline at end of file
### Feature
README.md
\ No newline at end of file
[![pipeline status](https://gitlab.yapbreak.fr/iot/libbutton/badges/master/pipeline.svg)](https://gitlab.yapbreak.fr/iot/libbutton/commits/master)
[![coverage report](https://gitlab.yapbreak.fr/iot/libbutton/badges/master/coverage.svg)](https://gitlab.yapbreak.fr/iot/libbutton/commits/master)
This is a simple button manager for any embedded board that supports Arduino
framework.
......
#!/bin/sh
git shortlog -sne > AUTHORS
./version.sh || exit 127
aclocal || exit 126
autoreconf --install --force --symlink || exit 125
# To use gettext translation system
#intltoolize --copy --force --automake
echo "Now run ./configure && make && sudo make install"
AC_PREREQ([2.69])
AC_INIT()
AM_INIT_AUTOMAKE([-Wall -Werror])
AC_CONFIG_MACRO_DIR([m4])
AC_CONFIG_SRCDIR([src/button.h])
AC_CONFIG_HEADERS([src/config.h])
AC_PREFIX_DEFAULT(/usr/local)
VERSION_CURRENT=___CURRENT___
VERSION_REVISION=___REVISION___
VERSION_AGE=___AGE___
AC_SUBST(VERSION_CURRENT)
AC_SUBST(VERSION_REVISION)
AC_SUBST(VERSION_AGE)
# Checks for programs
AC_PROG_CXX
AC_PROG_CC
AM_PROG_AR
AC_PROG_INSTALL
AC_PROG_MAKE_SET
LT_INIT
# Checks for libraries
extra_CFLAGS=""
extra_CXXFLAGS=""
extra_LDFLAGS=""
compiler_generic_flags=""
compiler_c_flags=""
compiler_cxx_flags=""
GCC_VERSION=""
GCC_VERSION_MAJOR=0
GCC_VERSION_MINOR=0
GCC_VERSION_PATCH=0
AS_IF([test "x$GCC" = "xyes"], [
GCC_VERSION="$($CC -dumpversion)"
GCC_VERSION_MAJOR=$(echo $GCC_VERSION | cut -d'.' -f1)
GCC_VERSION_MINOR=$(echo $GCC_VERSION | cut -d'.' -f2)
GCC_VERSION_PATCH=$(echo $GCC_VERSION | cut -d'.' -f3)
])
AS_IF([test $GCC_VERSION_MAJOR -ge 3], [
compiler_generic_flags+="-Wshadow "
compiler_generic_flags+="-Wformat=2 "
compiler_cxx_flags+="-Wold-style-cast "
])
AS_IF([test $GCC_VERSION_MAJOR -ge 4], [
AS_IF([test $GCC_VERSION_MAJOR -gt 4 -o $GCC_VERSION_MINOR -ge 3], [
compiler_generic_flags+="-Wlogical-op "
])
AS_IF([test $GCC_VERSION_MAJOR -gt 4 -o $GCC_VERSION_MINOR -ge 5], [
compiler_generic_flags+="-Wdouble-promotion "
compiler_c_flags+="-Wjump-misses-init "
])
AS_IF([test $GCC_VERSION_MAJOR -gt 4 -o $GCC_VERSION_MINOR -ge 8], [
compiler_cxx_flags+="-Wuseless-cast "
])
])
AS_IF([test $GCC_VERSION_MAJOR -ge 6], [
compiler_generic_flags+="-Wduplicated-cond "
compiler_generic_flags+="-Wnull-dereference "
])
AS_IF([test $GCC_VERSION_MAJOR -ge 7], [
compiler_generic_flags+="-Wduplicated-branches "
compiler_generic_flags+="-Wrestrict "
])
# Debug flags
AC_ARG_ENABLE(debug,
AS_HELP_STRING([--enable-debug],
[enable debugging [default: no]]),
[],
[enable_debug=no])
AM_CONDITIONAL(DEBUG, test "x${enable_debug}" = "xyes")
AM_COND_IF(DEBUG,
[AC_DEFINE(__DEBUG__, 1, [Define to 0 if this is a release build])
extra_CFLAGS+="-Werror -g $compiler_generic_flags $compiler_c_flags"
extra_CXXFLAGS+="-Werror -g $compiler_generic_flags $compiler_cxx_flags"
]
)
# Coverage flags
AC_ARG_ENABLE([coverage],
AS_HELP_STRING([--enable-coverage],
[enable coverage report while testing [default: no]]),
[],
[enable_coverage=no])
AS_IF([test "x$GCC" = "xyes"],
[AM_CONDITIONAL(COVERAGE, test "x${enable_coverage}" = "xyes")
AM_COND_IF(COVERAGE,
[extra_CFLAGS+="--coverage "
extra_CXXFLAGS+="--coverage "
extra_LDFLAGS+="-lgcov "
])
],
[AC_MSG_WARN([Coverage is currently not supported with a compiler other than GCC])]
)
# Profiling flags
AC_ARG_ENABLE([profile],
AS_HELP_STRING([--enable-profile],
[enable profiling functions while testing [default: no]]),
[],
[enable_profile=no])
AS_IF([test "x$GCC" = "xyes"],
[AM_CONDITIONAL(PROFILE, test "x${enable_profile}" = "xyes")
AM_COND_IF(PROFILE,
[extra_CFLAGS+="-pg "
extra_CXXFLAGS+="-pg "
])
],
[AC_MSG_WARN([Profiling is currently not supported with a compiler other than GCC])]
)
# Allow user to install test (mainly usefull for CI platform)
AC_ARG_WITH([install-test],
AS_HELP_STRING([--with-install-test],
[install test program in PREFIX/bin]))
AM_CONDITIONAL(INSTALLTEST, test "x${with_install_test}" = "xtrue")
AC_SUBST([extra_CFLAGS])
AC_SUBST([extra_CXXFLAGS])
AC_SUBST([extra_LDFLAGS])
# Checks for header files
AC_CHECK_HEADERS([stdint.h ])
# Checks for typedefs, structures, and compiler characteristics
AC_C_INLINE
AC_TYPE_SIZE_T
AC_CHECK_HEADER_STDBOOL
AC_CHECK_TYPES([uint8_t])
# TODO: complete
# Checks for library functions
#AC_FUNC_MALLOC
#AC_CHECK_FUNC([memcpy printf])
#AC_CHECK_FUNC([strerror_r])
# TODO: complete
# Check if test utility are present
PKG_CHECK_MODULES([CPPUTEST], [cpputest], [have_cpputest=yes], [have_cpputest=no])
AM_CONDITIONAL([CPPUTEST], [test "x${have_cpputest}" = "xyes"])
AS_IF([test "x$have_cpputest" = "xno"],
[AC_MSG_WARN([Please install CppUTest package to get support of unit tests.])])
# Check coverage tools
AC_CHECK_PROG([gcovr], [gcovr], [yes])
AM_CONDITIONAL(GCOVR, [test "x${gcovr}" = "xyes"])
AC_CHECK_PROG([lcov], [lcov], [yes])
AM_CONDITIONAL(LCOV, [test "x${lcov}" = "xyes"])
AC_CHECK_PROG([genhtml], [genhtml], [yes])
AM_CONDITIONAL(GENHTML, [test "x${genhtml}" = "xyes"])
AM_CONDITIONAL(PERLGD, [perldoc -l GD])
# Check doxygen installation
AC_CHECK_PROG([doxygen], [doxygen], [yes])
AM_CONDITIONAL(DOXYGEN, [test "x${doxygen}" = "xyes"])
# Generate files
AC_CONFIG_FILES([Makefile
utests/Makefile
utests/fixtures/Makefile
src/Makefile
doc/Makefile
doc/Doxyfile
])
AM_SILENT_RULES([yes])
AC_OUTPUT
# vi:syntax=config
#!/bin/bash
if [ ! -x /usr/bin/cppcheck ]; then
echo "No cppcheck found"
exit 127
fi
output=plain
if [ -n "$1" ]; then
case "$1" in
"xml")
output=xml
shift
;;
"plain")
output=plain
shift
;;
esac
fi
declare -a OUTPUT_FLAGS
if [ "$output" == "xml" ]; then
OUTPUT_FLAGS=("--xml" "--xml-version=2")
fi
/usr/bin/cppcheck --enable=all --verbose --quiet \
--suppress=missingIncludeSystem \
-I./src \
-I./utests/fixtures \
--inline-suppr \
-DHAVE_SOCAT=1 \
"${OUTPUT_FLAGS[@]}" \
"$@" \
src/
This diff is collapsed.
ACLOCAL_AMFLAGS = -I m4
if DOXYGEN
doc:
@(doxygen)
clean-local:
@rm -rf html/
.PHONY: doc
else
doc:
@(echo "Please install doxygen to get actual documentation")
endif
ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4
include $(top_srcdir)/Makefile.common
lib_LTLIBRARIES = libbutton.la
libbutton_la_SOURCES = button.h
libbutton_la_SOURCES += button.cpp
include_HEADERS = button.h
ACLOCAL_AMFLAGS = -I $(top_srcdir)/m4
include $(top_srcdir)/utests/Makefile.test.common
SUBDIRS = fixtures
TESTS = ut_button.xtest
noinst_PROGRAMS = $(TESTS)
check_PROGRAMS = $(TESTS)
ut_button_xtest_SOURCES = ut_button.h
ut_button_xtest_SOURCES += main.cpp
ut_button_xtest_CFLAGS = $(TESTCFLAGS)
ut_button_xtest_CXXFLAGS = $(TESTCXXFLAGS)
ut_button_xtest_LDFLAGS = $(TESTLDFLAGS)
ut_button_xtest_LDADD = $(top_builddir)/src/libbutton.la
ut_button_xtest_LDADD += $(top_builddir)/utests/fixtures/libfixtures.la
include $(top_srcdir)/Makefile.common
TEST_ROOT = $(top_srcdir)/utests
TESTCFLAGS = $(AM_CFLAGS)\
$(CPPUTEST_CFLAGS)
TESTCXXFLAGS = $(AM_CXXFLAGS)\
$(CPPUTEST_CFLAGS)
TESTLDFLAGS = $(AM_LDFLAGS) $(CPPUTEST_LIBS)
#include <map>
#include <sstream>
#include <string>
#include <iomanip>
#include "Arduino.h"
#include <CppUTest/TestHarness.h>
fixtures *fixtures::s_fixtures;
fixtures *fixtures::getInstance()
{
return s_fixtures;
}
void fixtures::registerInstance(fixtures &f)
{
s_fixtures = &f;
}
void analogWrite(uint8_t pin, uint8_t value)
{
fixtures *f = fixtures::getInstance();
BYTES_EQUAL(OUTPUT, f->get_actual_pin_mode(pin));
f->set_actual_analog_value(pin, value);
f->call("analogWrite");
}
void digitalWrite(uint8_t pin, uint8_t value)
{
fixtures *f = fixtures::getInstance();
BYTES_EQUAL(OUTPUT, f->get_actual_pin_mode(pin));
f->set_actual_digital_value(pin, value);
f->call("digitalWrite");
}
int digitalRead(uint8_t pin)
{
fixtures *f = fixtures::getInstance();
BYTES_EQUAL(INPUT, f->get_actual_pin_mode(pin));
f->call("digitalRead");
return f->get_actual_digital_value(pin);
}
unsigned long millis()
{
fixtures *f = fixtures::getInstance();
return f->get_millis();
}
void pinMode(uint8_t pin, uint8_t mode)
{
fixtures *f = fixtures::getInstance();
f->set_actual_pin_mode(pin, mode);
f->set_actual_analog_value(pin, UNDEFINED);
f->set_actual_digital_value(pin, UNDEFINED);
f->call("pinMode");
}
fixtures::fixtures()
: m_expected_pin_map()
, m_actual_pin_map()
, m_expected_function_call_map()
, m_actual_function_call_map()
, m_micros(0)
{
}
fixtures::~fixtures()
{
}
void fixtures::set_expected_call(const char *function, int count)
{
m_expected_function_call_map[function] = count;
}
int fixtures::get_expected_call(const char *function) const
{
return m_expected_function_call_map.at(function);
}
void fixtures::set_expected_pin_mode(uint8_t pin, uint8_t mode)
{
m_expected_pin_map[pin].mode = mode;
}
uint8_t fixtures::get_expected_pin_mode(uint8_t pin) const
{
return m_expected_pin_map.at(pin).mode;
}
void fixtures::set_expected_digital_value(uint8_t pin, uint16_t level)
{
m_expected_pin_map[pin].digital_value = level;
}
uint8_t fixtures::get_expected_digital_value(uint8_t pin) const
{
return m_expected_pin_map.at(pin).digital_value;
}
void fixtures::set_expected_analog_value(uint8_t pin, uint16_t value)
{
m_expected_pin_map[pin].analog_value = value;
}
uint8_t fixtures::get_expected_analog_value(uint8_t pin) const
{
return m_expected_pin_map.at(pin).analog_value;
}
void fixtures::set_actual_call(const char *function, int count)
{
m_actual_function_call_map[function] = count;
}
void fixtures::call(const char *function)
{
int count;