test: Add type-checked argument accessor functions
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 <noreply@anthropic.com> Signed-off-by: Simon Glass <simon.glass@canonical.com>
This commit is contained in:
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
66
test/ut.c
66
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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user