# Fault injection — test only

![Fault controls in the native application with a synthetic project](screenshot.png)

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:

```sh
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](../../docs/EXAMPLES.md).
The synthetic fault commands are implemented in [fault.cpp](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.
