Scaffolding Tests
ork simulate init runs the reconciler once against your Katalog and CR, captures the cycle-1 create operations, and writes a simulate.yaml pre-filled with expect: rules. You get a working assertion file without writing anything from scratch — edit and refine from there.
Basic usage
# katalog.yaml and cr.yaml in the current directory
ork simulate init
# Non-standard filenames
ork simulate init -f my-operator.yaml --cr my-cr.yaml
# Overwrite an existing simulate.yaml
ork simulate init --force
--dry-run prints to stdout without writing the file — useful for previewing before committing:
ork simulate init --dry-run
apiVersion: orkestra.orkspace.io/v1
kind: Simulate
metadata:
description: Generated by ork simulate init — edit to refine
name: my-operator-sim
spec:
cr: ./cr.yaml
cycles: 5
expect:
noErrors: true
ops:
- cycle: 1
name: my-app
resource: deployments
verb: create
# absent: # ops that must NOT appear — fill in for failure-path coverage
# - cycle: 1
# verb: create
# resource: deployments
steady: true
katalog: ./katalog.yaml
Output:
✓ Generated simulate.yaml
1 CRD(s), 3 op rule(s)
Run ork simulate to verify.
What it generates
ork simulate init produces a Simulate Pattern pre-filled with the observed cycle-1 create operations as expect: rules:
apiVersion: orkestra.orkspace.io/v1
kind: Simulate
metadata:
name: postgres-sim
description: Generated by ork simulate init — edit to refine
spec:
katalog: ./katalog.yaml
cr: ./cr.yaml
cycles: 5
expect:
noErrors: true
ops:
- cycle: 1
verb: create
resource: deployments
name: my-postgres
- cycle: 1
verb: create
resource: services
name: my-postgres
- cycle: 1
verb: create
resource: persistentvolumeclaims
name: my-postgres-data
# absent: # ops that must NOT appear — fill in for failure-path coverage
# - cycle: 1
# verb: create
# resource: deployments
steady: true
steady: true and noErrors: true are always included. ops lists every resource the reconciler created on its first cycle. Nothing is assumed — if a resource was created, it appears. If the operator creates nothing in cycle 1, ops is omitted.
For multi-CRD Katalogs the expect: block is scoped per CRD under a crds: key:
spec:
expect:
noErrors: true
crds:
database:
steady: true
noErrors: true
ops:
- { cycle: 1, verb: create, resource: statefulsets, name: my-db }
cache:
steady: true
noErrors: true
ops:
- { cycle: 1, verb: create, resource: deployments, name: my-cache }
Refining the output
The generated file is a starting point, not the final word. Run --debug-ops to see every op recorded across all cycles — this shows what happened beyond cycle 1 and anything init did not include:
ork simulate --debug-ops
[debug-ops] 5 total ops recorded across all cycles:
[debug-ops] cycle=1 verb=create resource=deployments name=my-postgres
[debug-ops] cycle=1 verb=create resource=services name=my-postgres
[debug-ops] cycle=1 verb=create resource=persistentvolumeclaims name=my-postgres-data
[debug-ops] cycle=2 verb=update resource=statuses name=my-postgres
[debug-ops] cycle=3 verb=update resource=statuses name=my-postgres
Copy any ops you want to assert on into the expect: block. Common refinements beyond that:
Remove rules for resources you do not care about — if a configmap is internal scaffolding, delete the rule. Only assert on what matters to the contract.
Add cycle: precision — the generated rules all target cycle 1. If you expect a resource to appear only after a condition is met (cycle 2+), update the cycle number.
Add absent: rules — specify resources that must never appear under this CR:
expect:
absent:
- resource: clusterrolebindings
- resource: secrets
name: plaintext-password
Tighten cycles: — the generated file defaults to cycles: 5. If your operator reaches steady state at cycle 2, set cycles: 2 to make the test stricter.
Once you are satisfied, run:
ork simulate
Simulate reads the simulate.yaml automatically and runs in assert mode — every rule is checked and the result is printed.
Flags
| Flag | Default | Description |
|---|---|---|
-f | katalog.yaml | Path to the Katalog file |
--cr | cr.yaml | Path to the CR YAML |
--force | false | Overwrite an existing simulate.yaml |
--dry-run | false | Print to stdout instead of writing the file |