Simulate

3 min read
Simulate is not a Kubernetes CRD
kubectl apply will not work. Orkestra kinds are consumed by the ork CLI and runtime — not by the Kubernetes API server. Your CRD is enough.

A Simulate Pattern declares what your operator should produce — which resources, in which cycle — and verifies it by running the reconciler against a fake in-memory cluster. No Kubernetes. No Docker. Sub-second.

Motif     — smallest reusable unit
Katalog   — operator declaration
Komposer  — platform declaration
Simulate  — in-memory reconciler verification

ork validate checks the structure. ork simulate runs it.


Wire format

With expect: — assert mode

apiVersion: orkestra.orkspace.io/v1
kind: Simulate

metadata:
  name: my-operator-sim
  description: Verify Deployment and Service created in cycle 1

spec:
  katalog: ./katalog.yaml
  cr: ./cr.yaml
  cycles: 5
  skipExternal: false

  expect:
    noErrors: true
    ops:
      - cycle: 1
        verb: create
        resource: deployments
        name: my-app
    # absent:   # ops that must NOT appear — fill in for failure-path coverage
    #   - cycle: 1
    #     verb: create
    #     resource: deployments
    steady: true

Without expect: — op-print mode

Same spec, no expect: block. Runs the reconciler, prints every op recorded per cycle, always exits 0. Used for exploration before you know the expected sequence.

Aggregator form

apiVersion: orkestra.orkspace.io/v1
kind: Simulate

metadata:
  name: my-suite

imports:
  - ./01-basic/simulate.yaml
  - ./02-with-hooks/simulate.yaml

No spec:. Each imported file runs independently. The suite fails if any file fails.


Field reference

metadata

FieldRequiredDescription
nameyesName of this simulate run — used in output headers
descriptionnoFree-text description shown in output and registry

spec

FieldRequiredDefaultDescription
katalogyesPath to the katalog.yaml (or komposer.yaml)
cryesPath to the CR YAML file. Multi-doc YAML supported — each doc matched to its CRD by kind
cyclesno10Maximum number of reconcile cycles to run
skipExternalnofalseStub all external: HTTP calls with an empty 200 response instead of hitting the real network

spec.expect

Optional. When omitted the run is in op-print mode — no assertions, always exits 0.

FieldTypeDescription
steadyboolReconciler must reach steady state within cycles
steadyAtintSteady state must be reached by this cycle number (≤ value)
noErrorsboolAny reconcile error fails the run
ops[]OpRuleOps that must appear — see below
absent[]OpRuleOps that must NOT appear — use for failure-path assertions
crdsmap[string]expectPer-CRD overrides for multi-CRD Katalogs. Top-level fields are defaults; a named entry overrides for that CRD only

OpRule

Used in both ops and absent.

FieldRequiredDescription
cycleyesReconcile cycle the op must (or must not) occur in
verbyescreate, update, delete, or patch
resourceyesKubernetes resource type: deployments, statefulsets, configmaps, …
namenoAssert a specific resource name
countnoMinimum number of matching ops (default: ≥1). Ignored in absent

Validation

ork validate -f simulate.yaml

Catches: missing required fields, verbs outside the four allowed values, imports paths that don’t resolve on disk.


Scaffold with ork simulate init

ork simulate init runs the reconciler once, captures the cycle-1 create ops, and writes a simulate.yaml pre-filled with expect: rules — including a commented absent: block seeded with the first observed resource type.

ork simulate init           # writes simulate.yaml
ork simulate init --dry-run # prints to stdout, nothing written
ork simulate init --force   # overwrites existing simulate.yaml

Scaffolding Tests


Try it

ork init --pack beginner
cd beginner/02-with-serviceaccount
ork simulate