[RFC i-g-t] kunit: Remove hard-coded test list from xe_live_ktest

John.C.Harrison at Intel.com John.C.Harrison at Intel.com
Fri Aug 23 18:24:18 UTC 2024


From: johnharr <johnharr at invalid-email.com>

The list of supported kunit tests is currently hard coded. Which means
that adding a new test to the kernel also requires patches to IGT as
well.

The list of available kunit tests is already exported by the kernel.
So there is no need to bake a list into the IGT source code. So, add
support for querying the test list dynamically.

NB: Currently, the test list can only be queried by root but the IGT
build system queries all tests at compile time. In theory this should
not be a problem. However, the kunit helper code is all written to run
inside a test and not inside the prep code, which means that when it
fails to open the root only interfaces, it calls 'skip'. And skip is
not allowed outside of running a test. Hence the build fails with:
  skipping is allowed only in fixtures, subtests or igt_simple_main

And of course, putting all the query code inside an igt_fixture block
means it doesn't get run as part of --show-testlist or --list-subtests.

Reworking the kunit code to fail cleanly rather than skipping
everywhere seems much more invasive. It is also not clear why the
kunit code is considered 'library' when it is execlusively used from
the kunit test alone!? So posting this as an RFC before going too far
down the possible rabbit hole.

Signed-off-by: John Harrison <John.C.Harrison at Intel.com>
---
 lib/igt_kmod.c              | 68 +++++++++++++++++++++++++++++++++++++
 lib/igt_kmod.h              |  6 ++++
 tests/intel/xe_live_ktest.c | 60 ++++++++++++++++----------------
 3 files changed, 103 insertions(+), 31 deletions(-)

diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c
index 464c0dcf484a..69c1254b397c 100644
--- a/lib/igt_kmod.c
+++ b/lib/igt_kmod.c
@@ -1414,6 +1414,74 @@ static void __igt_kunit(struct igt_ktest *tst,
 	}
 }
 
+/**
+ * igt_kunit:
+ * @module_name: the name of the module
+ * @suite: the name of test suite to be executed, also used as subtest name;
+ *	   if NULL then test cases from all test suites provided by the module
+ *	   are executed as dynamic sub-subtests of one IGT subtest, which name
+ *	   is derived from the module name by cutting off its optional trailing
+ *	   _test or _kunit suffix
+ * @opts: options to load the module
+ *
+ * Loads the test module, parses its (k)tap dmesg output, then unloads it
+ */
+void igt_kunit_get_test_names(const char *module_name, const char *opts, struct igt_list_head *names)
+{
+	char debugfs_path[PATH_MAX] = { '\0', };
+	struct igt_ktest tst = { .kmsg = -1, };
+	struct igt_ktap_results *ktap = NULL;
+	const char *subtest;
+	char *suite_name = NULL, *case_name = NULL;
+	DIR *debugfs_dir = NULL;
+	IGT_LIST_HEAD(tests);
+
+	subtest = strdup(module_name);
+	if (!igt_debug_on(!subtest)) {
+		char *suffix = strstr(subtest, "_test");
+
+		if (!suffix)
+			suffix = strstr(subtest, "_kunit");
+
+		if (suffix)
+			*suffix = '\0';
+	}
+
+	igt_require(subtest);
+
+	igt_require(!igt_ktest_init(&tst, module_name));
+	igt_require(!igt_ktest_begin(&tst));
+
+	igt_ignore_warn(igt_kmod_load("kunit", NULL));
+
+	kunit_debugfs_path(debugfs_path);
+	igt_info("kunit path: %s\n", debugfs_path);
+	if (igt_debug_on(!*debugfs_path) ||
+	    !kunit_get_tests(&tests, &tst, NULL, opts, debugfs_path, &debugfs_dir, &ktap)) {
+		igt_info("kunit - no tests found!?\n");
+	} else {
+		struct igt_ktap_result *t;
+		igt_info("kunit tests:\n");
+		igt_list_for_each_entry(t, &tests, link) {
+			struct igt_kunit_names *name = malloc(sizeof(*name));
+			name->suite = strdup(t->suite_name);
+			name->sub = strdup(t->case_name);
+			igt_info("  %s / %s\n", t->suite_name, t->case_name);
+			igt_list_add(&name->link, names);
+		}
+	}
+
+	igt_ktap_free(&ktap);
+
+	kunit_results_free(&tests, &suite_name, &case_name);
+
+	if (debugfs_dir)
+		closedir(debugfs_dir);
+
+	igt_ktest_end(&tst);
+	igt_ktest_fini(&tst);
+}
+
 /**
  * igt_kunit:
  * @module_name: the name of the module
diff --git a/lib/igt_kmod.h b/lib/igt_kmod.h
index efb46da128d4..2f608eb69d48 100644
--- a/lib/igt_kmod.h
+++ b/lib/igt_kmod.h
@@ -71,7 +71,13 @@ static inline int igt_xe_driver_unload(void)
 int igt_amdgpu_driver_load(const char *opts);
 int igt_amdgpu_driver_unload(void);
 
+struct igt_kunit_names {
+	char *suite;
+	char *sub;
+	struct igt_list_head link;
+};
 void igt_kunit(const char *module_name, const char *name, const char *opts);
+void igt_kunit_get_test_names(const char *module_name, const char *opts, struct igt_list_head *names);
 
 void igt_kselftests(const char *module_name,
 		    const char *module_options,
diff --git a/tests/intel/xe_live_ktest.c b/tests/intel/xe_live_ktest.c
index 4376d5df7751..13265e87ba9d 100644
--- a/tests/intel/xe_live_ktest.c
+++ b/tests/intel/xe_live_ktest.c
@@ -9,40 +9,38 @@
  * Sub-category: kunit
  * Functionality: kunit test
  * Test category: functionality test
- *
- * SUBTEST: xe_bo
- * Description:
- *	Kernel dynamic selftests to check if GPU buffer objects are
- *	being handled properly.
- * Functionality: bo
- *
- * SUBTEST: xe_dma_buf
- * Description: Kernel dynamic selftests for dmabuf functionality.
- * Functionality: dmabuf test
- *
- * SUBTEST: xe_migrate
- * Description:
- *	Kernel dynamic selftests to check if page table migrations
- *	are working properly.
- * Functionality: migrate
- *
- * SUBTEST: xe_mocs
- * Description:
- *	Kernel dynamic selftests to check mocs configuration.
- * Functionality: mocs configuration
  */
 
-static const char *live_tests[] = {
-	"xe_bo",
-	"xe_dma_buf",
-	"xe_migrate",
-	"xe_mocs",
-};
-
 igt_main
 {
-	int i;
+	IGT_LIST_HEAD(names);
+	IGT_LIST_HEAD(done);
+	struct igt_kunit_names *name, *cmp;
+
+	igt_kunit_get_test_names("xe_live_test", NULL, &names);
+
+	while (!igt_list_empty(&names)) {
+		bool found = false;
+
+		name = igt_list_first_entry(&names, name, link);
+		igt_list_del(&name->link);
+
+		/*
+		 * Retuned list is sub-tests.
+		 * So, need filter out duplicated top level names.
+		 */
+		igt_list_for_each_entry(cmp, &done, link) {
+			if (strcmp(name->suite, cmp->suite) != 0)
+				continue;
+
+			found = true;
+		}
+
+		if (found)
+			continue;
+
+		igt_list_add(&name->link, &done);
 
-	for (i = 0; i < ARRAY_SIZE(live_tests); i++)
-		igt_kunit("xe_live_test", live_tests[i], NULL);
+		igt_kunit("xe_live_test", name->suite, NULL);
+	}
 }
-- 
2.46.0



More information about the igt-dev mailing list