Testing¶
The required local quality gate is:
cargo fmt --check
cargo clippy --workspace --all-targets --all-features -- -D warnings
cargo test --workspace --all-features
cargo doc --workspace --all-features --no-deps
cargo deny check
On Windows, test postproject-ffi in a separate Cargo invocation from the rest
of the workspace. The public CLI executable and native library intentionally
share the installed name postproject, and concurrent MSVC links otherwise race
to write the same PDB file. CI runs both invocations sequentially, so no test
coverage is omitted.
A separate locked all-targets compile uses Rust 1.85.0, enforcing the stated minimum supported Rust version independently of the stable-toolchain test matrix.
Tests use real temporary SQLite databases and filesystems, a checked-in schema-0 migration fixture, and the complete multi-asset relocation scenario. Dedicated fuzz targets cover production opening, fingerprint input, C strings/errors, and ID parsing outside standard CI. Tests must not require network access, user locale, or wall-clock timing.
cargo-deny rejects wildcard dependencies, unknown sources, known advisories, and
licenses outside the repository’s explicit permissive allowlist. Duplicate crate
versions are reported for review because platform support and MSRV constraints can
make them temporarily unavoidable.
The C ABI job builds the optimized shared library, compiles a standalone C11
consumer using only the public header, runs create/open/error operations, and
compares the exported dynamic symbols against tests/abi/expected-symbols.txt.
The native package matrix installs the platform library, optional static archive,
C and C++ headers, CMake package files, and pkg-config metadata into temporary
prefixes on Linux, macOS, and Windows. It then configures a separate C11/C++17
CMake production against each prefix, builds with warnings denied, and runs
lifecycle, identity, transaction commit/rollback, relocation,
structured-evidence, confirmation, move-ownership, and error-propagation checks.
The consumer configuration and build never invokes Cargo. Each platform package
is uploaded as a CI artifact. The same job builds and runs the C and C++
quickstarts from their installed locations and runs the installed Python
quickstart against the packaged media fixture.
Every code example in the guides is an extract of a program that CI runs. The
code-variants Sphinx directive reads [name] … [/name] comment regions
from docs/examples/{c,cpp,python,cli} and from the
postproject-doc-examples workspace test, and the strict documentation build
fails when an example is neither present nor explicitly marked unavailable for
a surface. The Rust program runs under cargo test --workspace. The native
package job configures docs/examples against the installed prefix and runs one
shared scenario per surface through CTest: create a production, import media,
attach an identifier and metadata, move the media and confirm the relocated
candidate, add an image sequence, record provenance, drain the revision feed,
and round-trip a host binding. The CLI script needs bash and jq and is
skipped on Windows.
The native sanitizer job rebuilds both consumers with AddressSanitizer and UndefinedBehaviorSanitizer, enables leak detection, and runs their real lifecycle and transaction workflows against the release shared library.
The CLI integration test creates a production, imports media, removes the known file, discovers two byte-identical candidates under a configured root, verifies an explicit ambiguous representation and resource result, confirms one candidate, and reopens the production to observe the persisted locator. Commands exchange JSON in this test so the machine-readable contract is exercised alongside the domain workflow.
The storage E2E test moves a three-file media directory, verifies every known locator is offline, resolves two unique resources, refuses to choose between two byte-identical candidates for the third, explicitly confirms all choices in one transaction, reopens the production, and resolves from persisted locators with no roots supplied.
The iteration-two E2E test creates four representations on one asset, attaches typed metadata and an external identifier, records proxy-generation provenance, and verifies one atomic semantic revision. It then moves the single-file and compound media, discovers and confirms replacement locators, retires the old locators and root, removes one sequence frame, and verifies the resulting online/partial states and second revision after reopen.