test: make single-task job fixtures assert their own output - #174
Open
leongdl wants to merge 2 commits into
Open
test: make single-task job fixtures assert their own output#174leongdl wants to merge 2 commits into
leongdl wants to merge 2 commits into
Conversation
Signed-off-by: David Leong <leongdl@amazon.com>
Signed-off-by: David Leong <leongdl@amazon.com>
leongdl
force-pushed
the
conformance-single-task-self-assert
branch
from
August 15, 2026 19:45
e26ba4d to
bc609e1
Compare
mwiebe
requested changes
Aug 18, 2026
| - name: OpenJDConformanceAssert | ||
| type: TEXT | ||
| data: | | ||
| # Self-asserting conformance wrapper. Runs `sys.argv[1:]` -- this case's original |
Contributor
There was a problem hiding this comment.
Almost the whole diff appears to repeat this boilerplate. This likely reduces the readability of these tests for someone casually browsing these files. Are there other ways we could approach this?
Contributor
Author
There was a problem hiding this comment.
Yeah, thanks to claude Fable :) I have a new steering prompt to DELETE all this cruff.
Sorry I have not had time to review this one but it is necessary to make the tests robust and useful for backend.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed
187 single-task job fixtures across
base,EXPR,FEATURE_BUNDLE_1andREDACTED_ENV_VARSnow assert their own output, andrun_openjd_cli_tests.pynowrequires a valid job test to exit
0.1160 passed, 0 failed on openjd-rs and on openjd-cli 0.7.6. The diff is purely
additive: 187 files, +7856, −0.
Why
expected.outputis only checkable by a runner that can read the implementation'sstdout. An implementation that can only observe task status — a service rather than
a CLI whose pipe the runner holds — gets "a task ran and exited 0", not "it produced the
right answer".
{{Param.Version}}resolving to2.0instead of1.0exits 0 andpasses.
Each instrumented case's
onRuntakes one leading argument, anOpenJDConformanceAssertembedded file, followed by its original command and args:The wrapper runs
sys.argv[1:], echoes the output verbatim, compares it againstliterals baked into itself, and exits non-zero on mismatch.
expected.output/expected.forbiddenare untouched, so a log-scanning runner is unaffected — bothmechanisms now check the same thing by different means.
In-idiom rather than new:
expected.taskFailurealready lets exit status carry averdict.
928 of 1554 declared assertion lines are now checked inside the task:
baseEXPRFEATURE_BUNDLE_1REDACTED_ENV_VARSWRAP_ACTIONSTASK_CHUNKINGWhy the argv is passed through rather than embedded
Embedding the original argv in the wrapper's source works for
baseand would havequietly gutted several EXPR cases.
expr1.3.2--list-flattens-in-argsassertsARG0:--width…COUNT:10; its subject is how the implementation expands an argslist, flattening a list value into separate arguments and skipping a null one. Freezing
argv into the wrapper moves that expansion from the implementation into the fixture, so
the case keeps passing while testing nothing.
Passing argv through leaves the expansion where it belongs, and removes every escaping
hazard embedding had.
Two false passes found on the way
The runner never checked exit status for a valid case. A mutation probe — corrupt
what the job prints, leave the expected literal alone — passed:
Two independent causes, both fixed. The runner ignored
returncodewhen noexpected.taskFailurewas declared, so the verdict rested entirely on substringmatching; and the wrapper's diagnostic echoed the expected literal, so the log scan
matched the error message. Diagnostics now report
expected output line 1 of 2 not foundand never the text. The probe reports✗on both CLIs now.The exit-status requirement is a hole in the shared runner independent of the fixtures,
so it is a separate commit.
46 wrappers that never ran. All 47 instrumentable
WRAP_ACTIONScases passed afterinstrumentation, then the success marker showed 46 of them had not executed the wrapper
at all:
onWrapTaskRunreplaces the task action, so a hook likeargs: ["-c", "print('TIMEOUT={{WrappedAction.Timeout}}')"]never runsWrappedAction.Command. Shipping those would have added verification that looks presentand cannot fail — the same failure one layer up.
WRAP_ACTIONSis excluded wholesale.That is what
OPENJD_CONFORMANCE_ASSERT_OK: <n> expected, <m> forbiddenis for, and whyit is worth keeping.
Deliberately left status-only
4--openjd-redacted-envexpectsSECRET_IS:********, the implementation's redaction of what the task printed. The task sees the real value.unset-takes-precedenceis the one that does self-assert, because there the variable really is unset.7.3--env-file-referenceasserts a line printed by a job environment'sonEnter; its task prints something else.WRAP_ACTIONSwrap-no-argsWrappedAction.Argssurfaces as an empty list when the action has no args. Adding an argument changes the subject. Encoded as a rule: an action with no args is never instrumented.expected.taskFailurecasesEvery one of these except the first was found by instrumenting the case and watching it
fail, or watching it pass without asserting — not by reading the fixture.
Testing
2023-09/*2023-09/*✗on both;✓before the fixesexpectedpreservedThe 7 not confirmed are Windows-only and skipped on a POSIX host
(
7.3--path-param-mapping-windows,7.3--rawparam-no-mapping-windows, fourexpr2.3.2--uri-*-windows,6.1--end-of-line-auto-windows). Each has a POSIX siblingthat passes and differs only in which literal list the wrapper selects, so the risk is
low — but they are genuinely unverified until CI runs them on
windows-latest.