test(381): golden coverage for Sequential (YAML) playout builder; document Scripted deferral
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 28s
PR Gates / Docs update reminder (pull_request) Successful in 46s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m53s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 17s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 18s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m29s
PR Gates / decisions lifecycle (pull_request) Successful in 18s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 21m0s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
PR Gates / CI image pin matches docker/ci (pull_request) Successful in 28s
PR Gates / Docs update reminder (pull_request) Successful in 46s
Build ErsatzTV Image / Build & test (.NET) (pull_request) Successful in 7m53s
Build ErsatzTV Image / API docs in sync (OpenAPI + endpoint index) (pull_request) Successful in 17s
Build ErsatzTV Image / Formatting (changed .cs conform to .editorconfig) (pull_request) Successful in 18s
Build ErsatzTV Image / Functional E2E (curl contracts) (pull_request) Successful in 5m29s
PR Gates / decisions lifecycle (pull_request) Successful in 18s
Build ErsatzTV Image / EF migration integrity (SQLite + MySql) (pull_request) Successful in 21m0s
Build ErsatzTV Image / Build & push image (amd64) (pull_request) Has been skipped
Extends the #163 PlayoutBuildGoldenTests in-memory net to the Sequential (YAML) builder: a committed fixture (Goldens/Fixtures/sequential-schedule.yml) with two `count: 2` instructions over one chronological collection, built via SequentialPlayoutBuilder over the pinned window. The count/all/duration handlers do UTC-only arithmetic off the caller-supplied start, so the case is TZ-independent (passes, not skips, under a non-UTC TZ) and needs no Assume guard. Non-vacuity: a fixture count tweak flips the golden + the contiguity assertion. Scripted is deliberately excluded from the golden net — ScriptedPlayoutBuilder shells out via Cli.Wrap to an external process that drives SchedulingEngine over HTTP, which no in-memory golden can characterize. Recorded as the Done-when "documented decision" arm in docs/decisions.md (testing.scripted-playout-golden-deferred) + docs/testing.md; the scripted integration harness is tracked as follow-up #563. fixes #381 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -3473,3 +3473,31 @@ enabled`) because `/iptv/*` does not accept the SPA's `ctv-session` cookie and n
|
||||
for the browser. #552 closed that: the SPA now mints a short-lived token and appends it as
|
||||
`?access_token=`, so this projection no longer inspects JWT status at all. See
|
||||
`security.iptv-browser-token`.
|
||||
## 2026-07-22 — Sequential (YAML) playout gets a golden; Scripted is excluded from the golden net by construction (#381)
|
||||
|
||||
`key: testing.scripted-playout-golden-deferred` · `status: active` · `since: 2026-07-22` · `supersedes: none` · `superseded-by: none`
|
||||
**Rule:** The `PlayoutBuildGoldenTests` in-memory golden net covers Sequential (YAML) as of #381, but Scripted playout is deliberately excluded from it — Scripted shells out to an external process that calls back over HTTP, which no in-memory golden can characterize; its integration harness is tracked separately.
|
||||
**Signals:** why is there no scripted golden; SequentialPlayoutBuilder golden; scripted playout is not deterministic in-process; Cli.Wrap external process; SchedulingEngine HTTP callback · paths: `ErsatzTV.Core.Tests/Scheduling/Goldens/PlayoutBuildGoldenTests.cs`, `ErsatzTV.Core.Tests/Scheduling/Goldens/Fixtures/sequential-schedule.yml`, `ErsatzTV.Core/Scheduling/ScriptedScheduling/ScriptedPlayoutBuilder.cs`, `ErsatzTV.Core/Scheduling/YamlScheduling/SequentialPlayoutBuilder.cs` · issues: #381, #163, #563
|
||||
**Mechanics:** docs/testing.md → Golden-file nets
|
||||
|
||||
**Sequential (YAML) is golden-able and TZ-independent.** `SequentialPlayoutBuilder` reads a YAML schedule
|
||||
file (`Playout.ScheduleFile`) rather than a `ProgramSchedule`/Block calendar, but it is still a pure
|
||||
in-process build: content resolves from an in-memory-SQLite `Collection` by name, and the `count`/`all`/
|
||||
`duration` handlers do UTC-only arithmetic off the caller-supplied `start`. So the `Sequential_yaml` case
|
||||
uses the exact same harness as Classic/Block — a committed input fixture
|
||||
(`Goldens/Fixtures/sequential-schedule.yml`) with two `count: 2` instructions over one `chronological`
|
||||
collection — and needs **no** `Assume`/TZ guard (verified: it passes, not skips, under a non-UTC `TZ`,
|
||||
unlike Block). The fixture deliberately avoids the local-time-of-day handlers (`wait_until`, `pad_to_next`,
|
||||
`pad_until`) and shuffle order, which would reintroduce TZ- or seed-dependence. The builder checks the
|
||||
file via the injected `IFileSystem` but reads bytes with the static `System.IO.File`, so the test commits a
|
||||
real fixture on disk and stubs only `IFileSystem.File.Exists`; the JSON-schema validator is stubbed (it
|
||||
loads its schema from a runtime cache folder, irrelevant to characterizing builder output).
|
||||
|
||||
**Scripted is not golden-able.** `ScriptedPlayoutBuilder` builds nothing in-process: it `Cli.Wrap`-executes
|
||||
an external script process that drives `SchedulingEngine` over `http://localhost:{Settings.UiPort}`. An
|
||||
external-process + HTTP-callback flow cannot be pinned by the in-memory golden harness (shared SQLite, no
|
||||
I/O, deterministic clock). The deterministic core the scripts drive (`SchedulingEngine`) is in-process and
|
||||
unit-testable — there is a seed `SchedulingEngineTests` — but the scripted *builder* is process orchestration
|
||||
plus HTTP transport, i.e. integration-test territory. Rather than force a golden onto it, the scripted
|
||||
integration harness is deferred to **#563**; this is the Done-when-sanctioned "documented decision" arm of
|
||||
#381, not an omission.
|
||||
|
||||
Reference in New Issue
Block a user