Skip to content

ci: the --output render path has no CI coverage beyond the engine id #201

Description

@TMHSDigital

The gap

Smoke runs each example's default check path. The --output render path is exercised only at authoring time, on one version, by the author. A version-dependent render bug is therefore invisible to CI by construction — which is how an inverted EEVEE engine id shipped in two showcase pieces and survived until someone tried to render on 5.x.

tests/check_engine_id.py now closes the engine-id part of that gap at zero cost: it evaluates all 84 mappings in the tree against both eras. It does not cover the rest of the render path — the framing helper, material and node wiring, normal-map hookup, image write.

Why a render canary was not added

Measured on this machine, showcase/shipping-crate --output, wall-clock for the whole process including the check path:

Engine 4.5.11 5.1.2 5.2.1 Render-only delta
EEVEE (default) 2 914 ms 4 004 ms 3 515 ms 1 152 / 1 889 / 1 890 ms
Cycles, 32 samples CPU 14 449 ms — 12 559 ms ~11 000 / ~10 900 ms

Check-only baseline for the same piece: 1 762 / 2 115 / 1 625 ms.

Two things block the obvious version of this:

1. The cheap canary does not cover the motivating class. EEVEE at ~1.2–1.9 s per version is nearly free, but blender-smoke.yml deliberately does not render EEVEE. Its own comment says why:

Cycles (CPU) so this is reliable on GPU-less runners; the EEVEE-id regression itself is gated in run_smoke.py via engine assignment.

and in tests/smoke/run_smoke.py:

Render the non-black frame with Cycles (CPU): reliable on GPU-less headless runners, where an EEVEE GPU render aborts the process (no EGL).

2. The covering canary is the expensive one. Cycles is the engine CI can rely on, and Cycles never touches the EEVEE id — so a Cycles canary would not have caught either inversion. It costs ~11 s per version locally for a single piece, against a current showcase-suite total of 20.9 s on 5.2.1. GitHub runners are slower than this machine, so the real figure is plausibly 2–4× that, which would put one canary at or past the ~30 s per-version budget on its own.

So the cheap option does not cover, and the covering option is not cheap — and neither covers the class that motivated the work, because check_engine_id.py already does that better and for free.

What a canary would still buy

Everything in the render path that is not the engine id:

  • gallery_framing.check_framing — the exit-10 gate, including its matte render
  • normal-map node wiring (wire_normal) and material assignment at render time
  • image write and the webp/png format branch
  • anything that only touches bpy.ops.render.render

None of that is covered today on any version.

Options, if this is picked up

  1. Cycles canary on one piece, one version only (not per version). ~11 s once rather than three times. Catches non-engine render-path breakage; catches nothing version-specific.
  2. Add a resolution override to showcase pieces so a canary can render at, say, 320×180. The scripts hardcode 1280×720; examples/swatch-grid already takes --width, so there is precedent. Would make a per-version Cycles canary affordable, at the cost of touching 28 scripts.
  3. Establish whether EEVEE actually aborts on current runners. The Cycles-only decision is documented but the comment does not carry a date or a measurement. If EEVEE works on today's ubuntu-latest with the libraries the workflow already installs, the ~1.9 s per-version canary becomes available and covers the engine id too.

Option 3 is the one worth measuring first, because it is the only one that makes the cheap canary viable.

Not blocking

The engine-id class — the one that actually shipped a bug twice — is covered as of tests/check_engine_id.py. This issue is about the remainder.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    citestingTest harness and CI test coverage

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions