summaryrefslogtreecommitdiff
path: root/lib/drmtest.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2013-08-12 09:31:55 +0200
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-08-12 11:10:26 +0200
commitba0d2acf0ed9faf8025c54857db661d37c3a1339 (patch)
tree4a4f6dd9453bcca4fadb15713bc029827a7e433f /lib/drmtest.c
parent9f6365e4eacc7aa07fc3f9524500d1e217b61bb5 (diff)
lib/drmtest: skip/fail handling
Exitcode handling in igt testcases has too ugly facets in combination with subtests: - When individual subtest needed to be skipped for different reasons we need to painstakingly thread this information through the test to make sure that we still succeed if just one testcase worked (for running it with the simple automake test runner in igt). But it also needs to correctly report the skip exit value if only this one skipped testcase has been run (e.g. when run with piglit or in QA's test infrastructure). - We'd prefer to easily skip (and also fail) subtests without hampering other subtests. Again threading the return value of each subtest through the code is cumbersome. To simplify test case writing use longjmps to be able to get out of subcases easily. But since longjmps are funny things thug it all away into the newly added drmtest_subtest_block macro. Note that if drmtest_skip is called outside of a subtest, but in a testcase with subtests all subsequent subtests will be automatically skipped. Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'lib/drmtest.c')
-rw-r--r--lib/drmtest.c77
1 files changed, 75 insertions, 2 deletions
diff --git a/lib/drmtest.c b/lib/drmtest.c
index cae07a27..767c8dc8 100644
--- a/lib/drmtest.c
+++ b/lib/drmtest.c
@@ -657,6 +657,9 @@ void drmtest_stop_signal_helper(void)
/* subtests helpers */
static bool list_subtests = false;
static char *run_single_subtest = NULL;
+static bool in_subtest = false;
+static bool test_with_subtests = false;
+static bool skip_subtests_henceforth = false;
void drmtest_subtest_init(int argc, char **argv)
{
@@ -667,6 +670,8 @@ void drmtest_subtest_init(int argc, char **argv)
{NULL, 0, 0, 0,}
};
+ test_with_subtests = true;
+
/* supress getopt errors about unknown options */
opterr = 0;
/* restrict the option parsing to long option names to avoid collisions
@@ -695,16 +700,21 @@ out:
*/
bool drmtest_run_subtest(const char *subtest_name)
{
+ assert(in_subtest == false);
+
if (list_subtests) {
printf("%s\n", subtest_name);
return false;
}
+ if (skip_subtests_henceforth)
+ return false;
+
if (!run_single_subtest) {
- return true;
+ return in_subtest = true;
} else {
if (strcmp(subtest_name, run_single_subtest) == 0)
- return true;
+ return in_subtest = true;
return false;
}
@@ -715,6 +725,69 @@ bool drmtest_only_list_subtests(void)
return list_subtests;
}
+static bool skipped_one = false;
+static bool succeeded_one = false;
+static bool failed_one = false;
+static int drmtest_exitcode;
+
+static void exit_subtest(void) __attribute__((noreturn));
+static void exit_subtest(void)
+{
+ in_subtest = false;
+ longjmp(drmtest_subtest_jmpbuf, 1);
+}
+
+void drmtest_skip(void)
+{
+ skipped_one = true;
+ if (in_subtest)
+ exit_subtest();
+ else if (test_with_subtests)
+ skip_subtests_henceforth = true;
+ else
+ exit(77);
+}
+
+void drmtest_success(void)
+{
+ succeeded_one = true;
+ if (in_subtest)
+ exit_subtest();
+}
+
+void drmtest_fail(int exitcode)
+{
+ assert(exitcode != 0 && exitcode != 77);
+
+ if (!failed_one)
+ drmtest_exitcode = exitcode;
+
+ failed_one = true;
+
+ if (in_subtest)
+ exit_subtest();
+ else {
+ assert(!test_with_subtests);
+ exit(exitcode);
+ }
+}
+
+int drmtest_retval(void)
+{
+ if (drmtest_only_list_subtests())
+ return 0;
+
+ /* Calling this without calling one of the above is a failure */
+ assert(skipped_one || succeeded_one || failed_one);
+
+ if (failed_one)
+ return drmtest_exitcode;
+ else if (succeeded_one)
+ return 0;
+ else
+ return 77;
+}
+
static bool env_set(const char *env_var, bool default_value)
{
char *val;