CNA-BUG-202: In a multi-renderer build, non-default renderers' example CTests are registered but run under the default renderer
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
modules/renderers/CMakeLists.txt— per-family loop re-points CNA_GRAPHICS_RENDERER while entering each familymodules/renderers/sdl-gpu/examples/CMakeLists.txt— block guard on CNA_GRAPHICS_RENDERER STREQUAL SDL_GPU onlymodules/renderers/software/examples/CMakeLists.txt— block guard and the non-default include/link fix in cna_software_testmodules/renderers/stub/examples/CMakeLists.txt— block guard on CNA_GRAPHICS_RENDERER STREQUAL STUB onlymodules/renderers/stub/examples/stub_smoke_test.cpp— Draw: static_cast of the device renderer to StubRenderer&modules/renderers/vulkan/examples/CMakeLists.txt— block guard on CNA_BUILD_EXAMPLES, CNA_BUILD_TESTS and the identitymodules/renderers/headless/examples/CMakeLists.txt— the contrasting _cna_default_renderer_identity guard (VKPAR-0003)cmake/TestHelpers.cmake— cna_register_renderer_test sets no renderer selectionCMakePresets.json— multi-renderer preset: HEADLESS;SOFTWARE;STUB with HEADLESS as defaultmodules/renderers/opengl4/examples/opengl4_smoke_test.cpp— GL4-0035 run-time skip under another renderer
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.
Related pages
The same subject is explained at several altitudes. These are the neighbouring pages at each one.
- User guide
- Runtime renderer selection: build modes
- Internals
- Renderer selection internals: runtime policy · SOFTWARE renderer internals: tests · STUB renderer internals: tests
- Maintainer workflow
- Change the build configuration: renderer rules
- Tests and validation
- Test architecture: GPU tests
- Known issues
- Bug index