On Fri, Sep 13, 2013 at 10:01:20AM +0800, Sam Spilsbury wrote: > The new TEST_P macro takes a function name and a "data" argument to > point to an arbitrary array of known size of test data. This allows > multiple tests to be run with different datasets. The array is stored > as a void * but advanced by a known size on each iteration. > > The data for each invocation of the test is provided as a "data" argument, > it is the responsibility of the test to cast it to something sensible. > > Also fixed single-test running to only run the tests specified
That's a nice addition. Committed with one tweak, see below. Kristian > --- > tests/weston-test-runner.c | 123 > ++++++++++++++++++++++++++++----------------- > tests/weston-test-runner.h | 52 +++++++++++++------ > 2 files changed, 113 insertions(+), 62 deletions(-) > > diff --git a/tests/weston-test-runner.c b/tests/weston-test-runner.c > index ed5baf0..89eca40 100644 > --- a/tests/weston-test-runner.c > +++ b/tests/weston-test-runner.c > @@ -47,9 +47,9 @@ find_test(const char *name) > } > > static void > -run_test(const struct weston_test *t) > +run_test(const struct weston_test *t, void *data) > { > - t->run(); > + t->run(data); > exit(EXIT_SUCCESS); > } > > @@ -63,12 +63,75 @@ list_tests(void) > fprintf(stderr, " %s\n", t->name); > } > > +static int > +exec_and_report_test(const struct weston_test *t, void *test_data, int > iteration) > +{ > + int success = 0; > + int hardfail = 0; > + siginfo_t info; > + > + pid_t pid = fork(); > + assert(pid >= 0); > + > + if (pid == 0) > + run_test(t, test_data); /* never returns */ > + > + if (waitid(P_ALL, 0, &info, WEXITED)) { > + fprintf(stderr, "waitid failed: %m\n"); > + abort(); > + } > + > + if (test_data) > + fprintf(stderr, "test \"%s/%i\":\t", t->name, iteration); > + else > + fprintf(stderr, "test \"%s\":\t", t->name); > + > + switch (info.si_code) { > + case CLD_EXITED: > + fprintf(stderr, "exit status %d", info.si_status); > + if (info.si_status == EXIT_SUCCESS) > + success = 1; > + break; > + case CLD_KILLED: > + case CLD_DUMPED: > + fprintf(stderr, "signal %d", info.si_status); > + if (info.si_status != SIGABRT) > + hardfail = 1; > + break; > + } > + > + if (t->must_fail) > + success = !success; > + > + if (success && !hardfail) { > + fprintf(stderr, ", pass.\n"); > + return 1; > + } else { > + fprintf(stderr, ", fail.\n"); > + return 0; > + } > +} > + > +/* Returns number of tests and number of pass / fail in param args */ > +static int > +iterate_test(const struct weston_test *t, int *passed) > +{ > + int i; > + void *current_test_data = (void *) t->table_data; > + for (i = 0; i < t->n_elements; ++i, current_test_data += > t->element_size) > + { > + if (exec_and_report_test(t, current_test_data, i)) > + ++(*passed); > + } > + > + return t->n_elements; > +} > + > int main(int argc, char *argv[]) > { > const struct weston_test *t; > - pid_t pid; > - int total, pass; > - siginfo_t info; > + int total = 0; > + int pass = 0; > > if (argc == 2) { > const char *testname = argv[1]; > @@ -86,51 +149,19 @@ int main(int argc, char *argv[]) > exit(EXIT_FAILURE); > } > > - run_test(t); > + int number_passed_in_test = 0; > + total += iterate_test(t, &number_passed_in_test); > + pass += number_passed_in_test; > } > - > - pass = 0; > - for (t = &__start_test_section; t < &__stop_test_section; t++) { > - int success = 0; > - int hardfail = 0; > - > - pid = fork(); > - assert(pid >= 0); > - > - if (pid == 0) > - run_test(t); /* never returns */ > - > - if (waitid(P_ALL, 0, &info, WEXITED)) { > - fprintf(stderr, "waitid failed: %m\n"); > - abort(); > + else > + { We use cuddled else, that is: } else { not } else { > + for (t = &__start_test_section; t < &__stop_test_section; t++) { > + int number_passed_in_test = 0; > + total += iterate_test(t, &number_passed_in_test); > + pass += number_passed_in_test; > } > - > - fprintf(stderr, "test \"%s\":\t", t->name); > - switch (info.si_code) { > - case CLD_EXITED: > - fprintf(stderr, "exit status %d", info.si_status); > - if (info.si_status == EXIT_SUCCESS) > - success = 1; > - break; > - case CLD_KILLED: > - case CLD_DUMPED: > - fprintf(stderr, "signal %d", info.si_status); > - if (info.si_status != SIGABRT) > - hardfail = 1; > - break; > - } > - > - if (t->must_fail) > - success = !success; > - > - if (success && !hardfail) { > - pass++; > - fprintf(stderr, ", pass.\n"); > - } else > - fprintf(stderr, ", fail.\n"); > } > > - total = &__stop_test_section - &__start_test_section; > fprintf(stderr, "%d tests, %d pass, %d fail\n", > total, pass, total - pass); > > diff --git a/tests/weston-test-runner.h b/tests/weston-test-runner.h > index 41df386..457cf31 100644 > --- a/tests/weston-test-runner.h > +++ b/tests/weston-test-runner.h > @@ -1,5 +1,6 @@ > /* > * Copyright © 2012 Intel Corporation > + * Copyright © 2013 Sam Spilsbury <smspil...@gmail.com> > * > * Permission to use, copy, modify, distribute, and sell this software and > * its documentation for any purpose is hereby granted without fee, provided > @@ -23,34 +24,53 @@ > #ifndef _WESTON_TEST_RUNNER_H_ > #define _WESTON_TEST_RUNNER_H_ > > +#include <stdlib.h> > + > #ifdef NDEBUG > #error "Tests must not be built with NDEBUG defined, they rely on assert()." > #endif > > struct weston_test { > const char *name; > - void (*run)(void); > + void (*run)(void *); > + const void *table_data; > + size_t element_size; > + int n_elements; > int must_fail; > -} __attribute__ ((aligned (16))); > +} __attribute__ ((aligned (32))); > > -#define TEST(name) \ > - static void name(void); \ > +#define TEST_BEGIN(name, arg) \ > + static void name(arg) > + > +#define TEST_COMMON(func, name, ret, data, size, n_elem) \ > + static void func(void *); \ > \ > const struct weston_test test##name \ > - __attribute__ ((section ("test_section"))) = { \ > - #name, name, 0 \ > - }; \ > - \ > - static void name(void) > + __attribute__ ((section ("test_section"))) = \ > + { \ > + #name, func, data, size, n_elem, ret \ > + }; > > -#define FAIL_TEST(name) \ > +#define NO_ARG_TEST(name, ret) \ > + TEST_COMMON(wrap##name, name, ret, NULL, 0, 1) \ > static void name(void); \ > + static void wrap##name(void *data) \ > + { \ > + (void) data; \ > + name(); \ > + } \ > \ > - const struct weston_test test##name \ > - __attribute__ ((section ("test_section"))) = { \ > - #name, name, 1 \ > - }; \ > - \ > - static void name(void) > + TEST_BEGIN(name, void) > + > +#define ARG_TEST(name, ret, test_data) \ > + TEST_COMMON(name, name, ret, test_data, \ > + sizeof(test_data[0]), \ > + sizeof(test_data) / sizeof (test_data[0])) \ > + TEST_BEGIN(name, void *data) \ > + > +#define TEST(name) NO_ARG_TEST(name, 0) > +#define FAIL_TEST(name) NO_ARG_TEST(name, 1) > +#define TEST_P(name, data) ARG_TEST(name, 0, data) > +#define FAIL_TEST_P(name, data) ARG_TEST(name, 1, data) > > #endif > -- > 1.8.3.2 > > _______________________________________________ > wayland-devel mailing list > wayland-devel@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/wayland-devel _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel