# Testing
## Overview
ASX has a multi-layer test strategy:
| Unit tests | `src/**` (`#[cfg(test)]`) | Individual functions, edge cases |
| Integration tests | `tests/` | End-to-end protocol flows, concurrency |
| Property tests | `tests/profile_property_invariants.rs` | Randomized profile stack invariants |
| Interop matrix | `tests/fixtures/interop/` | Governed fixture corpus across strict/relaxed modes |
| WS-Security vectors | `tests/wssec_c14n_vectors.rs`, `tests/wssec_strict_matrix.rs` | C14N golden vectors, strict signature/reference verification |
| Session isolation | `tests/session_isolation_concurrency.rs` | Per-session policy isolation under concurrency |
| Fuzz / adversarial | `artifacts/fuzz/` | Adversarial inputs to profile loader, policy resolver, wire parser |
| Performance gate | `xtask/` | Regression detection against baseline ns/op values |
---
## Running the Full Test Suite
```bash
cargo test --all-features
```
Runs all 224+ unit and integration tests. Zero failures expected.
Run specific feature combinations:
```bash
cargo test --features "as2,client"
cargo test --features "as4,server"
cargo test --features "as2,as4,client,server"
```
---
## Integration Test Suites
### AS2 flows
```bash
cargo test --all-features as2_send_golden
cargo test --all-features as2_receive_mdn
```
Covers: MIME packaging, MIC computation (RFC 4130 §7.3.1), MDN generation/parsing, MDN signature verification, sync/async MDN modes, `As2MdnMode::None`.
### AS4 flows
```bash
cargo test --all-features as4_push_flow
cargo test --all-features as4_pull_flow
```
Covers: SOAP envelope construction, WS-Security signing and verification, AES-128-GCM encrypt/decrypt, RSA-OAEP/MGF1-SHA256 key wrap, pull store enqueue/dequeue, signed pull request generation, Two-Way MEP correlation, Test Service detection.
---
## Interop Fixture Repository
The interop fixture corpus governs AS2 MIME and AS4 SOAP strict/relaxed flows with declared expected outcomes.
### Fixture catalog
Location: `tests/fixtures/interop/catalog.json`
Schema (`schema_version: "1.0"`):
```json
{
"schema_version": "1.0",
"fixtures": [
{
"fixture_id": "as2-strict-001",
"protocol": "As2Mime",
"mode": "Strict",
"grouping": {
"partner_id": "partner-a",
"profile_name": "strict-edelivery",
"protocol_stage": "send"
},
"payload_path": "partner-a/strict/send/payload.mime",
"expected_outcome": "SuccessConfirmed",
"reason_annotations": ["RFC 4130 §6 compliant headers, signed"]
}
]
}
```
### Required coverage
The catalog must contain at least one fixture for each combination:
- `As2Mime/Strict`
- `As2Mime/Relaxed`
- `As4Soap/Strict`
- `As4Soap/Relaxed`
### Validate the repository
```bash
cargo run -p xtask -- fixture-repo-validate tests/fixtures/interop/catalog.json
```
Validation checks: schema version, non-empty fixture set, unique IDs, non-empty grouping metadata, non-empty reason annotations, payload file existence, protocol-specific file extension (`.mime` for AS2, `.xml` for AS4).
---
## Interop Matrix Executor
Runs all interop fixtures across policy/profile combinations and produces a machine-readable `MatrixSummary`:
```bash
cargo run -p xtask --all-features -- interop-matrix \
tests/fixtures/interop/catalog.json \
tests/fixtures/interop/quarantine.json \
3 # iteration count for flake detection
# or:
scripts/run_interop_matrix.sh
```
`MatrixSummary` output includes per-fixture pass/fail, observed error code, flakiness status, and quarantine owner.
### Quarantine policy
Flaky fixtures are allowed in CI only when listed in `tests/fixtures/interop/quarantine.json` with an owner assignment. Unquarantined flaky fixtures are blocking. The matrix runner exits non-zero when:
- Any fixture fails
- Any fixture is flaky without a quarantine entry
---
## WS-Security Canonicalization Golden Vectors
`tests/wssec_c14n_vectors.rs` validates the custom Exclusive C14N implementation against deterministic golden vectors:
```bash
cargo test --all-features wssec_c14n_vectors
cargo test --all-features wssec_strict_matrix
# Run as explicit gate:
scripts/run_wssec_vector_gate.sh
# or:
cargo run -p xtask --all-features -- wssec-vector-gate
```
Covered scenarios:
- Strict canonicalization against golden vector file
- Signature reference verification for a signed fixture
- Wrapped reference URI rejection under strict URI normalization rules
- Whitespace-preserving digest mismatch rejection under strict canonicalization rules
- Namespace propagation, attribute ordering, text/attribute escaping
- PI node forwarding, comment stripping, comment preservation
- InclusiveNamespaces PrefixList with ancestor binding rendering
Vector mismatch output uses `canonical_vector_diff(expected, actual)` — deterministic line-based diffs with expected/actual markers for reproducible triage.
---
## Session Isolation and Concurrency
`tests/session_isolation_concurrency.rs` validates session-scoped policy isolation under concurrent execution:
```bash
cargo test --all-features session_isolation_concurrency
```
Covered:
- Strict and relaxed session pairs executing concurrently without policy leakage
- Session-scoped exception behavior remains isolated
- Cross-session contamination attempts fail
- Per-session event ordering validated for critical audit/signing sequences
- AS2 concurrent strict-vs-relaxed MDN boundary-quirk flow
- AS4 concurrent strict-vs-relaxed UserMessage parse flow
---
## Property Tests
`tests/profile_property_invariants.rs` uses randomized inputs to verify profile stack invariants:
```bash
cargo test --all-features profile_property_invariants
```
Covered invariants:
- Deterministic resolution stability under randomized layer combinations (same input always produces same output)
- Monotonic precedence for partner overlays (last applicable partner layer wins)
- Fail-fast validation for malformed/conflicting policy combinations
---
## Fuzz and Adversarial Testing
The adversarial fuzz gate runs seeded adversarial cases over three targets:
1. **Profile loader** — `RegionalProfilePack::from_json` + regional pack application
2. **Policy resolver** — `ProfileStack::validate` + `resolve` determinism
3. **Wire parsing** — `WireEnvelope::from_http_request_with_limits`, stream bounded reads, transfer fingerprinting
```bash
scripts/run_fuzz_gate.sh 4000 2500 artifacts/fuzz
# or:
cargo run -p xtask --all-features -- fuzz-gate 4000 2500 artifacts/fuzz
```
Arguments: `[iterations] [budget_ms] [output_dir]`
Fail conditions:
- Any panic
- Determinism violation (different output for same input)
- Missing remediation hints or empty error messaging
- Stream/accounting mismatch
**Reproducer handling**: On failure, the gate minimizes the input payload by deterministic truncation and stores a reproducer in `artifacts/fuzz/reproducers/` as JSON with base64 bytes. CI uploads `artifacts/fuzz/` as a triage artifact.
---
## Performance Gate
Reference baseline values (ns/op):
| `as2_sign_encrypt` | 8 262 |
| `as2_mdn_generation` | 200 |
| `as2_verify_decrypt_mdn` | 2 072 |
| `as4_verify_decrypt` | 42 |
| `as4_verify_decrypt_receipt` | 5 962 |
| `as4_receipt_generation` | 59 |
These values are environment-relative. CI enforces a **25% maximum regression** threshold. Do not use them for absolute hardware claims.
Run the performance gate:
```bash
# Write new baseline:
cargo run --release -p xtask --all-features -- \
perf-gate --iterations 2000 --write-baseline docs/perf-baseline.txt
# Check against baseline (fails if any operation regresses >25%):
cargo run --release -p xtask --all-features -- \
perf-gate --iterations 2000 --check-baseline docs/perf-baseline.txt --max-regression 0.25
```
---
## Transport Server Tests (No Network)
Server handler tests use `tower::ServiceExt::oneshot` — no listening socket required:
```toml
[dev-dependencies]
tower = { version = "0.4", features = ["util"] }
```
```rust
use tower::ServiceExt;
let response = as2_router(Arc::new(handler), "/as2/receive")
.oneshot(request)
.await
.unwrap();
assert_eq!(response.status(), 200);
```
12 server integration tests ship with the crate and run as part of `cargo test --all-features`.
---
## Testing Feature Flag
```toml
asx-rs = { version = "0.2", features = ["testing"] }
```
The `testing` feature exposes `asx_rs::fixtures` and `asx_rs::matrix` — test scaffold modules with `InteropFixtureMetadata`, `FixtureCatalog`, `MatrixSummary`, and related helpers. These are not part of the production library surface and are absent from builds without this feature.