Skip to content

S08.03 slice 5: BDD harness pointed at FreeRTOS-on-QEMU target #304

Description

@DavidCozens

Slice 5 of S08.03 (parent: #268). Builds on #302.

Why

Slice 4 (#302 → PR #303) made the FreeRTOS example's identity, transport endpoint, and PRIVAL fields mutable in-RAM via set NAME VALUE over the existing UART command channel. That hand-rolled QEMU smoke (Python listener + UART heredoc + select() on two ports) is essentially a Behave scenario in disguise — slice 5 promotes it into Gherkin + the existing syslog-ng oracle, and adds the CI matrix entry that #268's acceptance list has been waiting on.

Slice 5 establishes the harness. Tagging-out failing scenarios is part of the deal; later slices remove @freertoswip tags as scenarios are made to pass.

Scope

Where Behave runs

Inside the cpputest-freertos-cross container, alongside QEMU. Behave spawns qemu-system-arm as a subprocess and pipes set … / send N / quit over stdin (UART). No cross-container PTY plumbing.

Same image local + CI

cpputest-freertos-cross is bumped (in CppUTestFreertosDocker) to add python3 + behave + Bdd/requirements.txt deps. Both the local freertos-target devcontainer service and the new CI job use the same image SHA.

Per-target oracle pairs

Each BDD target gets its own syslog-ng instance, paired via network_mode: service:syslog-ng-<target> so QEMU's slirp 10.0.2.2 NATs to the target-pair's loopback (where its own syslog-ng is bound on 0.0.0.0:5514). Scales to additional targets without re-thinking.

In ci/docker-compose.bdd.yml:

Target Behave service Oracle service
Linux behave-linux (rename of behave) syslog-ng-linux (rename of syslog-ng)
FreeRTOS behave-freertos (new) syslog-ng-freertos (new)

.devcontainer/docker-compose.yml mirrors the rename. The existing CI command for bdd-linux-syslog-ng is scoped to its own pair (up --exit-code-from behave-linux behave-linux syslog-ng-linux) so the FreeRTOS pair doesn't get dragged in.

Step-driver abstraction

Bdd/features/environment.py reads BDD_TARGET (default linux) and selects a target driver:

BDD_TARGET Driver Notes
linux LinuxSubprocessDriver wraps today's subprocess.Popen flow
windows WindowsSubprocessDriver same shape, otelcol oracle
freertos QemuFreertosDriver spawns qemu-system-arm, drives UART

Steps that today touch subprocess.Popen or process.stdin.write are refactored to call context.driver.send_command(…) (or equivalent). Same feature files; no sibling Bdd/features/freertos/ tree.

Scenario coverage

Enable every @udp-tagged feature for FreeRTOS. Tag scenarios that don't pass yet with @freertoswip and exclude them from the FreeRTOS run via --tags='not @freertoswip'. The slice-5 PR documents which scenarios were tagged and why — that list seeds the follow-up slices.

CI

New job bdd-freertos-qemu:

  • Depends on build-freertos-target, which gains an artifact upload step for the .elf.
  • Downloads the artifact, runs docker compose -f ci/docker-compose.bdd.yml up --abort-on-container-exit --exit-code-from behave-freertos behave-freertos syslog-ng-freertos.
  • Becomes a required check on main (branch protection update).
  • Surfaces JUnit results to the existing summary quality-monitor job.

Documentation

  • docs/containers.md: image SHA bump entry; service-rename in the "Switching to a different container" table.
  • CLAUDE.md: any image-SHA reference, plus the per-target oracle convention under "Container Images".
  • Bdd/README.md (new, or addition to existing): brief BDD_TARGET contract and a freertos worked example for local fault-finding.

Acceptance

  • cpputest-freertos-cross image bump lands and is referenced consistently in .devcontainer/docker-compose.yml, .github/workflows/ci.yml, and docs/containers.md.
  • ci/docker-compose.bdd.yml and .devcontainer/docker-compose.yml carry the per-target rename + new freertos pair; existing services depend on syslog-ng-linux; new ones on syslog-ng-freertos.
  • Bdd/features/environment.py selects a driver from BDD_TARGET; step modules use context.driver for spawn/IO.
  • bdd-linux-syslog-ng CI job still passes with the renamed pair.
  • bdd-windows-otel CI job still passes (no rename needed there; Windows runner doesn't use compose).
  • New bdd-freertos-qemu CI job is green and added as a required status check on main.
  • summary job's quality monitor surfaces FreeRTOS BDD JUnit alongside the existing two BDD jobs.
  • Locally, a developer can switch the devcontainer to freertos-target, run behave Bdd/features/syslog.feature, and see the walking-skeleton scenario pass end-to-end.
  • @freertoswip-tagged scenarios are listed in the DEVLOG entry, one line each on why each fails today (seed for follow-up slices).

Out of scope

  • Removing any @freertoswip tag — each is its own follow-up slice.
  • SolidSyslogFreeRtosStaticResolver dotted-quad parsing (separate slice; slice 5's scenarios shouldn't depend on set host taking effect on the wire).
  • CMake stack-budget scaling (separate slice).
  • Any expansion of OnSet grammar required by failing scenarios — if one is genuinely blocking the harness landing, raise it as a follow-up rather than expanding slice 5.
  • cpputest-freertos (host) image bump — only the cross image needs Python + Behave for slice 5.
  • Refactoring bdd-windows-otel to use the new target_driver abstraction — Windows runner already works with environment-var branching; rolling that into the new abstraction is a follow-up cleanup.

Metadata

Metadata

Assignees

No one assigned

    Labels

    storyStory issue

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions