Skip to content

test(generator): pin that generating a spec twice gives the same bytes - #123

Merged
giraffesyo merged 1 commit into
canaryfrom
determinism
Aug 21, 2026
Merged

test(generator): pin that generating a spec twice gives the same bytes#123
giraffesyo merged 1 commit into
canaryfrom
determinism

Conversation

@giraffesyo

Copy link
Copy Markdown
Member

Generated clients are committed and reviewed, so output that shifts between runs shows up as churn in a diff nobody made. Nothing held that property, and the usual way to lose it is a map iterated on the way out.

TestGenerationIsDeterministic generates the corpus spec twice and compares the bytes.

The corpus needed enriching for the guard to mean anything

My first version passed while I was actively sabotaging the generator: I made uniqueErrorTypes round-trip through a map, and the test still passed, because the corpus had exactly one error type and iterating a one-entry map is stable however it is written.

The corpus now declares a second named error shape and one with no name of its own, and the same sabotage fails the test:

e2e_combinations_test.go:149: errors.go differs between two runs of the same spec

Both new error shapes also exercise paths worth having in the corpus: a second wrapper in one package, and the operation-derived naming from #61 for a body with no type name.

Current state

Generation is already deterministic: ACTIVATE, GitHub, Stripe, Mealie, and the corpus each produce byte-identical output across repeated runs, so this adds no fix. It stops the property from being lost quietly.

gofmt, golangci-lint, go vet ./..., and go test ./... pass.

Generated clients are committed and reviewed, so output that shifts between
runs shows up as churn in a diff nobody made. Nothing held the property, and
the usual way to lose it is a map iterated somewhere on the way out.

Generating the corpus spec twice and comparing the bytes holds it. The five
real specs I have are deterministic today, so this adds no fix.

The corpus gains a second named error shape and one with no name of its own,
which the guard needed: with a single error type in the package, iterating
the map that holds them is stable however it is written, and the test could
not fail. With two, disabling the ordering makes it fail on errors.go, which
is what a guard has to do to be worth having.
@giraffesyo
giraffesyo merged commit feead27 into canary Aug 21, 2026
7 checks passed
@giraffesyo
giraffesyo deleted the determinism branch August 21, 2026 20:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant