Files
ota-reference-design/examples/simulations/ab-trial-boot/simulation.hpp
T
2026-10-20 12:27:04 -04:00

77 lines
2.0 KiB
C++

#pragma once
#include <filesystem>
#include <optional>
#include <ostream>
#include <string>
#include <vector>
namespace ota {
enum class Phase {
AConfirmed,
PreparingB,
BPrepared,
TrialPending,
TrialRunning,
BConfirmed,
RecoveryPending,
RecoveryRunning,
RecoveryChecked,
SeparateRecoveryRequired
};
enum class Slot { A,
B };
const char *name(Phase phase);
const char *name(Slot slot);
struct State {
Phase phase = Phase::AConfirmed;
Slot normal = Slot::A;
std::optional<Slot> trial;
int attempts_left = 0;
bool a_ready = true;
bool b_ready = false;
std::string outcome;
};
class Device {
public:
explicit Device(const std::filesystem::path &directory);
const State &state() const { return state_; }
std::optional<Slot> running() const { return running_; }
void prepare(bool complete = true);
void request_trial(int attempts = 2);
Slot boot();
void check(bool healthy);
private:
void save() const;
State state_;
std::filesystem::path path_;
// Volatile: reconstructing a Device requires another boot before checks.
std::optional<Slot> running_;
};
// Own only a freshly created directory and clean it up at scope exit.
class TemporaryDirectory {
public:
TemporaryDirectory();
~TemporaryDirectory();
TemporaryDirectory(const TemporaryDirectory &) = delete;
TemporaryDirectory &operator=(const TemporaryDirectory &) = delete;
const std::filesystem::path &path() const { return path_; }
private:
std::filesystem::path path_;
};
const std::vector<std::string> &scenarios();
Device run_scenario(const std::string &scenario,
const std::filesystem::path &directory,
std::ostream *output = nullptr);
}// namespace ota