7.3 KiB
Design
Context
See proposal.md — Why for the observed split. The pieces that shape the approach:
entrypoint.sh(apply_printer_options, lines ~341–383) validates everykey=valueagainstlpoptions -p <queue> -land then callslpadmin -p <queue> -o <opt>, loggingqueue default <opt> appliedon exit status 0. Exit status is the only signal it has, andlpadminreturns 0 even when the setting does not take effect.- The queue's settings are persisted in the queue's PPD copy
/etc/cups/ppd/<queue>.ppd(*DefaultTonerSaveMode: True,*DefaultBRColorMode: None), not asprinters.confDefault*lines; with this CUPS the settings file alone therefore cannot distinguish "applied" from "accepted and dropped". - Confirmed in two containers (manual
lpadmin -oand the entrypoint's own startup batch): afterlpadmin -o TonerSaveMode=Truethe PPD copy saysTrue, whilelpoptions -p <queue> -lkeeps showingTonerSaveMode/Toner Save: *False True;BRColorModein the same batch is consistent (PPD copyNone,-l*None). TonerSaveModeis a Boolean PPD option (assets/.../BR4150_2.PPD line 327) whoseTruebranch emitsstatusdict/tonersave known{statusdict begin true tonersave end}if; the sixAPPrinterPresetentries set*TonerSaveMode True|Falsefor draft/normal/high, which is how the documented driverless draft behaviour is implemented.- The rejected observation point:
lpoptions -p <queue>without-llists only IPP queue attributes, so it never shows PPD option defaults. The archivedfix-colour-defaults-and-client-optionsverification usedlpoptions -p <queue> -l(correct), and therevert-colour-mode-defaulttask 3.2 command was corrected to match during apply. - The repo has no test suite yet; the job-level check introduced here is a
self-contained script that drives
podman, a placeholderPRINTER_IPand a minimal hand-written PostScript/PDF sample (no sample fixtures exist in the repo), so it stays runnable without a printer and without network access to a real device.
Goals / Non-Goals
Goals:
- Determine whether a job actually receives an applied
TonerSaveModequeue default, from the emitted PostScript, not from settings files. - Turn the runtime-queue-default requirement into one that a job-level test can falsify, so the same class of "accepted but ineffective" defect cannot pass again.
- Leave the spec honest: a verified behaviour becomes the scenario; a verified limitation is recorded instead of an aspiration.
Non-Goals:
- Changing
entrypoint.shvalidation/plumbing unless the investigation identifies a fixable server-side cause. - Re-testing the colour-saturation limitation (documented by
revert-colour-mode-default) or re-openingBRColorModebehaviour, which is verified. - Adding job-level assertions for every PPD option; the example in the
requirement (
BRColorMode+TonerSaveMode) is the coverage.
Decisions
D1 — Observation point for queue defaults: lpoptions -p <queue> -l
(asterisks) plus the queue PPD copy; never lpoptions -p without -l.
Rationale: -p without -l shows IPP queue attributes only (see Context) and
produced a false negative during revert-colour-mode-default. -l reflects the
option the queue would use; the PPD copy shows what was persisted. Both are
still configuration views, so they are used only to set up and cross-check a
scenario, never as the acceptance signal.
Alternatives considered: printers.conf Default* lines (absent with this
CUPS — rejected); the CUPS web admin page (same settings source, needs auth —
rejected); lpstat -l -p (no option detail — rejected).
D2 — Acceptance signal is the emitted PostScript spooled by cupsd.
Rationale: it is the only artefact that shows what the printer receives, it
covers presets, queue defaults and per-job options in one channel, and the
existing spec already reasons in those terms (<</UseCIEColor false>>). The
spool file is the last file in /var/spool/cups/d<JobId>-* (its name comes from
the preceding lpstat -W completed -o line), and is readable as root inside the
container for a few minutes while the socket connection to the placeholder
PRINTER_IP fails.
Alternatives considered: asserting on lpoptions -l alone (that is exactly the
blind spot being fixed — rejected as the acceptance signal, kept as setup
cross-check); parsing the source /usr/share/cups/model/BR4150_2.PPD in the
image (proves packaging, not the job — rejected); a throwaway CUPS-side hook or
debug logging (more moving parts than one file read — rejected).
D3 — Investigate before specifying the TonerSaveMode outcome.
Rationale: the change must not encode an unverified assumption. Task group 1
runs the probe and records the result (spool PostScript, -l state, and — for a
second data point — an explicit per-job -o BRColorMode=Vivid in the same job
that must visibly differ from the queue default None). If the queue default
does reach the job, the scenario as written stands. If it does not, the
investigation result is added to this design and the scenario is reworded to the
verified behaviour plus an explicit limitation note before the checkboxes for
task group 2/3 are ticked.
Alternatives considered: writing the scenario as aspirational and letting the
test fail until someone fixes it (leaves a red suite and an untrue spec —
rejected); downgrading the scenario up front to "the PPD copy is written"
(keeps the blind spot — rejected).
D4 — Prefer a PostScript-text assertion over a rendered/printed test. Rationale: it is deterministic, needs no printer, and is CI-friendly. A physical print (toner save visibly lighter) stays a human check and is not part of the automation. Alternatives considered: rasterising the output and comparing image statistics (flaky, tooling-heavy — rejected).
D5 — TonerSaveMode is compared against the vendor False default, not the
preset wiring. Rationale: the requirement asserts the queue default path;
whether a client preset overrides it is the separate, already documented
driverless scenario. Both must remain visible in the emitted PostScript, which
the test checks by applying the documented PRINTER_OPTIONS example.
Risks / Trade-offs
- The spool file is lifetime-bounded (retention) and the test container's job
never reaches a printer, so the test must read the file soon after submission
and tolerate
connection refusedstate messages; if it races, the preferred per-job capture iscupsfilter <sample.pdf>inside the container with the same PPD, which produces the same PostScript text without a queue. lpadmin -obehaviour is option- and CUPS-version-specific; the test must state the CUPS version it was verified against so a future base-image bump does not silently reinterpret the assertion.- If the investigation finds the drop is a CUPS/driverd quirk with no image-side
fix, the change still lands value (honest spec + regression guard) but leaves
TonerSaveModeas a documented limitation; that outcome must be reported, not absorbed. - Boolean
TonerSaveModeis the same option the draft presets tune, so a future preset change can mask a broken queue default; the job-level test deliberately submits a job withoutprint-quality/preset attributes to keep the two paths separate.