1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

pkg/fff: Add fake functions framework package

This commit is contained in:
Jens Wetterich 2021-10-28 16:48:00 +02:00
parent ea1f41038e
commit 14f90f3c5e
11 changed files with 178 additions and 0 deletions

View File

@ -15,6 +15,7 @@ rsource "driver_atwinc15x0/Kconfig"
rsource "driver_bme680/Kconfig"
rsource "driver_sx126x/Kconfig"
rsource "emlearn/Kconfig"
rsource "fff/Kconfig"
rsource "gemmlowp/Kconfig"
rsource "hacl/Kconfig"
rsource "heatshrink/Kconfig"

12
pkg/fff/Kconfig Normal file
View File

@ -0,0 +1,12 @@
# Copyright (c) 2021 Jens Wetterich <jens@wetterich-net.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#
config PACKAGE_FFF
bool "Fake functions framework"
depends on TEST_KCONFIG
help
A header only fake functions framework for unit testing.

9
pkg/fff/Makefile Normal file
View File

@ -0,0 +1,9 @@
PKG_NAME=fff
PKG_URL=https://github.com/meekrosoft/fff
PKG_VERSION=7e09f07e5b262b1cc826189dc5057379e40ce886 # v1.1
PKG_LICENSE=MIT
include $(RIOTBASE)/pkg/pkg.mk
all:
@:

5
pkg/fff/Makefile.include Normal file
View File

@ -0,0 +1,5 @@
INCLUDES += -I$(PKGDIRBASE)/fff
# There's nothing to build in this package, it's used as a header only library.
# So it's declared as a pseudo-module
PSEUDOMODULES += fff

7
pkg/fff/doc.txt Normal file
View File

@ -0,0 +1,7 @@
/**
* @defgroup pkg_fff Fake Functions Framework
* @ingroup pkg
* @brief Fake Functions Framework (fff)
*
* @see https://github.com/meekrosoft/fff
*/

View File

@ -14,6 +14,7 @@
* @see https://sourceforge.net/projects/embunit
*
* @note Please refer to https://github.com/RIOT-OS/RIOT/wiki/Testing-RIOT
* @note If mocking would be helpful for your unit test, you can also have a look at @ref pkg_fff.
*
* @author Martine Lenders <mlenders@inf.fu-berlin.de>
*/

5
tests/pkg_fff/Makefile Normal file
View File

@ -0,0 +1,5 @@
include ../Makefile.tests_common
USEPKG += fff
# If periph_i2c is pulled in the real implementation conflicts with the mock
FEATURES_BLACKLIST += periph_i2c
include $(RIOTBASE)/Makefile.include

View File

@ -0,0 +1,2 @@
BOARD_INSUFFICIENT_MEMORY := \
nucleo-l011k4

View File

@ -0,0 +1 @@
CONFIG_PACKAGE_FFF=y

116
tests/pkg_fff/main.c Normal file
View File

@ -0,0 +1,116 @@
/*
* Copyright (C) 2021 Jens Wetterich <jens@wetterich-net.de>
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @ingroup tests
* @{
* @file
* @brief Unit test to test the usage of @ref pkg_fff module
* @author Jens Wetterich <jens@wetterich-net.de>
*/
#define FFF_ARG_HISTORY_LEN 1u
#define FFF_CALL_HISTORY_LEN 1u
#include "fff.h"
#include "periph/i2c.h"
#include <stdio.h>
DEFINE_FFF_GLOBALS
FAKE_VALUE_FUNC(int, i2c_read_bytes, i2c_t, uint16_t, void *, size_t, uint8_t)
FAKE_VALUE_FUNC(int, i2c_acquire, i2c_t)
FAKE_VOID_FUNC(i2c_release, i2c_t)
int test_i2c_basic(void *buffer, size_t len);
int read_fake_impl(i2c_t dev, uint16_t addr, void *data, size_t size, uint8_t flags);
const unsigned int fake_read_len = 6;
const char *fake_read_data = "hello";
const i2c_t device = 0;
const uint16_t address = 4;
const uint8_t flags = 0;
int test_i2c_basic(void *buffer, size_t len)
{
int acquire_return_val;
int read_return_val;
int failure = 0;
acquire_return_val = i2c_acquire(device);
if (acquire_return_val != 0) {
failure = 1;
}
read_return_val = i2c_read_bytes(device, address, buffer, len, flags);
if (read_return_val != 0) {
failure = 1;
}
i2c_release(device);
return -failure;
}
int read_fake_impl(i2c_t dev, uint16_t addr, void *data, size_t size, uint8_t fl)
{
(void)dev;
(void)addr;
(void)size;
(void)fl;
memcpy(data, fake_read_data, fake_read_len);
return 0;
}
int main(void)
{
uint8_t buffer[fake_read_len];
int basic_test_return_val;
int failure = 0;
puts("Testing fff");
/* Set fake implementation / return values of the mocks */
i2c_read_bytes_fake.custom_fake = read_fake_impl;
i2c_acquire_fake.return_val = 0;
/* Run function under test */
basic_test_return_val = test_i2c_basic(buffer, fake_read_len);
/* Assert correct interaction of the function under test with the mocked API */
if (basic_test_return_val != 0) {
failure = 1;
puts("The return value of the read_bytes mock didn't match the expected value");
}
if (i2c_read_bytes_fake.arg0_val != device) {
failure = 1;
puts("The device parameter to the read_bytes mock didn't match the expected value");
}
if (i2c_read_bytes_fake.arg1_val != address) {
failure = 1;
puts("The address parameter to the read_bytes mock didn't match the expected value");
}
if (memcmp(buffer, fake_read_data, fake_read_len) != 0) {
failure = 1;
puts("The read_bytes mock didn't write the expected data into the buffer");
}
if (i2c_read_bytes_fake.arg3_val != fake_read_len) {
failure = 1;
puts("The len parameter to the read_bytes mock didn't match the expected value");
}
if (i2c_read_bytes_fake.arg4_val != flags) {
failure = 1;
puts("The flags parameter to the read_bytes mock didn't match the expected value");
}
if (i2c_read_bytes_fake.call_count != 1) {
failure = 1;
puts("The call count for the read_bytes mock didn't match the expected value");
}
if (i2c_acquire_fake.call_count != 1) {
failure = 1;
puts("The call count for the acquire mock didn't match the expected value");
}
if (i2c_release_fake.call_count != 1) {
failure = 1;
puts("The call count for the release mock didn't match the expected value");
}
printf("FFF test completed: %s\n", failure ? "FAILURE" : "SUCCESS");
return 0;
}
/** @} */

19
tests/pkg_fff/tests/01-run.py Executable file
View File

@ -0,0 +1,19 @@
#!/usr/bin/env python3
# Copyright (C) 2021 Jens Wetterich <jens@wetterich-net.de>
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
import sys
from testrunner import run
def testfunc(child):
child.expect_exact("FFF test completed: SUCCESS")
print("All tests successful")
if __name__ == "__main__":
sys.exit(run(testfunc, timeout=1, echo=True, traceback=True))