CNA-BUG-202: In a multi-renderer build, non-default renderers' example CTests are registered but run under the default renderer

CNA snapshot 009d40f5  ·  Known Issues › Current bugs  ·  source links pinned to 009d40f5

✓

Evidence basis: source-verified at the pinned commit; tests exist (not executed for this page). Claims on this page were checked by reading the CNA source at commit 009d40f5; unless a sentence says otherwise, nothing here was built or executed. Nothing on this page was executed unless the Evidence section says so.

The SDL_GPU, SOFTWARE, STUB and VULKAN example blocks are entered for a non-default member of CNA_GRAPHICS_RENDERERS, yet their registrations select no renderer, so each executable runs under the build default.

Identifier
CNA-BUG-202
Category
Bug
Subsystem
Testing & evidence
Status
Open
Verified against
CNA 009d40f5 (009d40f5dd085c4e674d3479675fac84b12b3e0a)
Severity
Medium (a triage suggestion, not a project priority)
Evidence basis
Source-verified: read at TARGET, not executed
Tests touching this area
Yes: see Current tests
Affected contract
Renderer example CTests (SdlGpu_*, Software_*, Stub_Smoke, Vulkan_*) in a CNA_GRAPHICS_RENDERERS build, including CNA's multi-renderer preset

Expected behaviour

A CTest named for a renderer tests that renderer. CNA already enforces this for three families: the HEADLESS and EasyGL example blocks are entered only when that family is the build default (_cna_default_renderer_identity, VKPAR-0003), and GL4-0035 made the OpenGL4-only examples skip unless the device actually runs OPENGL4, after a static_cast to the wrong renderer crashed in a multi-renderer tree.

Actual behaviour at TARGET

modules/renderers/CMakeLists.txt re-points CNA_GRAPHICS_RENDERER to each family's identity while entering it, and the SDL_GPU, SOFTWARE, STUB and VULKAN example files guard only on CNA_GRAPHICS_RENDERER STREQUAL "<identity>" (VULKAN also on CNA_BUILD_EXAMPLES), so their blocks are entered for a non-default member. cna_register_renderer_test adds no CNA_GRAPHICS_RENDERER environment and the executables call no SetPreferred, so each runs under the build default. In CNA's multi-renderer preset (HEADLESS;SOFTWARE;STUB, default HEADLESS, tests on by default) Stub_Smoke runs on HEADLESS, static_casts the HEADLESS renderer to StubRenderer& (undefined behaviour) and, because HEADLESS also opens no window and initialises no SDL video, can pass while testing nothing of STUB; the Software_* suite runs its CPU-rasterizer assertions against HEADLESS. The SOFTWARE block even links cna_renderer_software for exactly this non-default case without selecting the renderer. Most other families' example files use the same identity-only guard.

Source locations

Evidence

Checked by reading at 009d40f5; no multi-renderer build was configured or run for this entry. CNA's CI multi-renderer jobs build named targets (CnaTests, the selection demo) and run CnaTests and CnaRendererDefaultSelection_* only, so the misattributed example CTests do not run there; they are registered in any local multi-renderer tree and run by a plain ctest. scripts/run-all-renderer-smoke-tests.sh --multi sets CNA_GRAPHICS_RENDERER per renderer itself, which is CNA's documented way to smoke-test several renderers from one build (docs/runtime-renderer-selection.md). The GL4-0035 change records the analogous OpenGL4 failure: an unconditional cast to OpenGL4Renderer was undefined behaviour when a multi-renderer tree selected EasyGL at run time, and crashed.

Focused reproduction

# Not executed for this entry.
cmake --preset multi-renderer
cmake --build cmake-build-multi --target cna_test_stub_smoke
ctest --test-dir cmake-build-multi -R '^Stub_Smoke$' --output-on-failure   # runs under HEADLESS

Current tests

CnaRendererDefaultSelection_* checks that the default is a member of the set, and CI proves each compiled-in renderer is reachable through cna_demo_renderer_selection; nothing checks that a renderer-named example ran on that renderer.

Regression test

Either guard each family's example block on _cna_default_renderer_identity as HEADLESS and EasyGL do, or have cna_register_renderer_test add CNA_GRAPHICS_RENDERER=<identity> to each registration's environment (the smoke script's mechanism), plus a configure-time check that in the multi-renderer preset every registered Stub_* and Software_* test carries its renderer selection.

Blast radius

Evidence produced by local multi-renderer trees, including CNA's own multi-renderer preset and sets such as OPENGLES3;VULKAN;SOFTWARE;HEADLESS;STUB: renderer-named example results describe the default renderer (false passes such as Stub_Smoke, false failures in suites that read pixels or cast the renderer). Single-renderer builds, CnaTests and the HEADLESS and EasyGL example blocks are unaffected.

Workaround

Run such examples with CNA_GRAPHICS_RENDERER=<identity> in the environment, as scripts/run-all-renderer-smoke-tests.sh --multi does, or collect renderer evidence from a single-renderer build.

The same subject is explained at several altitudes. These are the neighbouring pages at each one.

Tests and validation
Test architecture: GPU tests
Known issues
Bug index