mirror of
https://github.com/MobileGL-Dev/MobileGL
synced 2026-09-08 20:28:32 +09:00
[Test] (Pipe): pin the pre-fill window - every stamp of 0 is stale at serial 0, a read before any fill aborts naming "<none>", and the FATAL=0 child leaves through std::exit so the teardown summary is observed
- PipeCatalogue.PipeInputFieldsStartUnfilled asserted "unfilled" only after setting the serial to 1 by hand, stepping around the serial-0 window; it now asserts every field stale on a value-initialised state first (sticky fields included).
- PipeInputsTest.ReadingBeforeAnyFillAbortsNamingNoVerb: a live context, no fill, gPipeInputs.GetLineWidth() in a forked child; the parent expects SIGABRT, exactly Fatal{UnmigratedPipeInput, "GetLineWidth@<none>"}, no PipeVerifyDiffer and no arming line. In a verify build the child sets Features.PipeVerify first, the lane's shape.
- VerifyFatalOffLogsTheDivergenceAndContinues: the child _exit(0)ed, so VerifyState's destructor never ran and the "verify summary" line was covered only by a lane run; std::exit(0) runs it, and the parent now asserts "2 divergence(s) survived MOBILEGL_PIPE_VERIFY_FATAL=0".
This commit is contained in:
@@ -225,6 +225,12 @@ TEST(PipeCatalogue, CoverageAccountsForEveryInventoryRow) {
|
||||
TEST(PipeCatalogue, PipeInputFieldsStartUnfilled) {
|
||||
EXPECT_EQ(kMGPipeInputFieldCount, 63u);
|
||||
MGPipeFilledState state{};
|
||||
// Before the first fill the serial is 0 as well: 0 == 0 must not read as fresh, on the
|
||||
// sticky branch either (the window D6 names "<Field>@<none>").
|
||||
EXPECT_EQ(state.CurrentVerbSerial, 0u);
|
||||
for (SizeT f = 0; f < kMGPipeInputFieldCount; ++f) {
|
||||
EXPECT_FALSE(MGPipeInputFieldIsFresh(state, static_cast<MGPipeInputField>(f))) << kMGPipeInputFieldNames[f];
|
||||
}
|
||||
state.CurrentVerbSerial = 1;
|
||||
EXPECT_FALSE(MGPipeInputFieldIsFresh(state, MGPipeInputField::GetRenderStateParameters));
|
||||
state.FilledGen[static_cast<SizeT>(MGPipeInputField::GetRenderStateParameters)] = 1;
|
||||
|
||||
@@ -143,6 +143,9 @@ TEST(PipeInputsTest,ReadingAnOmittedFieldAbortsNamingTheVerb) {
|
||||
TEST(PipeInputsTest,ReadingAFilledFieldCompletes) {
|
||||
GTEST_SKIP() << "push not compiled in (MOBILEGL_PIPE_PUSH=OFF)";
|
||||
}
|
||||
TEST(PipeInputsTest,ReadingBeforeAnyFillAbortsNamingNoVerb) {
|
||||
GTEST_SKIP() << "push not compiled in (MOBILEGL_PIPE_PUSH=OFF)";
|
||||
}
|
||||
TEST(PipeInputsTest,CorruptedSnapshotFieldIsNamedWithItsSerial) {
|
||||
GTEST_SKIP() << "push not compiled in (MOBILEGL_PIPE_PUSH=OFF)";
|
||||
}
|
||||
@@ -257,6 +260,36 @@ TEST_F(PipeInputsTest, ReadingAFilledFieldCompletes) {
|
||||
#endif
|
||||
}
|
||||
|
||||
// The window before the first verb (P1 brief D6: "<Field>@<none>"). Nothing has filled this
|
||||
// process's block, so a backend-style read of a value field is Fatal naming no verb: the
|
||||
// serial and every stamp are 0, and 0 == 0 is not fresh. In a verify build the child also
|
||||
// sets the lane's knob first, the shape of a read reached from initialisation: the poison
|
||||
// fires at MGP_INPUT_CHECK, before the read hook (armed only by the first fill) could matter.
|
||||
TEST_F(PipeInputsTest, ReadingBeforeAnyFillAbortsNamingNoVerb) {
|
||||
#if !MOBILEGL_PIPE_POISON
|
||||
GTEST_SKIP() << "poison not compiled in (MOBILEGL_PIPE_POISON=0)";
|
||||
#elif !MGTEST_HAVE_FORK
|
||||
GTEST_SKIP() << "no fork() on this platform";
|
||||
#else
|
||||
ASSERT_FALSE(g_logPath.empty()) << "main() did not set MOBILEGL_LOG_FILE_PATH";
|
||||
if (gPipeInputs.FilledState().CurrentVerbSerial != 0) {
|
||||
GTEST_SKIP() << "another case already filled in this process; gtest_discover_tests runs each case alone";
|
||||
}
|
||||
MG_State::pGLContext->SetLineWidth(7.0f); // a live value the default storage (0) does not hold
|
||||
const ChildResult r = RunInChild([] {
|
||||
#if MOBILEGL_PIPE_VERIFY
|
||||
MG_Config::Features.PipeVerify = true;
|
||||
#endif
|
||||
(void)gPipeInputs.GetLineWidth(); // Fatal{UnmigratedPipeInput, "GetLineWidth@<none>"}
|
||||
::_exit(3); // reached only if the pre-fill window read as fresh
|
||||
});
|
||||
ASSERT_TRUE(DiedOfAbort(r)) << DescribeStatus(r) << "\n" << r.Log;
|
||||
EXPECT_NE(r.Log.find("Fatal{UnmigratedPipeInput, \"GetLineWidth@<none>\"}"), std::string::npos) << r.Log;
|
||||
EXPECT_EQ(r.Log.find("PipeVerifyDiffer"), std::string::npos) << r.Log;
|
||||
EXPECT_EQ(r.Log.find("verify armed"), std::string::npos) << r.Log;
|
||||
#endif
|
||||
}
|
||||
|
||||
// The MOBILEGL_PIPE_POISON_OMIT parser, through the Features field the loader fills: the
|
||||
// child sets the knob after its parent filled without it, and the first fill after that
|
||||
// parses it, logs the arming line and withholds the stamp exactly as the programmatic form.
|
||||
@@ -427,7 +460,9 @@ TEST_F(PipeInputsTest, BadVerifyCorruptKnobIsFatalNamingTheKnob) {
|
||||
}
|
||||
|
||||
// MOBILEGL_PIPE_VERIFY_FATAL=0: the divergence is logged with its field and serial and the
|
||||
// process goes on (the fill returns, the next fill's compare runs again).
|
||||
// process goes on (the fill returns, the next fill's compare runs again), and the teardown
|
||||
// summary counts both. The child leaves through std::exit so the comparator's static
|
||||
// destructor runs (a _exit would skip the summary line).
|
||||
TEST_F(PipeInputsTest, VerifyFatalOffLogsTheDivergenceAndContinues) {
|
||||
#if !MOBILEGL_PIPE_VERIFY
|
||||
GTEST_SKIP() << "verify not compiled in (MOBILEGL_PIPE_VERIFY=OFF)";
|
||||
@@ -443,10 +478,13 @@ TEST_F(PipeInputsTest, VerifyFatalOffLogsTheDivergenceAndContinues) {
|
||||
MG_Config::Features.PipeVerifyCorrupt = "GetRenderStateParameters";
|
||||
MGPipeFillForVerb(MGPipeVerb::DrawArrays);
|
||||
MGPipeFillForVerb(MGPipeVerb::DrawElements);
|
||||
::_exit(0);
|
||||
std::exit(0);
|
||||
});
|
||||
ASSERT_TRUE(ExitedWith(r, 0)) << DescribeStatus(r) << "\n" << r.Log;
|
||||
EXPECT_NE(r.Log.find("MGPipe: verify armed - 63 fields, 69 verbs, fatal=0"), std::string::npos) << r.Log;
|
||||
EXPECT_NE(r.Log.find("MGPipe: verify summary - 2 divergence(s) survived MOBILEGL_PIPE_VERIFY_FATAL=0"),
|
||||
std::string::npos)
|
||||
<< r.Log;
|
||||
const std::string first = "Fatal{PipeVerifyDiffer, \"GetRenderStateParameters@DrawArrays\", verb=" +
|
||||
std::to_string(serial) + ", where=entry}";
|
||||
const std::string second = "Fatal{PipeVerifyDiffer, \"GetRenderStateParameters@DrawElements\", verb=" +
|
||||
|
||||
Reference in New Issue
Block a user