Files

104 lines
7.1 KiB
Markdown
Raw Permalink Normal View History

2026-04-17 14:55:32 -04:00
---
source_files:
- DataPRO/StateMachine.Tests/States/RealtimeShould.cs
- DataPRO/StateMachine.Tests/States/ConfigureShould.cs
- DataPRO/StateMachine.Tests/States/RealtimeStartShould.cs
- DataPRO/StateMachine.Tests/States/DiagnoseShould.cs
- DataPRO/StateMachine.Tests/States/HardwareDiscoveryStartShould.cs
generated_at: "2026-04-16T04:24:35.181988+00:00"
model: "Qwen/Qwen3-Coder-Next-FP8"
schema_version: 1
sha256: "19e719e00bdf4549"
---
# StateMachine Module Documentation
## 1. Purpose
This module implements a finite state machine (FSM) for managing the operational states of a data acquisition system (DAS), with states such as `HardwareDiscovery`, `Configure`, `Diagnose`, `Realtime`, and their transition points (e.g., `RealtimeStart`, `HardwareDiscoveryStart`). It enables deterministic state transitions based on runtime status and configuration parameters, ensuring the system progresses through initialization, configuration, diagnostics, and real-time operation phases in a controlled manner. The tests validate the behavior of individual state classes and their `StateSelector()` logic, which determines the next state based on current status flags and parameters.
## 2. Public Interface
The following classes are defined in the `DTS.DASLib.Service.StateMachine` namespace (inferred from test imports). Each class represents a state in the state machine and exposes a `StateSelector()` method to determine the next state.
### `Realtime`
- **Constructor**: `Realtime()`
Initializes the state; sets `State` property to `State.Realtime`.
- **Property**: `State``State`
Returns the current state identifier (`State.Realtime`).
- **Method**: `StateSelector()``DASState` *(not tested directly, but implied by pattern)*
*Behavior inferred from other states: returns the next state based on status/params. Not directly exercised in provided tests.*
### `Configure`
- **Constructor**: `Configure()`
Initializes the state.
- **Method**: `StateSelector()``DASState`
Returns a `DASState` with `State` set to `State.ConfigureStart`.
### `RealtimeStart`
- **Constructor**: `RealtimeStart()`
Initializes the state.
- **Property**: `Status``Status` *(exposes `RealtimeStatus`)*
Contains `RealtimeStatus.CouldNotStartRealtime` (boolean).
- **Method**: `StateSelector()``DASState`
- If `RealtimeStatus.CouldNotStartRealtime == true`, returns `State.RealtimeStart`.
- If `RealtimeStatus.CouldNotStartRealtime == false`, returns `State.Realtime`.
### `Diagnose`
- **Constructor**: `Diagnose()`
Initializes the state.
- **Property**: `Status``Status` *(exposes `DiagnoseParams`)*
Contains:
- `DiagnoseParams.ProceedToRealtimeWhenDone` (bool)
- `DiagnoseParams.RequireAllUnitsPassDiagnostic` (bool)
- `DiagnoseParams.AllUnitsPassedDiagnostic` (bool)
- **Method**: `StateSelector()``DASState`
Returns:
- `State.RealtimeStart` if `ProceedToRealtimeWhenDone == true` **and**
(`RequireAllUnitsPassDiagnostic == false` **or** `AllUnitsPassedDiagnostic == true`).
- `State.Diagnose` otherwise (e.g., when `ProceedToRealtimeWhenDone == false`, or when `RequireAllUnitsPassDiagnostic == true` and `AllUnitsPassedDiagnostic == false`).
### `HardwareDiscoveryStart`
- **Constructor**: `HardwareDiscoveryStart()`
Initializes the state; sets `State` property to `State.HardwareDiscoveryStart`.
- **Property**: `State``State`
Returns `State.HardwareDiscoveryStart`.
- **Property**: `Status``Status` *(exposes `HardwareDiscoveryParams` and `HardwareDiscoveryStatusInfo`)*
Contains:
- `HardwareDiscoveryParams.ProceedWhenDone` (bool)
- `HardwareDiscoveryParams.RequireAllDASFound` (bool)
- `HardwareDiscoveryParams.GoToDownload` (bool)
- `HardwareDiscoveryStatusInfo.AllDASFound` (bool)
- `HardwareDiscoveryStatusInfo.SomeUnitsInArmState` (bool)
- **Method**: `StateSelector()``DASState`
Returns the next state based on:
- If `ProceedWhenDone == true`:
- `State.Download` if `GoToDownload == true` and `AllDASFound == true` (and `RequireAllDASFound == true`).
- `State.Configure` if `GoToDownload == false` and either `AllDASFound == true` or `RequireAllDASFound == false`.
- `State.Arm` if `AllDASFound == false`, `RequireAllDASFound == true`, `GoToDownload == false`, and `SomeUnitsInArmState == true`.
- `State.HardwareDiscovery` if `AllDASFound == false`, `RequireAllDASFound == true`, `GoToDownload == false`, and `SomeUnitsInArmState == false`.
## 3. Invariants
- Each state classs `State` property (where exposed) must return the corresponding `State` enum value (e.g., `Realtime.State == State.Realtime`).
- `StateSelector()` must return a non-null `DASState` object with a valid `State` field.
- Transitions are deterministic: given identical `Status` and parameter values, `StateSelector()` must return the same next state.
- `HardwareDiscoveryStart.StateSelector()` only evaluates transitions when `ProceedWhenDone == true` (based on test arrangements); behavior when `ProceedWhenDone == false` is not specified in tests.
## 4. Dependencies
- **Internal Dependencies**:
- `DTS.DASLib.Service.StateMachine` namespace (contains state classes and `State` enum).
- `Status` type (contains nested `RealtimeStatus`, `DiagnoseParams`, `HardwareDiscoveryParams`, `HardwareDiscoveryStatusInfo`).
- `DASState` type (returned by `StateSelector()`).
- `State` enum (defines state identifiers: `Realtime`, `ConfigureStart`, `RealtimeStart`, `Diagnose`, `HardwareDiscoveryStart`, `HardwareDiscovery`, `Arm`, `Download`, `Configure`).
- **Test Dependencies**:
- `NUnit` for test framework (`[TestFixture]`, `[Test]`, `Assert.That`).
- `NSubstitute` (used in `HardwareDiscoveryStartShould` tests, though not instantiated in provided snippets).
- **Inferred Consumers**:
A higher-level state machine controller (not shown) likely instantiates these state classes and calls `StateSelector()` to drive transitions.
## 5. Gotchas
- **Ambiguous `Status` Type**: The `Status` propertys full structure (e.g., `RealtimeStatus`, `DiagnoseParams`, `HardwareDiscoveryParams`) is inferred from test usage but not defined in the source. Its exact shape and default values are unknown.
- **Missing `StateSelector()` Implementation Details**: The tests do not cover edge cases (e.g., `ProceedWhenDone == false` in `HardwareDiscoveryStart`, or invalid parameter combinations). Behavior in untested scenarios is unspecified.
- **Redundant Test for `DiagnoseShould.State_ShouldBeRealtime`**: This test instantiates `new Realtime()` but asserts `sut.State == State.Realtime`, which is identical to `RealtimeShould.State_ShouldBeRealtime`. Likely a copy-paste error in tests.
- **No Error Handling Tests**: No tests verify behavior when `Status` is null, or when parameters conflict (e.g., `RequireAllUnitsPassDiagnostic == true` and `AllUnitsPassedDiagnostic == true` but `ProceedToRealtimeWhenDone == false`—though this is covered in `DiagnoseShould`).
- **State Names vs. Class Names**: The class `RealtimeStart` corresponds to `State.RealtimeStart`, but `Configure` class returns `State.ConfigureStart` (not `State.Configure`). This mismatch may cause confusion.
None identified beyond the above.