hasp-core 0.2.0-alpha

Core contracts, errors, and traits for hasp.
Documentation
//! Tests for the `memory-lock` Cargo feature.
//!
//! These tests exercise `lock_secret_pages` and `wrap_secret` at the
//! library level. They are compiled only when the `memory-lock` feature
//! is active; `cargo test --features memory-lock` runs them.
//!
//! Note on mlock availability: Linux CI runners have `RLIMIT_MEMLOCK`
//! set to 64 KiB by default, but the runner usually runs as root or
//! in a cgroup that has no limit. If the mlock syscall returns EAGAIN,
//! the test asserts `applied == false` (graceful degrade), not an error.

#[cfg(feature = "memory-lock")]
mod memory_lock_tests {
    use hasp_core::lock_secret_pages;
    use hasp_core::secret_mem::wrap_secret;
    use hasp_core::ExposeSecret;

    #[test]
    fn lock_pages_returns_at_least_one_outcome_on_non_empty_input() {
        let bytes = b"top-secret-value-do-not-log";
        let outcomes = lock_secret_pages(bytes);
        assert!(
            !outcomes.is_empty(),
            "lock_secret_pages must return at least one outcome on supported platforms"
        );
        // Report what happened — graceful degrade is acceptable.
        for o in &outcomes {
            eprintln!(
                "memory-lock: {} applied={} note={:?}",
                o.name, o.applied, o.note
            );
        }
    }

    #[test]
    fn lock_pages_returns_empty_for_zero_length_slice() {
        let outcomes = lock_secret_pages(&[]);
        // An empty slice has no pages to lock — no-op is correct.
        assert!(
            outcomes.is_empty(),
            "empty input should produce no lock attempts"
        );
    }

    #[test]
    fn wrap_secret_constructs_accessible_secret() {
        let s = wrap_secret("my-value".into());
        assert_eq!(s.expose_secret(), "my-value");
    }

    #[test]
    fn wrap_secret_on_large_string_does_not_panic() {
        // A 256-byte string spans multiple pages; exercise the
        // page-range boundary calculation.
        let large = "x".repeat(256);
        let s = wrap_secret(large.clone());
        assert_eq!(s.expose_secret(), &large);
    }
}