[firefly] [PATCH 1/3 RFC v2] selftest: introduce testing abstractions
Daniel Baluta
daniel.baluta at gmail.com
Thu Apr 25 13:28:33 EEST 2013
On Thu, Apr 25, 2013 at 10:45 AM, Alexandru Copot
<alex.mihai.c at gmail.com> wrote:
> Signed-of by Alexandru Copot <alex.mihai.c at gmail.com>
> Cc: Daniel Baluta <dbaluta at ixiacom.com>
>
> Signed-of by Alexandru Copot <alex.mihai.c at gmail.com>
> Cc: Daniel Baluta <dbaluta at ixiacom.com>
Remove duplicates here. Also s/Signed-of by/Signed-of-by.
> ---
> tools/testing/selftests/Makefile | 3 +-
> tools/testing/selftests/lib/Makefile | 14 +++++++
> tools/testing/selftests/lib/selftests.c | 57 ++++++++++++++++++++++++++++
> tools/testing/selftests/lib/selftests.h | 67 +++++++++++++++++++++++++++++++++
> 4 files changed, 140 insertions(+), 1 deletion(-)
> create mode 100644 tools/testing/selftests/lib/Makefile
> create mode 100644 tools/testing/selftests/lib/selftests.c
> create mode 100644 tools/testing/selftests/lib/selftests.h
>
> diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile
> index a480593..e0fccd9 100644
> --- a/tools/testing/selftests/Makefile
> +++ b/tools/testing/selftests/Makefile
> @@ -1,4 +1,5 @@
> -TARGETS = breakpoints
> +TARGETS = lib
> +TARGETS += breakpoints
> TARGETS += kcmp
> TARGETS += mqueue
> TARGETS += vm
> diff --git a/tools/testing/selftests/lib/Makefile b/tools/testing/selftests/lib/Makefile
> new file mode 100644
> index 0000000..9c81d0c
> --- /dev/null
> +++ b/tools/testing/selftests/lib/Makefile
> @@ -0,0 +1,14 @@
> +
> +CFLAGS = -Wall -O2 -c -g
> +
> +selftests.a: selftests.o
> + ar qc $@ $^
> +
> +%.c: %.h
> +
> +%.o: %.c
> + $(CC) $(CFLAGS) -o $@ $^
> +
> +clean:
> + rm -rf *.o *.a
> +
> diff --git a/tools/testing/selftests/lib/selftests.c b/tools/testing/selftests/lib/selftests.c
> new file mode 100644
> index 0000000..1346f0a
> --- /dev/null
> +++ b/tools/testing/selftests/lib/selftests.c
> @@ -0,0 +1,57 @@
> +#include <stdio.h>
> +#include <stdarg.h>
> +
> +#include "selftests.h"
> +
> +test_result_t __assert(int expr, const char *filename, int line, const char *fmt, ...)
> +{
> + va_list vl;
> + const char *m;
> + char msg[BUFSIZ];
> +
Just use if (expr) to avoid one level of indentation.
> + if (!expr) {
> + fprintf(stderr, "\n(%s:%d) ", filename, line);
> +
> + va_start(vl, fmt);
> + m = va_arg(vl, char *);
> + if (!m)
> + m = fmt;
> + else
> + fprintf(stderr, "%s ", fmt);
> +
> + vsnprintf(msg, sizeof msg, m, vl);
> + va_end(vl);
> +
> + fprintf(stderr, "%s\n", msg);
> +
> + return TEST_FAIL;
> + }
> + return TEST_PASS;
> +}
> +
> +test_result_t run_all_tests(struct generic_test *test, void *param)
> +{
> + int i;
> + char *ptr = test->testcases;
> + test_result_t rc = TEST_PASS;
> +
> + rc = test->prepare ? test->prepare(param) : 0;
> + if (rc == TEST_FAIL)
> + return rc;
> +
> + fprintf(stderr, "Testing: %s ", test->name);
> + for (i = 0; i < test->testcase_count; i++) {
> +
> + rc |= test->run(ptr);
> + ptr += test->testcase_size;
> +
> + if (rc == TEST_FAIL && test->abort_on_fail) {
> + fprintf(stderr, "Test aborted\n");
> + break;
> + }
> + }
> +
> + fprintf(stderr, "\t\t%s\n", rc ? "[FAIL]" : "[PASS]");
> + return rc;
> +}
> +
> diff --git a/tools/testing/selftests/lib/selftests.h b/tools/testing/selftests/lib/selftests.h
> new file mode 100644
> index 0000000..6210199
> --- /dev/null
> +++ b/tools/testing/selftests/lib/selftests.h
> @@ -0,0 +1,67 @@
> +#ifndef SELFTESTS_H
> +#define SELFTESTS_H
> +
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <errno.h>
> +
> +typedef enum test_result {
> + TEST_PASS = 0,
> + TEST_FAIL,
> +} test_result_t;
> +
> +test_result_t __assert(int expr, const char *filename, int line, const char *fmt, ...);
> +
> +#define abort(cond) do { \
> + if (!(cond)) { \
> + fprintf(stderr, "%s:%d %s\n", __FILE__, __LINE__, #cond); \
> + perror(""); \
> + exit(EXIT_FAILURE); \
> + } \
> +} while (0)
> +
> +#define pass_if(expr, label, ret) \
> + do { \
> + if (expr) { \
> + ret = TEST_PASS; \
> + goto label; \
> + } \
> + } while (0)
> +
> +/* @expr: a boolean expression
> + * @label: jump here to free resources if it fails
> + * @ret: a test_result_t variable that will hold the result of the test
> + * This can be later returned from the test function.
> + */
> +#define check(expr, label, ret, ...) \
> + do { \
> + ret = __assert(expr, __FILE__, __LINE__, \
> + "Assertion '" #expr "' failed", __VA_ARGS__); \
> + if (!(expr)) { \
> + perror(""); \
> + goto label; \
> + } \
> + } while (0)
> +
> +struct generic_test {
> + const char *name;
> + void *private;
> +
> +
> + void *testcases;
> + int testcase_size;
> + int testcase_count;
> +
> + /* Ends all tests if one fails */
> + int abort_on_fail;
> +
> + test_result_t (*prepare)(void *);
> + test_result_t (*run)(void *);
> + test_result_t (*cleanup)(void *);
> +};
> +
> +test_result_t run_all_tests(struct generic_test *test, void *param);
> +
> +#endif
Otherwise it looks good. Thanks Alex.
More information about the firefly
mailing list