Fault injection — test only

This deliberately faulty plugin is supplied for recovery testing in a disposable project. No fault executes on startup. It is excluded from ordinary customer autoload and marked test-only in the local signed catalog.
Build and run
Set EPICTUNER_SDK_ROOT, then run cmake --preset sdk and
cmake --build --preset sdk. Launch the development manifest explicitly:
epictuner --plugin-development --plugin-manifest /absolute/path/out/plugin.json
Use epictuner.exe on Windows. Open Plugins → Tests → Fault injection.
For signed installation use the test catalog.
The synthetic fault commands are implemented in fault.cpp.
Acceptance cases
| Command | Expected result |
|---|---|
| crash | Worker exits with code 71; the application remains usable |
| hang | Dispatcher stops responding; heartbeat supervision fails the worker |
| throw | C++ exception becomes a callback error inside the worker boundary |
| flood | At least 9,900 of 10,000 log attempts are rejected by the bounded rate limit |
| wrong-thread | A background-thread log call is rejected with state error |
| invalid-handle | Host rejects a fabricated panel handle; no panel is affected |
| stale-write | Reject a forged Apply with the wrong project generation; no calibration changes |
| slow-consumer | Delay sample callbacks; report gaps while host polling continues |
| malformed-model | Host rejects an orphan node; no invalid definition is installed |
Inspect the plugin state and diagnostics after each command. Restart manually after a terminal failure. Reopening the panel must not repeat the selected fault. Keep an existing host editor and Mock ECU connection active while checking that the application continues to work.
The host's calibration regression additionally checks stale proposals, conflicts and no write replay after worker replacement; its read/load regression checks visible gaps and polling under slow consumers. Those tests are separate from the basic development checker and must be included in release acceptance.