Safe Data Test Application
All test cases of the tests/safe_data test application, generated from
the doxygen XML of its annotated sources (module group safe_data_module,
one section per ztest suite).
Test Scenarios
Scenario |
Tags |
Extra config |
|---|---|---|
|
safe_data |
CONFIG_SAFE_DATA_REDUNDANT=y |
|
safe_data |
CONFIG_SAFE_DATA_REDUNDANT=n |
|
safe_data |
CONFIG_SAFE_DATA_LOCK_TIMEOUT_MS=20 |
|
safe_data |
CONFIG_SAFE_DATA_LEVEL_STRICT=y |
safe_data
Init seals and verification passes. SAFE_INIT seals the freshly written payload; SAFE_VERIFY on the untouched container returns 0. Source: main.c (line 44) |
Read returns the sealed value. A value written through SAFE_WRITE is returned bit-exact by a validated SAFE_READ. Source: main.c (line 61) |
Write replaces the payload and reseals. After SAFE_WRITE the container verifies clean and a subsequent read returns the new value: the tag can never go stale across a write. Status obsolete (demonstration of status handling): superseded by TC_SAFE_DATA_READ_ROUNDTRIP, which checks the resealed write through a validated read. The test still runs. Source: main.c (line 86) |
Update commits a mutator transaction. SAFE_UPDATE runs the mutator under the lock and reseals on a zero return; the committed value is visible to the next read. Source: main.c (line 125) |
Aborted update leaves a consistent container. A mutator returning a negative errno aborts the transaction. With the redundant shadow the payload is rolled back to the pre-update value; without it the partial write is detectable via the (not resealed) tag. Source: main.c (line 147) |
SAFE_SECTION reseals at scope exit. Modifications made through the typed pointer inside a SAFE_SECTION block are sealed automatically on normal scope exit and visible to the next read. Depends on: Source: main.c (line 181) |
Payload corruption detected; verification is pure. Out-of-band payload corruption is detected by SAFE_VERIFY without modifying the payload (pure check). With the shadow copy the subsequent locked read repairs and reseals; without it the fault is unrecoverable. Source: main.c (line 212) |
verify_repair restores the payload in place safe_data_verify_repair() (lock-held contract) restores a corrupted payload from the shadow copy in place; the container verifies clean afterwards. Depends on: Source: main.c (line 250) |
Unchecked commit reseals an external modification. SAFE_COMMIT re-tags the current contents after an audited direct modification of the storage (only available with CONFIG_SAFE_DATA_ALLOW_UNCHECKED_COMMIT). Depends on: Source: main.c (line 282) |
Stale tag with consistent data recovers. When only the stored tag is corrupted (payload and shadow agree), the fault is recoverable; a locked read makes the reseal durable. Status draft (demonstration of status handling): SD-REQ-009 is also verified by TC_SAFE_DATA_DETECTS_CORRUPTION and TC_SAFE_DATA_VERIFY_REPAIR_FIXES_IN_PLACE. The test still runs. Depends on: Source: main.c (line 319) |
Double fault is unrecoverable. Inconsistent corruption of payload AND shadow leaves no copy to vouch for the data: verification reports -EILSEQ. Depends on: Source: main.c (line 353) |
NULL and zero-size arguments are rejected. Every API entry point rejects missing required pointers and zero-length payloads with -EINVAL (a NULL lock is legal: locking is optional). Each entry point is called once per required pointer and once with a zero length; the locked entry points are also called with a NULL lock and valid arguments, which must succeed. Source: main.c (line 394) |
Optional API surface matches the configuration. SAFE_COMMIT and safe_data_commit() exist only with CONFIG_SAFE_DATA_ALLOW_UNCHECKED_COMMIT, and SAFE_SECTION only with CONFIG_SAFE_DATA_GNU_EXTENSIONS. Where an option is disabled, the macro is not defined and the image links no safe_data_commit(), so a use fails at build time. At the Strict level both are absent. Source: main.c (line 482) |
Concurrent access never yields torn snapshots. A producer mutating dependent fields under SAFE_UPDATE and a consumer using SAFE_READ run concurrently for many iterations; the consumer never observes a snapshot violating the payload invariant. Source: main.c (line 593) |
Self-test reports a healthy mechanism. safe_data_selftest() passes on a healthy system: CRC known-answer test plus a seal/corrupt/detect(/recover) round trip on a scratch container. Depends on: Source: main.c (line 633) |
Statistics count every integrity event. Recovered-payload, recovered-tag and unrecoverable detections each increment their dedicated counter exactly once per detection. Depends on: Source: main.c (line 653) |
Registered handler receives all event kinds. safe_data_fault_handler_register() accepts one callback (second registration is rejected with -EALREADY, re-registration is idempotent) and the callback receives recovery events as well as unrecoverable faults with a populated event descriptor. Source: main.c (line 721) |
Positive mutator return is clamped and aborted. A mutator returning a positive value violates the contract: SAFE_UPDATE returns -EINVAL, the transaction aborts (rollback with shadow), and the violation is counted. Source: main.c (line 777) |
Write observes corruption before overwriting. With CONFIG_SAFE_DATA_WRITE_CHECKS_OLD a write over corrupted contents still succeeds, but the destroyed evidence is counted in the statistics first. Depends on: Source: main.c (line 815) |
Blocked access fails within the lock bound. While another thread holds the container lock, every locked operation (read, write, update, and commit and SAFE_SECTION where configured) fails with -ETIMEDOUT within CONFIG_SAFE_DATA_LOCK_TIMEOUT_MS and each timeout is counted; the container is usable again after the holder releases. Depends on: Source: main.c (line 871) |