Skip to content

Test Plan

Stephan Zehrer edited this page Jun 23, 2026 · 12 revisions

Test Plan

This page traces every numbered requirement on the Requirements page to a verification method. A requirement is considered verified only when its method is implemented and passing.

Verification methods

Method Meaning
UT Automated unit test (#[cfg(test)], run by cargo test).
Gate Enforced by a tooling gate (cargo clippy, cargo build, review).
Design Verified by design review only; no code yet.
Inspection Verified by reading the source / on-disk artifact.

1. String Store (implemented — v1)

The String Store ships with 7 unit tests in src/string_store.rs.

Test What it covers Requirements
intern_dedups_and_assigns_sequential_ids Dedup; identical content stored once; sequential StrIds; distinct hashes. REQ-10, REQ-11, REQ-12
resolve_by_id_and_hash resolve_id, resolve_hash, id_of, hash_of agree for one string. REQ-11, REQ-12, REQ-19
missing_lookups_return_none Unknown id/hash lookups return None (no panics, no false hits). REQ-19
empty_and_unicode_strings Empty string and multi-byte Unicode round-trip exactly. REQ-14, REQ-17
roundtrip_save_open Save then re-open a single segment; dedup and hash identity survive. REQ-13, REQ-14, REQ-16, REQ-17
multi_block_roundtrip 500 strings across many ~64-byte blocks round-trip in order. REQ-15, REQ-16
open_rejects_corrupt_magic A corrupted header magic is rejected with an error. REQ-18
roundtrip_lz4 Save with LZ4 compression, re-open, all strings resolve correctly. REQ-20
roundtrip_zstd Save with Zstd compression, re-open, all strings resolve correctly. REQ-20

Additional String Store coverage:

Requirement Method Notes
REQ-13 (append-only) Inspection In-RAM model never mutates stored entries; save rewrites a fresh segment via temp + rename.
REQ-17 (CRC + UTF-8 on open) UT (roundtrip_*) + Inspection open re-checks every entry's CRC32 and UTF-8 validity.
REQ-20 (block compression) UT (roundtrip_lz4, roundtrip_zstd) + Bench LZ4 and Zstd algorithms implemented; compression ratio measured in benches/string_store.rs.
REQ-21 (Bloom filter) Design Footer flags reserve the signalling bit; not yet built.
REQ-22 (long-value routing) UT (long_string_routes_to_string_store) Graph::set_str routes strings > 14 bytes into the String Store.
REQ-23 (incremental append) Design v1 rewrites the whole segment.
REQ-24 (lazy decompression) Design (Planned) Blocks currently fully decompressed on open; on-demand per-entry decompression is a future architectural change.
REQ-25 (FSST) Design (Planned) Depends on REQ-24 and a production-ready Arrow-free Rust crate.

2. Node Store (implemented — v1)

The Node Store ships with 10 unit tests in src/node_store.rs.

Test What it covers Requirements
create_assigns_sequential_ids IDs are sequential from 0; len and live_count track correctly. REQ-30, REQ-31
create_typed create_typed sets type_id; first_out defaults to NO_ID. REQ-33
get_out_of_range_returns_none No panic or wrong data for unknown IDs. REQ-30
update_record update overwrites in place; out-of-range returns false. REQ-30
tombstone_sets_dead_flag tombstone sets DEAD; live_count decrements; len unchanged. REQ-33
flags_set_clear_subtype set, clear, with_subtype work independently. REQ-33
roundtrip_save_open Full serialize + deserialize; flags, type_id, first_out all survive. REQ-30, REQ-32
open_rejects_corrupt_header_magic Bad header magic → error. REQ-18 (same principle)
open_rejects_corrupt_record_crc Flipped byte in record region → CRC error on open. REQ-17 (same principle)
no_id_sentinel_never_allocated NO_ID = NodeId::MAX; normal create() never returns it. REQ-31

3. Graph model

Requirement Method Notes
REQ-01 Design Node/Edge/Property model — see General Concepts.
REQ-02 Design "Everything is a node."
REQ-03 Design Compact integer ID addressing.
REQ-04 Design Optional type reference to a class node.

4. Property Store (implemented — v1)

The Property Store ships with 13 unit tests in src/prop_store.rs.

Test What it covers Requirements
encode_decode_edge Edge record encodes end_node and round-trips. REQ-34, REQ-35
encode_decode_none Null/absent value round-trips. REQ-36
encode_decode_bool Bool true/false round-trips. REQ-41
encode_decode_i64 i64 edge cases (0, ±1, MIN, MAX) round-trip. REQ-41
encode_decode_f64 f64 values including PI and extremes round-trip. REQ-41
encode_decode_temporal Date, Time, DateTime, Duration round-trip. REQ-42
encode_decode_ref_types All StrId-referenced types (I128Ref, F128Ref, Uuid, Hash, Geo, StringRef, UrlRef) round-trip. REQ-37, REQ-43, REQ-44
encode_decode_inline_str Short strings (including Unicode) stored inline round-trip. REQ-40
inline_str_too_long_returns_error InlineStr > 14 bytes returns an error, not a panic. REQ-40
create_and_get Sequential PropIds; out-of-range returns None. REQ-34
update_record In-place overwrite; out-of-range returns false. REQ-34
roundtrip_save_open Full serialize + deserialize; all value types survive. REQ-34, REQ-36
open_rejects_corrupt_header_magic Bad header magic → error. REQ-18 (same principle)
open_rejects_corrupt_record_crc Flipped byte in record region → CRC error. REQ-17 (same principle)

4c. Graph API (implemented — v1)

The Graph API ships with 6 unit tests in src/graph.rs.

Test What it covers Requirements
build_a_small_graph Nodes, typed nodes, properties, edges; degree, out_edges, properties accessors. REQ-01, REQ-02, REQ-60, REQ-61, REQ-62
long_string_routes_to_string_store set_str keeps ≤14 bytes inline, routes longer strings to a StringRef; both resolve back. REQ-22, REQ-37, REQ-62
edge_sets_in_out_flags add_edge sets HAS_OUT on the start and HAS_IN on the end. REQ-61
operations_on_unknown_node_error Out-of-range nodes are rejected with an error, not a panic. REQ-60
build_index_matches_adjacency Exported CSR index matches the live adjacency. REQ-38, REQ-60
save_open_roundtrip Persist all four segments and reload; degree, edges, strings survive. REQ-63

4a. Index (implemented — v1)

The Index ships with 7 unit tests in src/index_store.rs.

Test What it covers Requirements
build_groups_records_by_owner CSR groups records per owner; add order preserved; gaps (nodes with no records) handled. REQ-38
unknown_node_returns_empty Out-of-range / record-less nodes return an empty slice; degree is 0. REQ-38
empty_graph A zero-node build yields a valid empty index. REQ-38
owner_out_of_range_is_error An association with owner >= node_count is rejected. REQ-38
roundtrip_save_open Full serialize + deserialize; all neighbour slices survive. REQ-38
open_rejects_corrupt_header_magic Bad header magic → error. REQ-18 (same principle)
open_rejects_corrupt_body_crc Flipped byte in offsets/neighbors region → CRC error. REQ-17 (same principle)

5. Persistent Layer — additional coverage

Requirement Method Notes
REQ-30 UT (Node Store + Prop Store roundtrip tests) Fixed-length records; direct access by ID verified.
REQ-31 UT + Inspection NodeId = u32, PropId = u32; NO_ID/NO_PROP sentinels never allocated by normal create().
REQ-32 UT (roundtrip_save_open in node_store) Option 2 (dedicated node file) implemented and tested.
REQ-33 UT (tombstone_sets_dead_flag, flags_set_clear_subtype) Node flags verified.
REQ-34 UT (prop_store roundtrip tests) 16-byte shared record verified.
REQ-35 UT (encode_decode_edge) Edge record carries end_node; start node is the owning node.
REQ-36 UT (encode/decode tests covering all 17 PropTypes) 16-byte buffer covers all implemented value types.
REQ-37 UT (encode_decode_ref_types) Values > 14 bytes stored in String Store; StrId round-trips.
REQ-38 UT (index_store tests) CSR adjacency; neighbors/degree/save/open verified.

6. Value types

Requirement Method Notes
REQ-40 UT (encode_decode_inline_str, inline_str_too_long_returns_error) Inline ≤14 bytes; overflow error (not panic).
REQ-41 UT (encode_decode_bool, encode_decode_i64, encode_decode_f64) Bool, i64, f64 all verified. i128 via StrId ref (I128Ref/F128Ref).
REQ-42 UT (encode_decode_temporal) Date, Time, DateTime, Duration verified.
REQ-43 UT (encode_decode_ref_types) UUID, Hash, Geo all round-trip via StrId.
REQ-44 UT (encode_decode_ref_types) UrlRef round-trips via StrId.
REQ-45 Design (Planned) VECTOR via optional vector store.
REQ-46 UT (all encode/decode tests) PropType discriminant in byte 0 of every record.

5. Non-functional

Requirement Method Notes
REQ-50 Design Minimal, embeddable footprint.
REQ-51 (no unsafe) Gate (review) No unsafe in our own crates.
REQ-52 (zero warnings) Gate cargo clippy --all-targets -- -D warnings and cargo build clean.
REQ-53 (little-endian) Inspection + UT All on-disk integers written little-endian; round-trip tests confirm.
REQ-54 (MIT) Inspection LICENSE file.
REQ-55 (ACID) N/A Explicitly out of scope for now.

Running the suite

cargo test                                     # unit + doc tests (46 tests)
cargo clippy --all-targets -- -D warnings      # lint gate (zero warnings)
cargo build                                    # zero compiler warnings
cargo bench --bench string_store               # intern / resolve / save / open / compression
cargo bench --bench graph                      # build / traverse / build_index / save+open
cargo bench -- compression_ratio              # compression ratio table (LZ4 vs Zstd vs none)

Clone this wiki locally