Testing
scrubctl uses fixture-based golden tests as its primary test strategy. The fixture files under testdata/fixtures/ are test inputs and expected outputs only. They are not runtime data used by the scrubctl binary.
Fixture Directories
Each directory under testdata/fixtures/ represents one resource scenario. Fixtures cover Deployments, StatefulSets, CronJobs, PVCs, Secrets, Services, Routes, and more.
Each fixture contains four files:
| File | Purpose |
|---|---|
input.yaml | A Kubernetes resource as it would appear from the cluster |
expected-classification.json | The expected classification result: include, cleanup, review, or exclude |
expected-sanitized.yaml | The expected sanitized resource after scrubctl strips defaults and server-assigned fields |
expected-archive.json | The expected archive output structure |
An optional fixture.json can override test defaults like secretHandling, namespace, or scannedAt.
Fixture Test Flow
TestFixturesMatchTSExpectations in internal/parity/parity_test.go auto-discovers fixture directories and runs each through the full pipeline.
Each comparison uses go-cmp/cmp.Diff. On failure, the test output shows exactly which fields differ between expected and actual output.
Sanitization Quality Test
TestSanitizationQuality in internal/sanitize/sanitize_quality_test.go runs every non-excluded fixture input through sanitization and checks invariants that must hold for all output.
Fixtures classified as exclude are skipped.
Structural Invariants
Every sanitized resource must satisfy these guarantees:
| Invariant | Examples |
|---|---|
| No server-assigned metadata | uid, resourceVersion, generation, creationTimestamp, managedFields, selfLink, ownerReferences |
| No status field | status is removed |
| No nested null timestamps | creationTimestamp: null is removed throughout the object tree |
| No empty default maps | Empty securityContext: {} and affinity: {} maps are removed |
Annotation Policy
The quality test enforces that these annotation prefixes never appear in sanitized output:
| Prefix | Why stripped |
|---|---|
kubectl.kubernetes.io/last-applied-configuration | Client-side apply bookkeeping |
pv.kubernetes.io/ | Volume provisioner runtime state |
volume.beta.kubernetes.io/ | Legacy volume annotations |
volume.kubernetes.io/ | Volume runtime annotations |
operator.openshift.io/ | OpenShift operator bookkeeping |
openshift.io/build. | OpenShift build annotations |
imageregistry.operator.openshift.io/ | Image registry operator state |
Updating Expected Outputs
When scrubctl behavior intentionally changes:
- Run
go test ./internal/parity/ -vto see fixture diffs. - Verify the diff is intentional.
- Update
expected-sanitized.yaml,expected-classification.json, andexpected-archive.json. - Run
go test ./....
When adding new fixtures, prefer inputs derived from real cluster resources and strip sensitive values before committing.