Files
2026-10-11 07:21:11 -04:00

44 lines
4.0 KiB
Markdown

# A/B trial boot simulation
This C++17 standard-library example follows the [trial boot diagram](../../../diagrams/plantuml/ab-trial-boot.puml), [chapter 04](../../../docs/04-starting-an-updated-system-or-service.md), and [ADR-014](../../../adr/ADR-014-trial-boot-and-confirmation.md). It illustrates boot decisions; it does not install software or access a device. No third-party libraries are required.
Build and run from the repository root with CMake 3.20 or later and a C++17 compiler. These commands use a Linux temporary build directory to keep generated files outside the repository:
```sh
cmake -S examples/simulations/ab-trial-boot -B /tmp/ota-ab-build -DCMAKE_BUILD_TYPE=Debug
cmake --build /tmp/ota-ab-build
/tmp/ota-ab-build/ab-simulate all
/tmp/ota-ab-build/ab-simulate attempts-exhausted
ctest --test-dir /tmp/ota-ab-build --output-on-failure
```
| Scenario | Expected result |
|---|---|
| `success` | Checks pass; B is confirmed and selected on the next boot. |
| `health-failure` | B fails checks; reset selects A; recovery checks pass. |
| `attempts-exhausted` | B never reaches checks; two unconfirmed attempts lead to A. |
| `restart-during-trial` | A reset preserves the consumed attempt; the second trial passes. |
| `interrupted-preparation` | Incomplete B remains ineligible; reset selects A. |
| `recovery-failure` | A also fails; stop at the boundary of a separate recovery policy. |
With no argument, `ab-simulate` runs all scenarios. Use `--help` to list the accepted arguments. Invalid arguments return a nonzero exit status.
The attempt limit of two is an illustrative choice. Each reset reconstructs the device from a versioned text record (`boot-state.txt`) in a temporary directory. The running slot is volatile. The saved normal slot stays A until B is confirmed. Boot control saves each consumed attempt before returning B as the selected system. A failed health check requests recovery immediately rather than spending the remaining trial attempts.
The example keeps boot state outside the simulated slots, as shown in the [storage diagram](../../../diagrams/plantuml/ab-storage-layout.puml). Each scenario uses a separate temporary directory, removed when it finishes. The model covers one A-to-B update; it does not model subsequent releases.
## Assumptions and limits
Installation and artifact verification are represented by one preparation operation. Health checks are supplied boolean outcomes, including a timeout represented as failure. Resets are explicit calls; watchdog coverage and real startup timing are not simulated. Recovery assumes that A and shared data remain usable, unless the recovery-failure scenario supplies a failed check.
The text file is a teaching stand-in for boot state, using standard C++ streams and `std::filesystem`. It records the phase, normal slot, optional trial slot, attempts remaining, slot readiness, and outcome. Replacement uses a temporary file and rename, but does not flush storage, implement redundant records, or recover invalid records. Unreadable records stop the simulation with an error; they are never treated as confirmation. This is not a power-loss-safe boot-state implementation. The simulation assumes completed valid writes; it does not test interruption within a write, coordination with OTA progress, data migration, signatures, bootloader integration, or hardware failure. These need platform-specific implementation and failure-injection tests.
Outcomes remain local in the model. There is no server dependency or reporting transport. A real implementation must retain pending reports separately and send them when connectivity returns.
## Source and checks
- [simulation.hpp](simulation.hpp) and [simulation.cpp](simulation.cpp): typed state model, saved records, reset behavior, and scenarios.
- [main.cpp](main.cpp): command-line runner.
- [tests.cpp](tests.cpp): scenario outcomes and invariants for saved attempts, incomplete slots, confirmation, and unreadable state. Checks remain enabled in Release builds.
- [CMakeLists.txt](CMakeLists.txt): builds the runner and registers the invariant and CLI checks with CTest.