All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC i-g-t] igt: Test tagging support
@ 2017-06-27 11:59 Tvrtko Ursulin
  2017-06-27 13:18 ` Daniel Vetter
  0 siblings, 1 reply; 8+ messages in thread
From: Tvrtko Ursulin @ 2017-06-27 11:59 UTC (permalink / raw)
  To: Intel-gfx; +Cc: Tomi Sarvela, Daniel Vetter

From: Tvrtko Ursulin <tvrtko.ursulin@intel.com>

Proposal to add test tags as a replacement for separate test
list which can be difficult to maintain and get out of date.

Putting this maintanenace inline with tests makes it easier
to remember to update the, now implicit, lists, and also enables
richer test selection possibilities for the test runner.

Test tags are string tokens separated by spaces meaning of which
we decide by creating a convetion and helped by the suitable
helper macros.

For example tags can be things like: gem, kms, guc, flip,
semaphore, bz12345678, gt4e, etc..

At runtime this would look something like this:

  root@e31:~/intel-gpu-tools# tests/gem_sync --list-subtests-with-tags
  default TAGS="gem "
  store-default TAGS="gem "
  many-default TAGS="gem "
  forked-default TAGS="gem "
  forked-store-default TAGS="gem "
  render TAGS="gem "
  store-render TAGS="gem "
  many-render TAGS="gem "
  forked-render TAGS="gem "
  forked-store-render TAGS="gem "
  bsd TAGS="gem "
  store-bsd TAGS="gem "
  many-bsd TAGS="gem "
  forked-bsd TAGS="gem "
  forked-store-bsd TAGS="gem "
  bsd1 TAGS="gem "
  store-bsd1 TAGS="gem "
  many-bsd1 TAGS="gem "
  forked-bsd1 TAGS="gem "
  forked-store-bsd1 TAGS="gem "
  bsd2 TAGS="gem "
  store-bsd2 TAGS="gem "
  many-bsd2 TAGS="gem "
  forked-bsd2 TAGS="gem "
  forked-store-bsd2 TAGS="gem "
  blt TAGS="gem "
  store-blt TAGS="gem "
  many-blt TAGS="gem "
  forked-blt TAGS="gem "
  forked-store-blt TAGS="gem "
  vebox TAGS="gem "
  store-vebox TAGS="gem "
  many-vebox TAGS="gem "
  forked-vebox TAGS="gem "
  forked-store-vebox TAGS="gem "
  each TAGS="gem basic"
  store-each TAGS="gem basic"
  many-each TAGS="gem basic"
  forked-each TAGS="gem basic"
  forked-store-each TAGS="gem "
  all TAGS="gem basic"
  store-all TAGS="gem basic"
  forked-all TAGS="gem extended"
  forked-store-all TAGS="gem extended"

Test runner can then enable usages like:

  ./run-tests --include gem --exclude kms,stress

Which I think could really be useful and more flexible than name
based selection.

This RFC implementation automatically adds "gem" and "kms" tags
to test binaries prefixed with those strings respectively.

I've converted gem_concurrent_all and gem_sync as examples only.

Source code usage looks like:

	igt_gem_subtest("basic", "each")
		sync_ring(fd, ~0u, 1, 5);

	igt_gem_subtest("extended", "forked-all")
		sync_all(fd, ncpus, 150);

We can of course polish the details of the API if the idea will
be deemed interesting.

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Daniel Vetter <daniel.vetter@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Petri Latvala <petri.latvala@intel.com>
Cc: Tomi Sarvela <tomi.p.sarvela@intel.com>
Cc: Radoslaw Szwichtenberg <radoslaw.szwichtenberg@intel.com>
---
 lib/igt_core.c             | 38 +++++++++++++++++++++++++++++++-------
 lib/igt_core.h             | 29 ++++++++++++++++++++++++++---
 tests/gem_concurrent_all.c | 34 +++++++++++++++++-----------------
 tests/gem_sync.c           | 28 ++++++++++++++--------------
 4 files changed, 88 insertions(+), 41 deletions(-)

diff --git a/lib/igt_core.c b/lib/igt_core.c
index 9a5ed40eeb22..37cd261daf2b 100644
--- a/lib/igt_core.c
+++ b/lib/igt_core.c
@@ -231,10 +231,10 @@ static unsigned int exit_handler_count;
 const char *igt_interactive_debug;
 
 /* subtests helpers */
-static bool list_subtests = false;
-static char *run_single_subtest = NULL;
+static bool list_subtests, list_subtests_tags;
+static char *run_single_subtest;
 static bool run_single_subtest_found = false;
-static const char *in_subtest = NULL;
+static const char *in_subtest, *subtest_tags;
 static struct timespec subtest_time;
 static clockid_t igt_clock = (clockid_t)-1;
 static bool in_fixture = false;
@@ -254,6 +254,7 @@ bool test_child;
 
 enum {
  OPT_LIST_SUBTESTS,
+ OPT_LIST_SUBTESTS_TAGS,
  OPT_RUN_SUBTEST,
  OPT_DESCRIPTION,
  OPT_DEBUG,
@@ -571,6 +572,7 @@ static void print_usage(const char *help_str, bool output_on_stderr)
 
 	fprintf(f, "Usage: %s [OPTIONS]\n", command_str);
 	fprintf(f, "  --list-subtests\n"
+		   "  --list-subtest-with-tags\n"
 		   "  --run-subtest <pattern>\n"
 		   "  --debug[=log-domain]\n"
 		   "  --interactive-debug[=domain]\n"
@@ -603,6 +605,7 @@ static int common_init(int *argc, char **argv,
 	int c, option_index = 0, i, x;
 	static struct option long_options[] = {
 		{"list-subtests", 0, 0, OPT_LIST_SUBTESTS},
+		{"list-subtests-with-tags", 0, 0, OPT_LIST_SUBTESTS_TAGS},
 		{"run-subtest", 1, 0, OPT_RUN_SUBTEST},
 		{"help-description", 0, 0, OPT_DESCRIPTION},
 		{"debug", optional_argument, 0, OPT_DEBUG},
@@ -714,6 +717,12 @@ static int common_init(int *argc, char **argv,
 			if (!run_single_subtest)
 				list_subtests = true;
 			break;
+		case OPT_LIST_SUBTESTS_TAGS:
+			if (!run_single_subtest) {
+				list_subtests = true;
+				list_subtests_tags = true;
+			}
+			break;
 		case OPT_RUN_SUBTEST:
 			if (!list_subtests)
 				run_single_subtest = strdup(optarg);
@@ -847,14 +856,22 @@ void igt_simple_init_parse_opts(int *argc, char **argv,
  * outside of places protected by igt_run_subtest checks - the piglit
  * runner adds every line to the subtest list.
  */
-bool __igt_run_subtest(const char *subtest_name)
+bool __igt_run_subtest(const char *subtest_name, const char *tags)
 {
 	int i;
 
 	assert(!in_subtest);
+	assert(!subtest_tags);
 	assert(!in_fixture);
 	assert(test_with_subtests);
 
+	if (!tags) {
+		if (!strncmp(command_str, "gem", 3))
+			tags = "gem";
+		else if (!strncmp(command_str, "kms", 3))
+			tags = "kms";
+	}
+
 	/* check the subtest name only contains a-z, A-Z, 0-9, '-' and '_' */
 	for (i = 0; subtest_name[i] != '\0'; i++)
 		if (subtest_name[i] != '_' && subtest_name[i] != '-'
@@ -865,7 +882,10 @@ bool __igt_run_subtest(const char *subtest_name)
 		}
 
 	if (list_subtests) {
-		printf("%s\n", subtest_name);
+		if (list_subtests_tags && tags)
+			printf("%s TAGS=\"%s\"\n", subtest_name, tags);
+		else
+			printf("%s\n", subtest_name);
 		return false;
 	}
 
@@ -890,7 +910,11 @@ bool __igt_run_subtest(const char *subtest_name)
 	_igt_log_buffer_reset();
 
 	gettime(&subtest_time);
-	return (in_subtest = subtest_name);
+
+	in_subtest = subtest_name;
+	subtest_tags = tags;
+
+	return true;
 }
 
 /**
@@ -941,7 +965,7 @@ static void exit_subtest(const char *result)
 	       (!__igt_plain_output) ? "\x1b[0m" : "");
 	fflush(stdout);
 
-	in_subtest = NULL;
+	in_subtest = subtest_tags = NULL;
 	siglongjmp(igt_subtest_jmpbuf, 1);
 }
 
diff --git a/lib/igt_core.h b/lib/igt_core.h
index a2ed972078bd..b6ca5d315f08 100644
--- a/lib/igt_core.h
+++ b/lib/igt_core.h
@@ -145,7 +145,7 @@ int igt_subtest_init_parse_opts(int *argc, char **argv,
 #define igt_subtest_init(argc, argv) \
 	igt_subtest_init_parse_opts(&argc, argv, NULL, NULL, NULL, NULL, NULL);
 
-bool __igt_run_subtest(const char *subtest_name);
+bool __igt_run_subtest(const char *subtest_name, const char *subtest_tags);
 #define __igt_tokencat2(x, y) x ## y
 
 /**
@@ -158,6 +158,29 @@ bool __igt_run_subtest(const char *subtest_name);
  */
 #define igt_tokencat(x, y) __igt_tokencat2(x, y)
 
+#define igt_tagged_subtest(tags, name) \
+	for (; __igt_run_subtest((name), (tags)) && \
+	       (sigsetjmp(igt_subtest_jmpbuf, 1) == 0); \
+	     igt_success())
+
+#define igt_gem_subtest(tags, name) igt_tagged_subtest("gem "tags, name)
+
+#define __igt_tagged_subtest_f(tags, tmp, format...) \
+	for (char tmp [256]; \
+	     snprintf( tmp , sizeof( tmp ), format), \
+	     __igt_run_subtest(tmp, tags) && \
+	     (sigsetjmp(igt_subtest_jmpbuf, 1) == 0); \
+	     igt_success())
+
+#define igt_tagged_subtest_f(tags, f...) \
+	__igt_tagged_subtest_f(tags, igt_tokencat(__tmpchar, __LINE__), f)
+
+#define igt_gem_subtest_f(tags, f...) \
+	igt_tagged_subtest_f("gem "tags, f)
+
+#define igt_gem_stress_subtest_f(tags, f...) \
+	igt_tagged_subtest_f("gem stress "tags, f)
+
 /**
  * igt_subtest:
  * @name: name of the subtest
@@ -169,14 +192,14 @@ bool __igt_run_subtest(const char *subtest_name);
  *
  * This is a simpler version of igt_subtest_f()
  */
-#define igt_subtest(name) for (; __igt_run_subtest((name)) && \
+#define igt_subtest(name) for (; __igt_run_subtest((name), NULL) && \
 				   (sigsetjmp(igt_subtest_jmpbuf, 1) == 0); \
 				   igt_success())
 #define __igt_subtest_f(tmp, format...) \
 	for (char tmp [256]; \
 	     snprintf( tmp , sizeof( tmp ), \
 		      format), \
-	     __igt_run_subtest( tmp ) && \
+	     __igt_run_subtest(tmp, NULL) && \
 	     (sigsetjmp(igt_subtest_jmpbuf, 1) == 0); \
 	     igt_success())
 
diff --git a/tests/gem_concurrent_all.c b/tests/gem_concurrent_all.c
index 201b491bc245..eef0c8878081 100644
--- a/tests/gem_concurrent_all.c
+++ b/tests/gem_concurrent_all.c
@@ -1492,47 +1492,47 @@ run_mode(const char *prefix,
 			igt_subtest_group  {
 				igt_fixture p->require();
 
-				igt_subtest_f("%s-%s-%s-sanitycheck0%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-sanitycheck0%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers, do_basic0,
 							p->copy, h->hang);
 				}
 
-				igt_subtest_f("%s-%s-%s-sanitycheck1%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-sanitycheck1%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers, do_basic1,
 							p->copy, h->hang);
 				}
 
-				igt_subtest_f("%s-%s-%s-sanitycheckN%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-sanitycheckN%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers, do_basicN,
 							p->copy, h->hang);
 				}
 
 				/* try to overwrite the source values */
-				igt_subtest_f("%s-%s-%s-overwrite-source-one%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-overwrite-source-one%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_overwrite_source__one,
 							p->copy, h->hang);
 				}
 
-				igt_subtest_f("%s-%s-%s-overwrite-source%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-overwrite-source%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_overwrite_source,
 							p->copy, h->hang);
 				}
 
-				igt_subtest_f("%s-%s-%s-overwrite-source-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-overwrite-source-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_overwrite_source_read_bcs,
 							p->copy, h->hang);
 				}
 
-				igt_subtest_f("%s-%s-%s-overwrite-source-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-overwrite-source-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					igt_require(rendercopy);
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
@@ -1540,7 +1540,7 @@ run_mode(const char *prefix,
 							p->copy, h->hang);
 				}
 
-				igt_subtest_f("%s-%s-%s-overwrite-source-rev%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-overwrite-source-rev%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_overwrite_source__rev,
@@ -1548,21 +1548,21 @@ run_mode(const char *prefix,
 				}
 
 				/* try to intermix copies with GPU copies*/
-				igt_subtest_f("%s-%s-%s-intermix-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-intermix-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					igt_require(rendercopy);
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_intermix_rcs,
 							p->copy, h->hang);
 				}
-				igt_subtest_f("%s-%s-%s-intermix-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-intermix-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					igt_require(rendercopy);
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_intermix_bcs,
 							p->copy, h->hang);
 				}
-				igt_subtest_f("%s-%s-%s-intermix-both%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-intermix-both%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					igt_require(rendercopy);
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
@@ -1571,7 +1571,7 @@ run_mode(const char *prefix,
 				}
 
 				/* try to read the results before the copy completes */
-				igt_subtest_f("%s-%s-%s-early-read%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-early-read%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_early_read,
@@ -1579,13 +1579,13 @@ run_mode(const char *prefix,
 				}
 
 				/* concurrent reads */
-				igt_subtest_f("%s-%s-%s-read-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-read-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_read_read_bcs,
 							p->copy, h->hang);
 				}
-				igt_subtest_f("%s-%s-%s-read-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-read-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					igt_require(rendercopy);
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
@@ -1594,13 +1594,13 @@ run_mode(const char *prefix,
 				}
 
 				/* split copying between rings */
-				igt_subtest_f("%s-%s-%s-write-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-write-read-bcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_write_read_bcs,
 							p->copy, h->hang);
 				}
-				igt_subtest_f("%s-%s-%s-write-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-write-read-rcs%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					igt_require(rendercopy);
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
@@ -1609,7 +1609,7 @@ run_mode(const char *prefix,
 				}
 
 				/* and finally try to trick the kernel into loosing the pending write */
-				igt_subtest_f("%s-%s-%s-gpu-read-after-write%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
+				igt_gem_stress_subtest_f("", "%s-%s-%s-gpu-read-after-write%s%s", prefix, mode->name, p->prefix, suffix, h->suffix) {
 					buffers_create(&buffers);
 					run_wrap_func(&buffers,
 							do_gpu_read_after_write,
diff --git a/tests/gem_sync.c b/tests/gem_sync.c
index 706462bc0ac7..36ce3c2880b1 100644
--- a/tests/gem_sync.c
+++ b/tests/gem_sync.c
@@ -730,36 +730,36 @@ igt_main
 	}
 
 	for (e = intel_execution_engines; e->name; e++) {
-		igt_subtest_f("%s", e->name)
+		igt_gem_subtest_f("", "%s", e->name)
 			sync_ring(fd, e->exec_id | e->flags, 1, 150);
-		igt_subtest_f("store-%s", e->name)
+		igt_gem_subtest_f("", "store-%s", e->name)
 			store_ring(fd, e->exec_id | e->flags, 1, 150);
-		igt_subtest_f("many-%s", e->name)
+		igt_gem_subtest_f("", "many-%s", e->name)
 			store_many(fd, e->exec_id | e->flags, 150);
-		igt_subtest_f("forked-%s", e->name)
+		igt_gem_subtest_f("", "forked-%s", e->name)
 			sync_ring(fd, e->exec_id | e->flags, ncpus, 150);
-		igt_subtest_f("forked-store-%s", e->name)
+		igt_gem_subtest_f("", "forked-store-%s", e->name)
 			store_ring(fd, e->exec_id | e->flags, ncpus, 150);
 	}
 
-	igt_subtest("basic-each")
+	igt_gem_subtest("basic", "each")
 		sync_ring(fd, ~0u, 1, 5);
-	igt_subtest("basic-store-each")
+	igt_gem_subtest("basic", "store-each")
 		store_ring(fd, ~0u, 1, 5);
-	igt_subtest("basic-many-each")
+	igt_gem_subtest("basic", "many-each")
 		store_many(fd, ~0u, 5);
-	igt_subtest("forked-each")
+	igt_gem_subtest("basic", "forked-each")
 		sync_ring(fd, ~0u, ncpus, 150);
-	igt_subtest("forked-store-each")
+	igt_gem_subtest("", "forked-store-each")
 		store_ring(fd, ~0u, ncpus, 150);
 
-	igt_subtest("basic-all")
+	igt_gem_subtest("basic", "all")
 		sync_all(fd, 1, 5);
-	igt_subtest("basic-store-all")
+	igt_gem_subtest("basic", "store-all")
 		store_all(fd, 1, 5);
-	igt_subtest("forked-all")
+	igt_gem_subtest("extended", "forked-all")
 		sync_all(fd, ncpus, 150);
-	igt_subtest("forked-store-all")
+	igt_gem_subtest("extended", "forked-store-all")
 		store_all(fd, ncpus, 150);
 
 	igt_fixture {
-- 
2.9.4

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

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

end of thread, other threads:[~2017-06-29  9:34 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-06-27 11:59 [RFC i-g-t] igt: Test tagging support Tvrtko Ursulin
2017-06-27 13:18 ` Daniel Vetter
2017-06-27 14:03   ` Tvrtko Ursulin
2017-06-29  8:49     ` Daniel Vetter
2017-06-29  9:07       ` Jani Nikula
2017-06-29  9:27         ` Tvrtko Ursulin
2017-06-29  9:23       ` Tvrtko Ursulin
2017-06-29  9:34         ` Daniel Vetter

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.