mirror of
https://github.com/rh-hideout/pokeemerald-expansion
synced 2025-10-06 03:12:47 +02:00
Fix crashing tests looping (#7299)
This commit is contained in:
@@ -219,6 +219,17 @@
|
||||
* {
|
||||
* KNOWN_FAILING; // #2596.
|
||||
*
|
||||
* KNOWN_CRASHING
|
||||
* Marks a test as crashing due to a bug. If there is an issue number
|
||||
* associated with the bug it should be included in a comment. If the
|
||||
* test passes the developer will be notified to remove KNOWN_CRASHING.
|
||||
* For example:
|
||||
* TEST("Crashes")
|
||||
* {
|
||||
* KNOWN_CRASHING; // #7255
|
||||
* void (*f)(void) = NULL;
|
||||
* f(); // Crashes!
|
||||
*
|
||||
* PARAMETRIZE
|
||||
* Runs a test multiple times. i will be set to which parameter is
|
||||
* running, and results will contain an entry for each parameter, e.g.:
|
||||
|
@@ -54,6 +54,14 @@ struct TestRunnerState
|
||||
u32 timeoutSeconds;
|
||||
};
|
||||
|
||||
struct PersistentTestRunnerState
|
||||
{
|
||||
u32 address:28;
|
||||
u32 state:1;
|
||||
u32 expectCrash:1;
|
||||
u32 unused_30:2;
|
||||
};
|
||||
|
||||
extern const u8 gTestRunnerN;
|
||||
extern const u8 gTestRunnerI;
|
||||
extern const char gTestRunnerArgv[256];
|
||||
@@ -71,11 +79,13 @@ extern const struct TestRunner gFunctionTestRunner;
|
||||
extern struct FunctionTestRunnerState *gFunctionTestRunnerState;
|
||||
|
||||
extern struct TestRunnerState gTestRunnerState;
|
||||
extern struct PersistentTestRunnerState gPersistentTestRunnerState;
|
||||
|
||||
void CB2_TestRunner(void);
|
||||
|
||||
void Test_ExpectedResult(enum TestResult);
|
||||
void Test_ExpectLeaks(bool32);
|
||||
void Test_ExpectCrash(bool32);
|
||||
void Test_ExitWithResult(enum TestResult, u32 stopLine, const char *fmt, ...);
|
||||
u32 SourceLine(u32 sourceLineOffset);
|
||||
u32 SourceLineOffset(u32 sourceLine);
|
||||
@@ -220,6 +230,9 @@ static inline struct Benchmark BenchmarkStop(void)
|
||||
#define KNOWN_LEAKING \
|
||||
Test_ExpectLeaks(TRUE)
|
||||
|
||||
#define KNOWN_CRASHING \
|
||||
Test_ExpectCrash(TRUE)
|
||||
|
||||
#define PARAMETRIZE if (gFunctionTestRunnerState->parameters++ == gFunctionTestRunnerState->runParameter)
|
||||
|
||||
#define PARAMETRIZE_LABEL(f, label) if (gFunctionTestRunnerState->parameters++ == gFunctionTestRunnerState->runParameter && (Test_MgbaPrintf(":N%s: " f " (%d/%d)", gTestRunnerState.test->name, label, gFunctionTestRunnerState->runParameter + 1, gFunctionTestRunnerState->parameters), 1))
|
||||
|
@@ -6,9 +6,10 @@ gInitialMainCB2 = CB2_TestRunner;
|
||||
|
||||
MEMORY
|
||||
{
|
||||
EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||
IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 32K
|
||||
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||
EWRAM (rwx) : ORIGIN = 0x2000000, LENGTH = 256K
|
||||
IWRAM (rwx) : ORIGIN = 0x3000000, LENGTH = 0x7F00
|
||||
IWRAM_PERSISTENT (rwx) : ORIGIN = 0x3007F00, LENGTH = 0x100
|
||||
ROM (rx) : ORIGIN = 0x8000000, LENGTH = 32M
|
||||
}
|
||||
|
||||
SECTIONS {
|
||||
@@ -60,13 +61,11 @@ SECTIONS {
|
||||
/* .persistent starts at 0x3007F00 */
|
||||
/* WARNING: This is the end of the IRQ stack, if there's too
|
||||
* much data it WILL be overwritten. */
|
||||
|
||||
. = 0x03007F00;
|
||||
.iwram.persistent (NOLOAD) :
|
||||
ALIGN(4)
|
||||
{
|
||||
test/*.o(.persistent);
|
||||
} > IWRAM
|
||||
} > IWRAM_PERSISTENT
|
||||
|
||||
/* BEGIN ROM DATA */
|
||||
. = 0x8000000;
|
||||
@@ -135,6 +134,7 @@ SECTIONS {
|
||||
ALIGN(4)
|
||||
{
|
||||
__start_tests = .;
|
||||
test/test_test_runner.o(.tests); /* Sanity checks first. */
|
||||
test/*.o(.tests);
|
||||
__stop_tests = .;
|
||||
test/*.o(.text);
|
||||
|
@@ -22,10 +22,7 @@ enum {
|
||||
CURRENT_TEST_STATE_RUN,
|
||||
};
|
||||
|
||||
__attribute__((section(".persistent"))) static struct {
|
||||
u32 address:28;
|
||||
u32 state:1;
|
||||
} sCurrentTest = {0};
|
||||
__attribute__((section(".persistent"))) struct PersistentTestRunnerState gPersistentTestRunnerState = {0};
|
||||
|
||||
void TestRunner_Battle(const struct Test *);
|
||||
|
||||
@@ -184,15 +181,16 @@ top:
|
||||
gSaveBlock2Ptr->optionsBattleStyle = OPTIONS_BATTLE_STYLE_SET;
|
||||
|
||||
// The current test restarted the ROM (e.g. by jumping to NULL).
|
||||
if (sCurrentTest.address != 0)
|
||||
if (gPersistentTestRunnerState.address != 0)
|
||||
{
|
||||
gTestRunnerState.test = __start_tests;
|
||||
while ((uintptr_t)gTestRunnerState.test != sCurrentTest.address)
|
||||
while ((uintptr_t)gTestRunnerState.test != gPersistentTestRunnerState.address)
|
||||
{
|
||||
AssignCostToRunner();
|
||||
gTestRunnerState.test++;
|
||||
}
|
||||
if (sCurrentTest.state == CURRENT_TEST_STATE_ESTIMATE)
|
||||
|
||||
if (gPersistentTestRunnerState.state == CURRENT_TEST_STATE_ESTIMATE)
|
||||
{
|
||||
u32 runner = MinCostProcess();
|
||||
gTestRunnerState.processCosts[runner] += 1;
|
||||
@@ -211,6 +209,9 @@ top:
|
||||
gTestRunnerState.state = STATE_REPORT_RESULT;
|
||||
gTestRunnerState.result = TEST_RESULT_CRASH;
|
||||
}
|
||||
|
||||
if (gPersistentTestRunnerState.expectCrash)
|
||||
gTestRunnerState.expectedResult = TEST_RESULT_CRASH;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -252,8 +253,8 @@ top:
|
||||
REG_TM2CNT_L = UINT16_MAX - (274 * 60); // Approx. 1 second.
|
||||
REG_TM2CNT_H = TIMER_ENABLE | TIMER_INTR_ENABLE | TIMER_1024CLK;
|
||||
|
||||
sCurrentTest.address = (uintptr_t)gTestRunnerState.test;
|
||||
sCurrentTest.state = CURRENT_TEST_STATE_ESTIMATE;
|
||||
gPersistentTestRunnerState.address = (uintptr_t)gTestRunnerState.test;
|
||||
gPersistentTestRunnerState.state = CURRENT_TEST_STATE_ESTIMATE;
|
||||
|
||||
// If AssignCostToRunner fails, we want to report the failure.
|
||||
gTestRunnerState.state = STATE_REPORT_RESULT;
|
||||
@@ -266,7 +267,8 @@ top:
|
||||
|
||||
case STATE_RUN_TEST:
|
||||
gTestRunnerState.state = STATE_REPORT_RESULT;
|
||||
sCurrentTest.state = CURRENT_TEST_STATE_RUN;
|
||||
gPersistentTestRunnerState.state = CURRENT_TEST_STATE_RUN;
|
||||
gPersistentTestRunnerState.expectCrash = FALSE;
|
||||
SeedRng(0);
|
||||
SeedRng2(0);
|
||||
if (gTestRunnerState.test->runner->setUp)
|
||||
@@ -423,6 +425,13 @@ void Test_ExpectLeaks(bool32 expectLeaks)
|
||||
gTestRunnerState.expectLeaks = expectLeaks;
|
||||
}
|
||||
|
||||
void Test_ExpectCrash(bool32 expectCrash)
|
||||
{
|
||||
gPersistentTestRunnerState.expectCrash = expectCrash;
|
||||
if (expectCrash)
|
||||
Test_ExpectedResult(TEST_RESULT_CRASH);
|
||||
}
|
||||
|
||||
static void FunctionTest_SetUp(void *data)
|
||||
{
|
||||
(void)data;
|
||||
|
9
test/test_test_runner.c
Normal file
9
test/test_test_runner.c
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "global.h"
|
||||
#include "test/test.h"
|
||||
|
||||
TEST("Tests resume after CRASH")
|
||||
{
|
||||
KNOWN_CRASHING;
|
||||
void (*f)(void) = NULL;
|
||||
f();
|
||||
}
|
Reference in New Issue
Block a user