[Fix] (MG_IntegrationTest): validate specialized controls and classify strict skips

This commit is contained in:
2026-10-05 08:45:28 -04:00
parent c90383db16
commit d8edc8baa2
7 changed files with 262 additions and 41 deletions
+27 -21
View File
@@ -1690,27 +1690,11 @@ jobs:
path: /tmp/core.*
if-no-files-found: ignore
# P5c gt (CONTRACT-P5C §6): the strict twin of integration-split. The role guards (the two
# layers of Fatal{RoleViolation, ...}) are COMPILED into every split build - there is no
# knob to arm them - so "guards armed" below means MOBILEGL_IPC_STRICT_ERRORS=1, the knob
# that promotes a BARRIER-PULLED residual read from counted debt to a named abort.
#
# TWO ASSERTIONS, NOT ONE, because the two halves of "strict is armed" are different
# statements:
#
# * the unit label must stay GREEN under it. A unit case that newly aborts under strict
# is a value-class read that crept back in (P5c rv's exit line is value-class = 0), and
# this step is what says so. FieldOwnershipTest owns the strict arms' behaviour cases;
#
# * the integration-split scenarios must all ABORT under it, BY DESIGN: the remaining
# residual pulls are the pinned object-class rows (GetFramebufferBindingSlot & co.,
# P3b/P4b/P7's), every drawing scenario reads one, and strict turns the first read into
# Fatal{UnmigratedPipeInput, ...} [BARRIER-PULLED, MOBILEGL_IPC_STRICT_ERRORS=1, ...].
# A lane that "passed" a scenario here would mean strict never armed - the same
# two-state shape as the E1/E3(a) negative controls, so the step asserts the abort AND
# greps the entry's private split-log for the strict marker. This half flips meaning
# when the object-class rows retire (P7): the scenarios then PASS under strict and the
# step is rewritten as an ordinary green lane.
# Shares build-linux-split with the functional/transport job above. This job
# checks state ownership: strict residual-read rules, distinct client/server
# blocks, zero-residual assertions, and complete per-entry result accounting.
# Configured controls must pass without skips. Capability gaps and known
# limitations are reported separately and accepted only by exact name/reason.
integration-split-strict:
runs-on: ubuntu-latest
timeout-minutes: 60
@@ -1918,6 +1902,22 @@ jobs:
# ---- P5f (f1), P5F-WIRE-COMPLETENESS.md §4: THE DUAL-BLOCK CENSUS LANE ---------------
#
# The same integration-split entries (plus Magma's own lane), re-run under
# These entries own assertions removed from generic transport registrations.
# Discovery, execution and zero-skip accounting must agree on the exact set.
- name: Specialized configuration controls
working-directory: build-split
env:
MOBILEGL_ITEST_REQUIRE_GPU: "1"
run: |
helper="${GITHUB_WORKSPACE}/MobileGL/MG_IntegrationTest/Harness/split_log_paths.py"
ctest --show-only=json-v1 > "${RUNNER_TEMP}/specialized-all.json"
python3 "${helper}" select-specialized "${RUNNER_TEMP}/specialized-all.json" \
"${RUNNER_TEMP}/specialized-selected.json" "${RUNNER_TEMP}/specialized-tests.txt"
ctest --tests-from-file "${RUNNER_TEMP}/specialized-tests.txt" --no-tests=error -j 4 \
--output-on-failure --output-junit "${RUNNER_TEMP}/specialized.xml"
python3 "${helper}" specialized-results "${RUNNER_TEMP}/specialized-all.json" \
"${RUNNER_TEMP}/specialized.xml"
# MOBILEGL_IPC_ROLE_SPLIT_STATE=1: the client's residual fill writes a client-role block
# and the backend reads a server-role one, so every BARRIER-PULLED read aborts with a
# named Fatal{UnmigratedPipeInput, "<field>@<verb>"}. THE RED IS THE CENSUS - it is the
@@ -2282,6 +2282,12 @@ jobs:
path: |
build-split/MobileGL/MG_IntegrationTest/*.log*
build-split/MobileGL/MG_IntegrationTest/split-logs/*.log
${{ runner.temp }}/specialized*.json
${{ runner.temp }}/specialized-tests.txt
${{ runner.temp }}/specialized.xml
${{ runner.temp }}/dualblock-lane.json
${{ runner.temp }}/dualblock.xml
${{ runner.temp }}/dualblock-split.txt
if-no-files-found: warn
# MobileGL/MG_Remote/Protocol/generated/protocol_generated.h is COMMITTED, and
+39 -10
View File
@@ -2407,6 +2407,34 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
#
# NO TcpDevice ARM ON MAGMA: the device endpoint is one phone, run serially, and doubling
# its matrix before the host lane is even green buys nothing. Stated rather than implied.
# Generic transport entries exercise ordinary behavior. Configuration-specific
# assertions run only in their pinned entries below, where CI requires a pass.
function(mgl_itest_generic_split_filter input backend output)
set(excluded
LargeArenaAdoptionScenario.AnAdoptionCostsExactlyOneMapPersistentRoundtrip
LargeArenaAdoptionScenario.AStreamSessionRefusesTheAdoptTierOnceByName
LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName
FencePollScenario.PacedFrameFenceWaitsBench
GenerateMipmapServerScenario.Rgb16fDrawnBaseWithARefusedReadbackDeclinesByName
GenerateMipmapServerScenario.Rgb16fUploadedBaseWithARefusedReadbackIsFilteredFromTheStore
ViewportArrayScenario.WithoutTheEmulationEveryIndexCollapsesOntoViewportZero
UnlocatedIoBlockScenario.TheEmulationIsActuallyArmedWhenTheEnvironmentPinsItOn
PointSizeDemotionScenario.TheDemotionIsActuallyArmedWhenTheEnvironmentPinsItOn
WireMipShapeScenario.Depth1DChainWithoutANativeBlitDeclinesByName)
if(backend STREQUAL "DirectGLES")
list(APPEND excluded
PointSizeDemotionScenario.ACaptureSurvivesAStageThatOnlyReadsThePointSize
WireIndirectDrawScenario.ShaderWrittenCommandsWithoutAnApplicationBarrierAreOrdered
WireIndirectDispatchScenario.ShaderWrittenGroupCountsWithoutAnApplicationBarrierAreOrdered)
endif()
list(JOIN excluded ":" excluded)
if(input MATCHES "-")
set(${output} "${input}:${excluded}" PARENT_SCOPE)
else()
set(${output} "${input}-${excluded}" PARENT_SCOPE)
endif()
endfunction()
macro(mgl_itest_register_split_arms_for_backend mglItestBackend scenarioFilter prefixTail)
# QUOTED DEREFERENCE, NOT A BARE NAME: a macro parameter is a textual substitution and
# not a variable, so `if(mglItestBackend STREQUAL ...)` would compare the literal string
@@ -2448,10 +2476,11 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
#
# IT MATTERS MORE ON THE SPAWN ARM: there TWO PROCESSES append to the path, so two
# entries sharing one file is not merely ambiguous, it interleaves two sessions.
mgl_itest_generic_split_filter("${scenarioFilter}" "${mglItestBackend}" mglItestGenericFilter)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "${mglItestBackend}.${mglItestArm}.${prefixTail}"
TEST_LIST "MGL_SPLIT_ARM_TESTS_${MGL_SPLIT_ARM_INDEX}"
TEST_FILTER "${scenarioFilter}"
TEST_FILTER "${mglItestGenericFilter}"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "${mglItestArmLabels}"
@@ -2486,7 +2515,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
mgl_itest_register_split_arms("PersistentCoherentMapScenario.*" "")
# P11 A2 (MG_Remote/CONTRACT-P11.md §2): the >= 16 MiB arena on all three arms. Its tier case
# is declared emulated per entry by SplitLogPaths (T2: every acquisition declines); the mpr and
# adopt-tier-refusal cases skip here for want of their lane markers. The Magma arms are the
# adopt-tier assertions are registered only in their configured controls. The Magma arms are the
# gated `Arena.` block beside `Pbo.` / `Fence.` below, plus the Buffers lane.
mgl_itest_register_split_arms("LargeArenaAdoptionScenario.*" "")
# P11 B2 addendum: A BUFFER DELETED WHILE BOUND TO AN INDEXED POINT (storage, uniform, atomic
@@ -2529,7 +2558,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectGLES.Tcp.AdoptTier0."
TEST_LIST "MGL_SPLIT_ARM_TESTS_${MGL_SPLIT_ARM_INDEX}"
TEST_FILTER "LargeArenaAdoptionScenario.*"
TEST_FILTER "LargeArenaAdoptionScenario.*-LargeArenaAdoptionScenario.AnAdoptionCostsExactlyOneMapPersistentRoundtrip:LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-gpu\;integration-tcp"
@@ -2552,7 +2581,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectGLES.${mglT0Arm}.AdoptTier0."
TEST_LIST "MGL_SPLIT_ARM_TESTS_${MGL_SPLIT_ARM_INDEX}"
TEST_FILTER "LargeArenaAdoptionScenario.*"
TEST_FILTER "LargeArenaAdoptionScenario.*-LargeArenaAdoptionScenario.AnAdoptionCostsExactlyOneMapPersistentRoundtrip:LargeArenaAdoptionScenario.AStreamSessionRefusesTheAdoptTierOnceByName"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-gpu\;integration-${mglT0ArmLower}"
@@ -4061,8 +4090,7 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
# table's FenceSync / GetSyncStatus / ClientWaitSync), so the same three cases.
foreach(fenceCase ZeroTimeoutPollLoopsEndInBoundedTime
PollsOfASignaledFenceCrossNothing
AFenceThatFinishesWhileTheClientOnlyPollsIsReported
PacedFrameFenceWaitsBench)
AFenceThatFinishesWhileTheClientOnlyPollsIsReported)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectVulkan.${mglItestArm}.Fence."
TEST_FILTER "FencePollScenario.${fenceCase}"
@@ -4118,15 +4146,16 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
# On tcp a stream refuses the tier by name at the client's handshake (A1, the stream case
# reads the line); over shared segments (split, spawn) the knob ASKS T0, a host has no
# AHardwareBuffer, and the session falls back to T2 by name (B2, the fallback case reads
# both lines). Each arm's marker makes the other arm's case skip, so the three arms carry
# the same names and spawn_lane_parity.py compares them like any other lane.
# both lines). Register only the assertion applicable to each transport; the
# parity check names these two transport-specific exceptions explicitly.
if(mglItestArm STREQUAL "Tcp")
set(mglItestAdoptTier0Env "MGITEST_ADOPT_TIER_REFUSAL=T0")
set(mglItestAdoptTier0Case AStreamSessionRefusesTheAdoptTierOnceByName)
else()
set(mglItestAdoptTier0Env "MGITEST_ADOPT_T0_FALLBACK=no AHardwareBuffer")
set(mglItestAdoptTier0Case ASessionThatCannotRunT0FallsBackToT2OnceByName)
endif()
foreach(arenaCase IN LISTS MGL_ITEST_ARENA_CASES ITEMS AStreamSessionRefusesTheAdoptTierOnceByName
ASessionThatCannotRunT0FallsBackToT2OnceByName)
foreach(arenaCase IN LISTS MGL_ITEST_ARENA_CASES ITEMS ${mglItestAdoptTier0Case})
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectVulkan.${mglItestArm}.AdoptTier0."
TEST_FILTER "LargeArenaAdoptionScenario.${arenaCase}"
@@ -181,6 +181,81 @@ DUALBLOCK_ALLOWED_SKIPS = {
}
# Capability gaps are not successful coverage. Keep them distinct from known
# implementation limitations, and print both categories in the strict report.
DUALBLOCK_CAPABILITY_SKIPS = {
"DirectGLES.Split.IterationRPFirstReductionScenario.SampledRgba32fFirstAverage":
"subgroup probe requires GL_KHR_shader_subgroup",
"DirectGLES.Split.IterationRPFirstReductionScenario.IndexedInputTopologyAndReduction":
"subgroup probe requires GL_KHR_shader_subgroup",
"DirectGLES.Split.IterationRPProgram203Scenario.FixedCompleteInputProducesFixedCompleteGoldenOutput":
"requires 512-invocation basic+arithmetic compute subgroups",
"DirectGLES.Split.IterationRPScratchFixScenario.FixtureShapedReductionSumsEveryInvocation":
"needs GL_KHR_shader_subgroup basic+arithmetic in compute",
"DirectGLES.Split.IterationRPScratchFixScenario.WideFixtureShapedReductionSumsEveryInvocation":
"needs GL_KHR_shader_subgroup basic+arithmetic in compute",
}
# Outstanding behavior, not a claim that another backend covers these semantics.
# See strict-known-limitations.md for the missing assertions and their scope.
DUALBLOCK_KNOWN_LIMITATIONS = {
"DirectGLES.Split.ClipDistanceScenario.ADisabledClipDistanceRemovesNothing":
"clips by a DISABLED gl_ClipDistance",
"DirectGLES.Split.ClipDistanceScenario.TheEnablesAreIndependentPerDistance":
"clips by every declared gl_ClipDistance regardless of the enables",
"DirectVulkan.Split.GpuContent.PartialUploadOverGpuContentScenario.OneDimensionalArraySubImageKeepsTheGpuClearedLayer":
"a 1D array layer does not attach on backend DirectVulkan",
"DirectGLES.Split.SsboDeclarationFormScenario.PackedBlockWithAnUnsizedArrayBeforeAnotherMember":
"known: a non-trailing unsized array overlaps the member after it",
"DirectGLES.Split.SsboDeclarationFormScenario.TwoUnsizedArraysInOneBlock":
"known: two runtime arrays in one block overlap",
}
# The older Magma ClipDistance exceptions describe the same unresolved behavior.
for _case in ("ADisabledClipDistanceRemovesNothing", "TheEnablesAreIndependentPerDistance"):
_name = "DirectVulkan.Split.Fm.ClipDistanceScenario." + _case
DUALBLOCK_KNOWN_LIMITATIONS[_name] = DUALBLOCK_ALLOWED_SKIPS.pop(_name)
def specialized_required():
"""Exact configured entries replacing inapplicable generic copies; no skip allowed."""
names = {
"DirectGLES.MapPersistentRoundtrips.LargeArenaAdoptionScenario.AnAdoptionCostsExactlyOneMapPersistentRoundtrip",
"DirectGLES.Spawn.AdoptT0Disallowed.LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName",
}
for backend in ("DirectGLES", "DirectVulkan"):
names.add(f"{backend}.Tcp.AdoptTier0.LargeArenaAdoptionScenario.AStreamSessionRefusesTheAdoptTierOnceByName")
for arm in ("Split", "Spawn"):
names.add(f"{backend}.{arm}.AdoptTier0.LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName")
for arm in ("Split", "Spawn"):
for case in ("Rgb16fDrawnBaseWithARefusedReadbackDeclinesByName",
"Rgb16fUploadedBaseWithARefusedReadbackIsFilteredFromTheStore"):
names.add(f"DirectGLES.{arm}.CpuMipRefused.GenerateMipmapServerScenario.{case}")
names.add(f"DirectVulkan.{arm}.ShaderMipDepth1D.WireMipShapeScenario.Depth1DChainWithoutANativeBlitDeclinesByName")
for arm in ("", "Split.", "Spawn.", "Tcp."):
for tail, case in (
("NoViewportArrayEmulation", "ViewportArrayScenario.WithoutTheEmulationEveryIndexCollapsesOntoViewportZero"),
("UnlocatedIoBlocks", "UnlocatedIoBlockScenario.TheEmulationIsActuallyArmedWhenTheEnvironmentPinsItOn"),
("PointSizeDemotion", "PointSizeDemotionScenario.ACaptureSurvivesAStageThatOnlyReadsThePointSize"),
("PointSizeDemotion", "PointSizeDemotionScenario.TheDemotionIsActuallyArmedWhenTheEnvironmentPinsItOn"),
):
names.add(f"DirectGLES.{arm}{tail}.{case}")
for arm in ("Split", "Spawn", "Tcp"):
names.add(f"DirectVulkan.{arm}.Indirect.WireIndirectDrawScenario.ShaderWrittenCommandsWithoutAnApplicationBarrierAreOrdered")
names.add(f"DirectVulkan.{arm}.IndirectDispatch.WireIndirectDispatchScenario.ShaderWrittenGroupCountsWithoutAnApplicationBarrierAreOrdered")
for case in ("ACaptureSurvivesAStageThatOnlyReadsThePointSize", "TheDemotionIsActuallyArmedWhenTheEnvironmentPinsItOn"):
names.add(f"DirectVulkan.PointSizeDemotion.PointSizeDemotionScenario.{case}")
return names
def select_specialized(document):
required = specialized_required()
tests = [t for t in document.get("tests", []) if t["name"] in required]
names = [t["name"] for t in tests]
if set(names) != required or len(names) != len(required):
raise ValueError(f"specialized controls missing or duplicated: missing={sorted(required - set(names))}")
return {"tests": tests}
def complete_results(document, junit_path, allowed_skips=None):
expected = [test["name"] for test in document.get("tests", [])]
if not expected or len(expected) != len(set(expected)):
@@ -196,14 +271,17 @@ def complete_results(document, junit_path, allowed_skips=None):
if missing or extra:
raise ValueError(f"result accounting: missing {sorted(missing)}, unexpected {sorted(extra)}")
allowed_skips = allowed_skips or {}
problems = []
for name, case in by_name.items():
if case.find("skipped") is not None:
reason = allowed_skips.get(name)
text = " ".join(" ".join(case.itertext()).split())
if reason is None or reason not in text:
raise ValueError(f"result accounting: unexpected skip/reason for {name}")
problems.append(f"unexpected skip/reason for {name}")
elif case.get("status") in ("notrun", "disabled"):
raise ValueError(f"result accounting: {name} did not execute ({case.get('status')})")
problems.append(f"{name} did not execute ({case.get('status')})")
if problems:
raise ValueError("result accounting: " + " | ".join(problems))
return by_name
@@ -342,7 +420,14 @@ def expect_fatal(document, junit_path, expected_path):
empty expected file IS the P5f exit state, which this mode then verifies rather than
obstructs."""
logs = marker_log_paths(document)
by_name = complete_results(document, junit_path, DUALBLOCK_ALLOWED_SKIPS)
by_name = complete_results(document, junit_path, {
**DUALBLOCK_ALLOWED_SKIPS, **DUALBLOCK_CAPABILITY_SKIPS, **DUALBLOCK_KNOWN_LIMITATIONS})
for category, entries in (("capability gaps (not covered)", DUALBLOCK_CAPABILITY_SKIPS),
("known limitations (unresolved)", DUALBLOCK_KNOWN_LIMITATIONS)):
skipped_entries = sorted(n for n in entries if n in by_name and by_name[n].find("skipped") is not None)
print(f"SplitLogPaths {category}: {len(skipped_entries)}")
for name in skipped_entries:
print(f" {name}: {entries[name]}")
problems = []
fatal, admitted, escalated = {}, {}, {}
scanned = skipped = green = red = 0
@@ -475,6 +560,29 @@ def markers(document, selector, allowed_path, expected_path, require_no_fatal):
def main():
mode = sys.argv[1]
if mode == "select-specialized":
selected = select_specialized(json.loads(Path(sys.argv[2]).read_text()))
Path(sys.argv[3]).write_text(json.dumps(selected))
Path(sys.argv[4]).write_text("\n".join(t["name"] for t in selected["tests"]) + "\n")
return
if mode == "specialized-results":
document = json.loads(Path(sys.argv[2]).read_text())
# CTest adds fixture setup/cleanup entries to JUnit; require those to pass too.
required = specialized_required()
fixture_names = set()
by_name = {t["name"]: t for t in document.get("tests", [])}
for test in select_specialized(document)["tests"]:
for prop in test.get("properties", []):
if prop["name"] == "FIXTURES_REQUIRED":
fixture_names.update(prop["value"])
selected = []
for test in by_name.values():
is_fixture = any(p["name"] in ("FIXTURES_SETUP", "FIXTURES_CLEANUP") and
fixture_names.intersection(p["value"]) for p in test.get("properties", []))
if test["name"] in required or is_fixture:
selected.append(test)
require_green({"tests": selected}, sys.argv[3], [t["name"] for t in selected])
return
if mode == "check":
data = subprocess.check_output([sys.argv[2], "--test-dir", sys.argv[3],
"--show-only=json-v1"], text=True)
@@ -0,0 +1,36 @@
# Strict lane coverage limitations
A skipped assertion is not a passing assertion. The strict result checker matches
both the exact entry and its documented reason; unknown skips still fail CI.
Configuration-specific controls are selected separately and must pass without skips.
## Unresolved behavior
- `ClipDistanceScenario.ADisabledClipDistanceRemovesNothing` and
`TheEnablesAreIndependentPerDistance`: per-distance enable semantics are missing
on the tested GLES and Vulkan paths. Neither backend supplies a passing control
on local llvmpipe/lavapipe. The strict list names the GLES and Magma Fm entries.
- `PartialUploadOverGpuContentScenario.OneDimensionalArraySubImageKeepsTheGpuClearedLayer`:
the Vulkan path cannot attach the 1D array layer. GLES passes, which does not
establish Vulkan coverage.
- `SsboDeclarationFormScenario.PackedBlockWithAnUnsizedArrayBeforeAnotherMember`
and `TwoUnsizedArraysInOneBlock`: the tests unconditionally skip before compiling
or drawing because the layout is known to overlap. No executing assertion exists
in either backend; resolving the intended shader/layout semantics is separate work.
The checker reports these as **known limitations (unresolved)**. Removing a skip
must not require adding a new exception: an executing, passing case is accepted.
## Driver capability gaps
The five GLES IterationRP subgroup probes need compute basic/arithmetic subgroups.
The tested llvmpipe GLES driver lacks these. The two FirstReduction probes also
require subgroup width 16..256; local lavapipe exposes 8, so those two have no local
execution coverage. Program203 and ScratchFix have passing Vulkan entries, which
is not proof of the GLES path. The checker reports **capability gaps (not covered)**.
## Optional measurement
`FencePollScenario.PacedFrameFenceWaitsBench` is not part of generic split correctness
registrations. It remains available in ambient/full-suite entries for an explicit
`MGITEST_FENCE_PACE_BENCH=1` measurement. Ordinary fence polling assertions remain gated.
@@ -123,6 +123,43 @@ class ResultAccountingTest(unittest.TestCase):
with self.assertRaisesRegex(ValueError, "unexpected skip"):
self.census()
def test_all_unexpected_skips_are_reported_together(self):
self.results([(A, "notrun", "skipped"), (B, "notrun", "skipped")])
with self.assertRaises(ValueError) as error:
self.census()
self.assertIn(A, str(error.exception))
self.assertIn(B, str(error.exception))
def test_capability_and_known_limitation_reasons_are_not_interchangeable(self):
for table in (helper.DUALBLOCK_CAPABILITY_SKIPS, helper.DUALBLOCK_KNOWN_LIMITATIONS):
name, reason = next(iter(table.items()))
for actual, accepted in ((reason, True), ("preflight failed: no EGL display", False)):
with self.subTest(name=name, accepted=accepted):
self.document = self.discovery([name])
self.results([(name, "notrun", "skipped")])
tree = ET.parse(self.xml)
ET.SubElement(tree.getroot().find("testcase"), "system-out").text = actual
tree.write(self.xml)
if accepted:
self.census()
else:
with self.assertRaisesRegex(ValueError, "unexpected skip"):
self.census()
def test_specialized_control_missing_or_skipped_is_rejected(self):
names = sorted(helper.specialized_required())
document = self.discovery(names)
helper.select_specialized(document)
with self.assertRaisesRegex(ValueError, "missing or duplicated"):
helper.select_specialized({"tests": document["tests"][1:]})
self.results([(n, "run", None) for n in names])
with contextlib.redirect_stdout(io.StringIO()):
helper.require_green(document, self.xml, names)
self.results([(n, "notrun", "skipped") if i == 0 else (n, "run", None)
for i, n in enumerate(names)])
with self.assertRaisesRegex(ValueError, "unexpected skip"):
helper.require_green(document, self.xml, names)
def test_admitted_or_fatal_on_passed_case_is_not_hidden(self):
for marker in ['Admitted{UnmigratedPipeInput, "GetProgramObject@Clear"}',
'Fatal{UnmigratedPipeInput, "GetProgramObject@Clear"}']:
+5 -7
View File
@@ -132,7 +132,7 @@ PRIMGEN_REROUTE_CASES = ("CountsADrawMadeWithNoCaptureSpan",
"APausedSpanCountsATessellatedPatchExactlyOnce",
"APausedSpanCountsAnInstancedDrawExactlyOnce",
"TheRerouteIsActuallyArmedWhenTheEnvironmentPinsItOn")
MAGMA_SERVER_ENV_KNOB_NO_TCP = (".ShaderMip1.", ".ShaderMip2.", ".DepthMip.",
MAGMA_SERVER_ENV_KNOB_NO_TCP = (".AdoptTier0.LargeArenaAdoptionScenario.ASessionThatCannotRunT0FallsBackToT2OnceByName", ".ShaderMip1.", ".ShaderMip2.", ".DepthMip.",
".DefaultBlitShape1.", ".MsResolve1.", ".StaleSerial.", ".MsFlip1.",
".MsResolveBug.", ".MsFlipBug.", ".MsResolveElide.",
".ImageUnitPrivate.InvalidImageUnitScenario.AStoreThroughAnInvalidUnitIsLoadedThroughNeitherAnotherInvalidUnitNorItself",
@@ -150,12 +150,10 @@ MAGMA_SERVER_ENV_KNOB_NO_TCP = (".ShaderMip1.", ".ShaderMip2.", ".DepthMip.",
".ShaderMipDepth1D.",)
# THE MIRROR SHAPE - entries that exist on tcp ALONE, by construction. Each tail must match at least
# one tcp entry, or the exception names nothing. P11 A1 put `.AdoptTier0.` here (over shared segments
# MOBILEGL_IPC_ADOPT_TIER=0 died at the handshake); P11 B2 made that knob an ASK that falls back to T2
# by name, so the Magma `.AdoptTier0.` lane now runs on all three arms with one case set and is
# compared like any other. The mechanism stays for the next tcp-only lane.
MAGMA_TCP_ONLY = ()
# The stream-refusal assertion is TCP-only. The shared-segment fallback assertion
# is required on split/spawn and listed in no_tcp above. Neither transport should
# register the other assertion merely to skip it.
MAGMA_TCP_ONLY = (".AdoptTier0.LargeArenaAdoptionScenario.AStreamSessionRefusesTheAdoptTierOnceByName",)
def lane_names(build_dir, label):
@@ -63,3 +63,10 @@ ProgramPipelineScenario.AReservedNameTakesStateBeforeItIsAProgramPipeline no-rec
# ---- pending-fix -------------------------------------------------------------------------------
# (none: P8-SE fixed the default-framebuffer depth/stencil case and registered it, notes/p8/SE.md)
# These ambient copies cannot run their assertion; pinned controls are checked separately.
LargeArenaAdoptionScenario.AnAdoptionCostsExactlyOneMapPersistentRoundtrip mechanism synchronous monolith accounting; required DirectGLES.MapPersistentRoundtrips control
DirectGLES:FencePollScenario.PacedFrameFenceWaitsBench mechanism optional measurement requiring MGITEST_FENCE_PACE_BENCH=1, not a correctness gate
DirectGLES:WireIndirectDrawScenario.ShaderWrittenCommandsWithoutAnApplicationBarrierAreOrdered single-backend Vulkan implicit indirect-command barrier
DirectGLES:WireIndirectDispatchScenario.ShaderWrittenGroupCountsWithoutAnApplicationBarrierAreOrdered single-backend Vulkan implicit indirect-command barrier
DirectGLES:WireMipShapeScenario.Depth1DChainWithoutANativeBlitDeclinesByName single-backend Vulkan forced shader-mip decline; DirectGLES generates the chain