Factor out munit test handling into a set of helpers

Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Peter Hutterer 2020-08-19 09:37:04 +10:00
parent 451f863894
commit 1fe93ae8be
11 changed files with 250 additions and 208 deletions

View file

@ -127,24 +127,35 @@ subproject('munit')
munit = dependency('munit', fallback: ['munit', 'munit_dep'])
lib_unittest = static_library('unittest',
'src/util-munit.h',
'src/util-munit.c',
dependencies: munit,
)
dep_unittest = declare_dependency(
link_with: lib_unittest,
dependencies: munit
)
test('iotest',
executable('iotest',
'test/iotest.c',
include_directories: 'src',
dependencies: munit))
dependencies: dep_unittest))
test('sourcestest',
executable('sourcestest',
'test/sourcestest.c',
include_directories: 'src',
dependencies: [munit, dep_libutil]))
dependencies: [dep_unittest, dep_libutil]))
test('libei-unit-test',
executable('libei-unit-test',
'test/libei-unit-test.c',
test('unit-tests',
executable('unit-tests',
'test/unit-tests.c',
src_libei,
include_directories: 'src',
c_args: ['-D_enable_tests_'],
dependencies: [munit, dep_libutil, dep_protobuf]))
dependencies: [dep_unittest, dep_libutil, dep_protobuf]))
lib_eierpecken = static_library('eierpecken',
'test/eierpecken.h',
@ -157,13 +168,13 @@ test('libei-integration-test',
executable('eitest',
'test/test-ei.c',
link_with: lib_eierpecken,
dependencies: [munit, dep_libei, dep_libeis]))
dependencies: [dep_unittest, dep_libei, dep_libeis]))
test('libeis-integration-test',
executable('eistest',
'test/test-eis.c',
link_with: lib_eierpecken,
dependencies: [munit, dep_libei, dep_libeis]))
dependencies: [dep_unittest, dep_libei, dep_libeis]))
valgrind = find_program('valgrind', required : false)

View file

@ -124,10 +124,9 @@ error:
#ifdef _enable_tests_
#include <munit.h>
#include "src/util-munit.h"
static MunitResult
test_proto_next_message(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_proto_next_message)
{
char data[64];
@ -192,8 +191,7 @@ send_data(int fd, const char *data, size_t data_size)
munit_assert_int(rc, ==, framelen + data_size);
}
static MunitResult
test_brei_dispatch(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_brei_dispatch)
{
int sv[2];
int rc = socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, sv);
@ -231,23 +229,4 @@ test_brei_dispatch(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
#define TEST(_func) \
{ .name = #_func, .test = _func }
static MunitTest ei_tests[] = {
TEST(test_proto_next_message),
TEST(test_brei_dispatch),
{ NULL },
};
static const MunitSuite libei_suite
__attribute__((used))
__attribute__((section("test_section"))) = {
"/brei/",
ei_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
#endif

View file

@ -565,10 +565,9 @@ ei_configure_name(struct ei *ei, const char *name)
}
#ifdef _enable_tests_
#include <munit.h>
#include "util-munit.h"
static MunitResult
test_init_unref(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_init_unref)
{
struct ei *ei = ei_new(NULL);
@ -592,8 +591,7 @@ test_init_unref(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_configure_name(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_configure_name)
{
struct ei *ei = ei_new(NULL);
@ -621,23 +619,4 @@ test_configure_name(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
#define TEST(_func) \
{ .name = #_func, .test = _func }
static MunitTest ei_tests[] = {
TEST(test_init_unref),
TEST(test_configure_name),
{ NULL },
};
static const MunitSuite libei_suite
__attribute__((used))
__attribute__((section("test_section"))) = {
"/",
ei_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
#endif

72
src/util-munit.c Normal file
View file

@ -0,0 +1,72 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include "util-munit.h"
#include "util-mem.h"
#include "util-strings.h"
/* All MUNIT_TEST functions are in the test_functions_section ELF section.
* __start and __stop point to the start and end of that section. See the
* __attribute__(section) documentation.
*/
extern const struct test_function __start_test_functions_section, __stop_test_functions_section;
int
munit_tests_run(int argc, char **argv)
{
size_t count = 1; /* For NULL-terminated entry */
for (const struct test_function *t = &__start_test_functions_section;
t < &__stop_test_functions_section;
t++)
count++;
_cleanup_free_ MunitTest *tests = calloc(count, sizeof(*tests));
size_t idx = 0;
for (const struct test_function *t = &__start_test_functions_section;
t < &__stop_test_functions_section;
t++) {
MunitTest test = {
.name = xaprintf("%s", t->name),
.test = t->func,
};
tests[idx++] = test;
}
MunitSuite suite = {
"",
tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
int rc = munit_suite_main(&suite, NULL, argc, argv);
for (idx = 0; idx < count; idx++)
free(tests[idx].name);
return rc;
}

68
src/util-munit.h Normal file
View file

@ -0,0 +1,68 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/* This is a wrapper around munit to make it faster to use for the simple
* type of test cases.
*
* Use with the MUNIT_TEST macro like this:
*
* MUNIT_TEST(some_test) {
* return MUNIT_OK;
* }
*
* int main(int argc, char **argv) {
* return munit_tests_run(argc, argv);
* }
*
*/
#pragma once
#include <munit.h>
typedef MunitResult (*munit_test_func_t)(const MunitParameter params[], void *user_data);
struct test_function {
const char *name; /* function name */
const char *file; /* file name */
munit_test_func_t func; /* test function */
} __attribute__((aligned(16)));
/**
* Defines a struct test_function in a custom ELF section that we can then
* loop over in munit_tests_run() to extract the tests. This removes the
* need of manually adding the tests to a suite or listing them somewhere.
*/
#define MUNIT_TEST(_func) \
static MunitResult _func(const MunitParameter params[], void *user_data); \
static const struct test_function _test_##_func \
__attribute__((used)) \
__attribute__((section("test_functions_section"))) = { \
.name = #_func, \
.func = _func, \
.file = __FILE__, \
}; \
static MunitResult _func(const MunitParameter params[], void *user_data)
int
munit_tests_run(int argc, char **argv);

View file

@ -1,14 +1,35 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include <sys/types.h>
#include <sys/socket.h>
#include <munit.h>
#include "util-io.h"
#include "util-munit.h"
static MunitResult
test_iobuf_new(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_iobuf_new)
{
/* test allocation and freeing a buffer */
struct iobuf *buf = iobuf_new(10);
@ -23,8 +44,7 @@ test_iobuf_new(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_iobuf_cleanup(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_iobuf_cleanup)
{
/* Test the attribute(cleanup) define. This test needs to run in
* valgrind --leak-check=full to be really useful */
@ -34,8 +54,7 @@ test_iobuf_cleanup(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_iobuf_append(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_iobuf_append)
{
/* Test appending data */
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(10);
@ -68,8 +87,7 @@ test_iobuf_append(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_iobuf_append_short(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_iobuf_append_short)
{
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(10);
@ -89,8 +107,7 @@ test_iobuf_append_short(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_iobuf_append_fd(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_iobuf_append_fd)
{
_cleanup_iobuf_ struct iobuf *buf = iobuf_new(10);
int fds[2];
@ -148,25 +165,8 @@ test_iobuf_append_fd(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitTest iotest_tests[] = {
{ "iobuf/new", test_iobuf_new, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{ "iobuf/cleanup", test_iobuf_cleanup, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{ "iobuf/append", test_iobuf_append, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{ "iobuf/append_short", test_iobuf_append_short, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{ "iobuf/append_fd", test_iobuf_append_fd, NULL, NULL, MUNIT_TEST_OPTION_NONE, NULL},
{ NULL },
};
static const MunitSuite iotest_suite = {
"iotest",
iotest_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
int
main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
{
return munit_suite_main(&iotest_suite, NULL, argc, argv);
return munit_tests_run(argc, argv);
}

View file

@ -1,37 +0,0 @@
#include "config.h"
#include <assert.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <munit.h>
#include "util-mem.h"
extern const MunitSuite __start_test_section, __stop_test_section;
int
main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
{
size_t sz = 10;
size_t count = 0;
_cleanup_free_ MunitSuite *suites = calloc(sz, sizeof(*suites));
for (const MunitSuite *s = &__start_test_section;
s < &__stop_test_section;
s++) {
assert(count < sz - 1);
suites[count] = *s;
count++;
}
const MunitSuite suite = {
"/ei",
NULL,
suites,
1,
MUNIT_SUITE_OPTION_NONE,
};
return munit_suite_main(&suite, NULL, argc, argv);
}

View file

@ -29,10 +29,9 @@
#include <signal.h>
#include <unistd.h>
#include <munit.h>
#include "util-macros.h"
#include "util-mem.h"
#include "util-munit.h"
#include "util-sources.h"
DEFINE_TRIVIAL_CLEANUP_FUNC(struct sink *, sink_unref);
@ -40,8 +39,8 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(struct sink *, sink_unref);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct source *, source_unref);
#define _cleanup_source_ _cleanup_(source_unrefp)
static MunitResult
test_sink(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_sink)
{
struct sink *sink = sink_new();
sink_dispatch(sink);
@ -76,8 +75,7 @@ read_buffer(struct source *source, void *user_data)
buffer->len = nread;
}
static MunitResult
test_source(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_source)
{
_cleanup_sink_ struct sink *sink = sink_new();
@ -136,8 +134,7 @@ drain_data(struct source *source, void *user_data)
read(source_get_fd(source), buf, sizeof(buf));
}
static MunitResult
test_source_readd(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_source_readd)
{
_cleanup_sink_ struct sink *sink = sink_new();
@ -156,23 +153,8 @@ test_source_readd(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitTest iotest_tests[] = {
{ .name = "/sink", .test = test_sink},
{ .name = "/source", .test = test_source},
{ .name = "/source/readd", .test = test_source_readd},
{ NULL },
};
static const MunitSuite iotest_suite = {
"/sources",
iotest_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
int
main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
main(int argc, char **argv)
{
return munit_suite_main(&iotest_suite, NULL, argc, argv);
return munit_tests_run(argc, argv);
}

View file

@ -3,13 +3,12 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <munit.h>
#include "util-munit.h"
#include "libei.h"
#include "eierpecken.h"
static MunitResult
test_ei_ref_unref(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_ref_unref)
{
struct ei *ei = ei_new(NULL);
@ -26,8 +25,7 @@ test_ei_ref_unref(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_ei_reject(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_reject)
{
_cleanup_peck_ struct peck *peck = peck_new();
@ -46,8 +44,7 @@ test_ei_reject(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_ei_reject_after_connect(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_reject_after_connect)
{
_cleanup_peck_ struct peck *peck = peck_new();
_cleanup_eis_client_ struct eis_client *client = NULL;
@ -84,8 +81,7 @@ test_ei_reject_after_connect(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_ei_device_basics(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_device_basics)
{
_cleanup_peck_ struct peck *peck = peck_new();
_cleanup_ei_device_ struct ei_device *device = NULL;
@ -131,8 +127,7 @@ test_ei_device_basics(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_ei_device_add(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_device_add)
{
_cleanup_peck_ struct peck *peck = peck_new();
@ -169,8 +164,7 @@ test_ei_device_add(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_ei_device_add_drop_caps(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_device_add_drop_caps)
{
_cleanup_peck_ struct peck *peck = peck_new();
@ -208,8 +202,7 @@ test_ei_device_add_drop_caps(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
test_ei_device_add_zero_caps(const MunitParameter params[], void *user_data)
MUNIT_TEST(test_ei_device_add_zero_caps)
{
_cleanup_peck_ struct peck *peck = peck_new();
@ -242,27 +235,8 @@ test_ei_device_add_zero_caps(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitTest ei_tests[] = {
{ .name = "/ei/ref", .test = test_ei_ref_unref },
{ .name = "/ei/reject", .test = test_ei_reject },
{ .name = "/ei/reject_after_connect", .test = test_ei_reject_after_connect },
{ .name = "/device/basics", .test = test_ei_device_basics },
{ .name = "/device/add", .test = test_ei_device_add },
{ .name = "/device/add_drop_caps", .test = test_ei_device_add_drop_caps },
{ .name = "/device/add_zero_caps", .test = test_ei_device_add_zero_caps },
{ NULL },
};
static const MunitSuite ei_suite = {
"/ei",
ei_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
int
main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
main(int argc, char **argv)
{
return munit_suite_main(&ei_suite, NULL, argc, argv);
return munit_tests_run(argc, argv);
}

View file

@ -23,12 +23,11 @@
#include "config.h"
#include <munit.h>
#include "util-munit.h"
#include "eierpecken.h"
static MunitResult
eistest_ref_unref(const MunitParameter params[], void *user_data)
MUNIT_TEST(eistest_ref_unref)
{
struct eis *eis = eis_new(NULL);
@ -45,8 +44,7 @@ eistest_ref_unref(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
eistest_name(const MunitParameter params[], void *user_data)
MUNIT_TEST(eistest_name)
{
_cleanup_peck_ struct peck *peck = peck_new();
@ -76,8 +74,7 @@ eistest_name(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitResult
eistest_ranges(const MunitParameter params[], void *user_data)
MUNIT_TEST(eistest_ranges)
{
_cleanup_peck_ struct peck *peck = peck_new();
@ -112,23 +109,8 @@ eistest_ranges(const MunitParameter params[], void *user_data)
return MUNIT_OK;
}
static MunitTest eis_tests[] = {
{ .name = "/ref", .test = eistest_ref_unref },
{ .name = "/name", .test = eistest_name },
{ .name = "/ranges", .test = eistest_ranges },
{ NULL },
};
static const MunitSuite eis_suite = {
"/eis",
eis_tests,
NULL,
1,
MUNIT_SUITE_OPTION_NONE,
};
int
main(int argc, char* argv[MUNIT_ARRAY_PARAM(argc + 1)])
main(int argc, char **argv)
{
return munit_suite_main(&eis_suite, NULL, argc, argv);
return munit_tests_run(argc, argv);
}

32
test/unit-tests.c Normal file
View file

@ -0,0 +1,32 @@
/*
* Copyright © 2020 Red Hat, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* 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 AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "config.h"
#include "util-munit.h"
int
main(int argc, char **argv)
{
return munit_tests_run(argc, argv);
}