Files
u-boot/test/common/bootstage.c
Simon Glass d26f3fe96a bootstage: Add a way to read the time from a record
Add a function which returns the time given a record ID.

Signed-off-by: Simon Glass <sjg@chromium.org>
2025-10-23 10:00:31 +01:00

202 lines
5.0 KiB
C

// SPDX-License-Identifier: GPL-2.0+
/*
* Tests for bootstage API
*
* Copyright 2025 Canonical Ltd
*/
#include <bootstage.h>
#include <linux/delay.h>
#include <test/common.h>
#include <test/test.h>
#include <test/ut.h>
/* Test bootstage_mark_name() */
static int test_bootstage_mark(struct unit_test_state *uts)
{
const struct bootstage_record *rec;
ulong time;
int count;
/* Get the current count so we know where our record will be */
count = bootstage_get_rec_count();
/* Mark a stage and verify we get a valid timestamp */
time = bootstage_mark_name(BOOTSTAGE_ID_USER + 50, "test_stage_mark");
ut_assert(time > 0);
/* Verify the count increased by 1 */
ut_asserteq(count + 1, bootstage_get_rec_count());
/* Check that the record was added correctly */
rec = bootstage_get_rec(count);
ut_assertnonnull(rec);
ut_asserteq(BOOTSTAGE_ID_USER + 50, rec->id);
ut_asserteq_str("test_stage_mark", rec->name);
ut_asserteq(time, rec->time_us);
ut_asserteq(0, rec->flags);
ut_asserteq(time, bootstage_get_time(BOOTSTAGE_ID_USER + 50));
/* Restore the original count */
bootstage_set_rec_count(count);
return 0;
}
COMMON_TEST(test_bootstage_mark, 0);
/* Test bootstage_error_name() */
static int test_bootstage_error(struct unit_test_state *uts)
{
const struct bootstage_record *rec;
ulong time;
int count;
count = bootstage_get_rec_count();
/* Mark an error stage and verify we get a valid timestamp */
time = bootstage_error_name(BOOTSTAGE_ID_USER + 51, "test_error");
ut_assert(time > 0);
/* Check the error record */
rec = bootstage_get_rec(count);
ut_assertnonnull(rec);
ut_asserteq(BOOTSTAGE_ID_USER + 51, rec->id);
ut_asserteq_str("test_error", rec->name);
ut_asserteq(time, rec->time_us);
ut_asserteq(BOOTSTAGEF_ERROR, rec->flags);
/* Restore the original count */
bootstage_set_rec_count(count);
return 0;
}
COMMON_TEST(test_bootstage_error, 0);
/* Test bootstage_start() and bootstage_accum() */
static int test_bootstage_accum(struct unit_test_state *uts)
{
enum bootstage_id id = BOOTSTAGE_ID_USER + 53;
uint start_time, elapsed1, elapsed2;
const struct bootstage_record *rec;
int index, count;
count = bootstage_get_rec_count();
/* Start an accumulator */
start_time = bootstage_start(id, "test_accum");
ut_assert(start_time > 0);
/* Check the accumulator record was created */
index = count;
rec = bootstage_get_rec(index);
ut_assertnonnull(rec);
ut_asserteq(id, rec->id);
ut_asserteq_str("test_accum", rec->name);
ut_asserteq(start_time, rec->start_us);
/* Accumulate the time */
udelay(1);
elapsed1 = bootstage_accum(id);
ut_assert(elapsed1 >= 0);
/* Check the accumulated time was recorded */
ut_asserteq(elapsed1, rec->time_us);
/* Start and accumulate again */
bootstage_start(id, "test_accum");
udelay(1);
elapsed2 = bootstage_accum(id);
ut_assert(elapsed2 >= 0);
/* Check the total time accumulated */
rec = bootstage_get_rec(index);
ut_asserteq(rec->time_us, elapsed1 + elapsed2);
ut_asserteq(rec->time_us, bootstage_get_time(id));
/* Restore the original count */
bootstage_set_rec_count(count);
return 0;
}
COMMON_TEST(test_bootstage_accum, 0);
/* Test bootstage_mark_code() */
static int test_bootstage_mark_code(struct unit_test_state *uts)
{
const struct bootstage_record *rec;
ulong time;
int count;
count = bootstage_get_rec_count();
/* Mark with file, function, and line number */
time = bootstage_mark_code("file.c", __func__, 123);
ut_assert(time > 0);
/* Check the record */
rec = bootstage_get_rec(count);
ut_assertnonnull(rec);
ut_asserteq(time, rec->time_us);
ut_asserteq_str("file.c,123: test_bootstage_mark_code", rec->name);
/* Restore the original count */
bootstage_set_rec_count(count);
return 0;
}
COMMON_TEST(test_bootstage_mark_code, 0);
/* Test bootstage_get_rec_count() */
static int test_bootstage_get_rec_count(struct unit_test_state *uts)
{
const struct bootstage_record *rec;
int orig, count;
/* Get initial count */
orig = bootstage_get_rec_count();
ut_assert(orig > 0);
/* Add a new record */
bootstage_mark_name(BOOTSTAGE_ID_USER + 52, "test_count");
/* Verify count increased */
count = bootstage_get_rec_count();
ut_asserteq(orig + 1, count);
/* Verify the record was added at the correct index */
rec = bootstage_get_rec(orig);
ut_assertnonnull(rec);
ut_asserteq(BOOTSTAGE_ID_USER + 52, rec->id);
ut_asserteq_str("test_count", rec->name);
/* Restore the original count */
bootstage_set_rec_count(orig);
return 0;
}
COMMON_TEST(test_bootstage_get_rec_count, 0);
/* Test bootstage_get_rec() */
static int test_bootstage_get_rec(struct unit_test_state *uts)
{
const struct bootstage_record *rec;
int count;
/* Get total count */
count = bootstage_get_rec_count();
ut_assert(count > 0);
/* Get first record (should be "reset") */
rec = bootstage_get_rec(0);
ut_assertnonnull(rec);
ut_asserteq_str("reset", rec->name);
/* Test out of bounds access */
ut_assertnull(bootstage_get_rec(count));
ut_assertnull(bootstage_get_rec(count + 100));
ut_assertnull(bootstage_get_rec(-1));
return 0;
}
COMMON_TEST(test_bootstage_get_rec, 0);