{"id":2222460,"url":"http://patchwork.ozlabs.org/api/1.1/patches/2222460/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/patch/20260412013451.2929001-7-sjg@chromium.org/","project":{"id":18,"url":"http://patchwork.ozlabs.org/api/1.1/projects/18/?format=json","name":"U-Boot","link_name":"uboot","list_id":"u-boot.lists.denx.de","list_email":"u-boot@lists.denx.de","web_url":null,"scm_url":null,"webscm_url":null},"msgid":"<20260412013451.2929001-7-sjg@chromium.org>","date":"2026-04-12T01:34:34","name":"[06/12] test: Add support for passing arguments to C tests","commit_ref":null,"pull_url":null,"state":"superseded","archived":false,"hash":"8c188c4f3c35a3d71543e38d469dafe4e0c14842","submitter":{"id":6170,"url":"http://patchwork.ozlabs.org/api/1.1/people/6170/?format=json","name":"Simon Glass","email":"sjg@chromium.org"},"delegate":{"id":3184,"url":"http://patchwork.ozlabs.org/api/1.1/users/3184/?format=json","username":"sjg","first_name":"Simon","last_name":"Glass","email":"sjg@chromium.org"},"mbox":"http://patchwork.ozlabs.org/project/uboot/patch/20260412013451.2929001-7-sjg@chromium.org/mbox/","series":[{"id":499582,"url":"http://patchwork.ozlabs.org/api/1.1/series/499582/?format=json","web_url":"http://patchwork.ozlabs.org/project/uboot/list/?series=499582","date":"2026-04-12T01:34:28","name":"test: Add support for passing arguments to C unit tests","version":1,"mbox":"http://patchwork.ozlabs.org/series/499582/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/2222460/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/2222460/checks/","tags":{},"headers":{"Return-Path":"<u-boot-bounces@lists.denx.de>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=chromium.org header.i=@chromium.org header.a=rsa-sha256\n header.s=google header.b=I9Hybibj;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=85.214.62.61; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)","phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=chromium.org","phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de","phobos.denx.de;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=chromium.org header.i=@chromium.org\n header.b=\"I9Hybibj\";\n\tdkim-atps=neutral","phobos.denx.de;\n dmarc=pass (p=none dis=none) header.from=chromium.org","phobos.denx.de;\n spf=pass smtp.mailfrom=sjg@chromium.org"],"Received":["from phobos.denx.de (phobos.denx.de [85.214.62.61])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4ftY5t5GCtz1xtJ\n\tfor <incoming@patchwork.ozlabs.org>; Sun, 12 Apr 2026 11:36:02 +1000 (AEST)","from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 77EDA84222;\n\tSun, 12 Apr 2026 03:35:32 +0200 (CEST)","by phobos.denx.de (Postfix, from userid 109)\n id D7485841FF; Sun, 12 Apr 2026 03:35:30 +0200 (CEST)","from mail-ot1-x330.google.com (mail-ot1-x330.google.com\n [IPv6:2607:f8b0:4864:20::330])\n (using TLSv1.3 with cipher TLS_AES_128_GCM_SHA256 (128/128 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 6C023841DF\n for <u-boot@lists.denx.de>; Sun, 12 Apr 2026 03:35:28 +0200 (CEST)","by mail-ot1-x330.google.com with SMTP id\n 46e09a7af769-7dbb89ab229so2957886a34.1\n for <u-boot@lists.denx.de>; Sat, 11 Apr 2026 18:35:28 -0700 (PDT)","from chromium.org ([73.34.74.121]) by smtp.gmail.com with ESMTPSA id\n 46e09a7af769-7dc2d1aca3asm4242826a34.6.2026.04.11.18.35.19\n (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256);\n Sat, 11 Apr 2026 18:35:20 -0700 (PDT)"],"X-Spam-Checker-Version":"SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de","X-Spam-Level":"","X-Spam-Status":"No, score=-2.6 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH,\n DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,\n RCVD_IN_DNSWL_BLOCKED,SPF_HELO_NONE,SPF_PASS autolearn=ham\n autolearn_force=no version=3.4.2","DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=chromium.org; s=google; t=1775957724; x=1776562524; darn=lists.denx.de;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:from:to:cc:subject:date\n :message-id:reply-to;\n bh=BNVGj+n3xDtvOKlfaLTb/Z3z55ErZhoMc1TFcWSnQYM=;\n b=I9HybibjdF/9bHx/QN+wxKfRupf+8UtWW0jrzo2zTkTXev6I1ZpKLphjHQWL6+cofv\n FArt6XjODl8W+rogog4rVQkDZvkSN5PE5Kq4HELD0+KPYSCbZphWwEFPrKB8at6P9ERF\n cjA9KBetdNsOrHSQr89nVJlc/V7hW7wstrekY=","X-Google-DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=1e100.net; s=20251104; t=1775957724; x=1776562524;\n h=content-transfer-encoding:mime-version:references:in-reply-to\n :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from\n :to:cc:subject:date:message-id:reply-to;\n bh=BNVGj+n3xDtvOKlfaLTb/Z3z55ErZhoMc1TFcWSnQYM=;\n b=CNb4COsXeyikVSikXg0WXdrjZxdn4jk3VkYTqpLbHbAH/ryADdcvGS+Mi/xzeqSk9v\n hzheNF2bXrUjRNXGbH9H1NYk4A/U+BIcNblKHXogmQl63uj6q+Gm56aUajd/8869ntuC\n kdSXMkFBaQPYbaU1hAUXzpTTIUkdJl75QWlWY2I7+iI9T+TjS6hiIYHI2svw8lFDKHMU\n zy/y61Bh5tVP/1piKbB2VJnBgiuDxv6KJ0enXL8qOggpGA6eaM3H/uPPAc71x4LYIsJx\n cKim5M+ge8CAmpZMBkCRKCnkM6wzeM4OKeZk15jxQNgm35ENeYgMoebMAEeyrB2dEpCg\n PKBQ==","X-Gm-Message-State":"AOJu0YwX0ebQmsFEkH5BC2qlItu6Fvfhz3y8O7qSmCVI3bYxz1QC4tN5\n 7MVX4mFdbSmmQKvCcUfTgEdwgndAnPJsawRQhQ/RYErVQdub7JfKd/pW8mDQe93BqKFLdft5Jxn\n 049oikA==","X-Gm-Gg":"AeBDiesYodUR3wdWCYe0V++X618hs0gD4hI9SZMXoJleaO0c/1/rug2QHo0VnSqtBPz\n jueNk7s3u9fcV8aDr+QV0YeE2AFUwU7i9LYP4UIUd7hffavE8u18Fq5JLJKk9hswbHNEE3u/ZB9\n w8Dj1lod6kPb7YQBQ/W0e/fPIAPi+eDHTqE97KGlpVyB7m6gNa7Eq8DGRnwppwJlhyfgu5ygCbw\n Nk5WHBWweow+a5rCpM5wDCnyRu2qOBYs0n0pX6oqqvGOoySHwR6PUMjM4qDmmz+gxVCnfxWmO2t\n UO+FDIfh354I1gvgN3pWfs1XT9oLkaQE0aizwd6hFAmuWgFa2uDm3HC0N/7HT5YEEbpfixqminM\n /LZeogIpLuDffBa37eRpihbd8IkapGkwq2L1k19L8styfqRpa9Wi/OkeFrijBKWB2m7Wnhp0V34\n nEe33vCqCTDvvX2qLKkLj2rhJc/HPL","X-Received":"by 2002:a05:6830:668a:b0:7d7:455d:1003 with SMTP id\n 46e09a7af769-7dc27dca0b9mr5941500a34.4.1775957723853;\n Sat, 11 Apr 2026 18:35:23 -0700 (PDT)","From":"Simon Glass <sjg@chromium.org>","To":"u-boot@lists.denx.de","Cc":"Heinrich Schuchardt <xypron.glpk@gmx.de>, Tom Rini <trini@konsulko.com>,\n Simon Glass <simon.glass@canonical.com>, Simon Glass <sjg@chromium.org>,\n Andrew Goodbody <andrew.goodbody@linaro.org>","Subject":"[PATCH 06/12] test: Add support for passing arguments to C tests","Date":"Sat, 11 Apr 2026 19:34:34 -0600","Message-ID":"<20260412013451.2929001-7-sjg@chromium.org>","X-Mailer":"git-send-email 2.43.0","In-Reply-To":"<20260412013451.2929001-1-sjg@chromium.org>","References":"<20260412013451.2929001-1-sjg@chromium.org>","MIME-Version":"1.0","Content-Transfer-Encoding":"8bit","X-BeenThere":"u-boot@lists.denx.de","X-Mailman-Version":"2.1.39","Precedence":"list","List-Id":"U-Boot discussion <u-boot.lists.denx.de>","List-Unsubscribe":"<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>","List-Archive":"<https://lists.denx.de/pipermail/u-boot/>","List-Post":"<mailto:u-boot@lists.denx.de>","List-Help":"<mailto:u-boot-request@lists.denx.de?subject=help>","List-Subscribe":"<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>","Errors-To":"u-boot-bounces@lists.denx.de","Sender":"\"U-Boot\" <u-boot-bounces@lists.denx.de>","X-Virus-Scanned":"clamav-milter 0.103.8 at phobos.denx.de","X-Virus-Status":"Clean"},"content":"From: Simon Glass <simon.glass@canonical.com>\n\nAdd support for passing key=value arguments to unit tests. The test\nframework parses arguments based on definitions provided by each test\nand makes them available via uts->args[]\n\nFor now the 'ut' command does not support this new feature.\n\nSigned-off-by: Simon Glass <simon.glass@canonical.com>\nSigned-off-by: Simon Glass <sjg@chromium.org>\n---\n\n arch/sandbox/cpu/spl.c |   3 +-\n include/test/test.h    |   5 ++\n include/test/ut.h      |   4 +-\n test/cmd_ut.c          |   3 +-\n test/test-main.c       | 169 ++++++++++++++++++++++++++++++++++++++++-\n 5 files changed, 177 insertions(+), 7 deletions(-)","diff":"diff --git a/arch/sandbox/cpu/spl.c b/arch/sandbox/cpu/spl.c\nindex 7ee4975523e..162b678314e 100644\n--- a/arch/sandbox/cpu/spl.c\n+++ b/arch/sandbox/cpu/spl.c\n@@ -152,7 +152,8 @@ void spl_board_init(void)\n \n \t\tut_init_state(&uts);\n \t\tret = ut_run_list(&uts, \"spl\", NULL, tests, count,\n-\t\t\t\t  state->select_unittests, 1, false, NULL);\n+\t\t\t\t  state->select_unittests, 1, false, NULL,\n+\t\t\t\t  0, NULL);\n \t\tut_report(&uts.cur, 1);\n \t\tut_uninit_state(&uts);\n \t\t/* continue execution into U-Boot */\ndiff --git a/include/test/test.h b/include/test/test.h\nindex cdd19392844..bd47025ce50 100644\n--- a/include/test/test.h\n+++ b/include/test/test.h\n@@ -9,6 +9,7 @@\n #include <malloc.h>\n #include <linux/bitops.h>\n \n+#define UT_MAX_ARGS\t8\n #define UT_PRIV_SIZE\t256\n \n /**\n@@ -92,6 +93,8 @@ struct ut_arg {\n  * @expect_str: Temporary string used to hold expected string value\n  * @actual_str: Temporary string used to hold actual string value\n  * @priv: Private data for tests to use as needed\n+ * @args: Parsed argument values for current test\n+ * @arg_count: Number of parsed arguments\n  */\n struct unit_test_state {\n \tstruct ut_stats cur;\n@@ -118,6 +121,8 @@ struct unit_test_state {\n \tchar expect_str[512];\n \tchar actual_str[512];\n \tchar priv[UT_PRIV_SIZE];\n+\tstruct ut_arg args[UT_MAX_ARGS];\n+\tint arg_count;\n };\n \n /* Test flags for each test */\ndiff --git a/include/test/ut.h b/include/test/ut.h\nindex 8f0e69a7734..1c4ee390fd8 100644\n--- a/include/test/ut.h\n+++ b/include/test/ut.h\n@@ -675,12 +675,14 @@ void ut_uninit_state(struct unit_test_state *uts);\n  * name is the name of the test to run. This is used to find which test causes\n  * another test to fail. If the one test fails, testing stops immediately.\n  * Pass NULL to disable this\n+ * @argc: Number of test arguments (key=value pairs), 0 if none\n+ * @argv: Test argument array, NULL if none\n  * Return: 0 if all tests passed, -1 if any failed\n  */\n int ut_run_list(struct unit_test_state *uts, const char *category,\n \t\tconst char *prefix, struct unit_test *tests, int count,\n \t\tconst char *select_name, int runs_per_test, bool force_run,\n-\t\tconst char *test_insert);\n+\t\tconst char *test_insert, int argc, char *const argv[]);\n \n /**\n  * ut_report() - Report stats on a test run\ndiff --git a/test/cmd_ut.c b/test/cmd_ut.c\nindex 44e5fdfdaa6..7304c32bec5 100644\n--- a/test/cmd_ut.c\n+++ b/test/cmd_ut.c\n@@ -130,7 +130,8 @@ static int run_suite(struct unit_test_state *uts, struct suite *ste,\n \tsnprintf(prefix, sizeof(prefix), \"%s_test_\", ste->name);\n \n \tret = ut_run_list(uts, ste->name, prefix, ste->start, n_ents,\n-\t\t\t  select_name, runs_per_test, force_run, test_insert);\n+\t\t\t  select_name, runs_per_test, force_run, test_insert,\n+\t\t\t  0, NULL);\n \n \treturn ret;\n }\ndiff --git a/test/test-main.c b/test/test-main.c\nindex 3254325e8b1..9d8ab794db8 100644\n--- a/test/test-main.c\n+++ b/test/test-main.c\n@@ -87,6 +87,154 @@ void ut_uninit_state(struct unit_test_state *uts)\n \t}\n }\n \n+/**\n+ * ut_count_args() - Count the number of arguments in a NULL-terminated array\n+ *\n+ * @defs: Argument definitions array (NULL-terminated)\n+ * Return: Number of arguments\n+ */\n+static int ut_count_args(const struct ut_arg_def *defs)\n+{\n+\tint count = 0;\n+\n+\tif (defs) {\n+\t\twhile (defs[count].name)\n+\t\t\tcount++;\n+\t}\n+\n+\treturn count;\n+}\n+\n+/**\n+ * ut_set_arg() - Find and set an argument value\n+ *\n+ * Search through argument definitions to find a matching key and set its value.\n+ *\n+ * @defs: Argument definitions array\n+ * @args: Argument values array to update\n+ * @count: Number of argument definitions\n+ * @key: Key name to search for\n+ * @key_len: Length of key name\n+ * @val: Value string to parse\n+ * Return: true if argument was found and set, false otherwise\n+ */\n+static bool ut_set_arg(const struct ut_arg_def *defs, struct ut_arg *args,\n+\t\t       int count, const char *key, int key_len, const char *val)\n+{\n+\tint j;\n+\n+\tfor (j = 0; j < count; j++) {\n+\t\tif (strlen(defs[j].name) == key_len &&\n+\t\t    !strncmp(defs[j].name, key, key_len)) {\n+\t\t\tswitch (defs[j].type) {\n+\t\t\tcase UT_ARG_INT:\n+\t\t\t\targs[j].vint = simple_strtol(val, NULL, 0);\n+\t\t\t\tbreak;\n+\t\t\tcase UT_ARG_BOOL:\n+\t\t\t\targs[j].vbool = *val == '1';\n+\t\t\t\tbreak;\n+\t\t\tcase UT_ARG_STR:\n+\t\t\t\targs[j].vstr = val;\n+\t\t\t\tbreak;\n+\t\t\t}\n+\t\t\targs[j].provided = true;\n+\t\t\treturn true;\n+\t\t}\n+\t}\n+\n+\treturn false;\n+}\n+\n+/**\n+ * ut_parse_args() - Parse command-line arguments for a test\n+ *\n+ * Parse key=value arguments from the command line and set up uts->args based on\n+ * the test's argument definitions.\n+ *\n+ * @uts: Unit test state (args and arg_count will be set)\n+ * @test: Test being run (provides arg_defs)\n+ * @argc: Number of arguments\n+ * @argv: Argument array (key=value strings)\n+ * Return: 0 on success, -EINVAL on parse error\n+ */\n+static int ut_parse_args(struct unit_test_state *uts, struct unit_test *test,\n+\t\t\t int argc, char *const argv[])\n+{\n+\tconst struct ut_arg_def *defs = test->arg_defs;\n+\tstruct ut_arg *args = uts->args;\n+\tint count = ut_count_args(defs);\n+\tint i;\n+\n+\tuts->arg_count = 0;\n+\n+\t/* No arguments expected */\n+\tif (!count) {\n+\t\tif (argc > 0) {\n+\t\t\tprintf(\"Test '%s' does not accept arguments\\n\",\n+\t\t\t       test->name);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\treturn 0;\n+\t}\n+\n+\tif (count > UT_MAX_ARGS) {\n+\t\tprintf(\"Test '%s' has too many arguments (%d > %d)\\n\",\n+\t\t       test->name, count, UT_MAX_ARGS);\n+\t\treturn -EINVAL;\n+\t}\n+\n+\t/* Initialise from defaults */\n+\tfor (i = 0; i < count; i++) {\n+\t\targs[i].name = defs[i].name;\n+\t\targs[i].type = defs[i].type;\n+\t\targs[i].provided = false;\n+\t\tswitch (defs[i].type) {\n+\t\tcase UT_ARG_INT:\n+\t\t\targs[i].vint = defs[i].def.vint;\n+\t\t\tbreak;\n+\t\tcase UT_ARG_BOOL:\n+\t\t\targs[i].vbool = defs[i].def.vbool;\n+\t\t\tbreak;\n+\t\tcase UT_ARG_STR:\n+\t\t\targs[i].vstr = defs[i].def.vstr;\n+\t\t\tbreak;\n+\t\t}\n+\t}\n+\n+\t/* Parse command-line key=value pairs */\n+\tfor (i = 0; i < argc; i++) {\n+\t\tconst char *arg = argv[i];\n+\t\tconst char *eq = strchr(arg, '=');\n+\t\tint key_len;\n+\n+\t\tif (!eq) {\n+\t\t\tprintf(\"Invalid argument '%s' (expected key=value)\\n\",\n+\t\t\t       arg);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t\tkey_len = eq - arg;\n+\n+\t\tif (!ut_set_arg(defs, args, count, arg, key_len, eq + 1)) {\n+\t\t\tprintf(\"Unknown argument '%.*s' for test '%s'\\n\",\n+\t\t\t       key_len, arg, test->name);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\t/* Check required arguments are provided */\n+\tfor (i = 0; i < count; i++) {\n+\t\tif (!args[i].provided && !(defs[i].flags & UT_ARGF_OPTIONAL)) {\n+\t\t\tprintf(\"Missing required argument '%s' for test '%s'\\n\",\n+\t\t\t       defs[i].name, test->name);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\t}\n+\n+\tuts->arg_count = count;\n+\n+\treturn 0;\n+}\n+\n /**\n  * dm_test_pre_run() - Get ready to run a driver model test\n  *\n@@ -588,12 +736,15 @@ static int ut_run_test_live_flat(struct unit_test_state *uts,\n  * @test_insert: String describing a test to run after n other tests run, in the\n  * format n:name where n is the number of tests to run before this one and\n  * name is the name of the test to run\n+ * @argc: Number of test arguments (key=value pairs)\n+ * @argv: Test argument array\n  * Return: 0 if all tests passed, -ENOENT if test @select_name was not found,\n  *\t-EBADF if any failed\n  */\n static int ut_run_tests(struct unit_test_state *uts, const char *prefix,\n \t\t\tstruct unit_test *tests, int count,\n-\t\t\tconst char *select_name, const char *test_insert)\n+\t\t\tconst char *select_name, const char *test_insert,\n+\t\t\tint argc, char *const argv[])\n {\n \tint prefix_len = prefix ? strlen(prefix) : 0;\n \tstruct unit_test *test, *one;\n@@ -649,6 +800,11 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,\n \n \t\tuts->cur.test_count++;\n \t\tif (one && upto == pos) {\n+\t\t\tret = ut_parse_args(uts, one, argc, argv);\n+\t\t\tif (ret) {\n+\t\t\t\tuts->cur.fail_count++;\n+\t\t\t\treturn ret;\n+\t\t\t}\n \t\t\tret = ut_run_test_live_flat(uts, one, NULL);\n \t\t\tif (uts->cur.fail_count != old_fail_count) {\n \t\t\t\tprintf(\"Test '%s' failed %d times (position %d)\\n\",\n@@ -662,6 +818,12 @@ static int ut_run_tests(struct unit_test_state *uts, const char *prefix,\n \t\tif (prefix_len && !strncmp(test_name, prefix, prefix_len))\n \t\t\ttest_name = test_name + prefix_len;\n \n+\t\tret = ut_parse_args(uts, test, argc, argv);\n+\t\tif (ret) {\n+\t\t\tfound++;\n+\t\t\tuts->cur.fail_count++;\n+\t\t\tcontinue;\n+\t\t}\n \t\tfor (i = 0; i < uts->runs_per_test; i++)\n \t\t\tret = ut_run_test_live_flat(uts, test, test_name);\n \t\tif (uts->cur.fail_count != old_fail_count) {\n@@ -701,9 +863,8 @@ void ut_report(struct ut_stats *stats, int run_count)\n int ut_run_list(struct unit_test_state *uts, const char *category,\n \t\tconst char *prefix, struct unit_test *tests, int count,\n \t\tconst char *select_name, int runs_per_test, bool force_run,\n-\t\tconst char *test_insert)\n+\t\tconst char *test_insert, int argc, char *const argv[])\n {\n-\t;\n \tbool has_dm_tests = false;\n \tulong start_offset = 0;\n \tulong test_offset = 0;\n@@ -745,7 +906,7 @@ int ut_run_list(struct unit_test_state *uts, const char *category,\n \t}\n \tuts->force_run = force_run;\n \tret = ut_run_tests(uts, prefix, tests, count, select_name,\n-\t\t\t   test_insert);\n+\t\t\t   test_insert, argc, argv);\n \n \t/* Best efforts only...ignore errors */\n \tif (has_dm_tests)\n","prefixes":["06/12"]}