[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