Skip to main content

VERIFY INFRASTRUCTURE WITH ASSERT STEPS

This guide shows you how to add assert steps to a workflow so that data-producing steps run first, then assert steps check the results.

Prerequisites

  • Swamp installed and on your PATH
  • An initialised repo (swamp repo init)
  • A model that produces data you want to verify (this guide uses command/shell)
  • Familiarity with workflow definitions

Add assert steps to a workflow

Place assert steps after the step that collects data. Use dependsOn so the assert waits for the data-producing step to finish, then reference its output with data.latest() in the expr field:

jobs:
  - name: verify
    steps:
      - name: collect-state
        task:
          type: model_method
          modelIdOrName: server-check
          methodName: execute
          inputs:
            run: echo '{"healthy":true,"count":3,"region":"us-east-1"}'

      - name: check-healthy
        dependsOn:
          - step: collect-state
            condition:
              type: succeeded
        task:
          type: assert
          expr: data.latest("server-check", "result").attributes.exitCode == 0
          message: "Server exited cleanly"
          severity: high

      - name: check-output
        dependsOn:
          - step: collect-state
            condition:
              type: succeeded
        task:
          type: assert
          expr: >-
            data.latest("server-check", "result").attributes.stdout.contains("healthy")
          message: >-
            Expected stdout to contain 'healthy', got
            ${{ data.latest("server-check", "result").attributes.stdout }}
          severity: medium

expr is a raw CEL expression — do not wrap it in ${{ }}. The message field does support ${{ }} interpolation for including dynamic values.

When a CEL expression contains double quotes, use a >- block scalar to avoid YAML quoting conflicts:

expr: >-
  data.latest("server-check", "result").attributes.stdout.contains("healthy")

Set severity levels

Each assert step accepts a severitylow, medium, or high (default high). Severity controls whether a failure causes the workflow run to fail, based on the --fail-on threshold.

Run with the default threshold (any failure fails the run):

swamp workflow run infra-verify

Run with a higher threshold so only high-severity failures fail the run:

swamp workflow run infra-verify --fail-on high

With --fail-on high, failed low and medium assertions are recorded but do not affect the exit code:

 system │ Starting workflow infra-verify

 verify │ start
 verify │ step collect-state · server-check · execute · start
 verify │ done collect-state
 verify │ done ✓ check-healthy
 verify │ failed ✗ check-count
 verify │   Expected count of 3 in output
 verify │ failed ✗ check-region
 verify │   Region must be us-east-1
 verify │ completed

 system │ Assertions: 1 passed, 2 failed

 system │ Completed workflow infra-verify succeeded

The run succeeds because the two failures are below the high threshold.

Generate JUnit XML for CI

Add --junit to emit assert results as JUnit XML that CI test reporters (GitHub Actions, GitLab, Jenkins) can consume:

swamp workflow run infra-verify --junit
<?xml version="1.0" encoding="UTF-8"?>
<testsuites name="infra-verify" tests="3" failures="0" time="0.1">
  <testsuite name="verify" tests="3" failures="0" time="0.0">
    <testcase name="check-healthy" classname="infra-verify.verify" time="0.0"/>
    <testcase name="check-output" classname="infra-verify.verify" time="0.0"/>
    <testcase name="check-no-errors" classname="infra-verify.verify" time="0.0"/>
  </testsuite>
</testsuites>

To write the XML to a file instead of stdout, add --out:

swamp workflow run infra-verify --junit --out results.xml

--junit and --json cannot be combined — use one or the other.

Reference