Deterministic Fault Injection: Five Fault Primitives, Reproduced at Tick N
Cyclone deterministic fault injection: five primitives (drop, delay, corrupt, freeze, CRC error) in declarative YAML — same fault, same tick, every run.
§1 · PROBLEMThe Three Deadlocks of Manual Fault Injection
Almost every ADAS / robotics test team has done fault injection, and in a strikingly uniform way: pull the cable, patch the code, write a one-off script. That road has three deadlocks you cannot untangle:
- No precise reproduction. Inject the same fault a second time and the timing, intensity, and duration window all differ from the first. Want to re-run it to verify the fix after the FAIL? Sorry — “that fault” no longer exists.
- Conclusions don’t align. The FAIL one engineer produces won’t reproduce on a colleague’s machine — the code didn’t change, the “luck” did. In the review meeting, nobody can convince anybody.
- Scenarios are not assets. One-off scripts sit on personal laptops: the owner can’t take a vacation, nobody dares touch the script — let alone review, version, or diff it.
§2 · SOLUTIONCyclone's Approach: Fault as Code
Cyclone’s fault-injection layer is called FaultPipe, and its core idea fits in one sentence: faults are declared, not handcrafted.
Five Fault Primitives Supported
| Primitive | Behavior | Typically Simulates |
|---|---|---|
Drop |
Frame drops | Sensor packet loss, bus overload |
Delay |
Delayed delivery | Network congestion, ECU scheduling jitter |
CorruptField |
Field corruption | Sensor drift, signal anomalies |
Freeze |
Freezing | Hung node, watchdog never fires |
CorruptCrc |
CRC errors | EMC interference, poor harness contact |
Tick-Precise Triggering
Declare the trigger by time window, frame count, or conditional expression. On a 1 ms schedule, the same fault fires at tick N, guaranteed — not “somewhere around then,” but the exact slot the deterministic scheduler promises. Rerun with the same seed and the evidence logs are byte-identical (SHA-256 verifiable).
Declarative YAML Configuration
# cases/aeb_frame_drop.yaml — a regression test case
fault:
type: Drop
target: front_camera.frames
trigger: { at_tick: 500, duration: 120 }
pattern: burst # burst drops, simulating a loose connector
verdict:
metric: recall_near
threshold: 0.98 # threshold derived via margin analysis, see §4
Fault scenarios as code: reviewable, versionable, diffable. A new engineer taking over doesn’t need “the old hand’s touch.”
§3 · WHY IT MATTERSOnly Deterministic Injection Makes a Verdict Possible
The finish line of fault injection isn’t “injected” — it’s “judged.” Cyclone welds injection and statistical verdict into a single pipeline: fault injection → metric degradation → verdict flip → evidence output. The verdict engine uses the Wilson lower bound and SPRT sequential testing, turning “ran it a few times, felt fine” into “fails at 95% confidence.”
- 30 Runs, 27 Passes: Why That Doesn’t Count as Verified →
- Wilson Lower-Bound Verdicts: An Honest Ruler for Pass Rates →
- SPRT and LLR: Sequential Testing That Delivers the Verdict as Soon as the Evidence Is In →
§4 · HONEST BOUNDARIESHonest Boundaries
- Physical environmental testing is not software’s job. High/low temperature, vibration, EMC, and salt spray (ISO 16750 / GB/T 28046) belong to climate chambers and rigs. What Cyclone does is the half of environmental stress projected onto the bus: drift, frame drops, bit flips, node freezes (some injection methods Prototype / Planned, see Test-type matrix §3.5).
- Interface status: SocketCAN / UDP / YAML DSL / JUnit XML Supported; DDS Prototype; SOME/IP, UDS, ASAM XIL API Planned. During the POC phase we evaluate priorities against your bus environment.
- Thresholds need calibration. The 0.98 in the example above is a demo value; the formal acceptance threshold must be derived via margin analysis against your SUT baseline — a standard POC service item.
Run it on your own scenario
A 30-minute demo: AEB regression → inject a fault → open the evidence report.
Book a 30-min demo Get the scenario pack