coreboot/tests/lib/ux_locales-test.c
Yu-Ping Wu e64507638e tests/lib/ux_locales-test: Avoid double quotes in CMUnitTest.name
From the Jenkins result of CB:90798, it appears that the generated
junit-tests_lib_ux_locales-test(tests).xml is not a valid XML file
possibly due to incorrect quotes handling by cmocka.

Therefore, in the UX_LOCALES_GET_TEXT_TEST macro definition, replace
`#_expect` with `_expect`, so that the `name` field of the CMUnitTest
struct won't contain double quotes.

Change-Id: Idfec437ae627208031854694e66ca79e22132385
Signed-off-by: Yu-Ping Wu <yupingso@chromium.org>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90801
Reviewed-by: Jakub "Kuba" Czapiga <czapiga@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
2026-01-20 20:16:59 +00:00

236 lines
7.8 KiB
C

/* SPDX-License-Identifier: GPL-2.0-only */
#include <cbfs.h>
#include <stdbool.h>
#include <string.h>
#include <tests/test.h>
#include <ux_locales.h>
#include <vb2_api.h>
#define DATA_DEFAULT \
( \
"\x01" /* Version. */ \
"memory_training_desc\x00" /* memory_training_desc, langs = [0, 2, 30]. */ \
"0\x00memory_training_desc_0\x00" \
"2\x00memory_training_desc_2\x00" \
"30\x00memory_training_desc_30\x00" \
"\x01" \
"low_battery_desc\x00" /* low_battery_desc, langs = [8]. */ \
"8\x00low_battery_desc_8\x00" \
"\x01" \
)
const unsigned char data_default[] = DATA_DEFAULT;
/*
* The data must be set in the setup function and might be used in cbfs related functions.
* The size of the data must be recorded because the data contains the null character \x00.
*
* Note that sizeof(DATA_DEFAULT) will count the '\0' at the end, so DATA_DEFAULT_SIZE, i.e.
* the real data size must be minus one.
*/
#define DATA_DEFAULT_SIZE (sizeof(DATA_DEFAULT) - 1)
#define MAX_DATA_SIZE (DATA_DEFAULT_SIZE + 1)
struct {
unsigned char raw[MAX_DATA_SIZE];
size_t size;
} data;
/* Mock functions. */
void cbfs_unmap(void *mapping)
{
/* No-op. */
}
/* We can't mock cbfs_ro_map() directly as it's a static inline function. */
void *_cbfs_alloc(const char *name, cbfs_allocator_t allocator, void *arg,
size_t *size_out, bool force_ro, enum cbfs_type *type)
{
/* Mock a successful CBFS mapping. */
if (mock_type(bool)) {
*size_out = data.size;
return data.raw;
}
*size_out = 0;
return NULL;
}
uint32_t vb2api_get_locale_id(struct vb2_context *ctx)
{
return mock_type(uint32_t);
}
struct vb2_context *vboot_get_context(void)
{
static struct vb2_context vboot2_ctx;
return &vboot2_ctx;
}
/* Test states for test_ux_locales_get_text with valid CBFS data. */
struct ux_locales_test_state {
enum ux_locale_msg msg_id;
uint32_t lang_id;
const char *expect;
};
/* Setup and teardown functions. */
static int setup_default(void **state)
{
void *ret;
/* Setup the mocked cbfs region data. */
data.size = DATA_DEFAULT_SIZE;
ret = memset(data.raw, 0xff, MAX_DATA_SIZE);
if (!ret)
return 1;
ret = memcpy(data.raw, data_default, data.size);
if (!ret)
return 1;
return 0;
}
static int setup_bad_version(void **state)
{
int ret = setup_default(state);
if (ret)
return ret;
/* Modify the version byte. */
data.raw[0] = ~data.raw[0];
return 0;
}
static int teardown_unmap(void **state)
{
/* We need to reset the cached_state in src/lib/ux_locales.c. */
ux_locales_unmap();
return 0;
}
/* Test items. */
static void test_ux_locales_get_text(void **state)
{
struct ux_locales_test_state *s = *state;
const char *ret;
if (s->msg_id < UX_LOCALE_MSG_NUM) {
will_return(_cbfs_alloc, true);
will_return(vb2api_get_locale_id, s->lang_id);
}
ret = ux_locales_get_text(s->msg_id);
if (s->expect) {
assert_non_null(ret);
assert_string_equal(ret, s->expect);
} else {
assert_null(ret);
}
}
static void test_ux_locales_bad_cbfs(void **state)
{
will_return(_cbfs_alloc, false);
will_return_maybe(vb2api_get_locale_id, 0);
assert_string_equal(ux_locales_get_text(UX_LOCALE_MSG_MEMORY_TRAINING),
"Your device is finishing an update. This may take 1-2 minutes.\n"
"Please do not turn off your device.");
}
static void test_ux_locales_bad_version(void **state)
{
will_return(_cbfs_alloc, true);
will_return(vb2api_get_locale_id, 0);
assert_string_equal(ux_locales_get_text(UX_LOCALE_MSG_MEMORY_TRAINING),
"Your device is finishing an update. This may take 1-2 minutes.\n"
"Please do not turn off your device.");
}
static void test_ux_locales_two_calls(void **state)
{
const char *ret;
/* We do not need to ensure that we cached the cbfs region. */
will_return_always(_cbfs_alloc, true);
/* Call #1: read (1, 30). */
will_return(vb2api_get_locale_id, 30);
ret = ux_locales_get_text(UX_LOCALE_MSG_MEMORY_TRAINING);
assert_non_null(ret);
assert_string_equal(ret, "memory_training_desc_30");
/* Call #2: read (1, 0). */
will_return(vb2api_get_locale_id, 0);
ret = ux_locales_get_text(UX_LOCALE_MSG_MEMORY_TRAINING);
assert_non_null(ret);
assert_string_equal(ret, "memory_training_desc_0");
}
static void test_ux_locales_null_terminated(void **state)
{
will_return_always(_cbfs_alloc, true);
will_return_always(vb2api_get_locale_id, 8);
/* Verify the access to the very last text. */
assert_non_null(ux_locales_get_text(UX_LOCALE_MSG_LOW_BATTERY));
/* Modify the last 2 bytes from "\x00\x01" to "XX" and unmap, */
data.raw[data.size - 1] = 'X';
data.raw[data.size - 2] = 'X';
ux_locales_unmap();
/* The last few characters are now changed so that the data is not NULL terminated.
This will prevent us from accessing the last text therefore, make use of fallback
text message */
assert_string_equal(ux_locales_get_text(UX_LOCALE_MSG_LOW_BATTERY),
"Battery low. Shutting down.");
}
/*
* This macro helps test ux_locales_get_text with `_msg_id` and `_lang_id`.
* If `_expect` is NULL, then the function should not find anything.
* Otherwise, the function should find the corresponding expect value.
*/
#define UX_LOCALES_GET_TEXT_TEST(_msg_id, _lang_id, _expect) \
((struct CMUnitTest) { \
.name = "test_ux_locales_get_text(msg_id=" #_msg_id ", lang_id=" #_lang_id \
", expect=" _expect ")", \
.test_func = test_ux_locales_get_text, \
.setup_func = setup_default, \
.teardown_func = teardown_unmap, \
.initial_state = &(struct ux_locales_test_state) { \
.msg_id = _msg_id, \
.lang_id = _lang_id, \
.expect = _expect, \
}, \
})
int main(void)
{
const struct CMUnitTest tests[] = {
/* Get text successfully. */
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_MEMORY_TRAINING, 0, "memory_training_desc_0"),
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_MEMORY_TRAINING, 2, "memory_training_desc_2"),
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_LOW_BATTERY, 8, "low_battery_desc_8"),
/* Check the whole string of lang_id. */
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_MEMORY_TRAINING, 3, "memory_training_desc_0"),
/* Validity check of lang_id > 100. We will fallback to 0. */
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_MEMORY_TRAINING, 100, "memory_training_desc_0"),
/* Ensure we show fallback message if `msg_id >= UX_LOCALE_MSG_NUM` */
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_NUM, 0, "Trying to display an unknown message?"),
/* Do not search for locale id with unmatched name. */
UX_LOCALES_GET_TEXT_TEST(UX_LOCALE_MSG_LOW_BATTERY, 4,
"Battery low. Shutting down."),
/* cbfs not found. */
cmocka_unit_test_setup_teardown(test_ux_locales_bad_cbfs, setup_default,
teardown_unmap),
/* Bad version. */
cmocka_unit_test_setup_teardown(test_ux_locales_bad_version, setup_bad_version,
teardown_unmap),
/* Read multiple times. */
cmocka_unit_test_setup_teardown(test_ux_locales_two_calls, setup_default,
teardown_unmap),
/* Validity check of NULL terminated. */
cmocka_unit_test_setup_teardown(test_ux_locales_null_terminated,
setup_default, teardown_unmap),
};
return cb_run_group_tests(tests, NULL, NULL);
}