Re: [PATCH 2/4] Add support for table-driven testing.

2013-09-13 Thread Kristian Høgsberg
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 

[PATCH 2/4] Add support for table-driven testing.

2013-09-12 Thread Sam Spilsbury
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
---
 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
+   {
+   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 = 

[PATCH 2/4] Add support for table-driven testing.

2013-09-12 Thread Sam Spilsbury
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
---
 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
+   {
+   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 = 

[PATCH 2/4] Add support for table-driven testing.

2013-09-11 Thread Sam Spilsbury
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
---
 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 27ea9e4..646e1c3 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,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
+   {
+   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++;
-