Writing a Simple Boot Test

Create a boot test that power cycles your board, flashes firmware, and verifies the device boots.

Prerequisites

  • fwci CLI installed and authenticated
  • Git repository with .firmwareci infrastructure initialized (see Repository Setup)
  • DUT connected through a control interface (DUTCTL-compatible device)
  • Access to target device over network

Quick Example

Complete boot test configuration:

DUT Configuration (.firmwareci/duts/arm-board/dut.yaml):

name: ARM-Board-DUT
label: arm-board
attributes:
  Host: "arm-board.lan"
  Flasher: "arm-board-dutctl.lan"

Pre-Stage (.firmwareci/duts/arm-board/pre.yaml):

pre-stage:
  - cmd: dutctl
    name: Power off DUT
    parameters:
      host: "[[attributes.Flasher]]"
      command: power
      args: ["off"]

  - cmd: dutctl
    name: Flash firmware
    parameters:
      host: "[[attributes.Flasher]]"
      command: flash
      args: [write, "[[input.Binary]]"]

  - cmd: dutctl
    name: Power on DUT
    parameters:
      host: "[[attributes.Flasher]]"
      command: power
      args: ["hardreset"]
    options:
      timeout: 2m

Post-Stage (.firmwareci/duts/arm-board/post.yaml):

post-stage:
  - cmd: dutctl
    name: Power off DUT
    parameters:
      host: "[[attributes.Flasher]]"
      command: power
      args: ["off"]

Workflow (.firmwareci/workflows/arm-board/workflow.yaml):

name: ARM-Board-Workflow
description: Boot tests for ARM board
runs-on: arm-board

Boot Test (.firmwareci/workflows/arm-board/tests/boot.yaml):

name: Boot Test
description: Verify board boots and accepts SSH connections

stages:
  - name: Boot Verification
    steps:
      - cmd: ping
        name: Wait for SSH service
        options:
          timeout: 2m
        parameters:
          host: "[[attributes.Host]]"

      - cmd: cmd
        name: Verify device responds
        transport:
          proto: ssh
          options:
            host: "[[attributes.Host]]"
            user: root
            # Uses auto-discovery for SSH keys
        parameters:
          executable: echo
          args: ["Hello, World!"]

Step-by-Step Setup

1. Configure DUT

Update .firmwareci/duts/<dut-name>/dut.yaml with your device details:

FieldDescriptionExample
nameDisplay nameARM-Board-DUT
labelHardware identifier for workflowsarm-board
attributes.HostTarget device hostname/IParm-board.lan
attributes.FlasherDUTCTL interface hostname/IParm-board-dutctl.lan

The label field connects workflows to hardware. Workflows targeting arm-board will run on DUTs with this label.

See DUT Configuration Reference for complete schema.

2. Configure Pre-Stage

Pre-stage operations prepare the DUT before tests run. Edit .firmwareci/duts/<dut-name>/pre.yaml:

pre-stage:
  - cmd: dutctl
    name: Power off DUT
    parameters:
      host: "[[attributes.Flasher]]"
      command: power
      args: ["off"]

  - cmd: dutctl
    name: Flash firmware
    parameters:
      host: "[[attributes.Flasher]]"
      command: flash
      args: [write, "[[input.Binary]]"]

  - cmd: dutctl
    name: Power on DUT
    parameters:
      host: "[[attributes.Flasher]]"
      command: power
      args: ["hardreset"]
    options:
      timeout: 2m

Templates used:

  • [[attributes.Flasher]]: DUTCTL interface address from DUT config
  • [[input.Binary]]: Firmware binary path provided when triggering workflow

See Templating Reference for template syntax.

3. Configure Post-Stage

Post-stage operations clean up after tests complete. Edit .firmwareci/duts/<dut-name>/post.yaml:

post-stage:
  - cmd: dutctl
    name: Power off DUT
    parameters:
      host: "[[attributes.Flasher]]"
      command: power
      args: ["off"]

Post-stage always runs, even if tests fail, ensuring proper hardware cleanup.

4. Update Workflow

Edit .firmwareci/workflows/<workflow-name>/workflow.yaml:

name: ARM-Board-Workflow
description: Boot tests for ARM board
runs-on: arm-board

The runs-on field must match the DUT’s label value.

See Workflow Reference for complete configuration options.

5. Create Boot Test

Create .firmwareci/workflows/<workflow-name>/tests/boot.yaml:

name: Boot Test
description: Verify board boots and accepts SSH connections

stages:
  - name: Boot Verification
    steps:
      - cmd: ping
        name: Wait for SSH service
        options:
          timeout: 2m
        parameters:
          host: "[[attributes.Host]]"

      - cmd: cmd
        name: Verify device responds
        transport:
          proto: ssh
          options:
            host: "[[attributes.Host]]"
            user: root
        parameters:
          executable: echo
          args: ["Hello, World!"]

Test execution flow:

  1. Pre-stage: Power off → Flash → Power on
  2. Ping command waits up to 2 minutes for SSH service
  3. SSH command executes on target device
  4. Post-stage: Power off

6. SSH Authentication

Option 1: Auto-Discovery (Recommended)

Omit identity_file and FirmwareCI automatically tries all organization SSH keys:

transport:
  proto: ssh
  options:
    host: "[[attributes.Host]]"
    user: root
    # No identity_file specified

Option 2: Specific Key

Reference a specific SSH key by name:

transport:
  proto: ssh
  options:
    host: "[[attributes.Host]]"
    user: root
    identity_file: "[[ssh-keys.arm_board_key]]"

Add SSH keys in the web interface under Settings → SSH Keys. See SSH Key Management.

Option 3: Password Authentication

Use for testing only - not recommended for production:

transport:
  proto: ssh
  options:
    host: "[[attributes.Host]]"
    user: root
    password: root

7. Validate and Deploy

Validate configuration:

fwci validate

Expected output:

- duts
  - all validations passed
- storage
  - all validations passed
- workflows
  - arm-board-workflow

Commit and push:

git add .firmwareci
git commit -m "Add ARM board boot test"
git push

FirmwareCI automatically syncs changes and the workflow becomes available for triggering.

Test Images

Use pre-configured test container images with required tooling:

FirmwareCI Base Images: firmwareci-base-image repository

These images include all test step dependencies and can be customized for your DUT requirements.

Common Issues

ProblemSolution
Ping timeoutIncrease timeout in ping step options. Verify network connectivity to DUT. Check attributes.Host address.
SSH authentication failsVerify SSH key exists in organization settings. Check username is correct. Confirm SSH service runs on DUT.
Flash command failsVerify DUTCTL interface is accessible. Check attributes.Flasher address. Ensure firmware binary path is correct.
DUT doesn’t boot after flashCheck power cycle commands execute successfully. Verify firmware binary is valid. Increase power-on timeout.
Template not resolvedVerify template name matches exactly (case-sensitive). Check attribute exists in dut.yaml. Ensure input provided when triggering.
Validation failsCheck YAML syntax (use YAML linter). Verify all referenced templates exist. Ensure runs-on matches DUT label.

See Also