[MG_IntegrationTest, MG_Pipe, ci] (P7): every verify case runs on the split (inproc) arm of both backends under integration-verify-split, armed per entry, and the comparator's oracle for the pack half inside the server's read_pixels window is the ID-49 neutral pack

This commit is contained in:
2026-09-22 20:34:50 -04:00
parent e8678dfad9
commit 64a2f4a300
4 changed files with 448 additions and 0 deletions
+200
View File
@@ -852,6 +852,206 @@ jobs:
path: /tmp/core.*
if-no-files-found: ignore
# P7 WAVE 3 (V1), CONTRACT-P7 §6 - EXIT GATE 2's SECOND COLUMN: the comparator on the split
# (inproc) arm, both backends, and the two negative controls red on that arm.
#
# ITS OWN BUILD, because neither existing one can carry it: build-linux-verify configures
# without MOBILEGL_BUILD_DISAGGREGATED (so MG_Remote and the transport parser do not exist and
# `MOBILEGL_TRANSPORT=inproc` would be accepted and ignored), and build-linux-split configures
# without MOBILEGL_PIPE_VERIFY (so the comparator does not exist). The integration-verify-split
# entries are registered only when BOTH options are on, so `--no-tests=error` below reds a build
# that lost either one instead of reporting a green run of nothing. Built and run in one job:
# nothing downstream consumes this library.
#
# INPROC ONLY, BY THE INSTRUMENT'S NATURE: the comparator's two arms (the applier-written
# gPipeInputs and the frontend GLContext) are co-resident only when both roles share a process.
# MG_IntegrationTest/CMakeLists.txt's verify-split block records the spawn measurement.
integration-verify-split:
runs-on: ubuntu-latest
timeout-minutes: 180
permissions:
actions: write
contents: read
env:
BUILD_DIR: build-verify-split
CCACHE_BASEDIR: ${{ github.workspace }}
CCACHE_COMPRESS: "true"
CCACHE_DIR: ${{ github.workspace }}/.ccache
CCACHE_MAXSIZE: 4G
CCACHE_NOHASHDIR: "true"
steps:
- name: Set Swap Space
uses: pierotofy/set-swap-space@v1.0
with:
swap-size-gb: 32
- name: Checkout repo
uses: actions/checkout@v6
with:
# recursive for build-linux-split's reason: MOBILEGL_BUILD_DISAGGREGATED shadows itself
# back to OFF when 3rdparty/flatbuffers/include is missing.
submodules: recursive
- name: Get CMake
uses: lukka/get-cmake@v4.3.3
- name: Restore ccache
uses: actions/cache/restore@v5
with:
path: .ccache
key: ${{ runner.os }}-test-${{ github.job }}-ccache-v1
restore-keys: |
${{ runner.os }}-test-${{ github.job }}-ccache-
- name: Prepare Vulkan SDK
uses: humbletim/setup-vulkan-sdk@v1.2.1
with:
vulkan-query-version: 1.4.304.1
vulkan-components: Vulkan-Headers, Vulkan-Loader
vulkan-use-cache: true
- name: Update glslang external sources
working-directory: 3rdparty/glslang
run: python update_glslang_sources.py
- name: Install build and runtime dependencies
run: |
sudo apt-get update
sudo apt-get install -y ccache clang-20 clang++-20 lld-20 libc++-20-dev libc++abi-20-dev libvulkan-dev libegl1-mesa-dev libgles2-mesa-dev libgl1-mesa-dri mesa-vulkan-drivers ninja-build libvulkan1 libegl1 libegl-mesa0 libgles2 libgl1
- name: Configure CMake
# Release/INFO for build-linux-verify's reason, and INFO is load-bearing here for
# build-linux-split's: ConfigLoader's resolved-transport line is logged at INFO and the
# arm-proof step below reads it back out of every entry's client log.
run: |
cmake -S . -B "${BUILD_DIR}" -G Ninja \
-DCMAKE_C_COMPILER=clang-20 \
-DCMAKE_CXX_COMPILER=clang++-20 \
-DCMAKE_C_COMPILER_LAUNCHER=ccache \
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache \
-DCMAKE_BUILD_TYPE=Release \
-DMOBILEGL_LOG_ACTIVE_LEVEL=MOBILEGL_LOG_LEVEL_INFO \
-DMOBILEGL_BUILD_TEST=ON \
-DMOBILEGL_BUILD_BENCHMARK=OFF \
-DMOBILEGL_BUILD_INTEGRATION_TEST=ON \
-DMOBILEGL_ITEST_VK_ICD=/usr/share/vulkan/icd.d/lvp_icd.json \
-DMOBILEGL_BUILD_TRACE_REPLAY=OFF \
-DMOBILEGL_PIPE_PUSH=ON \
-DMOBILEGL_BUILD_DISAGGREGATED=ON \
-DMOBILEGL_BUILD_DISAGGREGATED_INPROC=ON \
-DMOBILEGL_PIPE_VERIFY=ON \
-DCMAKE_POLICY_VERSION_MINIMUM=3.5
- name: Build
run: cmake --build "${BUILD_DIR}" --parallel "$(nproc)"
# Both options, both directions of "did it take" - the two jobs this one is the product of
# each check one of them, and this library has to pass both checks.
- name: The library carries both the comparator and MG_Remote
run: |
test -f "${BUILD_DIR}/libMobileGL.so"
defined=$(nm --defined-only "${BUILD_DIR}/libMobileGL.so" | wc -l)
if [ "${defined}" -lt 1000 ]; then
echo "::error::nm --defined-only sees only ${defined} symbols in ${BUILD_DIR}/libMobileGL.so - it looks stripped, so the checks below could not have failed honestly"
exit 1
fi
if ! nm --defined-only "${BUILD_DIR}/libMobileGL.so" | grep -q "MGPipeVerifyInputs"; then
echo "::error::libMobileGL.so defines no MGPipeVerifyInputs: -DMOBILEGL_PIPE_VERIFY=ON did not take, and the verify-split lane would compare nothing"
exit 1
fi
remote=$(nm --defined-only "${BUILD_DIR}/libMobileGL.so" | grep -c -i "MG_Remote" || true)
if [ "${remote}" -lt 1 ]; then
echo "::error::libMobileGL.so defines no MG_Remote symbol: -DMOBILEGL_BUILD_DISAGGREGATED=ON did not take, and every entry would run monolith under a name that says split"
exit 1
fi
echo "libMobileGL.so defines MGPipeVerifyInputs and ${remote} MG_Remote symbol(s) (${defined} defined symbols)"
- name: Show ccache stats
if: always()
run: ccache --show-stats
- name: Release superseded ccache entry
if: github.ref_name == github.event.repository.default_branch
env:
GH_TOKEN: ${{ github.token }}
CACHE_KEY: ${{ runner.os }}-test-${{ github.job }}-ccache-v1
run: gh cache delete "${CACHE_KEY}" || true
- name: Save ccache
if: github.ref_name == github.event.repository.default_branch
continue-on-error: true
uses: actions/cache/save@v5
with:
path: .ccache
key: ${{ runner.os }}-test-${{ github.job }}-ccache-v1
# The lane. `^...$` because ctest -L is a regex (ID-131) and `integration-verify` would
# otherwise also match this label and the monolith one would match both.
- name: Integration scenarios under MOBILEGL_PIPE_VERIFY on the split (inproc) arm
working-directory: build-verify-split
env:
MOBILEGL_ITEST_REQUIRE_GPU: "1"
run: |
ulimit -c unlimited
sudo sysctl -w kernel.core_pattern='/tmp/core.%e.%p'
ctest --output-on-failure -L '^integration-verify-split$' --no-tests=error -j 4
# THE ARM PROOF, per entry. Every ambient entry has a private log path (SplitLogPaths.cmake.in),
# so this grep - unlike integration-verify's, over a shared log - is a census:
# * ConfigLoader's `MOBILEGL_TRANSPORT=inproc` line in EVERY client log: an entry that ran
# monolith would have passed every assertion above and fails here by name;
# * `MGPipe: verify armed` in both VerifySplitArming. logs, and in at least 850 per-entry
# client logs. The line is latched at a process's first fill, so the processes that never
# reach a verb (limits queries, CapsMirror answers, the poison parent) honestly lack it -
# 909 of 1064 carried it on the landing run - and a count that falls through the floor
# means the comparator stopped arming somewhere after bring-up.
- name: The verify-split entries ran inproc and armed the comparator
working-directory: build-verify-split/MobileGL/MG_IntegrationTest
run: |
shopt -s nullglob
logs=(verify-split-logs/*.client.log)
if [ ${#logs[@]} -lt 1000 ]; then
echo "::error::found ${#logs[@]} per-entry client logs under verify-split-logs (expected ~1064): the private log paths did not take, so nothing below is a per-entry proof"
exit 1
fi
missing=$(grep -L 'Config: MOBILEGL_TRANSPORT=inproc' "${logs[@]}" | wc -l)
if [ "${missing}" -ne 0 ]; then
grep -L 'Config: MOBILEGL_TRANSPORT=inproc' "${logs[@]}" | head -20
echo "::error::${missing} verify-split entries carry no resolved MOBILEGL_TRANSPORT=inproc line: they did not run on the split arm"
exit 1
fi
for backend in DirectGLES DirectVulkan; do
if ! grep -q "MGPipe: verify armed" "pipe-verify-split-arming-${backend}.client.log"; then
echo "::error::pipe-verify-split-arming-${backend}.client.log carries no arming line"
exit 1
fi
done
armed=$(grep -l 'MGPipe: verify armed' "${logs[@]}" | wc -l)
if [ "${armed}" -lt 850 ]; then
echo "::error::only ${armed} of ${#logs[@]} verify-split entries armed the comparator (floor 850, 909 at landing)"
exit 1
fi
echo "${#logs[@]} entries resolved inproc; ${armed} of them armed the comparator"
- name: Upload verify-split lane logs
if: always()
uses: actions/upload-artifact@v7
with:
name: integration-verify-split-logs
path: |
build-verify-split/MobileGL/MG_IntegrationTest/verify-split-logs/**
build-verify-split/MobileGL/MG_IntegrationTest/pipe-*split*.log*
if-no-files-found: warn
- name: Upload core dumps
if: failure()
uses: actions/upload-artifact@v7
with:
name: integration-verify-split-core-dumps
path: /tmp/core.*
if-no-files-found: ignore
# P5's split build. The verify pair cloned, because the problem is the same one: a third
# configuration of the same sources whose whole value depends on the option having taken.
#
+67
View File
@@ -645,6 +645,56 @@ namespace MobileGL::MG_Pipe {
MGPipeInputField differing = MGPipeInputField::kFieldCount;
if (!MGPipeVerifyInputs(inputs, g_snapshot, mask, &differing)) ReportDivergence(differing, "entry");
}
#if MOBILEGL_BUILD_DISAGGREGATED
// ---- P7 wave 3 (V1): the compare-at-read oracle inside the server's read_pixels ----
//
// WHAT THE SPLIT ARM FOUND THE FIRST TIME VERIFY AND SPLIT SHARED A BUILD. Every
// glReadPixels on the inproc arm - 8530 reads over 220 of the lane's 1068 entries, and the
// VerifySplitArming. entries on both backends - aborted with
//
// MGPipe: verify read of GetPixelStoreParameters (index 0, 0) differs from the live context
// MGPipe: Fatal{PipeVerifyDiffer, "GetPixelStoreParameters@ReadPixels", verb=6, where=read}
//
// on the server's apply thread, and it was the ONLY field that diverged anywhere in the
// lane. The mechanism is ID-49 and is deliberate: the pack state never shapes the wire
// answer, so MG_Remote/Server/PipeApplier.cpp's read_pixels body writes a NEUTRAL pack
// into the applier's copy of the field (MGPipeApplySetPixelPackState), makes the backend
// read, and restores the pushed one; the client then scatters the tight reply through the
// application's own pack state. The frontend context - this comparator's oracle - still
// holds the application's pack (Alignment 4 by default), so the backend's read of the
// pack half answers {Alignment 1} where the live context says {Alignment 4}. On the
// monolith arm the same neutral window is opened on the frontend context itself
// (GL_Texture.cpp's ScopedNeutralPackState), which is why the monolith lane never saw it.
//
// SO THE ORACLE, NOT THE RULE, IS WHAT CHANGES, AND ONLY IN THAT WINDOW: under a server
// stamp, on the ReadPixels verb, the pack half's expected value is the neutral pack the
// applier reads with, and the UNPACK half and every other field keep the live context as
// their oracle. A server read of the pack half that is neither the application's value
// nor exactly the neutral one is still a divergence and still Fatal. What this gives up,
// stated: on the server's ReadPixels the comparator can no longer see a client that
// pushed a WRONG pack state, because the applier overwrites it before the backend reads;
// the client-side scatter that consumes the real pack is covered by the readback matrix
// cases, which compare bytes, not fields.
Bool ServerReadsInsideTheNeutralPackWindow(const PipeInputs& self, MGPipeInputField field) {
return field == MGPipeInputField::GetPixelStoreParameters && self.ServerStampedVerb() &&
self.CurrentVerb() == MGPipeVerb::ReadPixels;
}
// PipeApplier.cpp's `neutralPack`, field for field. A second spelling of a constant is
// the price of not reaching into MG_Remote/Server from here; if the two ever part, the
// server-side read stops matching this and the lane goes red by name, which is the
// direction that fails loudly.
PixelStoreParameters ServerReadPixelsNeutralPack() {
PixelStoreParameters neutral{};
neutral.RowLength = 0;
neutral.SkipRows = 0;
neutral.SkipPixels = 0;
neutral.SkipImages = 0;
neutral.Alignment = 1;
return neutral;
}
#endif // MOBILEGL_BUILD_DISAGGREGATED
#endif // MOBILEGL_PIPE_VERIFY
} // namespace
@@ -682,6 +732,23 @@ namespace MobileGL::MG_Pipe {
const Bool equal = MGPipeInputsFieldEqual(field, self, g_readScratch);
g_verify.InHook = false;
if (equal) return;
#if MOBILEGL_BUILD_DISAGGREGATED
if (ServerReadsInsideTheNeutralPackWindow(self, field)) {
// The live context is the application's pack state and the server is, by ID-49,
// reading with the neutral one; the oracle for THAT HALF is the neutral pack, and
// every other byte of the field still has to match the live context.
g_verify.InHook = true;
PipeInputs::VisitStorage(field, g_readScratch, g_readScratch, [](auto& live, auto&) {
if constexpr (std::is_same_v<std::remove_reference_t<decltype(live)>, PixelStoreParameters[2]>) {
live[0] = ServerReadPixelsNeutralPack();
}
return true;
});
const Bool equalToTheNeutralPack = MGPipeInputsFieldEqual(field, self, g_readScratch);
g_verify.InHook = false;
if (equalToTheNeutralPack) return;
}
#endif
MGLOG_E("MGPipe: verify read of %s (index %u, %u) differs from the live context", kMGPipeInputFieldNames[index],
index0, index1);
ReportDivergence(field, "read");
+161
View File
@@ -3778,6 +3778,167 @@ if (MOBILEGL_BUILD_DISAGGREGATED)
"integration-magma-full-{split,spawn,tcp} labels (no CI gate)")
endif()
# =====================================================================================
# P7 WAVE 3 (V1): integration-verify-split - THE COMPARATOR ON THE SPLIT ARM
# =====================================================================================
#
# CONTRACT-P7 §6, exit gate 2: "verify x {monolith, split(inproc)} x Magma, zero divergence".
# Until this block the verify block near the top of this file registered `MOBILEGL_TRANSPORT=
# monolith` on every one of its 1136 entries, so the gate's second column had no entries at all
# - not merely unmet, UNMEASURABLE, exactly as package L found exit gate 1's Magma column.
#
# IT HAD A PREREQUISITE AND THE PREREQUISITE IS PAID. A verify build under `inproc` used to die
# on the server apply thread before one case could arm:
#
# Fatal{PipeRespecifyScope} resource_respecify {slot=12, gen=0}: the descriptor carries a
# per-level respecify scope (target=258, level=0), and no path in this phase may set one
#
# That pin is now "a per-level producer must cover the range it declares"
# (MG_Pipe/PipeApply.cpp), which is the invariant it was actually guarding.
#
# BOTH BACKENDS, AND THE MAGMA HALF IS THE HALF THE GATE NAMES. `${MGL_ITEST_VULKAN_ENV}` and
# not `${MGL_ITEST_COMMON_ENV}` on the DirectVulkan entries, for package L's reason: that list
# carries VK_ICD_FILENAMES and the three lavapipe iterationRP repairs the monolith `DirectVulkan.`
# arm has been pinned to, and a lane that appended the common list would measure a different
# driver from the gate it is compared against. `MOBILEGL_ITEST_REQUIRE_GPU=1` is pinned for the
# same reason every split-family lane pins it: a lane that skipped everything and a lane that
# passed everything are the same green in ctest, and this lane is here to be an ARM.
#
# THE CASE SET IS THE MONOLITH VERIFY LANE'S, MINUS THREE THINGS, the first two because
# this arm carries a TRANSPORT and that lane does not:
#
# 1. ${MGL_ITEST_MONOLITH_MECHANISM_FILTER}. Those oracles toggle process-local push masks,
# pointer-key ABA, direct persistent adoption or synchronous stats slots and must not
# inherit a transport - which is why the ambient DirectGLES./DirectVulkan. registrations
# subtract them too and re-register them with MOBILEGL_TRANSPORT=monolith pinned. The
# monolith verify lane keeps them because there the pin and the lane agree. NOTE that the
# filter names PipeVerifyArmingScenario.* and PoisonOmissionScenario.*, which is why the
# arming entry and the two negative controls below are registered by hand, one per backend,
# exactly as the monolith verify block registers its own.
# 2. DualBlockScenario.*. Its green REQUIRES MOBILEGL_IPC_ROLE_SPLIT_STATE=1, and pinning that
# knob here would replace this lane's subject (the comparator) with a different experiment;
# without it the case is red by name. Tier 3 above filters it for the same reason and says
# so at more length. Its own lane, `integration-dualblock-split`, is where it is read.
# 3. On the DirectGLES half only, four Magma wire-arm decline cases that are red on DirectGLES
# x inproc with the comparator OFF (MGL_ITEST_VERIFY_SPLIT_GLES_MAGMA_DECLINE_FILTER below
# says which and why).
#
# NO MGITEST_SPLIT_LANE=1, AND THIS IS THE ONE PLACE THAT COSTS SOMETHING, so it is stated
# rather than discovered. That marker arms ScenarioFixture's destructor assertion "this case
# must have MOVED the client encoder's record ordinal", which is right for a curated lane where
# every entry draws and wrong for a whole-binary set: tier 3 measured 13 reds from it
# (AdvertisedLimitsScenario x8, SpirvShaderBinaryScenario x4, ProgramPipelineScenario's reserved
# name), every one of them a query answered from the client's CapsMirror without a verb. They
# would red on a DirectGLES set too - a property of the census, not of the transport.
#
# WHAT REPLACES IT IS STRONGER HERE THAN IT IS IN TIER 3, and it is why this lane is armed
# rather than green-skipping: EVERY ENTRY GETS A PRIVATE LOG PATH (below, through
# MGL_VERIFY_SPLIT_TEST_LISTS), and `.github/workflows/test.yml`'s integration-verify-split job
# reads all of them: ConfigLoader's resolved `MOBILEGL_TRANSPORT=inproc` line is required in EVERY
# client log, so a lane that silently ran monolith fails that step by name. The comparator's
# `MGPipe: verify armed` line is latched at a process's FIRST FILL, so it is absent - honestly -
# from the processes that never reach a verb (limits queries, CapsMirror answers, the poison
# parent that only forks; 155 of 1064 on the landing run, 99 of them skips); the step therefore
# requires it in both VerifySplitArming. logs and holds the per-entry count to a stated floor.
# The VerifySplitArming. entries assert it from inside the process as well, which is the shape
# the monolith lane's VerifyArming. entries already have.
if (MOBILEGL_BUILD_DISAGGREGATED AND MOBILEGL_PIPE_VERIFY)
# The transport half, joined onto each backend's own list. One place says what "the verify
# split arm" means, as MGL_ITEST_SPLIT_ARM_TRANSPORT_ENV does for the Magma lanes.
set(MGL_ITEST_VERIFY_SPLIT_ARM_ENV
"MOBILEGL_TRANSPORT=inproc" "MOBILEGL_IPC_SERVER_PATH=${MGL_ITEST_SPLIT_SERVER_PATH}"
"MOBILEGL_PIPE_VERIFY=1" "MOBILEGL_ITEST_REQUIRE_GPU=1")
mgl_itest_join_environment(MGL_ITEST_GLES_VERIFY_SPLIT_ENVIRONMENT
"MOBILEGL_BACKEND_TYPE=DirectGLES" ${MGL_ITEST_VERIFY_SPLIT_ARM_ENV}
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_COMMON_ENV})
mgl_itest_join_environment(MGL_ITEST_VULKAN_VERIFY_SPLIT_ENVIRONMENT
"MOBILEGL_BACKEND_TYPE=DirectVulkan" ${MGL_ITEST_VERIFY_SPLIT_ARM_ENV}
${MGL_ITEST_CAPABILITY_ENV} ${MGL_ITEST_VULKAN_ENV})
# THE FOUR MAGMA DECLINE CASES ARE SUBTRACTED FROM THE DirectGLES HALF ONLY, and not because
# of the comparator. They assert Magma's wire-arm decline contract (`@P7` retirements: the
# depth-stencil mip decline, the two multisample blit declines, the overlapping in-place copy)
# and skip on every monolith arm, so the only arm that registers them is DirectVulkan's
# split family. On DirectGLES x inproc they are RED WITH THE COMPARATOR OFF - measured on
# this build with MOBILEGL_PIPE_VERIFY=0 in the same environment, the same four assertions
# (GL error 0x0502 where the decline promises none, or none where it promises one; the
# overlap copy writes the level the decline leaves alone) - because Espryt does not decline
# those shapes at all. No DirectGLES split lane had ever run them; that is a finding about the
# DirectGLES whole-binary set on split, not about verify, and it is recorded in
# notes/p7/verify-split.md rather than hidden in a green. The DirectVulkan half keeps them.
set(MGL_ITEST_VERIFY_SPLIT_GLES_MAGMA_DECLINE_FILTER
"F1WireScenario.GenerateMipmapDepthStencilDeclinesAndKeepsTheSession:F1WireScenario.MultisampleBlitOntoAMultisampleDestinationDeclinesAndKeepsTheSession:F1WireScenario.MultisampleBlitFromASingleSampleSourceDeclinesAndKeepsTheSession:F1WireScenario.CopyImageInPlaceOverlapDeclinesAndLeavesTheLevelAlone")
set(MGL_VERIFY_SPLIT_TEST_LISTS "")
# The ambient set, per backend. The GLES half is registered TWICE for the monolith verify
# lane's reason and with its spelling: the texture-view cases need
# MOBILEGL_ESPRYT_ENABLE_TEXTURE_VIEW=1 or DirectGLES withholds GL_ARB_texture_view and they
# green-skip, so they are subtracted from the first registration and re-registered with the
# knob. "Every existing verify case on the split arm" is false without the second block.
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectGLES.VerifySplit."
TEST_LIST MGL_VERIFY_SPLIT_TESTS_GLES
TEST_FILTER "-${MGL_ITEST_MONOLITH_MECHANISM_FILTER}:${MGL_ITEST_GLES_VIEW_FILTER}:DualBlockScenario.*:${MGL_ITEST_VERIFY_SPLIT_GLES_MAGMA_DECLINE_FILTER}"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-verify-split"
TIMEOUT ${MGL_ITEST_VERIFY_TIMEOUT}
ENVIRONMENT "${MGL_ITEST_GLES_VERIFY_SPLIT_ENVIRONMENT}"
)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectGLES.VerifySplit."
TEST_LIST MGL_VERIFY_SPLIT_TESTS_GLES_VIEW
TEST_FILTER "${MGL_ITEST_GLES_VIEW_FILTER}"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-verify-split"
TIMEOUT ${MGL_ITEST_VERIFY_TIMEOUT}
ENVIRONMENT "${MGL_ITEST_GLES_VERIFY_SPLIT_ENVIRONMENT}\;MOBILEGL_ESPRYT_ENABLE_TEXTURE_VIEW=1"
)
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "DirectVulkan.VerifySplit."
TEST_LIST MGL_VERIFY_SPLIT_TESTS_VULKAN
TEST_FILTER "-${MGL_ITEST_MONOLITH_MECHANISM_FILTER}:DualBlockScenario.*"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-verify-split"
TIMEOUT ${MGL_ITEST_VERIFY_TIMEOUT}
ENVIRONMENT "${MGL_ITEST_VULKAN_VERIFY_SPLIT_ENVIRONMENT}"
)
list(APPEND MGL_VERIFY_SPLIT_TEST_LISTS MGL_VERIFY_SPLIT_TESTS_GLES
MGL_VERIFY_SPLIT_TESTS_GLES_VIEW MGL_VERIFY_SPLIT_TESTS_VULKAN)
# The arming assertion on this arm, one entry per backend, with a log path nothing else
# writes to - the monolith VerifyArming. entries' shape and their reason (the case reads the
# whole file, and a path shared with 500 neighbours races them under `-j 4`). This is the
# entry that cannot be green against a library with no comparator compiled in, and unlike the
# monolith pair it also cannot be green against one whose comparator never survived the
# server's bring-up - which is precisely what the relaxed respecify pin unblocked.
#
# MGITEST_PIPE_ARMING_LANE=1 is a harness marker the library never reads; it is what makes
# the case skip in an ambient lane rather than race there.
foreach(mglItestVerifyBackend DirectGLES DirectVulkan)
if (mglItestVerifyBackend STREQUAL "DirectGLES")
set(mglItestVerifyArmEnv "${MGL_ITEST_GLES_VERIFY_SPLIT_ENVIRONMENT}")
else()
set(mglItestVerifyArmEnv "${MGL_ITEST_VULKAN_VERIFY_SPLIT_ENVIRONMENT}")
endif()
gtest_discover_tests(MobileGLIntegrationTest
TEST_PREFIX "${mglItestVerifyBackend}.VerifySplitArming."
TEST_FILTER "PipeVerifyArmingScenario.Armed"
DISCOVERY_TIMEOUT 30
PROPERTIES
LABELS "integration-verify-split"
TIMEOUT ${MGL_ITEST_VERIFY_TIMEOUT}
ENVIRONMENT "${mglItestVerifyArmEnv}\;MGITEST_PIPE_ARMING_LANE=1\;MOBILEGL_LOG_FILE_PATH=${CMAKE_CURRENT_BINARY_DIR}/pipe-verify-split-arming-${mglItestVerifyBackend}.log"
RESOURCE_LOCK "pipe-verify-split-arming-${mglItestVerifyBackend}.log"
)
endforeach()
message(STATUS "Integration tests: P7 wave 3 - the verify comparator on the split (inproc) arm, "
"both backends, under integration-verify-split")
endif()
if (MOBILEGL_BUILD_DISAGGREGATED)
# LAST, so every mgl_itest_register_split_arms call above has already contributed its list
# name. Apply per-entry paths after GoogleTest discovery has populated the TEST_LISTs.
@@ -1,6 +1,7 @@
# Included by CTest after all GoogleTest discovery files (ID-53).
# CTest appends ENVIRONMENT here; keep all previously discovered lane settings.
file(MAKE_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/split-logs")
file(MAKE_DIRECTORY "@CMAKE_CURRENT_BINARY_DIR@/verify-split-logs")
# P5b t2's two lanes ride the same rule: one private log path per entry, or
# SplitLogPaths.PrivateAndDistinct is red for them (ID-53).
# P5e vi's client-array lane joins the same list for the same reason: its two entries are the
@@ -52,6 +53,25 @@ foreach(listName IN ITEMS @MGL_MAGMA_FULL_TEST_LISTS@)
endif()
endforeach()
endforeach()
# P7 wave 3 (V1): the verify comparator on the split arm. A LIST OF ITS OWN, like tier 3's and
# for tier 3's reason - the first loop also arms the strict-arming, pmap and server-counter lane
# markers by entry name, and this lane is here to compare fields, not to opt three unrelated
# oracles into a whole-binary set.
#
# THE PATH IS WHAT MAKES THE LANE ARMED RATHER THAN MERELY GREEN. These entries carry no
# MGITEST_SPLIT_LANE marker (MG_IntegrationTest/CMakeLists.txt says why: it reds 13 query-only
# cases that never move a verb), so the proof that the transport really resolved to inproc and
# that the comparator really armed is READ FROM THESE FILES by test.yml's verify-split job -
# ConfigLoader's `MOBILEGL_TRANSPORT=inproc` line and `MGPipe: verify armed`, per entry, in the
# CLIENT role's log. A shared path would make both unattributable, and under inproc the server
# role writes its own half of the same base name.
foreach(listName IN ITEMS @MGL_VERIFY_SPLIT_TEST_LISTS@)
foreach(entry IN LISTS ${listName})
set_tests_properties("${entry}" PROPERTIES ENVIRONMENT
"MOBILEGL_LOG_FILE_PATH=@CMAKE_CURRENT_BINARY_DIR@/verify-split-logs/${entry}.log")
endforeach()
endforeach()
foreach(entry IN LISTS MGL_SPLIT_PA_STRICT_DRAW_TESTS MGL_SPLIT_PA_STRICT_DISPATCH_TESTS)
set_tests_properties("${entry}" PROPERTIES ENVIRONMENT
"MOBILEGL_LOG_FILE_PATH=@CMAKE_CURRENT_BINARY_DIR@/split-logs/${entry}.log")