Problem
There is no CI coverage of the native launch path. Launch regressions surface only manually, on a developer machine, after the fact.
Corrected premise — read before implementing
This issue originally said the test "needs no retail data (engine reaches main loop with no content)". The engine cannot reach its main loop with no content. Verified in INI.cpp:222:
// Expect to open and load at least one file.
if (filesRead == 0)
{
throw INI_CANT_OPEN_FILE;
}
INI_CANT_OPEN_FILE is in an unnamed enum, so it throws a plain int, does not match catch (ErrorCode ec), and falls to catch (...) → RELEASE_CRASH → _exit(1). All of that is in upstream TheSuperHackers/GeneralsGameCode@main, not fork-local — observed behaviour, though not design intent: the routing is accidental (catch (ErrorCode ec) acts only on ERROR_INVALID_D3D and silently swallows anything else, so the plain-int route to catch (...) is what actually produces the crash). Assert what is observed, not that it was intended.
So the test as originally specified cannot be built. It is still worth building, asserting the opposite outcome.
What to assert instead
Launch the engine with no retail data and assert it exits 1 with the initialisation-failure diagnostic. That still validates a great deal, and needs no licensed content:
A test that reaches the main loop needs content and therefore cannot run in CI. That is a separate, local concern.
Flags: check fork status before relying on one
| Flag |
Upstream main |
bgfx trunk |
-headless |
yes |
yes |
-noDraw, -noaudio, -quickstart, -win |
yes |
yes |
-perfAutoExitSeconds |
no |
yes |
Use -headless — it exists in both. Do not build this test on -perfAutoExitSeconds: it is fork-only, so a test depending on it validates our client and breaks against upstream.
-perfAutoExitSeconds is still useful locally: the three real-client tests currently launch the game and hold it for 14 seconds, which is why they fail whenever a developer closes the window. Self-termination would fix that, and is fine there because those tests only ever run against our client.
Acceptance criteria
- A
macos-15 CI job launches the engine with no retail data and asserts exit 1 plus the expected diagnostic.
- No licensed game content in CI.
- Runtime is bounded, and the job fails rather than hangs if the engine neither exits nor produces the diagnostic.
- No dependency on fork-only flags.
Related
Problem
There is no CI coverage of the native launch path. Launch regressions surface only manually, on a developer machine, after the fact.
Corrected premise — read before implementing
This issue originally said the test "needs no retail data (engine reaches main loop with no content)". The engine cannot reach its main loop with no content. Verified in
INI.cpp:222:INI_CANT_OPEN_FILEis in an unnamed enum, so it throws a plain int, does not matchcatch (ErrorCode ec), and falls tocatch (...)→RELEASE_CRASH→_exit(1). All of that is in upstreamTheSuperHackers/GeneralsGameCode@main, not fork-local — observed behaviour, though not design intent: the routing is accidental (catch (ErrorCode ec)acts only onERROR_INVALID_D3Dand silently swallows anything else, so the plain-int route tocatch (...)is what actually produces the crash). Assert what is observed, not that it was intended.So the test as originally specified cannot be built. It is still worth building, asserting the opposite outcome.
What to assert instead
Launch the engine with no retail data and assert it exits 1 with the initialisation-failure diagnostic. That still validates a great deal, and needs no licensed content:
@executable_path/ RPATH — the failure mode Remove DYLD_LIBRARY_PATH and LD_LIBRARY_PATH from native launch #317 was aboutA test that reaches the main loop needs content and therefore cannot run in CI. That is a separate, local concern.
Flags: check fork status before relying on one
main-headless-noDraw,-noaudio,-quickstart,-win-perfAutoExitSecondsUse
-headless— it exists in both. Do not build this test on-perfAutoExitSeconds: it is fork-only, so a test depending on it validates our client and breaks against upstream.-perfAutoExitSecondsis still useful locally: the three real-client tests currently launch the game and hold it for 14 seconds, which is why they fail whenever a developer closes the window. Self-termination would fix that, and is fine there because those tests only ever run against our client.Acceptance criteria
macos-15CI job launches the engine with no retail data and asserts exit 1 plus the expected diagnostic.Related