From patchwork Sun Dec 14 17:54:37 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Simon Glass X-Patchwork-Id: 908 Return-Path: X-Original-To: u-boot-concept@u-boot.org Delivered-To: u-boot-concept@u-boot.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1765734963; bh=UvBU4wMutMuImQVNsKG7ueKPPkwmjmQSemgW4dAcYe4=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=CSNvEPeWCvx/Rn7krG2Pl+LQUa5sWimxqvzeSIAsi+BBV4sEuciGM4lc5/FWyayQ9 h5sTAuzMPIk3LQuMqeeR8Jb441KUMSSW/Y4XIZr/gzPQO/3THvt4lrFf1/XfkoDrFy p0Q/uo855ukF5GbiinJhYedKnMWLwCIxd5eG6pGiq1IcVFenqELM/ReADcibgxVzW1 n8ZDTWBSXmfcxnrz2YwLvtzq8DIx5bkz+hekPWpnlBF3qhEP66ljMKoP0vL0CFSck/ Zcx1C/52c+rWCaLJyirjJHc5bMMvuH0f1UTkREqLITmxm+Ii9Rg+tL0IMiVVQn7G2K tNJZzm7JN66NQ== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 93B0668AEA for ; Sun, 14 Dec 2025 10:56:03 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10024) with ESMTP id 1YVSmnsIW9j4 for ; Sun, 14 Dec 2025 10:56:03 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1765734963; bh=UvBU4wMutMuImQVNsKG7ueKPPkwmjmQSemgW4dAcYe4=; h=From:To:Date:In-Reply-To:References:CC:Subject:List-Id: List-Archive:List-Help:List-Owner:List-Post:List-Subscribe: List-Unsubscribe:From; b=CSNvEPeWCvx/Rn7krG2Pl+LQUa5sWimxqvzeSIAsi+BBV4sEuciGM4lc5/FWyayQ9 h5sTAuzMPIk3LQuMqeeR8Jb441KUMSSW/Y4XIZr/gzPQO/3THvt4lrFf1/XfkoDrFy p0Q/uo855ukF5GbiinJhYedKnMWLwCIxd5eG6pGiq1IcVFenqELM/ReADcibgxVzW1 n8ZDTWBSXmfcxnrz2YwLvtzq8DIx5bkz+hekPWpnlBF3qhEP66ljMKoP0vL0CFSck/ Zcx1C/52c+rWCaLJyirjJHc5bMMvuH0f1UTkREqLITmxm+Ii9Rg+tL0IMiVVQn7G2K tNJZzm7JN66NQ== Received: from mail.u-boot.org (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id 8296B68A96 for ; Sun, 14 Dec 2025 10:56:03 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1765734961; bh=K1MyuAhTnWuNehMmYfh2RTEf+OnXxfw+tLol2FyGxqI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=hzFkj1ECJqkPlzdQen0mYBl72krEuXbBr+p9rfbkH+hJFvaWL05tw4/TB/GxsHjJq qxLFtw3JnKD3a5AGmyolQAASc4mc+OktxaSB66jrwkGBzLLYV/lAxn4NLsorDjQ/Td SLGlxeXxleZALCUiniyDPKcmJc7HQCWZqiASYUlnrsxQ9M3c4+GxQjT2Eh72sSjto/ GWW4SYdJaEHMwqOXESbz2W7He+0O0lPi7NzbO0d+dFNg3hKDFlZthtfIOm1z9NEOV3 QhxxA6Cm6T4tRtK8zzxAa7MWPZqSisGnPa7bt44FYPvQhJNVJP24e98v8whjiGxBcn hYw0lcIEmVwRg== Received: from localhost (localhost [127.0.0.1]) by mail.u-boot.org (Postfix) with ESMTP id DE8BE68A92; Sun, 14 Dec 2025 10:56:01 -0700 (MST) X-Virus-Scanned: Debian amavis at Received: from mail.u-boot.org ([127.0.0.1]) by localhost (mail.u-boot.org [127.0.0.1]) (amavis, port 10026) with ESMTP id iaVpSm2vEPrV; Sun, 14 Dec 2025 10:56:01 -0700 (MST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=u-boot.org; s=default; t=1765734956; bh=4jFrpVZmvyDWcHdfMTEo+3mZvY/FXzvrerR6IKRcBwU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=tspHB2eTvvkM+JZ4v/AOgIUyfTIsXJDVs+y6RH+GkonhP2Gwjo5I3T8q0QDswDuPG UtlB79diLYNBk7XabDAcXApjloXWMwjUWJKUfH0+r5XtV6tz7Tlimt6S9lpAN9U+O6 OlqZYVHdPa8YFM1u7ZkiluxNjUCcKwKDxyHvwC78EjAuD8IAklxdN0QrBAL/zsjnRk 9j8gIN7GQB0CdvVEoxHYHcItAZoHIaod6btYYjCXsCN3kKdxWtIn1PYRslzimkCnwG J2uOyiTdRkR5qKeaY06Qvmsdzg2nfz2laFnpyWX7ND+EPPzIpPmC2CZaXiU6WTG+EB UZug06CRJS/RQ== Received: from u-boot.org (unknown [73.34.74.121]) by mail.u-boot.org (Postfix) with ESMTPSA id 675C768A89; Sun, 14 Dec 2025 10:55:56 -0700 (MST) From: Simon Glass To: U-Boot Concept Date: Sun, 14 Dec 2025 10:54:37 -0700 Message-ID: <20251214175449.3799539-16-sjg@u-boot.org> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251214175449.3799539-1-sjg@u-boot.org> References: <20251214175449.3799539-1-sjg@u-boot.org> MIME-Version: 1.0 Message-ID-Hash: 47QDEIXDIQJQLOWO5TFXOK3GMO24WAS5 X-Message-ID-Hash: 47QDEIXDIQJQLOWO5TFXOK3GMO24WAS5 X-MailFrom: sjg@u-boot.org X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: Heinrich Schuchardt , Simon Glass , Claude X-Mailman-Version: 3.3.10 Precedence: list Subject: [Concept] [PATCH 15/21] test: Add type-checked argument accessor functions List-Id: Discussion and patches related to U-Boot Concept Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Simon Glass Add ut_get_str(), ut_get_int(), and ut_get_bool() functions with corresponding ut_str(), ut_int(), and ut_bool() macros for accessing test arguments with type checking. These functions check that the argument index is within bounds and the type matches what was requested. The first failure for a test is reported via ut_failf() which should make it fairly easy to debug the test. Co-developed-by: Claude Signed-off-by: Simon Glass --- include/test/test.h | 2 ++ include/test/ut.h | 50 ++++++++++++++++++++++++++++++++++ test/test-main.c | 1 + test/ut.c | 66 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 119 insertions(+) diff --git a/include/test/test.h b/include/test/test.h index da38b8ee4f0..15ed8b37890 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -94,6 +94,7 @@ struct ut_arg { * @actual_str: Temporary string used to hold actual string value * @args: Parsed argument values for current test * @arg_count: Number of parsed arguments + * @arg_error: Set if ut_str/int/bool() detects a type mismatch */ struct unit_test_state { struct ut_stats cur; @@ -122,6 +123,7 @@ struct unit_test_state { char actual_str[1024]; struct ut_arg args[UT_MAX_ARGS]; int arg_count; + bool arg_error; }; /* Test flags for each test */ diff --git a/include/test/ut.h b/include/test/ut.h index 90b9bf79929..4a9a401cf48 100644 --- a/include/test/ut.h +++ b/include/test/ut.h @@ -635,4 +635,54 @@ int ut_run_list(struct unit_test_state *uts, const char *category, */ void ut_report(struct ut_stats *stats, int run_count); +/** + * ut_get_str() - Get a string test argument + * + * Fails the test if the argument type is not UT_ARG_STR. + * + * @uts: Test state + * @n: Argument index + * @file: Filename of caller + * @line: Line number of caller + * @func: Function name of caller + * Return: String value, or NULL if type mismatch + */ +const char *ut_get_str(struct unit_test_state *uts, int n, const char *file, + int line, const char *func); + +/** + * ut_get_int() - Get an integer test argument + * + * Fails the test if the argument type is not UT_ARG_INT. + * + * @uts: Test state + * @n: Argument index + * @file: Filename of caller + * @line: Line number of caller + * @func: Function name of caller + * Return: Integer value, or 0 if type mismatch + */ +long ut_get_int(struct unit_test_state *uts, int n, const char *file, + int line, const char *func); + +/** + * ut_get_bool() - Get a boolean test argument + * + * Fails the test if the argument type is not UT_ARG_BOOL. + * + * @uts: Test state + * @n: Argument index + * @file: Filename of caller + * @line: Line number of caller + * @func: Function name of caller + * Return: Boolean value, or false if type mismatch + */ +bool ut_get_bool(struct unit_test_state *uts, int n, const char *file, + int line, const char *func); + +/* Helpers for accessing test arguments with type checking */ +#define ut_str(n) ut_get_str(uts, n, __FILE__, __LINE__, __func__) +#define ut_int(n) ut_get_int(uts, n, __FILE__, __LINE__, __func__) +#define ut_bool(n) ut_get_bool(uts, n, __FILE__, __LINE__, __func__) + #endif diff --git a/test/test-main.c b/test/test-main.c index ac5680d77d0..c9e164da678 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -639,6 +639,7 @@ static int ut_run_test(struct unit_test_state *uts, struct unit_test *test, if (ret) return ret; + uts->arg_error = false; ret = test->func(uts); if (ret == -EAGAIN) skip_test(uts); diff --git a/test/ut.c b/test/ut.c index aed59cae0b9..fe9a177ab53 100644 --- a/test/ut.c +++ b/test/ut.c @@ -295,3 +295,69 @@ void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays) state_set_skip_delays(skip_delays); #endif } + +const char *ut_get_str(struct unit_test_state *uts, int n, const char *file, + int line, const char *func) +{ + if (n < 0 || n >= uts->arg_count) { + if (!uts->arg_error) + ut_failf(uts, file, line, func, "ut_str() arg check", + "arg %d is invalid (arg_count=%d)", n, + uts->arg_count); + uts->arg_error = true; + return NULL; + } + if (uts->args[n].type != UT_ARG_STR) { + if (!uts->arg_error) + ut_failf(uts, file, line, func, "ut_str() type check", + "arg %d is not a string", n); + uts->arg_error = true; + return NULL; + } + + return uts->args[n].vstr; +} + +long ut_get_int(struct unit_test_state *uts, int n, const char *file, + int line, const char *func) +{ + if (n < 0 || n >= uts->arg_count) { + if (!uts->arg_error) + ut_failf(uts, file, line, func, "ut_int() arg check", + "arg %d is invalid (arg_count=%d)", n, + uts->arg_count); + uts->arg_error = true; + return 0; + } + if (uts->args[n].type != UT_ARG_INT) { + if (!uts->arg_error) + ut_failf(uts, file, line, func, "ut_int() type check", + "arg %d is not an int", n); + uts->arg_error = true; + return 0; + } + + return uts->args[n].vint; +} + +bool ut_get_bool(struct unit_test_state *uts, int n, const char *file, + int line, const char *func) +{ + if (n < 0 || n >= uts->arg_count) { + if (!uts->arg_error) + ut_failf(uts, file, line, func, "ut_bool() arg check", + "arg %d is invalid (arg_count=%d)", n, + uts->arg_count); + uts->arg_error = true; + return false; + } + if (uts->args[n].type != UT_ARG_BOOL) { + if (!uts->arg_error) + ut_failf(uts, file, line, func, "ut_bool() type check", + "arg %d is not a bool", n); + uts->arg_error = true; + return false; + } + + return uts->args[n].vbool; +}