Skip to content

test(sdk): single-source verdict fixtures across Go + Python (#368)#398

Merged
trilamsr merged 1 commit into
mainfrom
sdk-368-codegen-verdict-fixtures
Jun 1, 2026
Merged

test(sdk): single-source verdict fixtures across Go + Python (#368)#398
trilamsr merged 1 commit into
mainfrom
sdk-368-codegen-verdict-fixtures

Conversation

@trilamsr

@trilamsr trilamsr commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Shipped-pattern verdict fixtures lived in three places — module/sdk/verdict/decode_test.go (Go SDK), python/tracecore_verdict/test_decode.py (Python SDK), and module/pkg/patterns/verdict_envelope_schema_test.go (envelope schema test) — each as a hand-rolled literal. Adding a pattern verdict at rc1 or v0.4 meant editing three places in lockstep; drift was inevitable (and we've already been bitten by SDK-schema drift on the $id field).

Replace the three literals with one canonical JSON file at docs/schemas/fixtures/shipped-patterns-v1.0.0-rc1.json. All three test sites parametrise off it at test time. Adding a pattern verdict is now a one-file edit — drift is impossible by construction.

Root cause

PR #356 cut the v1.0-rc1 SDKs (criterion 12) by duplicating the shipped-verdict fixture set across Go SDK + Python SDK + envelope schema test. There was no canonical artifact for "the v1.0-rc1 shipped-verdict set"; each test author rewrote the list. This PR creates that artifact and converts each test site to a consumer.

Why not code-gen?

The issue title says "code-gen" but the simpler primitive is runtime-load: both languages parse JSON natively, so a generator step adds zero safety beyond os.ReadFile/Path.read_text, and runtime-load eliminates the "generated file out of sync with source" failure mode. The existing generate-fixtures Make target codes-gen .pkl binary fixtures (where parse-at-test-time wouldn't work); JSON does not need that machinery.

CI gate (make verdict-fixtures-check)

Wired into make verify (pre-push) and make ci-full (everything CI runs). It asserts:

  1. The canonical file exists at docs/schemas/fixtures/shipped-patterns-v1.0.0-rc1.json.
  2. Each of the three consumer test files still references the canonical path by string — a reintroduced hand-rolled literal in any site trips this guard.
  3. Both SDK suites + the envelope-schema canonical-fixtures subtest round-trip the fixture set green.

Mutation-verified locally: deleting the canonical file fails the gate; dropping the reference from any consumer fails the gate.

The envelope test gains a new subtest TestVerdictEnvelopeV1RC1_CanonicalShippedFixturesValidate that validates every canonical fixture against the published envelope schema — closing the loop so an envelope-non-conforming fixture would fail before either SDK suite runs.

Diff shape

Net: -204 deletions / +332 insertions (the canonical JSON file is +146; the rest is the new envelope-validation subtest + Make target + README rows; over 100 lines of duplicated fixture literals deleted).

Test plan

  • make verdict-fixtures-check green
  • make verdict-fixtures-check red when canonical file deleted (mutation test)
  • make verdict-fixtures-check red when any consumer drops the reference (mutation test)
  • cd module && GOWORK=off go test ./sdk/verdict/ ./pkg/patterns/ -count=1 green
  • cd python/tracecore_verdict && python3 -m pytest . green (22/22)
  • golangci-lint run ./module/sdk/verdict/... ./module/pkg/patterns/... clean on touched files
  • Pre-push hook (vet, mod-verify, attribute-namespace-check, no-autoupdate-check) clean
sdk: shipped-pattern verdict fixtures consolidated to a single canonical file at `docs/schemas/fixtures/shipped-patterns-v1.0.0-rc1.json`; the Go SDK, Python SDK, and envelope schema tests now consume it directly. Adding a new pattern verdict is a one-file edit. `make verdict-fixtures-check` is the CI drift gate (issue #368).

Closes #368

Shipped-pattern verdict fixtures lived in three places — the Go SDK
decode test, the Python SDK decode test, and the envelope schema
test — and had to be hand-synced. Drift was inevitable.

Replace the three literal fixture sets with one canonical JSON file
at docs/schemas/fixtures/shipped-patterns-v1.0.0-rc1.json. All three
test sites parametrise off it at test time. Adding a pattern verdict
is now a one-file edit.

New CI gate `make verdict-fixtures-check` asserts the canonical file
exists, every consumer still references it by path, and all three
test sites round-trip the fixture set green. Wired into `verify` and
`ci-full`. Mutation-verified — deleting the canonical file fails the
gate, and dropping a reference from any consumer fails the gate.

Net diff: -204 / +176 (over 100 lines of duplicated fixture literals
eliminated).

Signed-off-by: Tri Lam <tri@maydow.com>
@trilamsr trilamsr enabled auto-merge (squash) June 1, 2026 22:16
@trilamsr trilamsr merged commit 2bdf453 into main Jun 1, 2026
23 checks passed
@trilamsr trilamsr deleted the sdk-368-codegen-verdict-fixtures branch June 1, 2026 22:21
trilamsr added a commit that referenced this pull request Jun 1, 2026
## Summary

Audit issue #421 finding-2 root-fix. PR #398 landed the canonical
v1.0-rc1 SDK fixture at
`docs/schemas/fixtures/shipped-patterns-v1.0.0-rc1.json` with five rows
carrying wrong `pattern.id` values — the fixture was hand-typed by
sequential counter (..14, 15, 16, **17, 18, 19, 20, 21**) instead of
being copied from the `PatternID*` constants in
`module/pkg/patterns/*.go`. The envelope schema only constrains
`pattern.id` to `type:string, minLength:1`, so per-pattern envelope
tests round-tripped the drift silently.

### Before / after pattern.id

| fixture row | before | canonical (`module/pkg/patterns/*.go`) |
|---|---|---|
| `hbm_ecc` | `"17"` | `PatternIDHBMECC = "3"` |
| `thermal_throttle` | `"18"` | `PatternIDThermalThrottle = "4"` |
| `pcie_aer` | `"19"` | `PatternIDPCIeAER = "5"` |
| `cuda_oom` | `"20"` | `PatternIDCUDAOOM = "10"` |
| `ib_link_flap` | `"21"` | `PatternIDIBLinkFlap = "2"` |

`pod_evicted` ("14"), `nccl_hang` ("15"), `xid_correlation` ("16"),
`silent_data_corruption` ("13") were already correct.

### Scoped-keys delta

The `ib_link_flap` row also used unscoped `"node"` while
`IBLinkFlapVerdict.Node` serializes as `"k8s.node.name"`
(customer-stable namespace per `docs/ATTRIBUTES.md` line 152-154 +
`docs/patterns/pattern-2-ib-link-flap.md`). Renamed in the fixture to
mirror what the Go struct actually emits. The other unscoped keys on
this row (`hca_device`, `port`, `transition_count`) match the Go
struct's `json:"..."` tags as-is — those are the **envelope** key names;
the operator-facing dashboard scoped names
(`tracecore.alert.ib_link_flap.transition_count`,
`hw.network.ib.device`, `hw.network.ib.port.num`) are the OTel
log-record attributes the processor promotes alongside the JSON payload,
a separate surface.

### Drift-prevention test

`TestCanonicalShippedFixtures_PatternIDsMatchDetectorConsts` in
`module/pkg/patterns/verdict_envelope_schema_test.go` pins each fixture
row's `pattern.id` to the `PatternID*` const in the detector package and
asserts symmetry (every const has a fixture, every fixture matches a
const). Confirmed RED with the buggy fixture (5 failures matching the
audit prediction exactly), GREEN after the fix.

```release-notes
Correct `pattern.id` values for five rows in the v1.0-rc1 canonical SDK fixture and add a drift-prevention test pinning fixtures to detector-package constants.
```

Refs #421
Refs #398

## Test plan

- [x] `go test ./pkg/patterns/...` PASS (new test + existing envelope
suite)
- [x] `go test ./sdk/verdict/...` PASS (Go SDK round-trip)
- [x] `python3 -m pytest python/tracecore_verdict/test_decode.py` 22/22
PASS
- [x] `make vet` clean
- [x] `make lint` 0 issues
- [x] RED→GREEN cycle confirmed on
`TestCanonicalShippedFixtures_PatternIDsMatchDetectorConsts`
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.

[sdk] code-gen verdict fixtures across Go + Python suites

1 participant