# 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.