Skip to content

Testing Guide

abduznik edited this page Jul 17, 2026 · 8 revisions

Testing Guide

Step-by-step walkthrough for testing libsavesync, based on the spec's suggested first test plan.

Current Test Suites

The project has 7 test suites totaling 360 tests:

Suite File Covers Count
Basic test/test_basic.c DEFAULT mode: register, save, dedup, pull, retention, orphaning 53
Strategy test/test_strategy.c STRATEGY mode: manifest lifecycle, identity resolution (Tier 1/2/3/rom_header/text_pattern), integration 48
Regressions test/test_regressions.c Historical bug regressions (serialize pointer, opaque accessor, dangling pointer, tiebreak) 34
Phase 3 Regressions test/test_phase3_regressions.c Phase 3 risk surfaces (coexistence, dedup after identity failure, shape mismatch, retention + game_id, metadata round-trip, hash-DB callback, template resolution, collision risk) 72
Real Manifests test/test_real_manifests.c Integration against 8 platform manifests (PCSX2 folder/file, PPSSPP, RPCS3, DuckStation, Dolphin GC, RetroArch SNES, Ryujinx) 96
ROM Header Identity test/test_rom_header_identity.c SV_IDENTITY_ROM_HEADER: ASCII extraction, hex fallback, file-not-found, manifest round-trip, Dolphin GC integration, no-regression 22
IPC Integration test/test_ipc.c IPC binary: init, manifest_load, register_with_manifest, save, pull, list_entries, list_registrations, error cases (malformed JSON, unknown method, missing param), shutdown 35

Running Tests

make test       # builds and runs all seven suites

Individual suites can be built and run manually from build/:

./build/test_basic
./build/test_strategy
./build/test_regressions
./build/test_phase3_regressions
./build/test_real_manifests
./build/test_rom_header_identity
./build/test_ipc

Test Classification: Invariant vs Snapshot

Every test is classified as either:

  • INVARIANT — asserts a rule that must always hold regardless of implementation details (e.g., "dedup must skip when hash matches most recent entry")
  • SNAPSHOT — checks today's specific output/return value (e.g., "sv_save returns SV_OK")

Invariant tests are more valuable because they survive refactors. The full classification is in docs/test-audit.md (engineering working note).

Test Order Rationale

The original test plan (from the spec) validated the hardest-to-get-right parts first:

  • Atomicity (temp file + rename)
  • Conflict handling (report vs override)
  • Retention (FIFO eviction)
  • ABI shape (opaque structs, zero-default fields)

...all against zero-risk fake data, deferring emulator-specific complexity to last.

Adding New Tests

See CONTRIBUTING.md for the full regression test convention and guidelines on where to add new tests.


See also: Architecture-Overview | Layer-4-Local-Save-and-Pull | Layer-5-Retention-and-Rotation | Examples

Clone this wiki locally