Scaffolding Tests

3 min read

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

FlagDefaultDescription
-fkatalog.yamlPath to the Katalog file
--crcr.yamlPath to the CR YAML
--forcefalseOverwrite an existing simulate.yaml
--dry-runfalsePrint to stdout instead of writing the file