From: Simon Glass <sjg@chromium.org> We generally don't want the pager to be active when running tests, since U-Boot appears to hang forever. Perhaps we could detect when the tests are being run interactively and use the pager in that case. But for now, just bypass it. Co-developed-by: Claude <noreply@anthropic.com> Signed-off-by: Simon Glass <sjg@chromium.org> --- common/pager.c | 20 +++++++++++++++++++- include/pager.h | 19 +++++++++++++++++++ test/common/pager.c | 36 ++++++++++++++++++++++++++++++++++++ test/test-main.c | 3 +++ 4 files changed, 77 insertions(+), 1 deletion(-) diff --git a/common/pager.c b/common/pager.c index 20aa8558654..a7ad77bea3b 100644 --- a/common/pager.c +++ b/common/pager.c @@ -19,7 +19,7 @@ const char *pager_post(struct pager *pag, bool use_pager, const char *s) struct membuf old; int ret, len; - if (!pag || !use_pager) + if (!pag || !use_pager || pag->state == PAGERST_TEST_BYPASS) return s; len = strlen(s); @@ -76,6 +76,8 @@ const char *pager_next(struct pager *pag, bool use_pager, int key) case PAGERST_CLEAR_PROMPT: pag->state = PAGERST_OK; break; + case PAGERST_TEST_BYPASS: + return NULL; } ret = membuf_getraw(&pag->mb, pag->buf.size - 1, false, &str); @@ -123,6 +125,22 @@ void pager_uninit(struct pager *pag) free(pag); } +bool pager_set_bypass(struct pager *pag, bool bypass) +{ + bool was_bypassed = false; + + if (!pag) + return false; + was_bypassed = pag->state == PAGERST_TEST_BYPASS; + + if (bypass) + pag->state = PAGERST_TEST_BYPASS; + else + pag->state = PAGERST_OK; + + return was_bypassed; +} + int pager_init(struct pager **pagp, int page_len, int buf_size) { struct pager *pag; diff --git a/include/pager.h b/include/pager.h index 7f7df690d7f..9bd99b5c959 100644 --- a/include/pager.h +++ b/include/pager.h @@ -26,12 +26,14 @@ * pager_next() will return a user prompt * @PAGERST_WAIT_USER: Waiting for the user to press a key * @PAGERST_CLEAR_PROMPT: Clearing the prompt ready for more output + * @PAGERST_TEST_BYPASS: Pager is being bypassed since tests are running */ enum pager_state { PAGERST_OK, PAGERST_AT_LIMIT, PAGERST_WAIT_USER, PAGERST_CLEAR_PROMPT, + PAGERST_TEST_BYPASS, }; /** @@ -109,6 +111,18 @@ const char *pager_post(struct pager *pag, bool use_pager, const char *s); */ const char *pager_next(struct pager *pag, bool use_pager, int ch); +/** + * pager_set_bypass() - put the pager into bypass mode + * + * This is used for tests. Bypass mode stops the pager from doing anything to + * interrupt output + * + * @pag: Pager to use, may be NULL in which case this function does nothing + * @bypass: true to put the pager in bypass mode, false to return to normal mode + * Return: old value of the bypass flag + */ +bool pager_set_bypass(struct pager *pag, bool bypass); + /** * pager_uninit() - Uninit the pager * @@ -130,6 +144,11 @@ static inline const char *pager_next(struct pager *pag, bool use_pager, int ch) return NULL; } +static inline bool pager_set_bypass(struct pager *pag, bool bypass) +{ + return true; +} + #endif /** diff --git a/test/common/pager.c b/test/common/pager.c index f72d0f40304..2512652ea01 100644 --- a/test/common/pager.c +++ b/test/common/pager.c @@ -389,3 +389,39 @@ static int pager_test_use_pager_param(struct unit_test_state *uts) return 0; } COMMON_TEST(pager_test_use_pager_param, 0); + +/* Test pager bypass mode */ +static int pager_test_bypass_mode(struct unit_test_state *uts) +{ + struct pager *pag; + const char *text = "This text should be returned directly"; + const char *result; + + /* Init with small page length to ensure paging would normally occur */ + ut_assertok(pager_init(&pag, 2, 1024)); + + /* Enable bypass mode */ + pager_set_bypass(pag, true); + + /* Post text - should get original string back directly */ + result = pager_post(pag, true, text); + ut_asserteq_ptr(text, result); /* Should be same pointer */ + + /* pager_next should return NULL in bypass mode */ + result = pager_next(pag, true, 0); + ut_assertnull(result); + + /* Disable bypass mode */ + pager_set_bypass(pag, false); + + /* Now pager should work normally */ + result = pager_post(pag, true, text); + ut_assertnonnull(result); + /* In normal mode, result should be different from original text */ + ut_assert(result != text); + + pager_uninit(pag); + + return 0; +} +COMMON_TEST(pager_test_bypass_mode, 0); diff --git a/test/test-main.c b/test/test-main.c index 8515a77fe42..4238bb196eb 100644 --- a/test/test-main.c +++ b/test/test-main.c @@ -14,6 +14,7 @@ #include <net.h> #include <of_live.h> #include <os.h> +#include <pager.h> #include <spl.h> #include <usb.h> #include <dm/ofnode.h> @@ -747,8 +748,10 @@ int ut_run_list(struct unit_test_state *uts, const char *category, memcpy(uts->fdt_copy, gd->fdt_blob, uts->fdt_size); } uts->force_run = force_run; + pager_set_bypass(gd_pager(), true); ret = ut_run_tests(uts, prefix, tests, count, select_name, test_insert); + pager_set_bypass(gd_pager(), false); /* Best efforts only...ignore errors */ if (has_dm_tests) -- 2.43.0