Hi,
On Wed, Sep 11, 2013 at 1:37 AM, Eoff, Ullysses A <ullysses.a.e...@intel.com> wrote: > > > -----Original Message----- > > From: wayland-devel-bounces+ullysses.a.eoff=intel....@lists.freedesktop.org > > [mailto:wayland-devel- > > bounces+ullysses.a.eoff=intel....@lists.freedesktop.org] On Behalf Of Sam > > Spilsbury > > Sent: Tuesday, September 10, 2013 9:15 AM > > To: wayland-devel@lists.freedesktop.org > > Cc: Sam Spilsbury > > Subject: [PATCH 1/3] Add support for table-driven testing. > > > > 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. > > --- > > tests/weston-test-runner.c | 117 > > ++++++++++++++++++++++++++++----------------- > > tests/weston-test-runner.h | 52 +++++++++++++------- > > 2 files changed, 108 insertions(+), 61 deletions(-) > > > > diff --git a/tests/weston-test-runner.c b/tests/weston-test-runner.c > > index 27ea9e4..1eb93ea 100644 > > --- a/tests/weston-test-runner.c > > +++ b/tests/weston-test-runner.c > > @@ -46,18 +46,81 @@ 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); > > } > > > > +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) { > > t = find_test(argv[1]); > > @@ -66,51 +129,15 @@ int main(int argc, char *argv[]) > > exit(EXIT_FAILURE); > > } > > > > - run_test(t); > > + run_test(t, (void *) t->table_data); > > Should we be iterating though each table_data element here, too? We do actually, see here: > > + 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); > > + } It just isn't particularly obvious because current_test_data is advanced in the iteration condition of the loop. Should that be changed? > > > } > > > > - 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(); > > - } > > - > > - 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"); > > + int number_passed_in_test = 0; > > + total += iterate_test(t, &number_passed_in_test); > > + pass += number_passed_in_test; > > } > > > > - 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 -- Sam Spilsbury _______________________________________________ wayland-devel mailing list wayland-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/wayland-devel