Use Cases

3 min read

Helm charts

Ship an e2e.yaml alongside your chart. Use setup.helm with chart: ./ to install the chart itself, add per-entry wait: to confirm it is ready, then assert the resources it creates. No crd: or cr: needed — everything goes through setup.

Real example: Orkestra dogfoods this pattern for its own Helm chart — charts/orkestra/e2e.yaml

All expectations use after: setup-complete (or omit after:, which means the same thing) since there is no CR lifecycle to wait for.

spec:
  custom:
    target: kubernetes
  setup:
    helm:
      - chart: ./
        release: my-app
        namespace: my-app
        createNamespace: true
        values:
          replicaCount: 2
        wait:
          - kind: Deployment
            name: my-app
            namespace: my-app
            ready: true
            timeout: 120s
  expect:
    - name: Deployment is ready
      timeout: 30s
      resources:
        - kind: Deployment
          name: my-app
          namespace: my-app
          ready: true
    - name: Service is created
      timeout: 30s
      resources:
        - kind: Service
          name: my-app
          namespace: my-app

When you need manifests applied before the chart (CRDs, namespaces, config), use setup.apply with per-entry waits to confirm each step before moving on:

setup:
  apply:
    - path: ./fixtures/crd.yaml
      wait:
        - kind: CustomResourceDefinition
          name: myresources.example.com
          timeout: 30s
    - path: ./fixtures/config.yaml
  helm:
    - chart: ./
      release: my-app
      namespace: my-app
      createNamespace: true
      wait:
        - kind: Deployment
          name: my-app
          namespace: my-app
          ready: true
          timeout: 120s

Third-party operators

Install an operator you did not write — cert-manager, ArgoCD, Crossplane, FluxCD — and assert the resources it manages. Apply the CRD and CR via setup.apply so the operator sees the CR on first boot, then use after: setup-complete for infrastructure checks.

spec:
  custom:
    target: kubernetes
  setup:
    apply:
      - path: ./fixtures/crd.yaml
        wait:
          - kind: CustomResourceDefinition
            name: certificates.cert-manager.io
            timeout: 30s
      - ./fixtures/cr-certificate.yaml
    helm:
      - repo: https://charts.jetstack.io
        chart: cert-manager
        namespace: cert-manager
        createNamespace: true
        version: v1.14.0
        values:
          installCRDs: true
        wait:
          - kind: Deployment
            name: cert-manager-webhook
            namespace: cert-manager
            ready: true
            timeout: 120s
  expect:
    - name: TLS Secret issued
      timeout: 60s
      resources:
        - kind: Secret
          name: my-tls-secret
          namespace: default

Platform stacks

Install multiple tools together and assert they interact correctly. Per-entry wait: on each helm install ensures the stack comes up in order.

spec:
  custom:
    target: kubernetes
  setup:
    helm:
      - repo: https://charts.jetstack.io
        chart: cert-manager
        namespace: cert-manager
        createNamespace: true
        values:
          installCRDs: true
        wait:
          - kind: Deployment
            name: cert-manager-webhook
            namespace: cert-manager
            ready: true
            timeout: 120s
      - repo: https://argoproj.github.io/argo-helm
        chart: argo-cd
        namespace: argocd
        createNamespace: true
        wait:
          - kind: Deployment
            name: argocd-server
            namespace: argocd
            ready: true
            timeout: 180s
  expect:
    - name: ArgoCD Application synced
      timeout: 60s
      commands:
        - run: kubectl get application my-app -n argocd -o jsonpath='{.status.sync.status}'
          outputContains: Synced
    - name: TLS Secret issued
      timeout: 60s
      resources:
        - kind: Secret
          name: my-app-tls
          namespace: default

Lifecycle events quick reference

after: valueWhen to use
setup-complete (default)Non-operator tests, infrastructure checks, anything without a CR lifecycle
cr-appliedAfter spec.cr is applied — operator reconciliation assertions
cr-deletedAfter spec.cr is deleted — cleanup assertions

Omitting after: is the same as writing after: setup-complete.