All of lore.kernel.org
 help / color / mirror / Atom feed
* [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers
@ 2020-02-25 16:52 Arkadiusz Hiler
  2020-02-25 16:52 ` [igt-dev] [PATCH i-g-t 2/9] lib/tests: Add support for redirecting fork output to /dev/null Arkadiusz Hiler
                   ` (10 more replies)
  0 siblings, 11 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:52 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

Because of excessive 'copy and paste' we ended up with multiple copies
of almost the same fork helper. This patch extracts the do_fork helper
out and switches all the tests over to it.

Additionally, preemptively I have extracted the more fancy fork helper
that captures stderr/out + related functions out of igt_describe tests.

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/tests/igt_assert.c               |  35 +++----
 lib/tests/igt_conflicting_args.c     |  25 ++---
 lib/tests/igt_describe.c             | 135 ++++++---------------------
 lib/tests/igt_dynamic_subtests.c     |  18 ----
 lib/tests/igt_fork.c                 |  71 ++++++--------
 lib/tests/igt_invalid_subtest_name.c |  18 ----
 lib/tests/igt_no_exit.c              |  18 ----
 lib/tests/igt_segfault.c             |  59 +++++-------
 lib/tests/igt_simulation.c           | 101 +++++++++-----------
 lib/tests/igt_tests_common.h         |  91 ++++++++++++++++++
 10 files changed, 232 insertions(+), 339 deletions(-)

diff --git a/lib/tests/igt_assert.c b/lib/tests/igt_assert.c
index 1caf5d88..c94ac698 100644
--- a/lib/tests/igt_assert.c
+++ b/lib/tests/igt_assert.c
@@ -38,8 +38,6 @@
 
 #include "igt_tests_common.h"
 
-char test[] = "test";
-char *argv_run[] = { test };
 void (*test_to_run)(void) = NULL;
 
 /*
@@ -55,26 +53,17 @@ void (*test_to_run)(void) = NULL;
 	exec_total++; \
 }
 
-static int do_fork(void)
+static void fake_test(void)
 {
-	int pid, status;
-	int argc;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		argc = ARRAY_SIZE(argv_run);
-		igt_simple_init(argc, argv_run);
-		test_to_run();
-		igt_exit();
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
-
-		return status;
-	}
+	char test[] = "test";
+	char *argv_run[] = { test };
+	int argc = ARRAY_SIZE(argv_run);
+
+	igt_simple_init(argc, argv_run);
+
+	test_to_run();
+
+	igt_exit();
 }
 
 static void test_cmpint_negative(void)
@@ -150,7 +139,7 @@ igt_main
 	 * we inherit the state from the parent, so ...
 	 */
 	test_to_run = test_cmpint_negative;
-	ret = do_fork();
+	ret = do_fork(fake_test);
 	igt_subtest("igt_cmpint_negative")
 		internal_assert_wexited(ret, IGT_EXIT_FAILURE);
 
@@ -158,7 +147,7 @@ igt_main
 		test_fd();
 
 	test_to_run = test_fd_negative;
-	ret = do_fork();
+	ret = do_fork(fake_test);
 	igt_subtest("igt_assert_fd_negative")
 		internal_assert_wexited(ret, IGT_EXIT_FAILURE);
 }
diff --git a/lib/tests/igt_conflicting_args.c b/lib/tests/igt_conflicting_args.c
index f600abd4..b644fd4b 100644
--- a/lib/tests/igt_conflicting_args.c
+++ b/lib/tests/igt_conflicting_args.c
@@ -43,25 +43,12 @@ static int opt_handler(int option, int option_index, void *input)
 	return 0;
 }
 
-static int do_fork(void)
+static void fake_test(void)
 {
 	char test_name[] = "test";
-
 	char *argv[] = { test_name };
 	int argc = ARRAY_SIZE(argv);
 
-	pid_t pid = fork();
-	internal_assert(pid != -1);
-
-	if (pid) {
-		int status;
-		while (waitpid(pid, &status, 0) == -1 && errno == EINTR)
-			;
-
-		return status;
-	}
-
-
 	igt_subtest_init_parse_opts(&argc, argv, short_options, long_options,
 				    "", opt_handler, NULL);
 	igt_subtest("dummy") {}
@@ -73,27 +60,27 @@ int main(int argc, char **argv)
 	/* no conflict */
 	long_options[0] = (struct option) { "iterations", required_argument, NULL, 'i'};
 	short_options = "";
-	internal_assert_wexited(do_fork(), 0);
+	internal_assert_wexited(do_fork(fake_test), 0);
 
 	/* conflict on short option */
 	long_options[0] = (struct option) { "iterations", required_argument, NULL, 'i'};
 	short_options = "h";
-	internal_assert_wsignaled(do_fork(), SIGABRT);
+	internal_assert_wsignaled(do_fork(fake_test), SIGABRT);
 
 	/* conflict on long option name */
 	long_options[0] = (struct option) { "help", required_argument, NULL, 'i'};
 	short_options = "";
-	internal_assert_wsignaled(do_fork(), SIGABRT);
+	internal_assert_wsignaled(do_fork(fake_test), SIGABRT);
 
 	/* conflict on long option 'val' representation vs short option */
 	long_options[0] = (struct option) { "iterations", required_argument, NULL, 'h'};
 	short_options = "";
-	internal_assert_wsignaled(do_fork(), SIGABRT);
+	internal_assert_wsignaled(do_fork(fake_test), SIGABRT);
 
 	/* conflict on long option 'val' representations */
 	long_options[0] = (struct option) { "iterations", required_argument, NULL, 500};
 	short_options = "";
-	internal_assert_wsignaled(do_fork(), SIGABRT);
+	internal_assert_wsignaled(do_fork(fake_test), SIGABRT);
 
 	return 0;
 }
diff --git a/lib/tests/igt_describe.c b/lib/tests/igt_describe.c
index 6f3a4319..7b4fa9af 100644
--- a/lib/tests/igt_describe.c
+++ b/lib/tests/igt_describe.c
@@ -28,9 +28,15 @@
 #include "drmtest.h"
 #include "igt_tests_common.h"
 
+char prog[] = "igt_describe";
+char fake_arg[100];
+char *fake_argv[] = {prog, fake_arg};
+int fake_argc = ARRAY_SIZE(fake_argv);
+
 IGT_TEST_DESCRIPTION("the top level description");
-static void fake_main(int argc, char **argv) {
-	igt_subtest_init(argc, argv);
+static void fake_main(void)
+{
+	igt_subtest_init(fake_argc, fake_argv);
 
 	igt_describe("Basic A");
 	igt_subtest("A")
@@ -101,33 +107,33 @@ static void fake_main(int argc, char **argv) {
 static const char DESCRIBE_ALL_OUTPUT[] = \
 	"the top level description\n"
 	"\n"
-	"SUB A ../lib/tests/igt_describe.c:36:\n"
+	"SUB A ../lib/tests/igt_describe.c:42:\n"
 	"  Basic A\n"
 	"\n"
-	"SUB B ../lib/tests/igt_describe.c:45:\n"
+	"SUB B ../lib/tests/igt_describe.c:51:\n"
 	"  Group with B, C & D\n"
 	"\n"
 	"  Basic B\n"
 	"\n"
-	"SUB C ../lib/tests/igt_describe.c:54:\n"
+	"SUB C ../lib/tests/igt_describe.c:60:\n"
 	"  Group with B, C & D\n"
 	"\n"
 	"  Group with C & D\n"
 	"\n"
 	"  Basic C\n"
 	"\n"
-	"SUB D ../lib/tests/igt_describe.c:58:\n"
+	"SUB D ../lib/tests/igt_describe.c:64:\n"
 	"  Group with B, C & D\n"
 	"\n"
 	"  Group with C & D\n"
 	"\n"
-	"SUB E ../lib/tests/igt_describe.c:66:\n"
+	"SUB E ../lib/tests/igt_describe.c:72:\n"
 	"  NO DOCUMENTATION!\n"
 	"\n"
-	"SUB F ../lib/tests/igt_describe.c:71:\n"
+	"SUB F ../lib/tests/igt_describe.c:77:\n"
 	"  NO DOCUMENTATION!\n"
 	"\n"
-	"SUB G ../lib/tests/igt_describe.c:80:\n"
+	"SUB G ../lib/tests/igt_describe.c:86:\n"
 	"  this description should be so long that it wraps itself nicely in the terminal this\n"
 	"  description should be so long that it wraps itself nicely in the terminal this description\n"
 	"  should be so long that it wraps itself nicely in the terminal this description should be so\n"
@@ -135,17 +141,17 @@ static const char DESCRIBE_ALL_OUTPUT[] = \
 	"  wraps itself nicely in the terminal this description should be so long that it wraps itself\n"
 	"  nicely in the terminal\n"
 	"\n"
-	"SUB F ../lib/tests/igt_describe.c:87:\n"
+	"SUB F ../lib/tests/igt_describe.c:93:\n"
 	"  verylongwordthatshoudlbeprintedeventhoughitspastthewrppinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n"
 	"  verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n"
 	"\n"
-	"SUB G ../lib/tests/igt_describe.c:91:\n"
+	"SUB G ../lib/tests/igt_describe.c:97:\n"
 	"  Subtest with dynamic subsubtests\n\n";
 
 static const char JUST_C_OUTPUT[] = \
 	"the top level description\n"
 	"\n"
-	"SUB C ../lib/tests/igt_describe.c:54:\n"
+	"SUB C ../lib/tests/igt_describe.c:60:\n"
 	"  Group with B, C & D\n"
 	"\n"
 	"  Group with C & D\n"
@@ -153,95 +159,22 @@ static const char JUST_C_OUTPUT[] = \
 	"  Basic C\n"
 	"\n";
 
-static void assert_pipe_empty(int fd)
-{
-	char buf[5];
-	internal_assert(0 == read(fd, buf, sizeof(buf)));
-}
-
-static void read_whole_pipe(int fd, char *buf, size_t buflen)
-{
-	ssize_t readlen;
-	off_t offset;
-
-	offset = 0;
-	while ((readlen = read(fd, buf+offset, buflen-offset))) {
-		if (readlen == -1) {
-			if (errno == EINTR) {
-				continue;
-			} else {
-				printf("read failed with %s\n", strerror(errno));
-				exit(1);
-			}
-		}
-		internal_assert(readlen != -1);
-		offset += readlen;
-	}
-}
-
-static pid_t do_fork(int argc, char **argv, int *out, int *err)
-{
-	int outfd[2], errfd[2];
-	pid_t pid;
-
-	internal_assert(pipe(outfd) != -1);
-	internal_assert(pipe(errfd) != -1);
-
-	pid = fork();
-	internal_assert(pid != -1);
-
-	if (pid == 0) {
-		while (dup2(outfd[1], STDOUT_FILENO) == -1 && errno == EINTR) {}
-		while (dup2(errfd[1], STDERR_FILENO) == -1 && errno == EINTR) {}
-
-		close(outfd[0]);
-		close(outfd[1]);
-		close(errfd[0]);
-		close(errfd[1]);
-
-		fake_main(argc, argv);
-
-		exit(-1);
-	} else {
-		/* close the writing ends */
-		close(outfd[1]);
-		close(errfd[1]);
-
-		*out = outfd[0];
-		*err = errfd[0];
-
-		return pid;
-	}
-}
-
-static int _wait(pid_t pid, int *status) {
-	int ret;
-
-	do {
-		ret = waitpid(pid, status, 0);
-	} while (ret == -1 && errno == EINTR);
-
-	return ret;
-}
-
 int main(int argc, char **argv)
 {
-	char prog[] = "igt_describe";
 	int status;
 	int outfd, errfd;
+	pid_t pid;
 
 	/* describe all subtest */ {
 		static char out[4096];
-		char arg[] = "--describe";
-		char *fake_argv[] = {prog, arg};
-		int fake_argc = ARRAY_SIZE(fake_argv);
+		strncpy(fake_arg, "--describe", sizeof(fake_arg));
 
-		pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+		pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd);
 
 		read_whole_pipe(outfd, out, sizeof(out));
 		assert_pipe_empty(errfd);
 
-		internal_assert(_wait(pid, &status) != -1);
+		internal_assert(safe_wait(pid, &status) != -1);
 		internal_assert(WIFEXITED(status));
 		internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS);
 		internal_assert(0 == strcmp(DESCRIBE_ALL_OUTPUT, out));
@@ -252,16 +185,14 @@ int main(int argc, char **argv)
 
 	/* describe C using a pattern */ {
 		static char out[4096];
-		char arg[] = "--describe=C";
-		char *fake_argv[] = {prog, arg};
-		int fake_argc = ARRAY_SIZE(fake_argv);
+		strncpy(fake_arg, "--describe=C", sizeof(fake_arg));
 
-		pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+		pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd);
 
 		read_whole_pipe(outfd, out, sizeof(out));
 		assert_pipe_empty(errfd);
 
-		internal_assert(_wait(pid, &status) != -1);
+		internal_assert(safe_wait(pid, &status) != -1);
 		internal_assert(WIFEXITED(status));
 		internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS);
 		internal_assert(0 == strcmp(JUST_C_OUTPUT, out));
@@ -272,15 +203,13 @@ int main(int argc, char **argv)
 
 	/* fail describing with a bad pattern */ {
 		static char err[4096];
-		char arg[] = "--describe=Z";
-		char *fake_argv[] = {prog, arg};
-		int fake_argc = ARRAY_SIZE(fake_argv);
+		strncpy(fake_arg, "--describe=Z", sizeof(fake_arg));
 
-		pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+		pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd);
 
 		read_whole_pipe(errfd, err, sizeof(err));
 
-		internal_assert(_wait(pid, &status) != -1);
+		internal_assert(safe_wait(pid, &status) != -1);
 		internal_assert(WIFEXITED(status));
 		internal_assert(WEXITSTATUS(status) == IGT_EXIT_INVALID);
 		internal_assert(strstr(err, "Unknown subtest: Z"));
@@ -291,15 +220,13 @@ int main(int argc, char **argv)
 
 	/* trying to igt_describe a dynamic subsubtest should assert */ {
 		static char err[4096];
-		char arg[] = "--run-subtest=G";
-		char *fake_argv[] = {prog, arg};
-		int fake_argc = ARRAY_SIZE(fake_argv);
+		strncpy(fake_arg, "--run-subtest=G", sizeof(fake_arg));
 
-		pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
+		pid = do_fork_bg_with_pipes(fake_main, &outfd, &errfd);
 
 		read_whole_pipe(errfd, err, sizeof(err));
 
-		internal_assert(_wait(pid, &status) != -1);
+		internal_assert(safe_wait(pid, &status) != -1);
 		internal_assert_wsignaled(status, SIGABRT);
 
 		close(outfd);
diff --git a/lib/tests/igt_dynamic_subtests.c b/lib/tests/igt_dynamic_subtests.c
index 606104c5..bd1e1675 100644
--- a/lib/tests/igt_dynamic_subtests.c
+++ b/lib/tests/igt_dynamic_subtests.c
@@ -29,24 +29,6 @@
 
 #include "igt_tests_common.h"
 
-static int do_fork(void (*test_to_run)(void))
-{
-	int pid, status;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		test_to_run();
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
-
-		return status;
-	}
-}
-
 static void dynamic_subtest_in_normal_subtest(void)
 {
 	char prog[] = "igt_no_exit";
diff --git a/lib/tests/igt_fork.c b/lib/tests/igt_fork.c
index e30584fd..4fd0e0c8 100644
--- a/lib/tests/igt_fork.c
+++ b/lib/tests/igt_fork.c
@@ -35,37 +35,52 @@
 #include "igt_tests_common.h"
 
 char test[] = "test";
-char *argv_run[] = { test };
+char *fake_argv[] = { test };
+int fake_argc = ARRAY_SIZE(fake_argv);
 
 static void igt_fork_vs_skip(void)
 {
+	igt_simple_init(fake_argc, fake_argv);
+
 	igt_fork(i, 1) {
 		igt_skip("skipping");
 	}
 
 	igt_waitchildren();
+
+	igt_exit();
 }
 
 static void igt_fork_vs_assert(void)
 {
+	igt_simple_init(fake_argc, fake_argv);
+
 	igt_fork(i, 1) {
 		igt_assert(0);
 	}
 
 	igt_waitchildren();
+
+	igt_exit();
 }
 
 static void igt_fork_leak(void)
 {
+	igt_simple_init(fake_argc, fake_argv);
+
 	igt_fork(i, 1) {
 		sleep(10);
 	}
+
+	igt_exit();
 }
 
 static void plain_fork_leak(void)
 {
 	int pid;
 
+	igt_simple_init(fake_argc, fake_argv);
+
 	switch (pid = fork()) {
 	case -1:
 		internal_assert(0);
@@ -74,59 +89,21 @@ static void plain_fork_leak(void)
 	default:
 		exit(0);
 	}
+
+	igt_exit();
 }
 
 static void igt_fork_timeout_leak(void)
 {
+	igt_simple_init(fake_argc, fake_argv);
+
 	igt_fork(i, 1) {
 		sleep(10);
 	}
 
 	igt_waitchildren_timeout(1, "library test");
-}
-
-static int do_fork(void (*test_to_run)(void))
-{
-	int pid, status;
-	int argc;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		argc = ARRAY_SIZE(argv_run);
-		igt_simple_init(argc, argv_run);
-		test_to_run();
-		igt_exit();
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
-
-		return status;
-	}
-}
-
-static int do_subtest(void (*test_to_run)(void))
-{
-	int pid, status;
-	int argc;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		argc = ARRAY_SIZE(argv_run);
-		igt_subtest_init(argc, argv_run);
-		test_to_run();
-		igt_exit();
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
 
-		return status;
-	}
+	igt_exit();
 }
 
 static void subtest_leak(void)
@@ -135,6 +112,8 @@ static void subtest_leak(void)
 		mmap(0, 4096, PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
 	const int num_children = 4096 / sizeof(*children);
 
+	igt_subtest_init(fake_argc, fake_argv);
+
 	igt_subtest("fork-leak") {
 		igt_fork(child, num_children)
 			children[child] = getpid();
@@ -148,6 +127,8 @@ static void subtest_leak(void)
 		assert(kill(children[i], 0) == -1 && errno == ESRCH);
 
 	munmap(children, 4096);
+
+	igt_exit();
 }
 
 int main(int argc, char **argv)
@@ -174,6 +155,6 @@ int main(int argc, char **argv)
 	ret = do_fork(plain_fork_leak);
 	internal_assert_wsignaled(ret, SIGABRT);
 
-	ret = do_subtest(subtest_leak);
+	ret = do_fork(subtest_leak);
 	internal_assert_wexited(ret, IGT_EXIT_FAILURE); /* not asserted! */
 }
diff --git a/lib/tests/igt_invalid_subtest_name.c b/lib/tests/igt_invalid_subtest_name.c
index 92e767ab..32c4bcbc 100644
--- a/lib/tests/igt_invalid_subtest_name.c
+++ b/lib/tests/igt_invalid_subtest_name.c
@@ -60,24 +60,6 @@ static void nonexisting_subtest(void)
 	igt_exit();
 }
 
-static int do_fork(void (*test_to_run)(void))
-{
-	int pid, status;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		test_to_run();
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
-
-		return status;
-	}
-}
-
 int main(int argc, char **argv)
 {
 	int ret;
diff --git a/lib/tests/igt_no_exit.c b/lib/tests/igt_no_exit.c
index 82f00b52..d303eba7 100644
--- a/lib/tests/igt_no_exit.c
+++ b/lib/tests/igt_no_exit.c
@@ -56,24 +56,6 @@ static void no_exit(void)
 		;
 }
 
-static int do_fork(void (*test_to_run)(void))
-{
-	int pid, status;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		test_to_run();
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
-
-		return status;
-	}
-}
-
 int main(int argc, char **argv)
 {
 	int ret;
diff --git a/lib/tests/igt_segfault.c b/lib/tests/igt_segfault.c
index 0d872f67..38c040a6 100644
--- a/lib/tests/igt_segfault.c
+++ b/lib/tests/igt_segfault.c
@@ -48,51 +48,38 @@
 bool simple;
 bool runa;
 bool runc;
-char test[] = "test";
-char *argv_run[] = { test };
 
 static void crashme(void)
 {
 	raise(SIGSEGV);
 }
 
-static int do_fork(void)
+static void fake_test(void)
 {
-	int pid, status;
-	int argc;
-
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		argc = ARRAY_SIZE(argv_run);
-		if (simple) {
-			igt_simple_init(argc, argv_run);
-			crashme();
+	char prog[] = "test";
+	char *fake_argv[] = { prog };
+	int fake_argc = ARRAY_SIZE(fake_argv);
 
-			igt_exit();
-		} else {
-			igt_subtest_init(argc, argv_run);
 
-			if(runa)
-				igt_subtest("A")
-					;
+	if (simple) {
+		igt_simple_init(fake_argc, fake_argv);
+		crashme();
 
-			igt_subtest("B")
-				crashme();
+		igt_exit();
+	} else {
+		igt_subtest_init(fake_argc, fake_argv);
+		if(runa)
+			igt_subtest("A")
+				;
 
-			if(runc)
-				igt_subtest("C")
-					;
+		igt_subtest("B")
+			crashme();
 
-			igt_exit();
-		}
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
+		if(runc)
+			igt_subtest("C")
+				;
 
-		return status;
+		igt_exit();
 	}
 }
 
@@ -104,20 +91,20 @@ int main(int argc, char **argv)
 	runc=false;
 	igt_info("Simple test.\n");
 	fflush(stdout);
-	internal_assert_wsignaled(do_fork(), SIGSEGV);
+	internal_assert_wsignaled(do_fork(fake_test), SIGSEGV);
 
 	/* Test crash in a single subtest is reported */
 	simple = false;
 	igt_info("Single subtest.\n");
 	fflush(stdout);
-	internal_assert_wexited(do_fork(), SIGSEGV + 128);
+	internal_assert_wexited(do_fork(fake_test), SIGSEGV + 128);
 
 	/* Test crash in a subtest following a pass is reported */
 	simple = false;
 	runa=true;
 	igt_info("Passing then crashing subtest.\n");
 	fflush(stdout);
-	internal_assert_wexited(do_fork(), SIGSEGV + 128);
+	internal_assert_wexited(do_fork(fake_test), SIGSEGV + 128);
 
 	/* Test crash in a subtest preceeding a pass is reported */
 	simple = false;
@@ -125,7 +112,7 @@ int main(int argc, char **argv)
 	runc=true;
 	igt_info("Crashing then passing subtest.\n");
 	fflush(stdout);
-	internal_assert_wexited(do_fork(), SIGSEGV + 128);
+	internal_assert_wexited(do_fork(fake_test), SIGSEGV + 128);
 
 	return 0;
 }
diff --git a/lib/tests/igt_simulation.c b/lib/tests/igt_simulation.c
index 3f3cd88f..a0ea7000 100644
--- a/lib/tests/igt_simulation.c
+++ b/lib/tests/igt_simulation.c
@@ -40,59 +40,44 @@ bool list_subtests;
 bool in_fixture;
 bool in_subtest;
 
-char test[] = "test";
-char list[] = "--list-subtests";
-char *argv_list[] = { test, list };
-char *argv_run[] = { test };
-
-static int do_fork(void)
+static void fake_test(void)
 {
-	int pid, status;
+	char test[] = "test";
+	char list[] = "--list-subtests";
+	char *argv_list[] = { test, list };
+	char *argv_run[] = { test };
 	int argc;
 
-	switch (pid = fork()) {
-	case -1:
-		internal_assert(0);
-	case 0:
-		if (simple) {
-			argc = 1;
-			igt_simple_init(argc, argv_run);
+	if (simple) {
+		argc = 1;
+		igt_simple_init(argc, argv_run);
 
-			igt_skip_on_simulation();
+		igt_skip_on_simulation();
 
-			igt_exit();
+		igt_exit();
+	} else {
+		if (list_subtests) {
+			argc = 2;
+			igt_subtest_init(argc, argv_list);
 		} else {
-			if (list_subtests) {
-				argc = 2;
-				igt_subtest_init(argc, argv_list);
-			} else {
-				argc = 1;
-				igt_subtest_init(argc, argv_run);
-			}
-
-			if (in_fixture) {
-				igt_fixture
-					igt_skip_on_simulation();
-			} if (in_subtest) {
-				igt_subtest("sim")
-					igt_skip_on_simulation();
-			} else
-				igt_skip_on_simulation();
-
-			if (!in_subtest)
-				igt_subtest("foo")
-					;
-
-			igt_exit();
+			argc = 1;
+			igt_subtest_init(argc, argv_run);
 		}
-	default:
-		while (waitpid(pid, &status, 0) == -1 &&
-		       errno == EINTR)
-			;
 
-		internal_assert(WIFEXITED(status));
+		if (in_fixture) {
+			igt_fixture
+				igt_skip_on_simulation();
+		} if (in_subtest) {
+			igt_subtest("sim")
+				igt_skip_on_simulation();
+		} else
+			igt_skip_on_simulation();
+
+		if (!in_subtest)
+			igt_subtest("foo")
+				;
 
-		return status;
+		igt_exit();
 	}
 }
 
@@ -101,10 +86,10 @@ int main(int argc, char **argv)
 	/* simple tests */
 	simple = true;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP);
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 	/* subtests, list mode */
 	simple = false;
@@ -112,28 +97,28 @@ int main(int argc, char **argv)
 
 	in_fixture = false;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 	in_fixture = true;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	in_fixture = false;
 	in_subtest = true;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	/* subtest, run mode */
@@ -142,29 +127,29 @@ int main(int argc, char **argv)
 
 	in_fixture = false;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP);
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	in_fixture = true;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP);
 
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	in_fixture = false;
 	in_subtest = true;
 	internal_assert(setenv("INTEL_SIMULATION", "1", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SKIP);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SKIP);
 
 
 	internal_assert(setenv("INTEL_SIMULATION", "0", 1) == 0);
-	internal_assert(WEXITSTATUS(do_fork()) == IGT_EXIT_SUCCESS);
+	internal_assert(WEXITSTATUS(do_fork(fake_test)) == IGT_EXIT_SUCCESS);
 
 
 	return 0;
diff --git a/lib/tests/igt_tests_common.h b/lib/tests/igt_tests_common.h
index e66ee37c..b3da3b34 100644
--- a/lib/tests/igt_tests_common.h
+++ b/lib/tests/igt_tests_common.h
@@ -26,6 +26,8 @@
 #define IGT_LIB_TESTS_COMMON_H
 
 #include <assert.h>
+#include <sys/wait.h>
+#include <errno.h>
 
 /*
  * We need to hide assert from the cocci igt test refactor spatch.
@@ -46,4 +48,93 @@ static inline void internal_assert_wsignaled(int wstatus, int signal)
 	internal_assert(WIFSIGNALED(wstatus) &&
 			WTERMSIG(wstatus) == signal);
 }
+
+static inline int do_fork(void (*test_to_run)(void))
+{
+	int pid, status;
+
+	switch (pid = fork()) {
+	case -1:
+		internal_assert(0);
+	case 0:
+		test_to_run();
+	default:
+		while (waitpid(pid, &status, 0) == -1 &&
+		       errno == EINTR)
+			;
+
+		return status;
+	}
+}
+
+static inline pid_t do_fork_bg_with_pipes(void (*test_to_run)(void), int *out, int *err)
+{
+	int outfd[2], errfd[2];
+	pid_t pid;
+
+	internal_assert(pipe(outfd) != -1);
+	internal_assert(pipe(errfd) != -1);
+
+	pid = fork();
+	internal_assert(pid != -1);
+
+	if (pid == 0) {
+		while (dup2(outfd[1], STDOUT_FILENO) == -1 && errno == EINTR) {}
+		while (dup2(errfd[1], STDERR_FILENO) == -1 && errno == EINTR) {}
+
+		close(outfd[0]);
+		close(outfd[1]);
+		close(errfd[0]);
+		close(errfd[1]);
+
+		test_to_run();
+
+		exit(-1);
+	} else {
+		/* close the writing ends */
+		close(outfd[1]);
+		close(errfd[1]);
+
+		*out = outfd[0];
+		*err = errfd[0];
+
+		return pid;
+	}
+}
+
+static inline int safe_wait(pid_t pid, int *status) {
+	int ret;
+
+	do {
+		ret = waitpid(pid, status, 0);
+	} while (ret == -1 && errno == EINTR);
+
+	return ret;
+}
+
+static inline void assert_pipe_empty(int fd)
+{
+	char buf[5];
+	internal_assert(0 == read(fd, buf, sizeof(buf)));
+}
+
+static inline void read_whole_pipe(int fd, char *buf, size_t buflen)
+{
+	ssize_t readlen;
+	off_t offset;
+
+	offset = 0;
+	while ((readlen = read(fd, buf+offset, buflen-offset))) {
+		if (readlen == -1) {
+			if (errno == EINTR) {
+				continue;
+			} else {
+				printf("read failed with %s\n", strerror(errno));
+				exit(1);
+			}
+		}
+		internal_assert(readlen != -1);
+		offset += readlen;
+	}
+}
 #endif
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 2/9] lib/tests: Add support for redirecting fork output to /dev/null
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
@ 2020-02-25 16:52 ` Arkadiusz Hiler
  2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 3/9] lib: Make it possible to abort the whole execution from inside of a test Arkadiusz Hiler
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:52 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

Trying to read interleaved writes is a bit tricky, so let's just use
/dev/null if we care about contents on only one of those pipes.

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/tests/igt_tests_common.h | 35 +++++++++++++++++++++++++++--------
 1 file changed, 27 insertions(+), 8 deletions(-)

diff --git a/lib/tests/igt_tests_common.h b/lib/tests/igt_tests_common.h
index b3da3b34..f285d657 100644
--- a/lib/tests/igt_tests_common.h
+++ b/lib/tests/igt_tests_common.h
@@ -28,6 +28,8 @@
 #include <assert.h>
 #include <sys/wait.h>
 #include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
 
 /*
  * We need to hide assert from the cocci igt test refactor spatch.
@@ -72,19 +74,32 @@ static inline pid_t do_fork_bg_with_pipes(void (*test_to_run)(void), int *out, i
 	int outfd[2], errfd[2];
 	pid_t pid;
 
-	internal_assert(pipe(outfd) != -1);
-	internal_assert(pipe(errfd) != -1);
+	if (out != NULL)
+		internal_assert(pipe(outfd) != -1);
+
+	if (err != NULL)
+		internal_assert(pipe(errfd) != -1);
 
 	pid = fork();
 	internal_assert(pid != -1);
 
 	if (pid == 0) {
+		/* we'll leak the /dev/null fds, let them die with the forked
+		 * process, also close reading ends if they are any */
+		if (out == NULL)
+			outfd[1] = open("/dev/null", O_WRONLY);
+		else
+			close(outfd[0]);
+
+		if (err == NULL)
+			errfd[1] = open("/dev/null", O_WRONLY);
+		else
+			close(errfd[0]);
+
 		while (dup2(outfd[1], STDOUT_FILENO) == -1 && errno == EINTR) {}
 		while (dup2(errfd[1], STDERR_FILENO) == -1 && errno == EINTR) {}
 
-		close(outfd[0]);
 		close(outfd[1]);
-		close(errfd[0]);
 		close(errfd[1]);
 
 		test_to_run();
@@ -92,11 +107,15 @@ static inline pid_t do_fork_bg_with_pipes(void (*test_to_run)(void), int *out, i
 		exit(-1);
 	} else {
 		/* close the writing ends */
-		close(outfd[1]);
-		close(errfd[1]);
+		if (out != NULL) {
+			close(outfd[1]);
+			*out = outfd[0];
+		}
 
-		*out = outfd[0];
-		*err = errfd[0];
+		if (err != NULL) {
+			close(errfd[1]);
+			*err = errfd[0];
+		}
 
 		return pid;
 	}
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 3/9] lib: Make it possible to abort the whole execution from inside of a test
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
  2020-02-25 16:52 ` [igt-dev] [PATCH i-g-t 2/9] lib/tests: Add support for redirecting fork output to /dev/null Arkadiusz Hiler
@ 2020-02-25 16:55 ` Arkadiusz Hiler
  2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 4/9] runner/runner_tests: Extract helper for inspecting test result Arkadiusz Hiler
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:55 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

igt_abort_on_f() is introduced which does very little cleanup and causes
a hard exit() of the test binary with a unique exit code
(IGT_EXIT_ABORT).

The exit code informs the monitoring process that there is a critical
issue with the testing environment which may have an impact on the
results if testing continues.

v2: Add a meta_test

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/igt_core.c        |  48 ++++++++-
 lib/igt_core.h        |  29 ++++++
 lib/tests/igt_abort.c | 227 ++++++++++++++++++++++++++++++++++++++++++
 lib/tests/meson.build |   1 +
 tests/meta_test.c     |   3 +
 5 files changed, 305 insertions(+), 3 deletions(-)
 create mode 100644 lib/tests/igt_abort.c

diff --git a/lib/igt_core.c b/lib/igt_core.c
index 51041793..58794bef 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -587,6 +587,7 @@ static void ftrace_dump_on_oops(bool enable)
 }
 
 bool igt_exit_called;
+bool igt_is_aborting;
 static void common_exit_handler(int sig)
 {
 	if (!igt_only_list_subtests()) {
@@ -595,7 +596,7 @@ static void common_exit_handler(int sig)
 
 	/* When not killed by a signal check that igt_exit() has been properly
 	 * called. */
-	assert(sig != 0 || igt_exit_called);
+	assert(sig != 0 || igt_exit_called || igt_is_aborting);
 }
 
 static void print_line_wrapping(const char *indent, const char *text)
@@ -1944,6 +1945,48 @@ void __igt_fail_assert(const char *domain, const char *file, const int line,
 	igt_fail(IGT_EXIT_FAILURE);
 }
 
+static void kill_children(void)
+{
+	for (int c = 0; c < num_test_children; c++)
+		kill(test_children[c], SIGKILL);
+}
+
+void __igt_abort(const char *domain, const char *file, const int line,
+		 const char *func, const char *expression,
+		 const char *f, ...)
+{
+	va_list args;
+	int err = errno;
+
+	igt_is_aborting = true;
+
+	igt_log(domain, IGT_LOG_CRITICAL,
+		"Test abort in function %s, file %s:%i:\n", func, file,
+		line);
+	igt_log(domain, IGT_LOG_CRITICAL, "abort condition: %s\n", expression);
+	if (err)
+		igt_log(domain, IGT_LOG_CRITICAL, "Last errno: %i, %s\n", err,
+			strerror(err));
+
+	if (f) {
+		va_start(args, f);
+		igt_vlog(domain, IGT_LOG_CRITICAL, f, args);
+		va_end(args);
+	}
+
+	/* just try our best, we are aborting the execution anyway */
+	kill_children();
+
+	print_backtrace();
+
+	if (running_under_gdb())
+		abort();
+
+	_igt_log_buffer_dump();
+
+	exit(IGT_EXIT_ABORT);
+}
+
 /**
  * igt_exit:
  *
@@ -1993,8 +2036,7 @@ void igt_exit(void)
 			 command_str, igt_exitcode);
 	igt_debug("Exiting with status code %d\n", igt_exitcode);
 
-	for (int c = 0; c < num_test_children; c++)
-		kill(test_children[c], SIGKILL);
+	kill_children();
 	assert(!num_test_children);
 
 	assert(waitpid(-1, &tmp, WNOHANG) == -1 && errno == ECHILD);
diff --git a/lib/igt_core.h b/lib/igt_core.h
index c17a7ba8..a79b41af 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -123,6 +123,14 @@ struct _GKeyFile *igt_load_igtrc(void);
  */
 #define IGT_EXIT_FAILURE 98
 
+/**
+ * IGT_EXIT_ABORT
+ *
+ * Exit status indicating a severe test/enviroment failure, any continued
+ * testing past this point can yeild unexpected reasults and is not recommended
+ */
+#define IGT_EXIT_ABORT 112
+
 bool __igt_fixture(void);
 void __igt_fixture_complete(void);
 void __igt_fixture_end(void) __attribute__((noreturn));
@@ -499,6 +507,11 @@ void __igt_fail_assert(const char *domain, const char *file,
 		       const int line, const char *func, const char *assertion,
 		       const char *format, ...)
 	__attribute__((noreturn));
+__attribute__((format(printf, 6, 7)))
+void __igt_abort(const char *domain, const char *file, const int line,
+		 const char *func, const char *expression,
+		 const char *f, ...)
+	__attribute__((noreturn));
 void igt_exit(void) __attribute__((noreturn));
 void igt_fatal_error(void) __attribute__((noreturn));
 
@@ -1027,6 +1040,22 @@ void igt_describe_f(const char *fmt, ...);
 	else igt_debug("Test requirement passed: !(%s)\n", #expr); \
 } while (0)
 
+
+/**
+ * igt_abort_on_f:
+ * @expr: condition to test
+ * @...: format string and optional arguments
+ *
+ * Aborts current execution if a condition is met.
+ *
+ * Should be used only when there is a serious issue with the environment and
+ * any further testing may be affected by it.
+ */
+#define igt_abort_on_f(expr, f...) \
+	do { if ((expr)) \
+		__igt_abort(IGT_LOG_DOMAIN, __FILE__, __LINE__, __func__, #expr , f); \
+	} while (0)
+
 /* fork support code */
 bool __igt_fork(void);
 
diff --git a/lib/tests/igt_abort.c b/lib/tests/igt_abort.c
new file mode 100644
index 00000000..53b7d4fd
--- /dev/null
+++ b/lib/tests/igt_abort.c
@@ -0,0 +1,227 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ *
+ */
+
+#include "igt_core.h"
+#include "drmtest.h"
+
+#include "igt_tests_common.h"
+
+char test[] = "test";
+char *fake_argv[] = { test };
+int fake_argc = ARRAY_SIZE(fake_argv);
+
+static void fake_simple_test(void)
+{
+	igt_simple_init(fake_argc, fake_argv);
+
+	igt_abort_on_f(true, "I'm out!\n");
+
+	exit(0); /* unreachable */
+}
+
+static void fake_fixture_test(void)
+{
+	igt_subtest_init(fake_argc, fake_argv);
+
+	igt_fixture {
+		igt_abort_on_f(true, "I'm out!\n");
+	}
+
+	exit(0); /* unreachable */
+}
+
+static void fake_outside_fixture_test(void)
+{
+	igt_subtest_init(fake_argc, fake_argv);
+
+	igt_abort_on_f(true, "I'm out!\n");
+
+	exit(0); /* unreachable */
+}
+
+static void fake_subtest_test(void)
+{
+	igt_subtest_init(fake_argc, fake_argv);
+
+	igt_subtest("A")
+		;
+
+	igt_subtest("B")
+		igt_abort_on_f(true, "I'm out!\n");
+
+	igt_subtest("C")
+		exit(0); /* unreachable */
+
+	exit(0); /* unreachable */
+}
+
+static void fake_dynamic_test(void)
+{
+	igt_subtest_init(fake_argc, fake_argv);
+
+	igt_subtest_with_dynamic("A") {
+		igt_dynamic("AA")
+			;
+		igt_dynamic("AB")
+			igt_abort_on_f(true, "I'm out!\n");
+
+		igt_dynamic("AC")
+			exit(0); /* unreachable */
+
+	}
+
+	igt_subtest("B")
+		exit(0); /* unreachable */
+
+	exit(0); /* unreachable */
+}
+
+static void fake_outside_dynamic_test(void)
+{
+	igt_subtest_init(fake_argc, fake_argv);
+
+	igt_subtest_with_dynamic("A") {
+		igt_dynamic("AA")
+			;
+
+		igt_abort_on_f(true, "I'm out!\n");
+
+		igt_dynamic("AB")
+			exit(0); /* unreachable */
+
+		igt_dynamic("AC")
+			exit(0); /* unreachable */
+
+	}
+
+	igt_subtest("B")
+		exit(0); /* unreachable */
+
+	exit(0); /* unreachable */
+}
+
+int main(int argc, char **argv)
+{
+	int status;
+	pid_t pid;
+
+	/* make sure that we log the message and can abort from a simple test*/ {
+		static char err[4096];
+		int errfd;
+
+		pid = do_fork_bg_with_pipes(fake_simple_test, NULL, &errfd);
+
+		read_whole_pipe(errfd, err, sizeof(err));
+
+		internal_assert(strstr(err, "CRITICAL: Test abort"));
+		internal_assert(strstr(err, "I'm out!"));
+
+		internal_assert(safe_wait(pid, &status) != -1);
+		internal_assert_wexited(status, IGT_EXIT_ABORT);
+	}
+
+	/* make sure that we can abort from a fixture */ {
+		pid = do_fork_bg_with_pipes(fake_fixture_test, NULL, NULL);
+		internal_assert(safe_wait(pid, &status) != -1);
+		internal_assert_wexited(status, IGT_EXIT_ABORT);
+	}
+
+	/* make sure that we can abort from outside fixture/subtest */ {
+		pid = do_fork_bg_with_pipes(fake_outside_fixture_test, NULL, NULL);
+		internal_assert(safe_wait(pid, &status) != -1);
+		internal_assert_wexited(status, IGT_EXIT_ABORT);
+	}
+
+	/* make sure we abort during B and don't see B's end/C start */ {
+		static char out[4096];
+		int outfd;
+
+		pid = do_fork_bg_with_pipes(fake_subtest_test, &outfd, NULL);
+
+		read_whole_pipe(outfd, out, sizeof(out));
+
+		internal_assert(safe_wait(pid, &status) != -1);
+		internal_assert_wexited(status, IGT_EXIT_ABORT);
+
+		internal_assert(strstr(out, "Starting subtest: A"));
+		internal_assert(strstr(out, "Subtest A:"));
+
+		internal_assert(strstr(out, "Starting subtest: B"));
+		internal_assert(!strstr(out, "Subtest B:"));
+
+		internal_assert(!strstr(out, "Starting subtest: C"));
+
+		close(outfd);
+	}
+
+	/* make sure we abort during AB and don't see AC/B */ {
+		static char out[4096];
+		int outfd;
+
+		pid = do_fork_bg_with_pipes(fake_dynamic_test, &outfd, NULL);
+
+		read_whole_pipe(outfd, out, sizeof(out));
+
+		internal_assert(safe_wait(pid, &status) != -1);
+		internal_assert_wexited(status, IGT_EXIT_ABORT);
+
+		internal_assert(strstr(out, "Starting subtest: A"));
+		internal_assert(strstr(out, "Starting dynamic subtest: AA"));
+		internal_assert(strstr(out, "Dynamic subtest AA:"));
+
+		internal_assert(strstr(out, "Starting dynamic subtest: AB"));
+		internal_assert(!strstr(out, "Dynamic subtest AB:"));
+
+		internal_assert(!strstr(out, "Starting subtest: B"));
+
+		close(outfd);
+
+	}
+
+	/* make sure we abort between AA and AB */ {
+		static char out[4096];
+		int outfd;
+
+		pid = do_fork_bg_with_pipes(fake_outside_dynamic_test, &outfd, NULL);
+
+		read_whole_pipe(outfd, out, sizeof(out));
+
+		internal_assert(safe_wait(pid, &status) != -1);
+		internal_assert_wexited(status, IGT_EXIT_ABORT);
+
+		internal_assert(strstr(out, "Starting subtest: A"));
+		internal_assert(strstr(out, "Starting dynamic subtest: AA"));
+		internal_assert(strstr(out, "Dynamic subtest AA:"));
+
+		internal_assert(!strstr(out, "Starting dynamic subtest: AB"));
+		internal_assert(!strstr(out, "Dynamic subtest AB:"));
+
+		internal_assert(!strstr(out, "Starting subtest: B"));
+
+		close(outfd);
+
+	}
+
+	return 0;
+}
diff --git a/lib/tests/meson.build b/lib/tests/meson.build
index 6cd8cb0e..22aa19da 100644
--- a/lib/tests/meson.build
+++ b/lib/tests/meson.build
@@ -1,5 +1,6 @@
 lib_tests = [
 	'igt_assert',
+	'igt_abort',
 	'igt_can_fail',
 	'igt_can_fail_simple',
 	'igt_conflicting_args',
diff --git a/tests/meta_test.c b/tests/meta_test.c
index a67b4c5e..c37610c7 100644
--- a/tests/meta_test.c
+++ b/tests/meta_test.c
@@ -149,6 +149,9 @@ igt_main
 	igt_subtest("piglit-timeout")
 		test_piglit_timeout();
 
+	igt_subtest("abort")
+		igt_abort_on_f(true, "ojoj\n");
+
 	igt_subtest("generate-panic")
 		test_panic();
 }
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 4/9] runner/runner_tests: Extract helper for inspecting test result
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
  2020-02-25 16:52 ` [igt-dev] [PATCH i-g-t 2/9] lib/tests: Add support for redirecting fork output to /dev/null Arkadiusz Hiler
  2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 3/9] lib: Make it possible to abort the whole execution from inside of a test Arkadiusz Hiler
@ 2020-02-25 16:55 ` Arkadiusz Hiler
  2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 5/9] runner: Abort the run when test exits with IGT_EXIT_ABORT Arkadiusz Hiler
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:55 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

to make this bit of code more readable and to reuse it in the following patch

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 runner/runner_tests.c | 37 ++++++++++++++++++++++++-------------
 1 file changed, 24 insertions(+), 13 deletions(-)

diff --git a/runner/runner_tests.c b/runner/runner_tests.c
index 2f4e0abb..139ee9fd 100644
--- a/runner/runner_tests.c
+++ b/runner/runner_tests.c
@@ -32,6 +32,23 @@ static const char testdatadir[] = TESTDATA_DIRECTORY;
 /* The total number of test binaries in runner/testdata/ */
 #define NUM_TESTDATA_BINARIES 4
 
+static const char *igt_get_result(struct json_object *tests, const char* testname)
+{
+	struct json_object *obj;
+
+	igt_assert(json_object_object_get_ex(tests, testname, &obj));
+	igt_assert(json_object_object_get_ex(obj, "result", &obj));
+
+	return json_object_get_string(obj);
+}
+
+static void igt_assert_no_result_for(struct json_object *tests, const char* testname)
+{
+	struct json_object *obj;
+	igt_assert(!json_object_object_get_ex(tests, testname, &obj));
+}
+
+
 static void igt_assert_eqstr(const char *one, const char *two)
 {
 	if (one == NULL && two == NULL)
@@ -1438,7 +1455,7 @@ igt_main
 
 		igt_subtest("dynamic-subtests-in-testlist") {
 			struct execute_state state;
-			struct json_object *results, *obj;
+			struct json_object *results, *tests;
 			const char *argv[] = { "runner",
 					       "--test-list", filename,
 					       testdatadir,
@@ -1459,16 +1476,13 @@ igt_main
 			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 				     "Results parsing failed\n");
 
-			obj = results;
-			igt_assert(json_object_object_get_ex(obj, "tests", &obj));
+			igt_assert(json_object_object_get_ex(results, "tests", &tests));
 
 			/* Check that the dynamic subtest we didn't request is not reported */
-			igt_assert(!json_object_object_get_ex(obj, "igt@dynamic@dynamic-subtest@failing", NULL));
+			igt_assert_no_result_for(tests, "igt@dynamic@dynamic-subtest@failing");
 
 			/* Check that the dynamic subtest we did request is */
-			igt_assert(json_object_object_get_ex(obj, "igt@dynamic@dynamic-subtest@passing", &obj));
-			igt_assert(json_object_object_get_ex(obj, "result", &obj));
-			igt_assert_eqstr(json_object_get_string(obj), "pass");
+			igt_assert_eqstr(igt_get_result(tests, "igt@dynamic@dynamic-subtest@passing"), "pass");
 
 			igt_assert_eq(json_object_put(results), 1);
 		}
@@ -1496,7 +1510,7 @@ igt_main
 
 		igt_subtest("dynamic-subtest-failure-should-not-cause-warn") {
 			struct execute_state state;
-			struct json_object *results, *obj;
+			struct json_object *results, *tests;
 			const char *argv[] = { "runner",
 					       "-t", "dynamic",
 					       testdatadir,
@@ -1513,12 +1527,9 @@ igt_main
 			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
 				     "Results parsing failed\n");
 
-			obj = results;
-			igt_assert(json_object_object_get_ex(obj, "tests", &obj));
-			igt_assert(json_object_object_get_ex(obj, "igt@dynamic@dynamic-subtest@passing", &obj));
-			igt_assert(json_object_object_get_ex(obj, "result", &obj));
+			igt_assert(json_object_object_get_ex(results, "tests", &tests));
 
-			igt_assert_eqstr(json_object_get_string(obj), "pass");
+			igt_assert_eqstr(igt_get_result(tests, "igt@dynamic@dynamic-subtest@passing"), "pass");
 
 			igt_assert_eq(json_object_put(results), 1);
 		}
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 5/9] runner: Abort the run when test exits with IGT_EXIT_ABORT
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (2 preceding siblings ...)
  2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 4/9] runner/runner_tests: Extract helper for inspecting test result Arkadiusz Hiler
@ 2020-02-25 16:55 ` Arkadiusz Hiler
  2020-02-25 16:56 ` [igt-dev] [PATCH i-g-t 6/9] lib/chamelium: Clear error after checking if chamelium is reachable Arkadiusz Hiler
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:55 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

Now that the IGT tests have a mechanism for signaling broken testing
conditions we can stop the run on the first test that has noticed it,
and possibly has triggered that state.

Traditionally run would have continued with that test failing and the
side effects would trickle down into the other tests causing a lot of
skip/fails.

v2: extra explanations, small cleanup (Petri)

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 runner/executor.c                             |   3 +
 .../aborted-after-a-test/reference.json       |   6 +
 .../aborted-on-boot/reference.json            |   6 +
 .../dmesg-escapes/reference.json              |   3 +
 .../dmesg-results/reference.json              |   5 +
 .../reference.json                            |   3 +
 .../reference.json                            |   3 +
 .../dmesg-warn-level/reference.json           |   3 +
 .../reference.json                            |   3 +
 .../dynamic-subtests/reference.json           |   3 +
 .../empty-result-files/reference.json         |   3 +
 .../reference.json                            |   5 +
 .../json_tests_data/normal-run/reference.json |   5 +
 .../reference.json                            |   4 +
 .../notrun-results/reference.json             |   5 +
 .../piglit-style-dmesg/reference.json         |   5 +
 .../unprintable-characters/reference.json     |   5 +-
 .../warnings-with-dmesg-warns/reference.json  |   5 +
 .../json_tests_data/warnings/reference.json   |   5 +
 runner/resultgen.c                            |  31 ++
 runner/runner_tests.c                         | 290 +++++++++++++++++-
 runner/testdata/abort-dynamic.c               |  46 +++
 runner/testdata/abort-fixture.c               |  37 +++
 runner/testdata/abort-simple.c                |  29 ++
 runner/testdata/abort.c                       |  36 +++
 runner/testdata/meson.build                   |   4 +
 26 files changed, 547 insertions(+), 6 deletions(-)
 create mode 100644 runner/testdata/abort-dynamic.c
 create mode 100644 runner/testdata/abort-fixture.c
 create mode 100644 runner/testdata/abort-simple.c
 create mode 100644 runner/testdata/abort.c

diff --git a/runner/executor.c b/runner/executor.c
index 72e45b65..95c11897 100644
--- a/runner/executor.c
+++ b/runner/executor.c
@@ -1065,6 +1065,9 @@ static int monitor_output(pid_t child,
 					fdatasync(outputs[_F_JOURNAL]);
 				}
 
+				if (status == IGT_EXIT_ABORT)
+					aborting = true;
+
 				if (time_spent)
 					*time_spent = time;
 			}
diff --git a/runner/json_tests_data/aborted-after-a-test/reference.json b/runner/json_tests_data/aborted-after-a-test/reference.json
index 583242c7..0776f758 100644
--- a/runner/json_tests_data/aborted-after-a-test/reference.json
+++ b/runner/json_tests_data/aborted-after-a-test/reference.json
@@ -60,6 +60,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":1,
@@ -72,6 +73,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":1,
@@ -84,6 +86,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -96,6 +99,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -108,6 +112,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
@@ -120,6 +125,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
diff --git a/runner/json_tests_data/aborted-on-boot/reference.json b/runner/json_tests_data/aborted-on-boot/reference.json
index d354fbac..75f19466 100644
--- a/runner/json_tests_data/aborted-on-boot/reference.json
+++ b/runner/json_tests_data/aborted-on-boot/reference.json
@@ -54,6 +54,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":5,
       "fail":1,
@@ -66,6 +67,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":5,
       "fail":1,
@@ -78,6 +80,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
@@ -90,6 +93,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -102,6 +106,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
@@ -114,6 +119,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
diff --git a/runner/json_tests_data/dmesg-escapes/reference.json b/runner/json_tests_data/dmesg-escapes/reference.json
index 70d6b366..91c57310 100644
--- a/runner/json_tests_data/dmesg-escapes/reference.json
+++ b/runner/json_tests_data/dmesg-escapes/reference.json
@@ -30,6 +30,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -42,6 +43,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -54,6 +56,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-results/reference.json b/runner/json_tests_data/dmesg-results/reference.json
index 0edbae93..e9e01185 100644
--- a/runner/json_tests_data/dmesg-results/reference.json
+++ b/runner/json_tests_data/dmesg-results/reference.json
@@ -81,6 +81,7 @@
       "dmesg-warn":2,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -93,6 +94,7 @@
       "dmesg-warn":2,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -105,6 +107,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -117,6 +120,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -129,6 +133,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json b/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json
index 4ccb18ae..8d266cdf 100644
--- a/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json
+++ b/runner/json_tests_data/dmesg-warn-level-one-piglit-style/reference.json
@@ -31,6 +31,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -43,6 +44,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -55,6 +57,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json b/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json
index d706ee4c..4a1e8b31 100644
--- a/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json
+++ b/runner/json_tests_data/dmesg-warn-level-piglit-style/reference.json
@@ -31,6 +31,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -43,6 +44,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -55,6 +57,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dmesg-warn-level/reference.json b/runner/json_tests_data/dmesg-warn-level/reference.json
index 11cc39d9..400e9cfb 100644
--- a/runner/json_tests_data/dmesg-warn-level/reference.json
+++ b/runner/json_tests_data/dmesg-warn-level/reference.json
@@ -31,6 +31,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -43,6 +44,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -55,6 +57,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json b/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json
index 370fce4d..514de06a 100644
--- a/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json
+++ b/runner/json_tests_data/dynamic-subtest-name-in-multiple-subtests/reference.json
@@ -42,6 +42,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -54,6 +55,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -66,6 +68,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/dynamic-subtests/reference.json b/runner/json_tests_data/dynamic-subtests/reference.json
index ca8f6cd7..c013d282 100644
--- a/runner/json_tests_data/dynamic-subtests/reference.json
+++ b/runner/json_tests_data/dynamic-subtests/reference.json
@@ -90,6 +90,7 @@
       "dmesg-warn":0,
       "skip":1,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":2,
@@ -102,6 +103,7 @@
       "dmesg-warn":0,
       "skip":1,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":2,
@@ -114,6 +116,7 @@
       "dmesg-warn":0,
       "skip":1,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":2,
diff --git a/runner/json_tests_data/empty-result-files/reference.json b/runner/json_tests_data/empty-result-files/reference.json
index ef225601..f81ffb81 100644
--- a/runner/json_tests_data/empty-result-files/reference.json
+++ b/runner/json_tests_data/empty-result-files/reference.json
@@ -24,6 +24,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -36,6 +37,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -48,6 +50,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/incomplete-before-any-subtests/reference.json b/runner/json_tests_data/incomplete-before-any-subtests/reference.json
index b8a76dd7..2a4bd456 100644
--- a/runner/json_tests_data/incomplete-before-any-subtests/reference.json
+++ b/runner/json_tests_data/incomplete-before-any-subtests/reference.json
@@ -49,6 +49,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -61,6 +62,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -73,6 +75,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":1,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -85,6 +88,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -97,6 +101,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
diff --git a/runner/json_tests_data/normal-run/reference.json b/runner/json_tests_data/normal-run/reference.json
index 982038f9..0a00b1ca 100644
--- a/runner/json_tests_data/normal-run/reference.json
+++ b/runner/json_tests_data/normal-run/reference.json
@@ -78,6 +78,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
@@ -90,6 +91,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
@@ -102,6 +104,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":1,
@@ -114,6 +117,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -126,6 +130,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/notrun-results-multiple-mode/reference.json b/runner/json_tests_data/notrun-results-multiple-mode/reference.json
index 492c0a9e..3f8b7fb0 100644
--- a/runner/json_tests_data/notrun-results-multiple-mode/reference.json
+++ b/runner/json_tests_data/notrun-results-multiple-mode/reference.json
@@ -48,6 +48,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":3,
       "fail":0,
@@ -60,6 +61,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":3,
       "fail":0,
@@ -72,6 +74,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -84,6 +87,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
diff --git a/runner/json_tests_data/notrun-results/reference.json b/runner/json_tests_data/notrun-results/reference.json
index 49a2f693..800de38c 100644
--- a/runner/json_tests_data/notrun-results/reference.json
+++ b/runner/json_tests_data/notrun-results/reference.json
@@ -54,6 +54,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -66,6 +67,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":4,
       "fail":0,
@@ -78,6 +80,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -90,6 +93,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":1,
       "fail":0,
@@ -102,6 +106,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":2,
       "fail":0,
diff --git a/runner/json_tests_data/piglit-style-dmesg/reference.json b/runner/json_tests_data/piglit-style-dmesg/reference.json
index 45d6108e..bf5d86ee 100644
--- a/runner/json_tests_data/piglit-style-dmesg/reference.json
+++ b/runner/json_tests_data/piglit-style-dmesg/reference.json
@@ -78,6 +78,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -90,6 +91,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -102,6 +104,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -114,6 +117,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -126,6 +130,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/unprintable-characters/reference.json b/runner/json_tests_data/unprintable-characters/reference.json
index d3add1eb..88c62c34 100644
--- a/runner/json_tests_data/unprintable-characters/reference.json
+++ b/runner/json_tests_data/unprintable-characters/reference.json
@@ -30,6 +30,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -42,6 +43,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -54,6 +56,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -69,4 +72,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/runner/json_tests_data/warnings-with-dmesg-warns/reference.json b/runner/json_tests_data/warnings-with-dmesg-warns/reference.json
index fa571703..bd0bb3a3 100644
--- a/runner/json_tests_data/warnings-with-dmesg-warns/reference.json
+++ b/runner/json_tests_data/warnings-with-dmesg-warns/reference.json
@@ -79,6 +79,7 @@
       "dmesg-warn":1,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -91,6 +92,7 @@
       "dmesg-warn":1,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -103,6 +105,7 @@
       "dmesg-warn":1,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -115,6 +118,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -127,6 +131,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/json_tests_data/warnings/reference.json b/runner/json_tests_data/warnings/reference.json
index 53e0c3c7..a2b79da9 100644
--- a/runner/json_tests_data/warnings/reference.json
+++ b/runner/json_tests_data/warnings/reference.json
@@ -78,6 +78,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -90,6 +91,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -102,6 +104,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -114,6 +117,7 @@
       "dmesg-warn":0,
       "skip":0,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
@@ -126,6 +130,7 @@
       "dmesg-warn":0,
       "skip":2,
       "incomplete":0,
+      "abort":0,
       "timeout":0,
       "notrun":0,
       "fail":0,
diff --git a/runner/resultgen.c b/runner/resultgen.c
index 611d36cb..fe59aafe 100644
--- a/runner/resultgen.c
+++ b/runner/resultgen.c
@@ -645,6 +645,23 @@ static void process_dynamic_subtest_output(const char *piglit_name,
 					     &dynresulttext, &dyntime,
 					     dyn_result_idx < 0 ? NULL : matches.items[dyn_result_idx].where,
 					     dynend);
+
+			/*
+			 * If a dynamic subsubtest is considered incomplete we
+			 * need to check parent's status first, to be sure that
+			 * the binary hasn't aborted (exit code). If it has
+			 * aborted then we have to attribute this status to our
+			 * subsubtest.
+			 */
+			if (!strcmp(dynresulttext, "incomplete")) {
+				struct json_object *parent_subtest;
+
+				if (json_object_object_get_ex(tests, piglit_name, &parent_subtest) &&
+				    json_object_object_get_ex(parent_subtest, "result", &parent_subtest) &&
+				    !strcmp(json_object_get_string(parent_subtest), "abort"))
+					dynresulttext = "abort";
+			}
+
 			set_result(current_dynamic_test, dynresulttext);
 			set_runtime(current_dynamic_test, dyntime);
 		}
@@ -1078,6 +1095,8 @@ static const char *result_from_exitcode(int exitcode)
 		return "pass";
 	case IGT_EXIT_INVALID:
 		return "skip";
+	case IGT_EXIT_ABORT:
+		return "abort";
 	case INCOMPLETE_EXITCODE:
 		return "incomplete";
 	default:
@@ -1154,6 +1173,17 @@ static void fill_from_journal(int fd,
 		}
 	}
 
+	if (subtests->size && exitcode == IGT_EXIT_ABORT) {
+		char *last_subtest = subtests->subs[subtests->size - 1].name;
+		char subtest_piglit_name[256];
+		struct json_object *subtest_obj;
+
+		generate_piglit_name(entry->binary, last_subtest, subtest_piglit_name, sizeof(subtest_piglit_name));
+		subtest_obj = get_or_create_json_object(tests, subtest_piglit_name);
+
+		set_result(subtest_obj, "abort");
+	}
+
 	if (subtests->size == 0) {
 		char *subtestname = NULL;
 		char piglit_name[256];
@@ -1322,6 +1352,7 @@ static struct json_object *get_totals_object(struct json_object *totals,
 	json_object_object_add(obj, "dmesg-warn", json_object_new_int(0));
 	json_object_object_add(obj, "skip", json_object_new_int(0));
 	json_object_object_add(obj, "incomplete", json_object_new_int(0));
+	json_object_object_add(obj, "abort", json_object_new_int(0));
 	json_object_object_add(obj, "timeout", json_object_new_int(0));
 	json_object_object_add(obj, "notrun", json_object_new_int(0));
 	json_object_object_add(obj, "fail", json_object_new_int(0));
diff --git a/runner/runner_tests.c b/runner/runner_tests.c
index 139ee9fd..60e00960 100644
--- a/runner/runner_tests.c
+++ b/runner/runner_tests.c
@@ -28,9 +28,10 @@ static const char testdatadir[] = TESTDATA_DIRECTORY;
  * that test binaries without subtests should still be counted as one
  * for this macro.
  */
-#define NUM_TESTDATA_SUBTESTS 6
+#define NUM_TESTDATA_SUBTESTS 15
+#define NUM_TESTDATA_ABORT_SUBTESTS 9
 /* The total number of test binaries in runner/testdata/ */
-#define NUM_TESTDATA_BINARIES 4
+#define NUM_TESTDATA_BINARIES 8
 
 static const char *igt_get_result(struct json_object *tests, const char* testname)
 {
@@ -954,6 +955,7 @@ igt_main
 			struct execute_state state;
 			const char *argv[] = { "runner",
 					       "--dry-run",
+					       "-x", "^abort",
 					       testdatadir,
 					       dirname,
 			};
@@ -964,7 +966,7 @@ igt_main
 			igt_assert(initialize_execute_state(&state, settings, list));
 			igt_assert_eq(state.next, 0);
 			igt_assert(state.dry);
-			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS);
+			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS - NUM_TESTDATA_ABORT_SUBTESTS);
 
 			igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
 				     "Dry run initialization didn't create the results directory.\n");
@@ -985,7 +987,7 @@ igt_main
 			igt_assert(initialize_execute_state_from_resume(dirfd, &state, settings, list));
 			igt_assert_eq(state.next, 0);
 			igt_assert(!state.dry);
-			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS);
+			igt_assert_eq(list->size, NUM_TESTDATA_SUBTESTS - NUM_TESTDATA_ABORT_SUBTESTS);
 			/* initialize_execute_state_from_resume() closes the dirfd */
 			igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
 				     "Dry run resume somehow deleted the results directory.\n");
@@ -1512,7 +1514,7 @@ igt_main
 			struct execute_state state;
 			struct json_object *results, *tests;
 			const char *argv[] = { "runner",
-					       "-t", "dynamic",
+					       "-t", "^dynamic$",
 					       testdatadir,
 					       dirname,
 			};
@@ -1541,6 +1543,284 @@ igt_main
 		}
 	}
 
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+		char dirname[] = "tmpdirXXXXXX";
+
+		igt_fixture {
+			igt_require(mkdtemp(dirname) != NULL);
+			rmdir(dirname);
+
+			init_job_list(list);
+		}
+
+		igt_subtest("execute-abort-simple") {
+			struct execute_state state;
+			struct json_object *results, *tests;
+			const char *argv[] = { "runner",
+					       "-t", "^abort-simple$",
+					       testdatadir,
+					       dirname,
+			};
+
+			igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+			igt_assert(create_job_list(list, settings));
+			igt_assert(initialize_execute_state(&state, settings, list));
+			igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+			igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+				     "Execute didn't create the results directory\n");
+			igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+				     "Results parsing failed\n");
+
+			igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+			igt_assert_eqstr(igt_get_result(tests, "igt@abort-simple"), "abort");
+
+			igt_assert_eq(json_object_put(results), 1);
+		}
+
+		igt_fixture {
+			close(dirfd);
+			clear_directory(dirname);
+			free_job_list(list);
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+
+			igt_fixture {
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner",
+						       "-t", "^abort$",
+						       multiple ? "--multiple-mode" : "--sync",
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort@a-subtest"), "pass");
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort@b-subtest"), "abort");
+
+				if (multiple) /* no notrun injection for multiple mode */
+					igt_assert_no_result_for(tests, "igt@abort@c-subtest");
+				else
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort@c-subtest"), "notrun");
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+
+			igt_fixture {
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort-fixture%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
+						       "-t", "^abort-fixture$",
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				if (multiple) {
+					/*
+					 * running the whole binary via -t, no
+					 * way of blaming the particular subtest
+					 */
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture"), "abort");
+					igt_assert_no_result_for(tests, "igt@abort-fixture@a-subtest");
+					igt_assert_no_result_for(tests, "igt@abort-fixture@b-subtest");
+				} else {
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@a-subtest"), "abort");
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@b-subtest"), "notrun");
+				}
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+			char filename[] = "tmplistXXXXXX";
+			const char testlisttext[] = "igt@abort-fixture@b-subtest\n"
+				"igt@abort-fixture@a-subtest\n";
+
+			igt_fixture {
+				int fd;
+				igt_require((fd = mkstemp(filename)) >= 0);
+				igt_require(write(fd, testlisttext, strlen(testlisttext)) == strlen(testlisttext));
+				close(fd);
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort-fixture-testlist%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
+						       "--test-list", filename,
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				if (multiple) /* multiple mode = no notruns */
+					igt_assert_no_result_for(tests, "igt@abort-fixture@a-subtest");
+				else
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@a-subtest"), "notrun");
+
+
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-fixture@b-subtest"), "abort");
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				unlink(filename);
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
+	igt_subtest_group {
+		struct job_list *list = malloc(sizeof(*list));
+		volatile int dirfd = -1;
+
+		for (int multiple = 0; multiple <= 1; ++multiple) {
+			char dirname[] = "tmpdirXXXXXX";
+
+			igt_fixture {
+				igt_require(mkdtemp(dirname) != NULL);
+				rmdir(dirname);
+
+				init_job_list(list);
+			}
+
+			igt_subtest_f("execute-abort-dynamic%s", multiple ? "-multiple" : "") {
+				struct execute_state state;
+				struct json_object *results, *tests;
+				const char *argv[] = { "runner", multiple ? "--multiple-mode" : "--sync",
+						       "-t", "^abort-dynamic$",
+						       testdatadir,
+						       dirname,
+				};
+
+				igt_assert(parse_options(ARRAY_SIZE(argv), (char**)argv, settings));
+				igt_assert(create_job_list(list, settings));
+				igt_assert(initialize_execute_state(&state, settings, list));
+				igt_assert(!execute(&state, settings, list)); /* false = signal abort */
+
+				igt_assert_f((dirfd = open(dirname, O_DIRECTORY | O_RDONLY)) >= 0,
+					     "Execute didn't create the results directory\n");
+				igt_assert_f((results = generate_results_json(dirfd)) != NULL,
+					     "Results parsing failed\n");
+
+				igt_assert(json_object_object_get_ex(results, "tests", &tests));
+
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@a-subtest@dynamic-1"), "pass");
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@b-subtest@dynamic-1"), "pass");
+				igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@b-subtest@dynamic-2"), "abort");
+
+				igt_assert_no_result_for(tests, "igt@abort-dynamic@b-subtest@dynamic-3");
+
+				if (multiple) /* multiple mode = no notruns */
+					igt_assert_no_result_for(tests, "igt@abort-dynamic@c-subtest");
+				else
+					igt_assert_eqstr(igt_get_result(tests, "igt@abort-dynamic@c-subtest"), "notrun");
+
+				igt_assert_eq(json_object_put(results), 1);
+			}
+
+			igt_fixture {
+				close(dirfd);
+				clear_directory(dirname);
+				free_job_list(list);
+			}
+		}
+	}
+
 	igt_subtest("file-descriptor-leakage") {
 		int i;
 
diff --git a/runner/testdata/abort-dynamic.c b/runner/testdata/abort-dynamic.c
new file mode 100644
index 00000000..66cf13a7
--- /dev/null
+++ b/runner/testdata/abort-dynamic.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_main
+{
+	igt_subtest_with_dynamic("a-subtest") {
+		igt_dynamic("dynamic-1")
+			;
+	}
+
+	igt_subtest_with_dynamic("b-subtest") {
+		igt_dynamic("dynamic-1")
+			;
+
+		igt_dynamic("dynamic-2")
+			igt_abort_on_f(true, "I'm out!\n");
+
+		igt_dynamic("dynamic-3")
+			;
+	}
+
+	igt_subtest("c-subtest")
+		;
+}
diff --git a/runner/testdata/abort-fixture.c b/runner/testdata/abort-fixture.c
new file mode 100644
index 00000000..6a1cb986
--- /dev/null
+++ b/runner/testdata/abort-fixture.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_main
+{
+	igt_fixture {
+		igt_abort_on_f(true, "I'm out!\n");
+	}
+
+	igt_subtest("a-subtest")
+		;
+
+	igt_subtest("b-subtest")
+		;
+}
diff --git a/runner/testdata/abort-simple.c b/runner/testdata/abort-simple.c
new file mode 100644
index 00000000..94eef72c
--- /dev/null
+++ b/runner/testdata/abort-simple.c
@@ -0,0 +1,29 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_simple_main
+{
+	igt_abort_on_f(true, "I'm out!\n");
+}
diff --git a/runner/testdata/abort.c b/runner/testdata/abort.c
new file mode 100644
index 00000000..074946a4
--- /dev/null
+++ b/runner/testdata/abort.c
@@ -0,0 +1,36 @@
+/*
+ * Copyright © 2020 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include "igt.h"
+
+igt_main
+{
+	igt_subtest("a-subtest")
+		;
+
+	igt_subtest("b-subtest")
+		igt_abort_on_f(true, "I'm out!\n");
+
+	igt_subtest("c-subtest")
+		;
+}
diff --git a/runner/testdata/meson.build b/runner/testdata/meson.build
index 631ba5b9..1f822591 100644
--- a/runner/testdata/meson.build
+++ b/runner/testdata/meson.build
@@ -3,6 +3,10 @@ testdata_progs = [ 'successtest',
 		   'no-subtests',
 		   'skippers',
 		   'dynamic',
+		   'abort',
+		   'abort-dynamic',
+		   'abort-fixture',
+		   'abort-simple',
 		 ]
 
 testdata_executables = []
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 6/9] lib/chamelium: Clear error after checking if chamelium is reachable
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (3 preceding siblings ...)
  2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 5/9] runner: Abort the run when test exits with IGT_EXIT_ABORT Arkadiusz Hiler
@ 2020-02-25 16:56 ` Arkadiusz Hiler
  2020-02-25 16:56 ` [igt-dev] [PATCH i-g-t 7/9] lib/chamelium: Make it clear that function asserts Arkadiusz Hiler
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:56 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

Otherwise this may get us stuck in perpetual failure mode.

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/igt_chamelium.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index aaf17d51..b347682d 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -361,11 +361,17 @@ static bool __chamelium_is_reachable(struct chamelium *chamelium)
 	if (res != NULL)
 		xmlrpc_DECREF(res);
 
-	if (chamelium->env.fault_occurred)
+	if (chamelium->env.fault_occurred) {
 		igt_debug("Chamelium RPC call failed: %s\n",
 			  chamelium->env.fault_string);
 
-	return !chamelium->env.fault_occurred;
+		xmlrpc_env_clean(&chamelium->env);
+		xmlrpc_env_init(&chamelium->env);
+
+		return false;
+	}
+
+	return true;
 }
 
 void chamelium_wait_reachable(struct chamelium *chamelium, int timeout)
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 7/9] lib/chamelium: Make it clear that function asserts
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (4 preceding siblings ...)
  2020-02-25 16:56 ` [igt-dev] [PATCH i-g-t 6/9] lib/chamelium: Clear error after checking if chamelium is reachable Arkadiusz Hiler
@ 2020-02-25 16:56 ` Arkadiusz Hiler
  2020-02-25 16:57 ` [igt-dev] [PATCH i-g-t 8/9] lib/chamelium: Add functions to initialize XMLRPC only Arkadiusz Hiler
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:56 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

chamelium_wait_reachable() is asserting internally if the chamelium not
reachable. Let's make it return bool instead and create
void chamelium_assert_reachable() that fails the run.

v2: Add docs (Petri)

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/igt_chamelium.c   | 24 +++++++++++++++++++++---
 lib/igt_chamelium.h   |  3 ++-
 tests/kms_chamelium.c |  4 ++--
 3 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index b347682d..28706012 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -374,11 +374,29 @@ static bool __chamelium_is_reachable(struct chamelium *chamelium)
 	return true;
 }
 
-void chamelium_wait_reachable(struct chamelium *chamelium, int timeout)
+/**
+ * chamelium_wait_reachable:
+ * @chamelium: The Chamelium instance to use
+ * @timeout: Time (in seconds) to wait for chamelium to be reachable
+ *
+ * Returns: %true if the Chamelium is reachable, %false otherwise.
+ */
+bool chamelium_wait_reachable(struct chamelium *chamelium, int timeout)
 {
-	bool chamelium_online = igt_wait(__chamelium_is_reachable(chamelium),
-					 timeout * 1000, 100);
+	return igt_wait(__chamelium_is_reachable(chamelium),
+			timeout * 1000, 100);
+}
 
+/**
+ * chamelium_assert_reachable:
+ * @chamelium: The Chamelium instance to use
+ * @timeout: Time (in seconds) to wait for chamelium to be reachable
+ *
+ * Asserts that the chamelium is reachable.
+ */
+void chamelium_assert_reachable(struct chamelium *chamelium, int timeout)
+{
+	bool chamelium_online = chamelium_wait_reachable(chamelium, timeout);
 	igt_assert_f(chamelium_online,
 		     "Couldn't connect to Chamelium for %ds", timeout);
 }
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index d03c924a..db6803b1 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -112,7 +112,8 @@ drmModeConnector *chamelium_port_get_connector(struct chamelium *chamelium,
 					       bool reprobe);
 const char *chamelium_port_get_name(struct chamelium_port *port);
 
-void chamelium_wait_reachable(struct chamelium *chamelium, int timeout);
+bool chamelium_wait_reachable(struct chamelium *chamelium, int timeout);
+void chamelium_assert_reachable(struct chamelium *chamelium, int timeout);
 void chamelium_plug(struct chamelium *chamelium, struct chamelium_port *port);
 void chamelium_unplug(struct chamelium *chamelium, struct chamelium_port *port);
 bool chamelium_is_plugged(struct chamelium *chamelium,
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 5c4a1892..8243d2ef 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -376,7 +376,7 @@ try_suspend_resume_hpd(data_t *data, struct chamelium_port *port,
 
 	igt_system_suspend_autoresume(state, test);
 	igt_assert(wait_for_hotplug(mon, &timeout));
-	chamelium_wait_reachable(data->chamelium, ONLINE_TIMEOUT);
+	chamelium_assert_reachable(data->chamelium, ONLINE_TIMEOUT);
 
 	if (port) {
 		igt_assert_eq(reprobe_connector(data, port), target_state);
@@ -493,7 +493,7 @@ test_suspend_resume_edid_change(data_t *data, struct chamelium_port *port,
 
 	igt_system_suspend_autoresume(state, test);
 	igt_assert(igt_hotplug_detected(mon, HOTPLUG_TIMEOUT));
-	chamelium_wait_reachable(data->chamelium, ONLINE_TIMEOUT);
+	chamelium_assert_reachable(data->chamelium, ONLINE_TIMEOUT);
 
 	get_connectors_link_status_failed(data, link_status_failed[1]);
 
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 8/9] lib/chamelium: Add functions to initialize XMLRPC only
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (5 preceding siblings ...)
  2020-02-25 16:56 ` [igt-dev] [PATCH i-g-t 7/9] lib/chamelium: Make it clear that function asserts Arkadiusz Hiler
@ 2020-02-25 16:57 ` Arkadiusz Hiler
  2020-02-25 16:57 ` [igt-dev] [PATCH i-g-t 9/9] lib/kms: Try to plug all Chamelium ports, abort if it fails Arkadiusz Hiler
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

Let's extract the bit that reads the config and initializes xmlrpc so we
can do some basic things with chamelium without the need to do port
auto-discovery and connector mapping.

Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/igt_chamelium.c | 89 +++++++++++++++++++++++++++++++++------------
 lib/igt_chamelium.h |  2 +
 2 files changed, 68 insertions(+), 23 deletions(-)

diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 28706012..874e161b 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -2308,7 +2308,7 @@ static bool chamelium_autodiscover(struct chamelium *chamelium, int drm_fd)
 	return true;
 }
 
-static bool chamelium_read_config(struct chamelium *chamelium, int drm_fd)
+static bool chamelium_read_config(struct chamelium *chamelium)
 {
 	GError *error = NULL;
 
@@ -2325,10 +2325,7 @@ static bool chamelium_read_config(struct chamelium *chamelium, int drm_fd)
 		return false;
 	}
 
-	if (!chamelium_read_port_mappings(chamelium, drm_fd)) {
-		return false;
-	}
-	return chamelium_autodiscover(chamelium, drm_fd);
+	return true;
 }
 
 /**
@@ -2352,6 +2349,64 @@ static void chamelium_exit_handler(int sig)
 		chamelium_deinit(cleanup_instance);
 }
 
+/**
+ * chamelium_deinit_rpc_only:
+ * @chamelium: The Chamelium instance to use
+ *
+ * Frees the resources used by a connection to the chamelium that was set up
+ * with #chamelium_init_rpc_only.
+ */
+void chamelium_deinit_rpc_only(struct chamelium *chamelium)
+{
+	xmlrpc_env_clean(&chamelium->env);
+	free(chamelium);
+}
+
+/**
+ * chamelium_init_rpc_only:
+ *
+ * Sets up a connection with a chamelium, using the URL specified in the
+ * Chamelium configuration. The function initializes only the RPC - no port
+ * autodiscovery happens, which means only the functions that do not require
+ * struct #chamelium_port can be called with an instance produced by this
+ * function.
+ *
+ * #chamelium_init is almost always a better choice.
+ *
+ * Returns: A newly initialized chamelium struct, or NULL on lack of
+ * configuration
+ */
+struct chamelium *chamelium_init_rpc_only(void)
+{
+	struct chamelium *chamelium = malloc(sizeof(struct chamelium));
+
+	if (!chamelium)
+		return NULL;
+
+	memset(chamelium, 0, sizeof(*chamelium));
+
+	chamelium->drm_fd = -1;
+
+	/* Setup the libxmlrpc context */
+	xmlrpc_env_init(&chamelium->env);
+	xmlrpc_client_setup_global_const(&chamelium->env);
+	xmlrpc_client_create(&chamelium->env, XMLRPC_CLIENT_NO_FLAGS, PACKAGE,
+			     PACKAGE_VERSION, NULL, 0, &chamelium->client);
+	if (chamelium->env.fault_occurred) {
+		igt_debug("Failed to init xmlrpc: %s\n",
+			  chamelium->env.fault_string);
+		goto error;
+	}
+
+	if (!chamelium_read_config(chamelium))
+		goto error;
+
+	return chamelium;
+error:
+	chamelium_deinit_rpc_only(chamelium);
+	return NULL;
+}
+
 /**
  * chamelium_init:
  * @chamelium: The Chamelium instance to use
@@ -2368,9 +2423,9 @@ static void chamelium_exit_handler(int sig)
  */
 struct chamelium *chamelium_init(int drm_fd)
 {
-	struct chamelium *chamelium = malloc(sizeof(struct chamelium));
+	struct chamelium *chamelium = chamelium_init_rpc_only();
 
-	if (!chamelium)
+	if (chamelium == NULL)
 		return NULL;
 
 	/* A chamelium instance was set up previously, so clean it up before
@@ -2379,34 +2434,22 @@ struct chamelium *chamelium_init(int drm_fd)
 	if (cleanup_instance)
 		chamelium_deinit(cleanup_instance);
 
-	memset(chamelium, 0, sizeof(*chamelium));
 	chamelium->drm_fd = drm_fd;
 	IGT_INIT_LIST_HEAD(&chamelium->edids);
 
-	/* Setup the libxmlrpc context */
-	xmlrpc_env_init(&chamelium->env);
-	xmlrpc_client_setup_global_const(&chamelium->env);
-	xmlrpc_client_create(&chamelium->env, XMLRPC_CLIENT_NO_FLAGS, PACKAGE,
-			     PACKAGE_VERSION, NULL, 0, &chamelium->client);
-	if (chamelium->env.fault_occurred) {
-		igt_debug("Failed to init xmlrpc: %s\n",
-			  chamelium->env.fault_string);
+	if (!chamelium_read_port_mappings(chamelium, drm_fd))
 		goto error;
-	}
 
-	if (!chamelium_read_config(chamelium, drm_fd))
+	if (!chamelium_autodiscover(chamelium, drm_fd))
 		goto error;
 
 	cleanup_instance = chamelium;
 	igt_install_exit_handler(chamelium_exit_handler);
 
 	return chamelium;
-
 error:
-	xmlrpc_env_clean(&chamelium->env);
-	free(chamelium);
-
-	return NULL;
+	chamelium_deinit_rpc_only(chamelium);
+	return chamelium;
 }
 
 /**
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index db6803b1..3b9a1242 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -100,6 +100,8 @@ struct chamelium_edid;
  */
 #define CHAMELIUM_MAX_AUDIO_CHANNELS 8
 
+void chamelium_deinit_rpc_only(struct chamelium *chamelium);
+struct chamelium *chamelium_init_rpc_only(void);
 struct chamelium *chamelium_init(int drm_fd);
 void chamelium_deinit(struct chamelium *chamelium);
 void chamelium_reset(struct chamelium *chamelium);
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] [PATCH i-g-t 9/9] lib/kms: Try to plug all Chamelium ports, abort if it fails
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (6 preceding siblings ...)
  2020-02-25 16:57 ` [igt-dev] [PATCH i-g-t 8/9] lib/chamelium: Add functions to initialize XMLRPC only Arkadiusz Hiler
@ 2020-02-25 16:57 ` Arkadiusz Hiler
  2020-02-26 10:31 ` [igt-dev] ✗ GitLab.Pipeline: failure for series starting with [i-g-t,1/9] lib/tests: Extract fork helpers Patchwork
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 12+ messages in thread
From: Arkadiusz Hiler @ 2020-02-25 16:57 UTC (permalink / raw)
  To: igt-dev; +Cc: Petri Latvala

Using chamelium as a display for non-chamelium-aware test is
challenging. The board can be left in multiple different states after
kms_chamelium tests even though we have atexit() handlers and other
measures which try to assure that all ports are plugged in. Sadly this
is not 100% reliable. We also had a few boards hard hanging (happens
very seldom) and requiring manual intervention.

This leads to changes in the testing configuration - we may end up with
any number of connectors plugged in which makes a lot of kms_ tests to
flip between skip and pass depending on a run.

In an attempt to make connectors state less random this patch makes
igt_display_require() chamelium-aware. If chamelium is configured for
given machine we try to reach it and make sure everything is plugged in.
If we fail to do so we abort the execution because the testing
configuration is an unknown.

For machines without a configured chamelium this boils down to a nop.

I have run a bunch of tests and measured how much time we spend in the
Chamelium section of igt_display_require() (n = 1000) with chamelium
configured:

    Min: 0.0030s     Max:    0.0113s
    Avg: 0.0089s     Median: 0.0089s

With ~1000 of KMS subtests in a run it's only a mere 9s.

This will however add a bit of extra execution time to test skips
because of doing kmstest_set_vt_graphics_mode() and
igt_display_require() before even checking whether Chamelium is
configured.

v2: do kmstest_set_vt_graphics_mode() before requiring display (Petri)

Fixes: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/20
Signed-off-by: Arkadiusz Hiler <arkadiusz.hiler@intel.com>
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
---
 lib/igt_chamelium.c         | 55 +++++++++++++++++++++++++++++++++++--
 lib/igt_chamelium.h         |  1 +
 lib/igt_kms.c               | 18 ++++++++++++
 tests/kms_chamelium.c       | 13 +++++----
 tests/kms_color_chamelium.c |  7 +++--
 5 files changed, 83 insertions(+), 11 deletions(-)

diff --git a/lib/igt_chamelium.c b/lib/igt_chamelium.c
index 874e161b..3c9faeeb 100644
--- a/lib/igt_chamelium.c
+++ b/lib/igt_chamelium.c
@@ -1992,7 +1992,13 @@ static size_t chamelium_get_video_ports(struct chamelium *chamelium,
 	int res_len, i, port_id;
 	size_t port_ids_len = 0;
 
-	res = chamelium_rpc(chamelium, NULL, "GetSupportedInputs", "()");
+	res = __chamelium_rpc(chamelium, NULL, "GetSupportedInputs", "()");
+	if (chamelium->env.fault_occurred) {
+		igt_debug("Chamelium RPC call failed: %s\n",
+		     chamelium->env.fault_string);
+
+		return -1;
+	}
 	res_len = xmlrpc_array_size(&chamelium->env, res);
 	for (i = 0; i < res_len; i++) {
 		xmlrpc_array_read_item(&chamelium->env, res, i, &res_port);
@@ -2195,6 +2201,8 @@ static bool chamelium_autodiscover(struct chamelium *chamelium, int drm_fd)
 	candidate_ports_len = chamelium_get_video_ports(chamelium,
 							candidate_ports);
 
+	igt_assert(candidate_ports_len > 0);
+
 	igt_debug("Starting Chamelium port auto-discovery on %zu ports\n",
 		  candidate_ports_len);
 	igt_gettime(&start);
@@ -2313,14 +2321,14 @@ static bool chamelium_read_config(struct chamelium *chamelium)
 	GError *error = NULL;
 
 	if (!igt_key_file) {
-		igt_warn("No configuration file available for chamelium\n");
+		igt_debug("No configuration file available for chamelium\n");
 		return false;
 	}
 
 	chamelium->url = g_key_file_get_string(igt_key_file, "Chamelium", "URL",
 					       &error);
 	if (!chamelium->url) {
-		igt_warn("Couldn't read chamelium URL from config file: %s\n",
+		igt_debug("Couldn't read chamelium URL from config file: %s\n",
 			 error->message);
 		return false;
 	}
@@ -2416,6 +2424,9 @@ error:
  * Chamelium configuration. This must be called first before trying to use the
  * chamelium.
  *
+ * Needs to happen *after* igt_display_require() as otherwise the board will
+ * get reset.
+ *
  * If we fail to establish a connection with the chamelium, fail to find a
  * configured connector, etc. we fail the current test.
  *
@@ -2495,6 +2506,44 @@ void chamelium_deinit(struct chamelium *chamelium)
 	free(chamelium);
 }
 
+bool chamelium_plug_all(struct chamelium *chamelium)
+{
+	size_t port_count;
+	int port_ids[CHAMELIUM_MAX_PORTS];
+	xmlrpc_value *v;
+	v = __chamelium_rpc(chamelium, NULL, "Reset", "()");
+
+	if (v != NULL)
+		xmlrpc_DECREF(v);
+
+	if (chamelium->env.fault_occurred) {
+		igt_debug("Chamelium RPC call failed: %s\n",
+		     chamelium->env.fault_string);
+
+		return false;
+	}
+
+	port_count = chamelium_get_video_ports(chamelium, port_ids);
+	if (port_count <= 0)
+		return false;
+
+	for (int i = 0; i < port_count; ++i) {
+		v = __chamelium_rpc(chamelium, NULL, "Plug", "(i)", port_ids[i]);
+
+		if (v != NULL)
+			xmlrpc_DECREF(v);
+
+		if (chamelium->env.fault_occurred) {
+			igt_debug("Chamelium RPC call failed: %s\n",
+			     chamelium->env.fault_string);
+
+			return false;
+		}
+	}
+
+	return true;
+}
+
 igt_constructor {
 	/* Frame dumps can be large, so we need to be able to handle very large
 	 * responses
diff --git a/lib/igt_chamelium.h b/lib/igt_chamelium.h
index 3b9a1242..fb273b1a 100644
--- a/lib/igt_chamelium.h
+++ b/lib/igt_chamelium.h
@@ -217,5 +217,6 @@ void chamelium_crop_analog_frame(struct chamelium_frame_dump *dump, int width,
 void chamelium_destroy_frame_dump(struct chamelium_frame_dump *dump);
 void chamelium_destroy_audio_file(struct chamelium_audio_file *audio_file);
 void chamelium_infoframe_destroy(struct chamelium_infoframe *infoframe);
+bool chamelium_plug_all(struct chamelium *chamelium);
 
 #endif /* IGT_CHAMELIUM_H */
diff --git a/lib/igt_kms.c b/lib/igt_kms.c
index 54de45e5..7f9fafb3 100644
--- a/lib/igt_kms.c
+++ b/lib/igt_kms.c
@@ -58,6 +58,9 @@
 #include "igt_device.h"
 #include "igt_sysfs.h"
 #include "sw_sync.h"
+#ifdef HAVE_CHAMELIUM
+#include "igt_chamelium.h"
+#endif
 
 /**
  * SECTION:igt_kms
@@ -1886,6 +1889,21 @@ void igt_display_require(igt_display_t *display, int drm_fd)
 	if (!resources)
 		goto out;
 
+#ifdef HAVE_CHAMELIUM
+	{
+		struct chamelium *chamelium;
+
+		chamelium = chamelium_init_rpc_only();
+		if (chamelium) {
+			igt_abort_on_f(!chamelium_wait_reachable(chamelium, 20),
+				       "cannot reach the configured chamelium!\n");
+			igt_abort_on_f(!chamelium_plug_all(chamelium),
+				       "failed to plug all the chamelium ports!\n");
+			chamelium_deinit_rpc_only(chamelium);
+		}
+	}
+#endif
+
 	/*
 	 * We cache the number of pipes, that number is a physical limit of the
 	 * hardware and cannot change of time (for now, at least).
diff --git a/tests/kms_chamelium.c b/tests/kms_chamelium.c
index 8243d2ef..f127de8c 100644
--- a/tests/kms_chamelium.c
+++ b/tests/kms_chamelium.c
@@ -2622,7 +2622,14 @@ igt_main
 	size_t i;
 
 	igt_fixture {
+		/* So fbcon doesn't try to reprobe things itself */
+		kmstest_set_vt_graphics_mode();
+
 		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
+		igt_display_require(&data.display, data.drm_fd);
+		igt_require(data.display.is_atomic);
+
+		/* we need to initalize chamelium after igt_display_require */
 		data.chamelium = chamelium_init(data.drm_fd);
 		igt_require(data.chamelium);
 
@@ -2633,12 +2640,6 @@ igt_main
 			data.edids[i] = chamelium_new_edid(data.chamelium,
 							   get_edid(i));
 		}
-
-		/* So fbcon doesn't try to reprobe things itself */
-		kmstest_set_vt_graphics_mode();
-
-		igt_display_require(&data.display, data.drm_fd);
-		igt_require(data.display.is_atomic);
 	}
 
 	igt_describe("DisplayPort tests");
diff --git a/tests/kms_color_chamelium.c b/tests/kms_color_chamelium.c
index 34a1888c..7f5a911c 100644
--- a/tests/kms_color_chamelium.c
+++ b/tests/kms_color_chamelium.c
@@ -724,6 +724,11 @@ igt_main
 		data.drm_fd = drm_open_driver_master(DRIVER_ANY);
 		if (is_i915_device(data.drm_fd))
 			data.devid = intel_get_drm_devid(data.drm_fd);
+
+		igt_display_require(&data.display, data.drm_fd);
+		igt_require(data.display.is_atomic);
+
+		/* we need to initalize chamelium after igt_display_require */
 		data.chamelium = chamelium_init(data.drm_fd);
 		igt_require(data.chamelium);
 
@@ -734,8 +739,6 @@ igt_main
 			igt_skip("No ports connected\n");
 
 		kmstest_set_vt_graphics_mode();
-		igt_display_require(&data.display, data.drm_fd);
-		igt_require(data.display.is_atomic);
 	}
 
 	for_each_pipe_static(pipe)
-- 
2.24.1

_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [igt-dev] ✗ GitLab.Pipeline: failure for series starting with [i-g-t,1/9] lib/tests: Extract fork helpers
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (7 preceding siblings ...)
  2020-02-25 16:57 ` [igt-dev] [PATCH i-g-t 9/9] lib/kms: Try to plug all Chamelium ports, abort if it fails Arkadiusz Hiler
@ 2020-02-26 10:31 ` Patchwork
  2020-02-26 12:15 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
  2020-02-26 18:49 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  10 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2020-02-26 10:31 UTC (permalink / raw)
  To: Arkadiusz Hiler; +Cc: igt-dev

== Series Details ==

Series: series starting with [i-g-t,1/9] lib/tests: Extract fork helpers
URL   : https://patchwork.freedesktop.org/series/73920/
State : failure

== Summary ==

ERROR! This series introduces new undocumented tests:

meta_test@abort

Can you document them as per the requirement in the [CONTRIBUTING.md]?

[Documentation] has more details on how to do this.

Here are few examples:
https://gitlab.freedesktop.org/drm/igt-gpu-tools/commit/0316695d03aa46108296b27f3982ec93200c7a6e
https://gitlab.freedesktop.org/drm/igt-gpu-tools/commit/443cc658e1e6b492ee17bf4f4d891029eb7a205d

Thanks in advance!

[CONTRIBUTING.md]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/blob/master/CONTRIBUTING.md#L19
[Documentation]: https://drm.pages.freedesktop.org/igt-gpu-tools/igt-gpu-tools-Core.html#igt-describe

Other than that, pipeline status: SUCCESS.

see https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/112757 for the overview.

== Logs ==

For more details see: https://gitlab.freedesktop.org/gfx-ci/igt-ci-tags/pipelines/112757
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [igt-dev] ✓ Fi.CI.BAT: success for series starting with [i-g-t,1/9] lib/tests: Extract fork helpers
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (8 preceding siblings ...)
  2020-02-26 10:31 ` [igt-dev] ✗ GitLab.Pipeline: failure for series starting with [i-g-t,1/9] lib/tests: Extract fork helpers Patchwork
@ 2020-02-26 12:15 ` Patchwork
  2020-02-26 18:49 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork
  10 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2020-02-26 12:15 UTC (permalink / raw)
  To: Arkadiusz Hiler; +Cc: igt-dev

== Series Details ==

Series: series starting with [i-g-t,1/9] lib/tests: Extract fork helpers
URL   : https://patchwork.freedesktop.org/series/73920/
State : success

== Summary ==

CI Bug Log - changes from IGT_5467 -> IGTPW_4223
====================================================

Summary
-------

  **SUCCESS**

  No regressions found.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/index.html

Known issues
------------

  Here are the changes found in IGTPW_4223 that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@kms_chamelium@dp-crc-fast:
    - fi-cml-u2:          [PASS][1] -> [FAIL][2] ([i915#217])
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-cml-u2/igt@kms_chamelium@dp-crc-fast.html
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-cml-u2/igt@kms_chamelium@dp-crc-fast.html

  * igt@kms_chamelium@hdmi-hpd-fast:
    - fi-kbl-7500u:       [PASS][3] -> [FAIL][4] ([fdo#111407])
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-kbl-7500u/igt@kms_chamelium@hdmi-hpd-fast.html

  
#### Warnings ####

  * igt@kms_chamelium@common-hpd-after-suspend:
    - fi-pnv-d510:        [SKIP][5] ([fdo#109271] / [fdo#111827]) -> [SKIP][6] ([fdo#109271]) +8 similar issues
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-pnv-d510/igt@kms_chamelium@common-hpd-after-suspend.html
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-pnv-d510/igt@kms_chamelium@common-hpd-after-suspend.html

  * igt@kms_chamelium@dp-crc-fast:
    - fi-bwr-2160:        [SKIP][7] ([fdo#109271] / [fdo#111827]) -> [SKIP][8] ([fdo#109271]) +8 similar issues
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-bwr-2160/igt@kms_chamelium@dp-crc-fast.html
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-bwr-2160/igt@kms_chamelium@dp-crc-fast.html
    - fi-gdg-551:         [SKIP][9] ([fdo#109271] / [fdo#111827]) -> [SKIP][10] ([fdo#109271]) +8 similar issues
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-gdg-551/igt@kms_chamelium@dp-crc-fast.html
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-gdg-551/igt@kms_chamelium@dp-crc-fast.html

  * igt@kms_chamelium@hdmi-edid-read:
    - fi-blb-e6850:       [SKIP][11] ([fdo#109271] / [fdo#111827]) -> [SKIP][12] ([fdo#109271]) +8 similar issues
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-blb-e6850/igt@kms_chamelium@hdmi-edid-read.html
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-blb-e6850/igt@kms_chamelium@hdmi-edid-read.html
    - fi-kbl-8809g:       [SKIP][13] ([fdo#109271] / [fdo#111827]) -> [SKIP][14] ([fdo#109271]) +8 similar issues
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/fi-kbl-8809g/igt@kms_chamelium@hdmi-edid-read.html
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/fi-kbl-8809g/igt@kms_chamelium@hdmi-edid-read.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#111407]: https://bugs.freedesktop.org/show_bug.cgi?id=111407
  [fdo#111827]: https://bugs.freedesktop.org/show_bug.cgi?id=111827
  [i915#1233]: https://gitlab.freedesktop.org/drm/intel/issues/1233
  [i915#217]: https://gitlab.freedesktop.org/drm/intel/issues/217


Participating hosts (49 -> 45)
------------------------------

  Additional (1): fi-tgl-y 
  Missing    (5): fi-hsw-4200u fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus 


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5467 -> IGTPW_4223

  CI-20190529: 20190529
  CI_DRM_8005: 81f641f60edbfa1ccb169689206f0af360a06e31 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4223: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/index.html
  IGT_5467: 2684f182424582c66e67bcbbda77cd60901627b8 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools



== Testlist changes ==

+igt@meta_test@abort

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [igt-dev] ✗ Fi.CI.IGT: failure for series starting with [i-g-t,1/9] lib/tests: Extract fork helpers
  2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
                   ` (9 preceding siblings ...)
  2020-02-26 12:15 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
@ 2020-02-26 18:49 ` Patchwork
  10 siblings, 0 replies; 12+ messages in thread
From: Patchwork @ 2020-02-26 18:49 UTC (permalink / raw)
  To: Arkadiusz Hiler; +Cc: igt-dev

== Series Details ==

Series: series starting with [i-g-t,1/9] lib/tests: Extract fork helpers
URL   : https://patchwork.freedesktop.org/series/73920/
State : failure

== Summary ==

CI Bug Log - changes from IGT_5467_full -> IGTPW_4223_full
====================================================

Summary
-------

  **FAILURE**

  Serious unknown changes coming with IGTPW_4223_full absolutely need to be
  verified manually.
  
  If you think the reported changes have nothing to do with the changes
  introduced in IGTPW_4223_full, please notify your bug team to allow them
  to document this new failure mode, which will reduce false positives in CI.

  External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/index.html

Possible new issues
-------------------

  Here are the unknown changes that may have been introduced in IGTPW_4223_full:

### IGT changes ###

#### Possible regressions ####

  * igt@sw_sync@sync_multi_producer_single_consumer:
    - shard-tglb:         NOTRUN -> [TIMEOUT][1]
   [1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb1/igt@sw_sync@sync_multi_producer_single_consumer.html

  
#### Warnings ####

  * igt@i915_pm_rpm@modeset-non-lpsp-stress:
    - shard-tglb:         [SKIP][2] ([fdo#111644]) -> [SKIP][3]
   [2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-tglb3/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
   [3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb2/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
    - shard-iclb:         [SKIP][4] ([fdo#110892]) -> [SKIP][5]
   [4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb5/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
   [5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb5/igt@i915_pm_rpm@modeset-non-lpsp-stress.html

  
Known issues
------------

  Here are the changes found in IGTPW_4223_full that come from known issues:

### IGT changes ###

#### Issues hit ####

  * igt@gem_ctx_isolation@rcs0-s3:
    - shard-kbl:          [PASS][6] -> [DMESG-WARN][7] ([i915#180]) +3 similar issues
   [6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-kbl6/igt@gem_ctx_isolation@rcs0-s3.html
   [7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-kbl7/igt@gem_ctx_isolation@rcs0-s3.html

  * igt@gem_exec_balancer@smoke:
    - shard-iclb:         [PASS][8] -> [SKIP][9] ([fdo#110854])
   [8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb4/igt@gem_exec_balancer@smoke.html
   [9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb8/igt@gem_exec_balancer@smoke.html

  * igt@gem_exec_schedule@pi-userfault-bsd:
    - shard-iclb:         [PASS][10] -> [SKIP][11] ([i915#677])
   [10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb7/igt@gem_exec_schedule@pi-userfault-bsd.html
   [11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb1/igt@gem_exec_schedule@pi-userfault-bsd.html

  * igt@gem_exec_schedule@preempt-queue-bsd1:
    - shard-iclb:         [PASS][12] -> [SKIP][13] ([fdo#109276]) +16 similar issues
   [12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb4/igt@gem_exec_schedule@preempt-queue-bsd1.html
   [13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb8/igt@gem_exec_schedule@preempt-queue-bsd1.html

  * igt@gem_exec_schedule@reorder-wide-bsd:
    - shard-iclb:         [PASS][14] -> [SKIP][15] ([fdo#112146]) +4 similar issues
   [14]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb3/igt@gem_exec_schedule@reorder-wide-bsd.html
   [15]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb1/igt@gem_exec_schedule@reorder-wide-bsd.html

  * igt@gem_ppgtt@flink-and-close-vma-leak:
    - shard-kbl:          [PASS][16] -> [FAIL][17] ([i915#644])
   [16]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-kbl4/igt@gem_ppgtt@flink-and-close-vma-leak.html
   [17]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-kbl1/igt@gem_ppgtt@flink-and-close-vma-leak.html

  * igt@gem_userptr_blits@sync-unmap-cycles:
    - shard-snb:          [PASS][18] -> [DMESG-WARN][19] ([fdo#111870] / [i915#478]) +1 similar issue
   [18]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-snb2/igt@gem_userptr_blits@sync-unmap-cycles.html
   [19]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-snb2/igt@gem_userptr_blits@sync-unmap-cycles.html
    - shard-hsw:          [PASS][20] -> [DMESG-WARN][21] ([fdo#111870]) +1 similar issue
   [20]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-hsw6/igt@gem_userptr_blits@sync-unmap-cycles.html
   [21]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-hsw4/igt@gem_userptr_blits@sync-unmap-cycles.html

  * igt@i915_pm_rpm@modeset-non-lpsp-stress:
    - shard-hsw:          [PASS][22] -> [SKIP][23] ([fdo#109271]) +2 similar issues
   [22]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-hsw5/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
   [23]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-hsw4/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
    - shard-glk:          [PASS][24] -> [SKIP][25] ([fdo#109271]) +2 similar issues
   [24]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-glk5/igt@i915_pm_rpm@modeset-non-lpsp-stress.html
   [25]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-glk9/igt@i915_pm_rpm@modeset-non-lpsp-stress.html

  * igt@i915_pm_rps@waitboost:
    - shard-iclb:         [PASS][26] -> [FAIL][27] ([i915#413])
   [26]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb8/igt@i915_pm_rps@waitboost.html
   [27]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb5/igt@i915_pm_rps@waitboost.html

  * igt@i915_suspend@fence-restore-tiled2untiled:
    - shard-apl:          [PASS][28] -> [DMESG-WARN][29] ([i915#180]) +1 similar issue
   [28]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-apl4/igt@i915_suspend@fence-restore-tiled2untiled.html
   [29]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-apl6/igt@i915_suspend@fence-restore-tiled2untiled.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-kbl:          [PASS][30] -> [INCOMPLETE][31] ([fdo#103665] / [i915#600])
   [30]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-kbl3/igt@kms_flip@flip-vs-suspend.html
   [31]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-kbl7/igt@kms_flip@flip-vs-suspend.html

  * igt@kms_plane_lowres@pipe-a-tiling-y:
    - shard-glk:          [PASS][32] -> [FAIL][33] ([i915#899])
   [32]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-glk3/igt@kms_plane_lowres@pipe-a-tiling-y.html
   [33]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-glk1/igt@kms_plane_lowres@pipe-a-tiling-y.html

  * igt@kms_psr@psr2_primary_page_flip:
    - shard-iclb:         [PASS][34] -> [SKIP][35] ([fdo#109441])
   [34]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb2/igt@kms_psr@psr2_primary_page_flip.html
   [35]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb3/igt@kms_psr@psr2_primary_page_flip.html

  * igt@perf_pmu@busy-check-all-vcs1:
    - shard-iclb:         [PASS][36] -> [SKIP][37] ([fdo#112080]) +9 similar issues
   [36]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb1/igt@perf_pmu@busy-check-all-vcs1.html
   [37]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb3/igt@perf_pmu@busy-check-all-vcs1.html

  * igt@perf_pmu@rc6-runtime-pm-long:
    - shard-iclb:         [PASS][38] -> [SKIP][39] ([i915#293])
   [38]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb3/igt@perf_pmu@rc6-runtime-pm-long.html
   [39]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb5/igt@perf_pmu@rc6-runtime-pm-long.html
    - shard-tglb:         [PASS][40] -> [SKIP][41] ([fdo#111719])
   [40]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-tglb3/igt@perf_pmu@rc6-runtime-pm-long.html
   [41]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb2/igt@perf_pmu@rc6-runtime-pm-long.html

  
#### Possible fixes ####

  * igt@gem_busy@busy-vcs1:
    - shard-iclb:         [SKIP][42] ([fdo#112080]) -> [PASS][43] +9 similar issues
   [42]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb5/igt@gem_busy@busy-vcs1.html
   [43]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb2/igt@gem_busy@busy-vcs1.html

  * {igt@gem_ctx_persistence@close-replace-race}:
    - shard-tglb:         [INCOMPLETE][44] ([i915#1291]) -> [PASS][45]
   [44]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-tglb6/igt@gem_ctx_persistence@close-replace-race.html
   [45]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb2/igt@gem_ctx_persistence@close-replace-race.html

  * {igt@gem_exec_schedule@implicit-read-write-bsd1}:
    - shard-iclb:         [SKIP][46] ([fdo#109276] / [i915#677]) -> [PASS][47] +1 similar issue
   [46]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb5/igt@gem_exec_schedule@implicit-read-write-bsd1.html
   [47]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb2/igt@gem_exec_schedule@implicit-read-write-bsd1.html

  * igt@gem_exec_schedule@pi-common-bsd1:
    - shard-iclb:         [SKIP][48] ([fdo#109276]) -> [PASS][49] +19 similar issues
   [48]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb8/igt@gem_exec_schedule@pi-common-bsd1.html
   [49]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb1/igt@gem_exec_schedule@pi-common-bsd1.html

  * igt@gem_exec_schedule@pi-shared-iova-bsd:
    - shard-iclb:         [SKIP][50] ([i915#677]) -> [PASS][51]
   [50]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb2/igt@gem_exec_schedule@pi-shared-iova-bsd.html
   [51]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb7/igt@gem_exec_schedule@pi-shared-iova-bsd.html

  * igt@gem_exec_schedule@preemptive-hang-bsd:
    - shard-iclb:         [SKIP][52] ([fdo#112146]) -> [PASS][53] +2 similar issues
   [52]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb4/igt@gem_exec_schedule@preemptive-hang-bsd.html
   [53]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb8/igt@gem_exec_schedule@preemptive-hang-bsd.html

  * igt@gem_mmap_offset@pf-nonblock:
    - shard-hsw:          [DMESG-WARN][54] -> [PASS][55]
   [54]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-hsw6/igt@gem_mmap_offset@pf-nonblock.html
   [55]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-hsw7/igt@gem_mmap_offset@pf-nonblock.html
    - shard-snb:          [DMESG-WARN][56] ([i915#478]) -> [PASS][57]
   [56]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-snb2/igt@gem_mmap_offset@pf-nonblock.html
   [57]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-snb2/igt@gem_mmap_offset@pf-nonblock.html

  * igt@gem_ppgtt@flink-and-close-vma-leak:
    - shard-glk:          [FAIL][58] ([i915#644]) -> [PASS][59]
   [58]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-glk1/igt@gem_ppgtt@flink-and-close-vma-leak.html
   [59]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-glk2/igt@gem_ppgtt@flink-and-close-vma-leak.html

  * igt@gem_workarounds@suspend-resume-fd:
    - shard-kbl:          [DMESG-WARN][60] ([i915#180]) -> [PASS][61] +2 similar issues
   [60]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-kbl3/igt@gem_workarounds@suspend-resume-fd.html
   [61]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-kbl1/igt@gem_workarounds@suspend-resume-fd.html

  * igt@kms_big_fb@x-tiled-32bpp-rotate-180:
    - shard-kbl:          [DMESG-FAIL][62] ([i915#95]) -> [PASS][63]
   [62]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-kbl6/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html
   [63]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-kbl7/igt@kms_big_fb@x-tiled-32bpp-rotate-180.html

  * igt@kms_cursor_crc@pipe-b-cursor-suspend:
    - shard-apl:          [DMESG-WARN][64] ([i915#180]) -> [PASS][65] +2 similar issues
   [64]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-apl4/igt@kms_cursor_crc@pipe-b-cursor-suspend.html
   [65]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-apl7/igt@kms_cursor_crc@pipe-b-cursor-suspend.html

  * igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size:
    - shard-glk:          [FAIL][66] ([IGT#5] / [i915#697]) -> [PASS][67]
   [66]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-glk6/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html
   [67]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-glk8/igt@kms_cursor_legacy@flip-vs-cursor-atomic-transitions-varying-size.html

  * igt@kms_frontbuffer_tracking@fbc-2p-shrfb-fliptrack:
    - shard-glk:          [FAIL][68] ([i915#49]) -> [PASS][69]
   [68]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-glk9/igt@kms_frontbuffer_tracking@fbc-2p-shrfb-fliptrack.html
   [69]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-glk4/igt@kms_frontbuffer_tracking@fbc-2p-shrfb-fliptrack.html

  * igt@kms_psr@psr2_primary_mmap_cpu:
    - shard-iclb:         [SKIP][70] ([fdo#109441]) -> [PASS][71] +2 similar issues
   [70]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb7/igt@kms_psr@psr2_primary_mmap_cpu.html
   [71]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb2/igt@kms_psr@psr2_primary_mmap_cpu.html

  * igt@perf@gen12-mi-rpc:
    - shard-tglb:         [FAIL][72] -> [PASS][73]
   [72]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-tglb1/igt@perf@gen12-mi-rpc.html
   [73]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb1/igt@perf@gen12-mi-rpc.html

  
#### Warnings ####

  * igt@gem_ctx_isolation@vcs1-nonpriv:
    - shard-iclb:         [SKIP][74] ([fdo#112080]) -> [FAIL][75] ([IGT#28])
   [74]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb7/igt@gem_ctx_isolation@vcs1-nonpriv.html
   [75]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb4/igt@gem_ctx_isolation@vcs1-nonpriv.html

  * igt@gem_userptr_blits@map-fixed-invalidate-busy-gup:
    - shard-hsw:          [DMESG-WARN][76] ([fdo#110789] / [fdo#111870]) -> [DMESG-WARN][77] ([fdo#111870])
   [76]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-hsw6/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html
   [77]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-hsw7/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html
    - shard-snb:          [DMESG-WARN][78] ([fdo#110789] / [fdo#111870] / [i915#478]) -> [DMESG-WARN][79] ([fdo#111870] / [i915#478])
   [78]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-snb5/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html
   [79]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-snb2/igt@gem_userptr_blits@map-fixed-invalidate-busy-gup.html

  * igt@i915_pm_rpm@dpms-non-lpsp:
    - shard-tglb:         [SKIP][80] ([fdo#111644]) -> [SKIP][81] ([i915#1316])
   [80]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-tglb8/igt@i915_pm_rpm@dpms-non-lpsp.html
   [81]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb2/igt@i915_pm_rpm@dpms-non-lpsp.html
    - shard-iclb:         [SKIP][82] ([fdo#110892]) -> [SKIP][83] ([i915#1316])
   [82]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-iclb7/igt@i915_pm_rpm@dpms-non-lpsp.html
   [83]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-iclb5/igt@i915_pm_rpm@dpms-non-lpsp.html

  * igt@i915_selftest@live_gt_lrc:
    - shard-tglb:         [INCOMPLETE][84] ([i915#1233]) -> [DMESG-FAIL][85] ([i915#1233])
   [84]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-tglb7/igt@i915_selftest@live_gt_lrc.html
   [85]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-tglb3/igt@i915_selftest@live_gt_lrc.html

  * igt@kms_content_protection@srm:
    - shard-kbl:          [TIMEOUT][86] ([i915#1319]) -> [TIMEOUT][87] ([i915#1319] / [i915#727])
   [86]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-kbl3/igt@kms_content_protection@srm.html
   [87]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-kbl1/igt@kms_content_protection@srm.html

  * igt@kms_flip@flip-vs-suspend:
    - shard-apl:          [DMESG-WARN][88] ([i915#180]) -> [INCOMPLETE][89] ([fdo#103927])
   [88]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5467/shard-apl1/igt@kms_flip@flip-vs-suspend.html
   [89]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/shard-apl4/igt@kms_flip@flip-vs-suspend.html

  
  {name}: This element is suppressed. This means it is ignored when computing
          the status of the difference (SUCCESS, WARNING, or FAILURE).

  [IGT#28]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/28
  [IGT#5]: https://gitlab.freedesktop.org/drm/igt-gpu-tools/issues/5
  [fdo#103665]: https://bugs.freedesktop.org/show_bug.cgi?id=103665
  [fdo#103927]: https://bugs.freedesktop.org/show_bug.cgi?id=103927
  [fdo#109271]: https://bugs.freedesktop.org/show_bug.cgi?id=109271
  [fdo#109276]: https://bugs.freedesktop.org/show_bug.cgi?id=109276
  [fdo#109441]: https://bugs.freedesktop.org/show_bug.cgi?id=109441
  [fdo#110789]: https://bugs.freedesktop.org/show_bug.cgi?id=110789
  [fdo#110854]: https://bugs.freedesktop.org/show_bug.cgi?id=110854
  [fdo#110892]: https://bugs.freedesktop.org/show_bug.cgi?id=110892
  [fdo#111644]: https://bugs.freedesktop.org/show_bug.cgi?id=111644
  [fdo#111719]: https://bugs.freedesktop.org/show_bug.cgi?id=111719
  [fdo#111870]: https://bugs.freedesktop.org/show_bug.cgi?id=111870
  [fdo#112080]: https://bugs.freedesktop.org/show_bug.cgi?id=112080
  [fdo#112146]: https://bugs.freedesktop.org/show_bug.cgi?id=112146
  [i915#1233]: https://gitlab.freedesktop.org/drm/intel/issues/1233
  [i915#1291]: https://gitlab.freedesktop.org/drm/intel/issues/1291
  [i915#1316]: https://gitlab.freedesktop.org/drm/intel/issues/1316
  [i915#1319]: https://gitlab.freedesktop.org/drm/intel/issues/1319
  [i915#180]: https://gitlab.freedesktop.org/drm/intel/issues/180
  [i915#293]: https://gitlab.freedesktop.org/drm/intel/issues/293
  [i915#413]: https://gitlab.freedesktop.org/drm/intel/issues/413
  [i915#478]: https://gitlab.freedesktop.org/drm/intel/issues/478
  [i915#49]: https://gitlab.freedesktop.org/drm/intel/issues/49
  [i915#58]: https://gitlab.freedesktop.org/drm/intel/issues/58
  [i915#600]: https://gitlab.freedesktop.org/drm/intel/issues/600
  [i915#644]: https://gitlab.freedesktop.org/drm/intel/issues/644
  [i915#677]: https://gitlab.freedesktop.org/drm/intel/issues/677
  [i915#697]: https://gitlab.freedesktop.org/drm/intel/issues/697
  [i915#727]: https://gitlab.freedesktop.org/drm/intel/issues/727
  [i915#899]: https://gitlab.freedesktop.org/drm/intel/issues/899
  [i915#95]: https://gitlab.freedesktop.org/drm/intel/issues/95
  [k.org#198133]: https://bugzilla.kernel.org/show_bug.cgi?id=198133


Participating hosts (8 -> 8)
------------------------------

  No changes in participating hosts


Build changes
-------------

  * CI: CI-20190529 -> None
  * IGT: IGT_5467 -> IGTPW_4223

  CI-20190529: 20190529
  CI_DRM_8005: 81f641f60edbfa1ccb169689206f0af360a06e31 @ git://anongit.freedesktop.org/gfx-ci/linux
  IGTPW_4223: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/index.html
  IGT_5467: 2684f182424582c66e67bcbbda77cd60901627b8 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools

== Logs ==

For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4223/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2020-02-26 18:49 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-25 16:52 [igt-dev] [PATCH i-g-t 1/9] lib/tests: Extract fork helpers Arkadiusz Hiler
2020-02-25 16:52 ` [igt-dev] [PATCH i-g-t 2/9] lib/tests: Add support for redirecting fork output to /dev/null Arkadiusz Hiler
2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 3/9] lib: Make it possible to abort the whole execution from inside of a test Arkadiusz Hiler
2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 4/9] runner/runner_tests: Extract helper for inspecting test result Arkadiusz Hiler
2020-02-25 16:55 ` [igt-dev] [PATCH i-g-t 5/9] runner: Abort the run when test exits with IGT_EXIT_ABORT Arkadiusz Hiler
2020-02-25 16:56 ` [igt-dev] [PATCH i-g-t 6/9] lib/chamelium: Clear error after checking if chamelium is reachable Arkadiusz Hiler
2020-02-25 16:56 ` [igt-dev] [PATCH i-g-t 7/9] lib/chamelium: Make it clear that function asserts Arkadiusz Hiler
2020-02-25 16:57 ` [igt-dev] [PATCH i-g-t 8/9] lib/chamelium: Add functions to initialize XMLRPC only Arkadiusz Hiler
2020-02-25 16:57 ` [igt-dev] [PATCH i-g-t 9/9] lib/kms: Try to plug all Chamelium ports, abort if it fails Arkadiusz Hiler
2020-02-26 10:31 ` [igt-dev] ✗ GitLab.Pipeline: failure for series starting with [i-g-t,1/9] lib/tests: Extract fork helpers Patchwork
2020-02-26 12:15 ` [igt-dev] ✓ Fi.CI.BAT: success " Patchwork
2020-02-26 18:49 ` [igt-dev] ✗ Fi.CI.IGT: failure " Patchwork

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.