# Nextest configuration for libsoliton workspace.
#
# Profiles:
#   default      — runs all tests normally
#   miri         — runs only PQ-free tests (safe for MIRI's instruction-level
#                  interpretation; PQ operations like ML-KEM/ML-DSA are tested
#                  upstream by the ml-kem and ml-dsa crates under their own MIRI)

[profile.default]
# Default profile — all tests, no special configuration.

[profile.default.junit]
path = "target/nextest/default/junit.xml"

[profile.miri]
# MIRI profile: skip tests that are impractical under MIRI's instruction-level
# interpreter. Three categories are excluded:
#
#   1. PQ crypto (ML-KEM, ML-DSA, X-Wing keygen/encap/decap) — 2-18 min each;
#      memory safety tested upstream by ml-kem/ml-dsa crate MIRI runs.
#   2. zstd compression (C FFI) — MIRI cannot call foreign function ZSTD_createCCtx.
#   3. Proptest / iteration-heavy tests — hundreds of iterations are wasteful
#      under MIRI; a single iteration already validates UB.
#
# Included (~408 tests):
#   libsoliton (~184):
#     random (4), sha3_256 (6), hmac (12), hkdf (10), aead (11), argon2 (18),
#     x25519 (8), ed25519 (9), xwing combiner/label/from_bytes (9), call (18),
#     storage (33, excluding 3 zstd-dependent + 2 proptests + 1 ignored),
#     constants (2), streaming (22 — empty/error-path/pure-math + 7 small-data
#       MIRI variants; full-chunk tests use 1 MiB AEAD which exceeds MIRI timeout),
#     ratchet/11 (decode_optional_bytes_zero_length_rejected,
#       all_default_rejected_by_root_key_check,
#       all_default_structural_invariant_rejected,
#       recv_seen_cap_in_blob, kdf_msg_key_kat,
#       kdf_msg_key_different_counters_produce_different_keys,
#       kdf_msg_key_different_epochs_produce_different_keys,
#       kdf_root_kat, nonce_from_counter_values, from_bytes_wrong_sized_xwing_sk,
#       reset_zeroes_all_fields),
#     identity from_bytes/3 (public key, secret key, hybrid signature),
#     kex/8 (kex_derivation_kat: from_bytes + HKDF only, no keygen/encap;
#       decode_session_init_*: pure parser, zeroed key bytes, no PQ ops)
#   libsoliton_capi (~262):
#     All error-path and PQ-free happy-path CAPI tests. Covers null-pointer
#     guards, output-zeroing, co-presence guards, and safe round-trips
#     (aead, sha3_256, hmac, hkdf, argon2id, ratchet PQ-free, storage w/o zstd,
#     xwing length-only, verification phrase, streaming). Storage tests use
#     compress=false to avoid the zstd C FFI. Streaming uses ruzstd (pure Rust).
#
# Excluded:
#   libsoliton:
#     PQ-dependent modules: mlkem, mldsa, xwing keygen/round-trip/proptest,
#     identity, auth, most kex, ratchet, verification, integration_kex_ratchet,
#     integration_storage (absent from positive filter; would also fail via zstd C FFI)
#     zstd FFI: encrypt_decrypt_compressed, empty_plaintext_both_modes,
#     invalid_compressed_data
#     streaming full-chunk (1 MiB AEAD per test, exceeds MIRI timeout):
#       all tests using chunk_plaintext() / multi-chunk encrypt-decrypt
#     Iteration-heavy: proptest_derive_round_trip, proptest_round_trip,
#     round_trip_large_plaintext, sign_bit_normalization,
#     boundary_t_cost_accepted, boundary_p_cost_accepted, advance_multiple_steps
#     zeroize_verify tests (use xwing keygen/encapsulate — PQ-heavy)
#     header_up_to_date (spawns cbindgen subprocess — MIRI cannot exec)
#   libsoliton_capi:
#     pq::* in binary libsoliton_capi::capi_tests — xwing/identity/auth/kex PQ round-trips
#     streaming full-chunk CAPI tests (1 MiB AEAD): capi_stream_round_trip_*,
#       capi_stream_random_access, stream_decrypt_chunk_out_too_small,
#       stream_decrypt_chunk_zeros_output_on_failure, stream_decrypt_expected_index_increments
#
# Usage:
#   MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri nextest run \
#     -p libsoliton -p libsoliton_capi --profile miri -j$(nproc)
default-filter = """
  (
    test(/^primitives::random::/)
    | test(/^primitives::sha3_256::/)
    | test(/^primitives::hmac::/)
    | test(/^primitives::hkdf::/)
    | test(/^primitives::aead::/)
    | test(/^primitives::argon2::/)
    | test(/^primitives::x25519::/)
    | test(/^primitives::ed25519::/)
    | test(/^primitives::xwing::tests::combiner_/)
    | test(/^primitives::xwing::tests::label_/)
    | test(/^primitives::xwing::tests::encapsulate_wrong/)
    | test(/^primitives::xwing::tests::decapsulate_wrong/)
    | test(/^primitives::xwing::tests::sk_from_bytes/)
    | test(/^call::/)
    | test(/^storage::/)
    | test(/^constants::/)
    | test(/^ratchet::tests::decode_optional_bytes_zero_length_rejected$/)
    | test(/^ratchet::tests::all_default_rejected/)
    | test(/^ratchet::tests::recv_seen_cap_in_blob$/)
    | test(/^ratchet::tests::kdf_msg_key_kat$/)
    | test(/^ratchet::tests::kdf_msg_key_different_counters_produce_different_keys$/)
    | test(/^ratchet::tests::kdf_msg_key_different_epochs_produce_different_keys$/)
    | test(/^ratchet::tests::kdf_root_kat$/)
    | test(/^ratchet::tests::nonce_from_counter_values$/)
    | test(/^ratchet::tests::from_bytes_wrong_sized_xwing_sk_returns_invalid_data$/)
    | test(/^ratchet::tests::reset_zeroes_all_fields$/)
    | test(/^identity::tests::identity_public_key_from_bytes_wrong_size$/)
    | test(/^identity::tests::identity_secret_key_from_bytes_wrong_size$/)
    | test(/^identity::tests::hybrid_signature_from_bytes_wrong_size$/)
    | test(/^kex::tests::kex_derivation_kat$/)
    | test(/^kex::tests::decode_session_init_/)
    | test(/^streaming::tests::encrypt_decrypt_empty_file$/)
    | test(/^streaming::tests::encrypt_after_finalization$/)
    | test(/^streaming::tests::decrypt_after_finalization$/)
    | test(/^streaming::tests::chunk_too_short$/)
    | test(/^streaming::tests::uncompressed_non_final_wrong_ciphertext_size$/)
    | test(/^streaming::tests::compression_bypassed_for_empty_final$/)
    | test(/^streaming::tests::decrypt_init_wrong_version$/)
    | test(/^streaming::tests::decrypt_init_version_0x02$/)
    | test(/^streaming::tests::decrypt_init_reserved_flags$/)
    | test(/^streaming::tests::nonce_uniqueness_/)
    | test(/^streaming::tests::nonce_injectivity$/)
    | test(/^streaming::tests::base_nonce_freshness$/)
    | test(/^streaming::tests::nonce_derivation_kat$/)
    | test(/^streaming::tests::aad_construction_kat$/)
    | test(/^streaming::tests::header_construction_kat$/)
    | test(/^streaming::tests::miri_/)
    | binary_id(/^libsoliton_capi::capi_tests$/)
  )
  - test(/proptest/)
  - test(/round_trip_large_plaintext/)
  - test(/sign_bit_normalization/)
  - test(/^storage::tests::encrypt_decrypt_compressed$/)
  - test(/^storage::tests::empty_plaintext_both_modes$/)
  - test(/^storage::tests::invalid_compressed_data$/)
  - (test(/^pq::/) & binary_id(/^libsoliton_capi::capi_tests$/))
  - test(/^capi_stream_round_trip/)
  - test(/^capi_stream_random_access$/)
  - test(/^stream_decrypt_chunk_out_too_small$/)
  - test(/^stream_decrypt_chunk_zeros_output_on_failure$/)
  - test(/^stream_decrypt_expected_index_increments$/)
  - test(/concurrent_access_detected/)
  - test(/^primitives::argon2::tests::boundary_t_cost_accepted$/)
  - test(/^primitives::argon2::tests::boundary_p_cost_accepted$/)
  - test(/^call::tests::advance_multiple_steps$/)
  - test(/^header_up_to_date$/)
"""

[[profile.miri.overrides]]
# MIRI is slow even for lightweight tests — extend timeout.
filter = "all()"
slow-timeout = { period = "60s", terminate-after = 4 }
