Authentication-Results: mail-b.sr.ht; dkim=pass header.d=riseup.net header.i=@riseup.net Received: from mx1.riseup.net (mx1.riseup.net [198.252.153.129]) by mail-b.sr.ht (Postfix) with ESMTPS id 428CE11EE9A for <~lkcamp/patches@lists.sr.ht>; Sat, 5 Mar 2022 13:53:44 +0000 (UTC) Received: from fews1.riseup.net (fews1-pn.riseup.net [10.0.1.83]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256 client-signature RSA-PSS (2048 bits) client-digest SHA256) (Client CN "mail.riseup.net", Issuer "R3" (not verified)) by mx1.riseup.net (Postfix) with ESMTPS id 4K9mQv2BsczF43l; Sat, 5 Mar 2022 05:53:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=riseup.net; s=squak; t=1646488423; bh=O1Ay3UtER9Wtsq+lXfdzYDN80tEgKtqVY4PpGVjrydw=; h=From:To:Cc:Subject:Date:From; b=NaXusH2CVxDiAVnC7Ofzk2q36Rxv2T5623lsjDMMIq3bY4m2jJNEmpMwZZs67gBKO pmHRa6/3CqgJbLwU1ypyDVs6FpXR5BXlcVSNb774YSy160iCmdcioVWElnXDC8Wlsz edCC+ZS/TthpvAUGqBiWzZkBeRvas40u7Nu55RHI= X-Riseup-User-ID: 967C2AB024B02FFA22BA9955B5C92CE62A0D0D91AAD5E3D896EB8F6229E37E0A Received: from [127.0.0.1] (localhost [127.0.0.1]) by fews1.riseup.net (Postfix) with ESMTPSA id 4K9mQr4rkNz5vLn; Sat, 5 Mar 2022 05:53:40 -0800 (PST) From: Isabella Basso To: siqueirajordao@riseup.net, mwen@igalia.com, maira.canal@usp.br, magalilemes00@gmail.com Cc: ~lkcamp/patches@lists.sr.ht, Isabella Basso Subject: [PATCH 1/2] igt_kmod: add compatibility for KUnit Date: Sat, 5 Mar 2022 10:53:31 -0300 Message-Id: <20220305135332.59071-1-isabbasso@riseup.net> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit This adds functions for both executing the tests as well as parsing TAP kmsg output. Signed-off-by: Isabella Basso --- lib/igt_kmod.c | 169 +++++++++++++++++++++++++++++++++++++++++++++++++ lib/igt_kmod.h | 13 ++++ 2 files changed, 182 insertions(+) diff --git a/lib/igt_kmod.c b/lib/igt_kmod.c index cf7a3b22..5d8e8b94 100644 --- a/lib/igt_kmod.c +++ b/lib/igt_kmod.c @@ -345,6 +345,175 @@ igt_kmod_list_loaded(void) kmod_module_unref_list(list); } +static void kmsg_parse_tap(int fd) +{ + char record[4096 + 1]; + const char *num_tests_str, *nok_str, *ok_str, *end_str_success, *end_str_fail; + bool has_num = false; + + num_tests_str = ".."; + nok_str = " not ok "; + ok_str = " ok "; + end_str_fail = "not ok "; + end_str_success = "ok "; + + if (fd == -1) { + igt_warn("Unable to retrieve kernel log (from /dev/kmsg)\n"); + return; + } + + record[sizeof(record) - 1] = '\0'; + + for (;;) { + const char *end, *result; + ssize_t r; + + r = read(fd, record, sizeof(record) - 1); + if (r < 0) { + if (errno == EINTR) + continue; + + if (errno == EPIPE) { + igt_warn("kmsg truncated: too many messages. You may want to increase log_buf_len in kmcdline\n"); + continue; + } + + if (errno != EAGAIN) + igt_warn("kmsg truncated: unknown error (%m)\n"); + + break; + } + + /* deal with partial string from read */ + if (record[r - 1] == NULL) { + fseek(fd, 0, end); + continue; + } + + if (!has_num) { + result = strstr(record, num_tests_str); + if (result) { + result += strlen(num_tests_str); + end = strchrnul(result, '\n'); + igt_info("[IGT] running %.*s tests...\n", + (int)(end - result), result); + has_num = true; + } + continue; + } + + /* all results have 'ok' in them */ + result = strstr(record, "ok"); + + if (result) { + end = strchrnul(result, '\n'); + + /* subtest succeded (i.e. ok_str) */ + result = strstr(record, ok_str); + + if (result) { + result += strlen(ok_str); + igt_info("[IGT] SUBTEST %.*s\n", + (int)(end - result), result); + continue; + } + + /* subtest failed (i.e. nok_str) */ + result = strstr(record, nok_str); + + if (result) { + result += strlen(nok_str); + igt_warn("[IGT] SUBTEST FAILED %.*s\n", + (int)(end - result), result); + continue; + } + + /* test ended (i.e. end_str_success) */ + result = strchr(record, ';') + 1; + + if (strncmp(result, end_str_success, strlen(end_str_success)) == 0) { + igt_info("[IGT] TEST SUCCEEDED %.*s\n", + (int)(end - result), result); + + igt_success(); + } + + if (strncmp(result, end_str_fail, strlen(end_str_fail)) == 0) { + igt_warn("[IGT] TEST FAILED %.*s\n", + (int)(end - result), result); + igt_fail(IGT_EXIT_FAILURE); + } + } + } +} + +/** + * igt_kunit: tests a kunit module + * @mod_name: the name of the module + * @options: options to load the module + * @req_mods: array with additional dependencies to run the KUnit test + * @req_mod_len: size of req_mods array + * + * Loads the kunit module, parses its dmesg output, then unloads it + */ +void igt_kunit(const char *mod_name, const char *options, + const char **req_mods, int req_mod_len) +{ + int kmsg_fd, cmi; + struct igt_kselftest tst; + const char *norm_name; + + /* get normalized module name */ + igt_require(igt_kselftest_init(&tst, mod_name) == 0); + + norm_name = kmod_module_get_name(tst.kmod); + + if (!igt_kmod_is_loaded(norm_name)) { + /* The kunit module is required for running any kunit tests */ + if (!igt_kmod_is_loaded("kunit")) + igt_require(igt_kmod_load("kunit", NULL) == 0); + + for (cmi = 0; cmi < req_mod_len; cmi++) { + if (strcmp(req_mods[cmi], "kunit") == 0) + continue; + if (igt_kmod_load(req_mods[cmi], NULL)) + goto unload; + } + } else { + /* Unload module if loaded (maybe previous run bailed out?) */ + igt_kmod_unload(mod_name, 0); + } + + kmsg_fd = open("/dev/kmsg", O_RDONLY | O_NONBLOCK); + + if (kmsg_fd < 0) { + igt_warn("Could not open /dev/kmsg"); + goto unload; + } + + if (lseek(kmsg_fd, 0, SEEK_END)) { + igt_warn("Could not seek the end of /dev/kmsg"); + close(kmsg_fd); + goto unload; + } + + igt_require(igt_kmod_load(mod_name, options) == 0); + + kmsg_parse_tap(kmsg_fd); + + igt_kmod_unload(mod_name, 0); + + close(kmsg_fd); +unload: + igt_kmod_unload("kunit", 0); + + for (cmi--; cmi >= 0; cmi--) { + if (strcmp(req_mods[cmi], "kunit") == 0) + continue; + igt_kmod_unload(req_mods[cmi], 0); + } +} + /** * igt_i915_driver_load: * @opts: options to pass to i915 driver diff --git a/lib/igt_kmod.h b/lib/igt_kmod.h index 0898122b..60e7a750 100644 --- a/lib/igt_kmod.h +++ b/lib/igt_kmod.h @@ -28,6 +28,16 @@ #include "igt_list.h" +#define MAX_MOD_NAME_LEN 40 + +/** + * ARRAY_SIZE: + * @arr: static array + * + * Macro to compute the size of the static array @arr. + */ +#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr[0])) + bool igt_kmod_is_loaded(const char *mod_name); void igt_kmod_list_loaded(void); @@ -36,6 +46,9 @@ bool igt_kmod_has_param(const char *mod_name, const char *param); int igt_kmod_load(const char *mod_name, const char *opts); int igt_kmod_unload(const char *mod_name, unsigned int flags); +void igt_kunit(const char *mod_name, const char *options, + const char **req_mods, int req_mod_len); + int igt_i915_driver_load(const char *opts); int igt_i915_driver_unload(void); int __igt_i915_driver_unload(const char **whom); -- 2.35.1