From ef1c60de67a1af3d945efe421c925fb0ea62e026 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Sun, 15 Oct 2023 18:53:11 +0100 Subject: [PATCH 1/3] Buffer 'GBA: '-prefixed messages TODO: Detect illegal opcodes in the test runner because mgba-rom-test evaluates them very slowly, making the TIMEOUT mechanism effectively realtime. --- tools/mgba-rom-test-hydra/main.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/mgba-rom-test-hydra/main.c b/tools/mgba-rom-test-hydra/main.c index 123d8a255..c2189ac0d 100644 --- a/tools/mgba-rom-test-hydra/main.c +++ b/tools/mgba-rom-test-hydra/main.c @@ -2,9 +2,9 @@ * parses the output to display human-readable progress. * * Output lines starting with "GBA Debug: :" are parsed as commands to - * Hydra, other output lines starting with "GBA Debug: " are parsed as - * output from the current test, and any other lines are parsed as - * output from the mgba-rom-test process itself. + * Hydra, other output lines starting with "GBA Debug: " or with "GBA: " + * are parsed as output from the current test, and any other lines are + * parsed as output from the mgba-rom-test process itself. * * COMMANDS * N: Sets the test name to the remainder of the line. @@ -75,10 +75,17 @@ static void handle_read(int i, struct Runner *runner) { eol++; size_t n = eol - sol; - if (runner->input_buffer_size >= strlen("GBA Debug: ") - && !strncmp(sol, "GBA Debug: ", strlen("GBA Debug: "))) + char *soc; + if (runner->input_buffer_size >= strlen("GBA: ") + && !strncmp(sol, "GBA: ", strlen("GBA: "))) { - char *soc = sol + strlen("GBA Debug: "); + soc = sol + strlen("GBA: "); + goto buffer_output; + } + else if (runner->input_buffer_size >= strlen("GBA Debug: ") + && !strncmp(sol, "GBA Debug: ", strlen("GBA Debug: "))) + { + soc = sol + strlen("GBA Debug: "); if (soc[0] == ':') { switch (soc[1]) From 6e7e7fdafa21654bca58d9b68d739201c0b66746 Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Mon, 23 Oct 2023 07:03:45 +0100 Subject: [PATCH 2/3] make check MODERN=1 in a separate build directory --- Makefile | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Makefile b/Makefile index 80ee5303d..532638302 100644 --- a/Makefile +++ b/Makefile @@ -85,7 +85,11 @@ ELF = $(ROM:.gba=.elf) MAP = $(ROM:.gba=.map) SYM = $(ROM:.gba=.sym) +ifeq ($(MODERN),0) TEST_OBJ_DIR_NAME := build/test +else +TEST_OBJ_DIR_NAME := build/modern-test +endif TESTELF = $(ROM:.gba=-test.elf) HEADLESSELF = $(ROM:.gba=-test-headless.elf) From b0b6e1604264722f63807c3649d996164565884f Mon Sep 17 00:00:00 2001 From: Martin Griffin Date: Mon, 23 Oct 2023 06:57:57 +0100 Subject: [PATCH 3/3] Separate ASSIGN_TEST from NEXT_TEST Silences a warning about an invalid pointer when building with modern. --- include/test/test.h | 1 + test/test_runner.c | 28 +++++++++++++++++++++------- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/include/test/test.h b/include/test/test.h index 5b3ab8af0..e9c920bd0 100644 --- a/include/test/test.h +++ b/include/test/test.h @@ -47,6 +47,7 @@ struct TestRunnerState u8 expectedResult; bool8 expectLeaks:1; bool8 inBenchmark:1; + bool8 tearDown:1; u32 timeoutSeconds; }; diff --git a/test/test_runner.c b/test/test_runner.c index 0ae4f0a18..ddfe23b3e 100644 --- a/test/test_runner.c +++ b/test/test_runner.c @@ -56,9 +56,10 @@ static bool32 PrefixMatch(const char *pattern, const char *string) enum { STATE_INIT, - STATE_NEXT_TEST, + STATE_ASSIGN_TEST, STATE_RUN_TEST, STATE_REPORT_RESULT, + STATE_NEXT_TEST, STATE_EXIT, }; @@ -152,17 +153,15 @@ void CB2_TestRunner(void) } else { - gTestRunnerState.state = STATE_NEXT_TEST; - gTestRunnerState.test = __start_tests - 1; + gTestRunnerState.state = STATE_ASSIGN_TEST; + gTestRunnerState.test = __start_tests; } gTestRunnerState.exitCode = 0; gTestRunnerState.skipFilename = NULL; break; - case STATE_NEXT_TEST: - gTestRunnerState.test++; - + case STATE_ASSIGN_TEST: if (gTestRunnerState.test == __stop_tests) { gTestRunnerState.state = STATE_EXIT; @@ -172,6 +171,7 @@ void CB2_TestRunner(void) if (gTestRunnerState.test->runner != &gAssumptionsRunner && !PrefixMatch(gTestRunnerArgv, gTestRunnerState.test->name)) { + gTestRunnerState.state = STATE_NEXT_TEST; return; } @@ -191,6 +191,8 @@ void CB2_TestRunner(void) sCurrentTest.address = (uintptr_t)gTestRunnerState.test; sCurrentTest.state = CURRENT_TEST_STATE_ESTIMATE; + // If AssignCostToRunner fails, we want to report the failure. + gTestRunnerState.state = STATE_REPORT_RESULT; if (AssignCostToRunner() == gTestRunnerI) gTestRunnerState.state = STATE_RUN_TEST; else @@ -204,7 +206,10 @@ void CB2_TestRunner(void) SeedRng(0); SeedRng2(0); if (gTestRunnerState.test->runner->setUp) + { gTestRunnerState.test->runner->setUp(gTestRunnerState.test->data); + gTestRunnerState.tearDown = TRUE; + } // NOTE: Assumes that the compiler interns __FILE__. if (gTestRunnerState.skipFilename == gTestRunnerState.test->filename) // Assumption fails for tests in this file. { @@ -216,13 +221,17 @@ void CB2_TestRunner(void) gTestRunnerState.test->runner->run(gTestRunnerState.test->data); } break; + case STATE_REPORT_RESULT: REG_TM2CNT_H = 0; gTestRunnerState.state = STATE_NEXT_TEST; - if (gTestRunnerState.test->runner->tearDown) + if (gTestRunnerState.tearDown && gTestRunnerState.test->runner->tearDown) + { gTestRunnerState.test->runner->tearDown(gTestRunnerState.test->data); + gTestRunnerState.tearDown = FALSE; + } if (gTestRunnerState.result == TEST_RESULT_PASS && !gTestRunnerState.expectLeaks) @@ -342,6 +351,11 @@ void CB2_TestRunner(void) break; + case STATE_NEXT_TEST: + gTestRunnerState.state = STATE_ASSIGN_TEST; + gTestRunnerState.test++; + break; + case STATE_EXIT: MgbaExit_(gTestRunnerState.exitCode); break;