#[cfg(test)]
extern crate std;
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(not(miri))] fn test_get_returns_valid() {
let det = get();
assert_eq!(det.arch, Arch::current());
}
#[test]
#[cfg(not(miri))] fn test_detect_uncached_consistent() {
let d1 = detect_uncached();
let d2 = detect_uncached();
assert_eq!(d1.caps, d2.caps);
assert_eq!(d1.arch, d2.arch);
}
#[test]
#[cfg(not(miri))] #[cfg(not(feature = "portable-only"))]
fn test_convenience_functions() {
let det = get();
assert_eq!(caps(), det.caps);
assert_eq!(arch(), det.arch);
}
#[test]
#[cfg(all(feature = "portable-only", not(miri)))]
fn test_caps_returns_none_with_portable_only_feature() {
assert_eq!(caps(), Caps::NONE, "portable-only must zero out caps()");
let det = get();
assert_eq!(arch(), det.arch);
}
#[test]
#[cfg(all(target_arch = "x86_64", not(miri)))]
fn test_x86_64_baseline() {
use crate::platform::caps::x86;
let det = get();
assert!(det.caps.has(x86::SSE2));
}
#[test]
#[cfg(all(target_arch = "aarch64", not(miri)))]
fn test_aarch64_baseline() {
use crate::platform::caps::aarch64;
let det = get();
assert!(det.caps.has(aarch64::NEON));
}
#[test]
#[cfg(miri)]
fn test_miri_returns_portable() {
let det = get();
assert_eq!(det.caps, Caps::NONE);
assert_eq!(det.arch, Arch::Other);
}
#[test]
fn test_caps_static_is_const() {
const STATIC_CAPS: Caps = caps_static();
let _ = STATIC_CAPS; }
#[test]
#[cfg(target_arch = "x86_64")]
fn test_caps_static_x86_64_baseline() {
use crate::platform::caps::x86;
let caps = caps_static();
assert!(caps.has(x86::SSE2), "x86_64 must have SSE2 baseline in caps_static");
}
#[test]
#[cfg(target_arch = "aarch64")]
fn test_caps_static_aarch64_baseline() {
use crate::platform::caps::aarch64;
let caps = caps_static();
assert!(
caps.has(aarch64::NEON),
"aarch64 must have NEON baseline in caps_static"
);
}
#[test]
#[cfg(not(miri))] #[cfg(not(feature = "portable-only"))]
fn test_caps_static_subset_of_runtime() {
let static_caps = caps_static();
let runtime_caps = caps();
assert!(
runtime_caps.has(static_caps),
"caps_static() must be subset of caps(): static={:?}, runtime={:?}",
static_caps,
runtime_caps
);
}
#[test]
fn test_caps_static_consistent() {
let a = caps_static();
let b = caps_static();
assert_eq!(a, b, "caps_static() must be deterministic");
}
#[test]
#[cfg(all(target_arch = "x86_64", not(miri)))]
fn test_caps_static_x86_features() {
use crate::platform::caps::x86;
let caps = caps_static();
if cfg!(target_feature = "avx2") {
assert!(caps.has(x86::AVX2), "AVX2 must be detected when target_feature enabled");
}
if cfg!(target_feature = "avx512f") {
assert!(
caps.has(x86::AVX512F),
"AVX512F must be detected when target_feature enabled"
);
}
if cfg!(target_feature = "vpclmulqdq") {
assert!(
caps.has(x86::VPCLMULQDQ),
"VPCLMULQDQ must be detected when target_feature enabled"
);
}
}
#[test]
#[cfg(all(target_arch = "aarch64", not(miri)))]
fn test_caps_static_aarch64_features() {
use crate::platform::caps::aarch64;
let caps = caps_static();
if cfg!(target_feature = "aes") {
assert!(
caps.has(aarch64::AES),
"AES must be detected when target_feature enabled"
);
assert!(
caps.has(aarch64::PMULL),
"PMULL must be detected when aes target_feature enabled"
);
}
if cfg!(target_feature = "sha3") {
assert!(
caps.has(aarch64::SHA3),
"SHA3 must be detected when target_feature enabled"
);
assert!(
caps.has(aarch64::SHA512),
"SHA512 must be detected when sha3 target_feature enabled"
);
}
if cfg!(target_feature = "sme") {
assert!(
caps.has(aarch64::SME),
"SME must be detected when target_feature enabled"
);
}
}
#[test]
#[cfg(all(target_arch = "aarch64", target_os = "macos", feature = "std", not(miri)))]
fn test_apple_silicon_detection_runs() {
let chip_gen = detect_apple_silicon_gen();
if let Some(detected) = chip_gen {
assert!(matches!(
detected,
AppleSiliconGen::M1 | AppleSiliconGen::M2 | AppleSiliconGen::M3 | AppleSiliconGen::M4
));
}
}
#[test]
#[cfg(all(target_arch = "aarch64", target_os = "linux", not(miri)))]
fn test_sve_vlen_detection_runs() {
let vlen = detect_sve_vlen();
if vlen > 0 {
assert!(vlen >= 128, "SVE VL too small: {vlen}");
assert!(vlen <= 2048, "SVE VL too large: {vlen}");
assert!(vlen.is_power_of_two(), "SVE VL not power of 2: {vlen}");
}
}
#[test]
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "std"))]
fn test_is_intel_hybrid_amd_returns_false() {
assert!(!is_intel_hybrid(true, 6, 0x97)); assert!(!is_intel_hybrid(true, 25, 0)); assert!(!is_intel_hybrid(true, 26, 0)); }
#[test]
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "std"))]
fn test_is_intel_hybrid_known_models() {
assert!(is_intel_hybrid(false, 6, 0x97)); assert!(is_intel_hybrid(false, 6, 0x9A));
assert!(is_intel_hybrid(false, 6, 0xB7)); assert!(is_intel_hybrid(false, 6, 0xBA));
assert!(!is_intel_hybrid(false, 6, 0x8F)); assert!(!is_intel_hybrid(false, 6, 0x6A)); }
#[test]
#[allow(unsafe_code)]
#[cfg(all(any(target_arch = "x86_64", target_arch = "x86"), feature = "std"))]
fn test_hybrid_avx512_override_default() {
unsafe { std::env::remove_var("RSCRYPTO_FORCE_AVX512") };
assert!(!hybrid_avx512_override());
}
#[test]
#[cfg(all(target_arch = "x86_64", not(miri)))]
fn test_x86_64_model_extraction() {
let det = detect_uncached();
assert_eq!(det.arch, Arch::X86_64);
assert!(det.caps.count() >= 1);
}
#[test]
#[cfg(all(
target_arch = "aarch64",
not(miri),
any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos")
))]
fn test_macos_extended_features() {
use crate::platform::caps::aarch64;
let det = get();
std::eprintln!("Detected features: {}", det.caps.count());
std::eprintln!(" I8MM: {}", det.caps.has(aarch64::I8MM));
std::eprintln!(" BF16: {}", det.caps.has(aarch64::BF16));
std::eprintln!(" FRINTTS: {}", det.caps.has(aarch64::FRINTTS));
std::eprintln!(" LSE2: {}", det.caps.has(aarch64::LSE2));
assert!(det.caps.has(aarch64::FRINTTS), "FRINTTS should be detected on M1+");
}
#[test]
#[cfg(all(
target_arch = "aarch64",
feature = "std",
not(miri),
any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos")
))]
fn test_detect_apple_sme_features_exists() {
let sme_caps = detect_apple_sme_features();
std::eprintln!("SME caps detected: {}", sme_caps.count());
std::eprintln!(" SME: {}", sme_caps.has(crate::platform::caps::aarch64::SME));
std::eprintln!(" SME2: {}", sme_caps.has(crate::platform::caps::aarch64::SME2));
}
#[test]
#[cfg(all(
target_arch = "aarch64",
feature = "std",
not(miri),
any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos")
))]
fn test_detect_apple_silicon_gen_exists() {
if let Some(chip_gen) = detect_apple_silicon_gen() {
std::eprintln!("Detected Apple Silicon generation: {:?}", chip_gen);
match chip_gen {
AppleSiliconGen::M1 | AppleSiliconGen::M2 | AppleSiliconGen::M3 => {
std::eprintln!("M1-M3 chip detected (no SME expected)");
}
AppleSiliconGen::M4 => {
std::eprintln!("M4 chip detected (SME expected)");
}
AppleSiliconGen::M5 => {
std::eprintln!("M5 chip detected (SME2 expected)");
}
}
} else {
std::eprintln!("Unknown or A-series chip detected");
}
}
fn test_arch_to_u8(arch: Arch) -> u8 {
match arch {
Arch::X86_64 => 1,
Arch::X86 => 2,
Arch::Aarch64 => 3,
Arch::Arm => 4,
Arch::Riscv64 => 5,
Arch::Riscv32 => 6,
Arch::Power => 7,
Arch::S390x => 8,
Arch::Wasm32 => 10,
Arch::Wasm64 => 11,
Arch::Other => 0,
}
}
fn test_arch_from_u8(v: u8) -> Arch {
match v {
1 => Arch::X86_64,
2 => Arch::X86,
3 => Arch::Aarch64,
4 => Arch::Arm,
5 => Arch::Riscv64,
6 => Arch::Riscv32,
7 => Arch::Power,
8 => Arch::S390x,
10 => Arch::Wasm32,
11 => Arch::Wasm64,
_ => Arch::Other,
}
}
#[test]
fn test_arch_round_trip() {
let variants: &[Arch] = &[
Arch::Other,
Arch::X86_64,
Arch::X86,
Arch::Aarch64,
Arch::Arm,
Arch::Riscv64,
Arch::Riscv32,
Arch::Power,
Arch::S390x,
Arch::Wasm32,
Arch::Wasm64,
];
for &arch in variants {
let encoded = test_arch_to_u8(arch);
let decoded = test_arch_from_u8(encoded);
assert_eq!(
arch, decoded,
"Arch round-trip failed: {:?} -> {} -> {:?}",
arch, encoded, decoded
);
}
assert_eq!(test_arch_from_u8(12), Arch::Other);
assert_eq!(test_arch_from_u8(255), Arch::Other);
}
#[test]
fn test_arch_no_collisions() {
use alloc::collections::BTreeSet;
let variants: &[Arch] = &[
Arch::Other,
Arch::X86_64,
Arch::X86,
Arch::Aarch64,
Arch::Arm,
Arch::Riscv64,
Arch::Riscv32,
Arch::Power,
Arch::S390x,
Arch::Wasm32,
Arch::Wasm64,
];
let mut seen = BTreeSet::new();
for &arch in variants {
let val = test_arch_to_u8(arch);
assert!(
seen.insert(val),
"Arch::{:?} has duplicate encoded u8 value {}",
arch,
val
);
}
assert_eq!(seen.len(), 11, "Expected 11 Arch variants with unique encodings");
}
#[test]
fn test_has_override_exists() {
let _ = has_override();
}
#[test]
fn test_detected_portable_constructor() {
let det = Detected::portable();
assert_eq!(det.caps, Caps::NONE);
assert_eq!(det.arch, Arch::Other);
}
#[test]
fn test_detected_equality() {
let a = Detected::portable();
let b = Detected::portable();
assert_eq!(a, b);
let c = Detected {
caps: Caps::bit(0),
arch: Arch::X86_64,
};
assert_ne!(a, c);
}
#[test]
fn test_detected_debug() {
let det = Detected::portable();
let s = alloc::format!("{:?}", det);
assert!(s.contains("Detected"));
assert!(s.contains("caps"));
assert!(s.contains("arch"));
}
}