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

Test Scenarios

Scenario

Tags

Extra config

safe_data.api

safe_data

CONFIG_SAFE_DATA_REDUNDANT=y

safe_data.api.plain

safe_data

CONFIG_SAFE_DATA_REDUNDANT=n

safe_data.api.timeout

safe_data

CONFIG_SAFE_DATA_LOCK_TIMEOUT_MS=20

safe_data.api.strict

safe_data

CONFIG_SAFE_DATA_LEVEL_STRICT=y

safe_data

Test Case: init and verify TC_SAFE_DATA_INIT_AND_VERIFY
status: active
test_function: test_init_and_verify
test_module: tests/safe_data
suite: safe_data
suite_title: 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)

Test Case: read roundtrip TC_SAFE_DATA_READ_ROUNDTRIP
status: active
test_function: test_read_roundtrip
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data

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)

Test Case: write reseals TC_SAFE_DATA_WRITE_RESEALS
status: obsolete
test_function: test_write_reseals
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-006

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)

Test Case: update commits TC_SAFE_DATA_UPDATE_COMMITS
status: active
test_function: test_update_commits
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-007

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)

Test Case: update abort keeps integrity TC_SAFE_DATA_UPDATE_ABORT_KEEPS_INTEGRITY
status: active
test_function: test_update_abort_keeps_integrity
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-007

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)

Test Case: section scope TC_SAFE_DATA_SECTION_SCOPE
status: active
test_function: test_section_scope
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_GNU_EXTENSIONS
verifies: SD-REQ-021

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: CONFIG_SAFE_DATA_GNU_EXTENSIONS

Source: main.c (line 181)

Test Case: detects corruption TC_SAFE_DATA_DETECTS_CORRUPTION
status: active
test_function: test_detects_corruption
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data

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)

Test Case: verify repair fixes in place TC_SAFE_DATA_VERIFY_REPAIR_FIXES_IN_PLACE
status: active
test_function: test_verify_repair_fixes_in_place
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_REDUNDANT

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: CONFIG_SAFE_DATA_REDUNDANT

Source: main.c (line 250)

Test Case: commit reseals external write TC_SAFE_DATA_COMMIT_RESEALS_EXTERNAL_WRITE
status: active
test_function: test_commit_reseals_external_write
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_ALLOW_UNCHECKED_COMMIT
verifies: SD-REQ-022

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: CONFIG_SAFE_DATA_ALLOW_UNCHECKED_COMMIT

Source: main.c (line 282)

Test Case: stale tag recovers TC_SAFE_DATA_STALE_TAG_RECOVERS
status: draft
test_function: test_stale_tag_recovers
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_REDUNDANT
verifies: SD-REQ-009

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: CONFIG_SAFE_DATA_REDUNDANT

Source: main.c (line 319)

Test Case: double fault unrecoverable TC_SAFE_DATA_DOUBLE_FAULT_UNRECOVERABLE
status: active
test_function: test_double_fault_unrecoverable
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_REDUNDANT
verifies: SD-REQ-010

Double fault is unrecoverable.

Inconsistent corruption of payload AND shadow leaves no copy to vouch for the data: verification reports -EILSEQ.

Depends on: CONFIG_SAFE_DATA_REDUNDANT

Source: main.c (line 353)

Test Case: null args TC_SAFE_DATA_NULL_ARGS
status: active
test_function: test_null_args
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-002

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)

Test Case: reduced api surface TC_SAFE_DATA_REDUCED_API_SURFACE
status: active
test_function: test_reduced_api_surface
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-020

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)

Test Case: concurrent access is serialised TC_SAFE_DATA_CONCURRENT_ACCESS_IS_SERIALISED
status: active
test_function: test_concurrent_access_is_serialised
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-016

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)

Test Case: selftest TC_SAFE_DATA_SELFTEST
status: active
test_function: test_selftest
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_SELFTEST
verifies: SD-REQ-017

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: CONFIG_SAFE_DATA_SELFTEST

Source: main.c (line 633)

Test Case: stats count events TC_SAFE_DATA_STATS_COUNT_EVENTS
status: active
test_function: test_stats_count_events
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_STATS
verifies: SD-REQ-012

Statistics count every integrity event.

Recovered-payload, recovered-tag and unrecoverable detections each increment their dedicated counter exactly once per detection.

Depends on: CONFIG_SAFE_DATA_STATS

Source: main.c (line 653)

Test Case: fault handler events TC_SAFE_DATA_FAULT_HANDLER_EVENTS
status: active
test_function: test_fault_handler_events
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data

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)

Test Case: update clamps positive mutator return TC_SAFE_DATA_UPDATE_CLAMPS_POSITIVE_MUTATOR_RETURN
status: active
test_function: test_update_clamps_positive_mutator_return
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
verifies: SD-REQ-008

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)

Test Case: write observes overwritten corruption TC_SAFE_DATA_WRITE_OBSERVES_OVERWRITTEN_CORRUPTION
status: active
test_function: test_write_observes_overwritten_corruption
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_WRITE_CHECKS_OLD; CONFIG_SAFE_DATA_STATS
verifies: SD-REQ-018

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: CONFIG_SAFE_DATA_WRITE_CHECKS_OLD; CONFIG_SAFE_DATA_STATS

Source: main.c (line 815)

Test Case: lock timeout is bounded and reported TC_SAFE_DATA_LOCK_TIMEOUT_IS_BOUNDED_AND_REPORTED
status: active
test_function: test_lock_timeout_is_bounded_and_reported
test_module: tests/safe_data
suite: safe_data
suite_title: safe_data
depends_on: CONFIG_SAFE_DATA_LOCK_TIMEOUT_MS > 0; CONFIG_SAFE_DATA_LOCKING
verifies: SD-REQ-014

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: CONFIG_SAFE_DATA_LOCK_TIMEOUT_MS > 0; CONFIG_SAFE_DATA_LOCKING

Source: main.c (line 871)