5.2 KiB
ATN parser tests and CI
.github/workflows/atn.yml adds a focused parser check on every pull request, merge-group run,
main push, nightly run and manual dispatch. It runs even on unrelated pull requests so its
stable ATN parser gate check is always available for branch protection. Making that check
required is a repository setting; adding the workflow does not change branch protection.
Native platform matrix
| OS image | Executed target |
|---|---|
| Ubuntu 24.04 x64 | x86_64-unknown-linux-gnu |
| Ubuntu 24.04 ARM64 | aarch64-unknown-linux-gnu |
| Windows Server 2025 x64 | x86_64-pc-windows-msvc |
| Windows 11 ARM64 | aarch64-pc-windows-msvc |
| macOS 15 Intel | x86_64-apple-darwin |
| macOS 15 Apple Silicon | aarch64-apple-darwin |
Runner labels are listed in GitHub's hosted-runner reference.
Every leg verifies the runner architecture, runs the parser unit tests, and executes the public parser contract suite in debug and release. These are native test executions, not cross-compile checks. The release check disables LTO to keep CI small while retaining optimized arithmetic behavior. At most three matrix legs run concurrently. Full workspace CI keeps its existing platform selection; this separate job builds only the standalone PSD crate and its dependencies.
The matrix tests CPU parsing and writing. It does not certify graphics drivers, GPU previews, UI cancellation, ATN command conversion/playback, WebAssembly execution or Photoshop parity. Those need their own execution and expected-result checks. Processor architecture coverage is not an exhaustive inventory of CPU models or operating-system versions.
Contract and fixtures
crates/psd/tests/atn_contract.rs exercises the public photocraft_psd::atn::{parse, write} APIs.
Its four committed synthetic fixtures are independently encoded, not generated by the writer
under test. The checks cover:
- Byte-exact parsing/writing, explicit endianness, names, action/step order and empty actions.
- UTF-16 units, including supplementary characters and unpaired surrogates.
- Function keys, modifiers, panel state, enabled state, dialog flags and unknown event names.
- Every descriptor value variant and reference form, including opaque alias/path/raw bytes.
- Exact floating-point bits, including NaN payloads, signed zero and infinities.
- Every truncated fixture, invalid versions/tags, declared action/step limits and excessive descriptor nesting, with passing valid controls.
- Deterministic generated metadata/float cases and seed mutations through the same invariant called by the real fuzz target.
The parser preserves file representation; native engine option semantics remain the
responsibility of crates/engine/src/atn_cmds/tests.rs and future playback regression suites.
Run the focused checks from the repository root:
cargo test --locked -p photocraft-psd --lib atn::tests::
cargo test --locked -p photocraft-psd --test atn_contract
cargo test --locked --release -p photocraft-psd --test atn_contract
Fixtures and their provenance/checksums are documented in
crates/psd/tests/fixtures/atn/README.md. New Photoshop-authored interoperability oracles belong
in the separately pinned photocraft-corpus repository, following the existing corpus policy.
Fuzzing
The dedicated ATN workflow runs the existing psd/atn cargo-fuzz target on Linux nightly and on
manual dispatch. It starts with the four valid fixtures, runs for 60 seconds nightly, and caps
input length at 64 KiB, resident memory at 512 MiB and a single input at five seconds. Manual
runs can select 60, 300 or 600 seconds. The general CI workflow's existing manual fuzz matrix
also includes psd/atn.
The shared invariant in tests/common/atn_roundtrip.rs requires every successfully parsed set
to write and reparse with the same set/action metadata, descriptor structure and floating-point
bits. NaNs are compared by bits before normalization for AST equality, avoiding false failures
from NaN != NaN. Only trailing-input diagnostic warnings are excluded from serialized state.
Canonical output must remain byte-stable on another write.
mkdir -p crates/psd/fuzz/corpus/atn
cp crates/psd/tests/fixtures/atn/*.atn crates/psd/fuzz/corpus/atn/
cd crates/psd
cargo +nightly fuzz run atn -- -max_total_time=60 -max_len=65536 -rss_limit_mb=512 -timeout=5
Run cargo-fuzz where its sanitizer/runtime are supported; the deterministic contract suite runs on every matrix platform. Every real failure gets a minimized committed regression fixture and an expected behavior assertion. Do not hide a failure by adding an ignore or weakening a check.
Evidence and scope
Parser legs upload the exact commit, runner/image, architecture, Rust/Cargo versions, and test logs, including failures. Fuzz runs upload environment details, fixture checksums, the evolved corpus, logs and crash artifacts. Evidence is retained for 14 days. A failed, cancelled or skipped parser matrix prevents the aggregate gate from succeeding.
Local validation on one platform does not establish that hosted jobs have passed. Confirm all six native legs in GitHub Actions before describing the change as verified on that matrix.