diff --git a/extensions/llamacpp-extension/src/backend.ts b/extensions/llamacpp-extension/src/backend.ts index a597a9a15..b47839d58 100644 --- a/extensions/llamacpp-extension/src/backend.ts +++ b/extensions/llamacpp-extension/src/backend.ts @@ -43,9 +43,9 @@ export async function listSupportedBackends(): Promise< if (features.vulkan) supportedBackends.push('win-vulkan-x64') } // not available yet, placeholder for future - else if (sysType == 'windows-aarch64') { + else if (sysType === 'windows-aarch64' || sysType === 'windows-arm64') { supportedBackends.push('win-arm64') - } else if (sysType == 'linux-x86_64') { + } else if (sysType === 'linux-x86_64' || sysType === 'linux-x86') { supportedBackends.push('linux-noavx-x64') if (features.avx) supportedBackends.push('linux-avx-x64') if (features.avx2) supportedBackends.push('linux-avx2-x64') @@ -69,11 +69,11 @@ export async function listSupportedBackends(): Promise< if (features.vulkan) supportedBackends.push('linux-vulkan-x64') } // not available yet, placeholder for future - else if (sysType === 'linux-aarch64') { + else if (sysType === 'linux-aarch64' || sysType === 'linux-arm64') { supportedBackends.push('linux-arm64') - } else if (sysType === 'macos-x86_64') { + } else if (sysType === 'macos-x86_64' || sysType === 'macos-x86') { supportedBackends.push('macos-x64') - } else if (sysType === 'macos-aarch64') { + } else if (sysType === 'macos-aarch64' || sysType === 'macos-arm64') { supportedBackends.push('macos-arm64') } @@ -262,10 +262,7 @@ async function _getSupportedFeatures() { features.cuda12 = true } // Vulkan support check - only discrete GPUs with 6GB+ VRAM - if ( - gpuInfo.vulkan_info?.api_version && - gpuInfo.total_memory >= 6 * 1024 - ) { + if (gpuInfo.vulkan_info?.api_version && gpuInfo.total_memory >= 6 * 1024) { // 6GB (total_memory is in MB) features.vulkan = true } diff --git a/src-tauri/plugins/tauri-plugin-hardware/src/cpu.rs b/src-tauri/plugins/tauri-plugin-hardware/src/cpu.rs index 5b35088cd..926ca04a2 100644 --- a/src-tauri/plugins/tauri-plugin-hardware/src/cpu.rs +++ b/src-tauri/plugins/tauri-plugin-hardware/src/cpu.rs @@ -24,7 +24,7 @@ impl CpuStaticInfo { CpuStaticInfo { name, core_count: System::physical_core_count().unwrap_or(0), - arch: std::env::consts::ARCH.to_string(), + arch: System::cpu_arch(), extensions: CpuStaticInfo::get_extensions(), } } diff --git a/src-tauri/plugins/tauri-plugin-hardware/src/tests.rs b/src-tauri/plugins/tauri-plugin-hardware/src/tests.rs index 394092543..1d4975104 100644 --- a/src-tauri/plugins/tauri-plugin-hardware/src/tests.rs +++ b/src-tauri/plugins/tauri-plugin-hardware/src/tests.rs @@ -1,4 +1,5 @@ use crate::commands::*; +use crate::types::CpuStaticInfo; use tauri::test::mock_app; #[test] @@ -14,3 +15,125 @@ fn test_system_usage() { let usage = get_system_usage(app.handle().clone()); println!("System Usage Info: {:?}", usage); } + +#[cfg(test)] +mod cpu_tests { + use super::*; + + #[test] + fn test_cpu_static_info_new() { + let cpu_info = CpuStaticInfo::new(); + + // Test that all fields are populated + assert!(!cpu_info.name.is_empty()); + assert_ne!(cpu_info.name, "unknown"); // Should have detected a CPU name + assert!(cpu_info.core_count > 0); + assert!(!cpu_info.arch.is_empty()); + + // Architecture should be one of the expected values + assert!( + cpu_info.arch == "aarch64" || + cpu_info.arch == "arm64" || + cpu_info.arch == "x86_64" || + cpu_info.arch == std::env::consts::ARCH + ); + + // Extensions should be a valid list (can be empty on non-x86) + + println!("CPU Info: {:?}", cpu_info); + } + + #[test] + fn test_cpu_info_consistency() { + // Test that multiple calls return consistent information + let info1 = CpuStaticInfo::new(); + let info2 = CpuStaticInfo::new(); + + assert_eq!(info1.name, info2.name); + assert_eq!(info1.core_count, info2.core_count); + assert_eq!(info1.arch, info2.arch); + assert_eq!(info1.extensions, info2.extensions); + } + + #[test] + fn test_cpu_name_not_empty() { + let cpu_info = CpuStaticInfo::new(); + assert!(!cpu_info.name.is_empty()); + assert!(cpu_info.name.len() > 0); + } + + #[test] + fn test_core_count_positive() { + let cpu_info = CpuStaticInfo::new(); + assert!(cpu_info.core_count > 0); + } + + #[test] + #[cfg(any(target_arch = "x86", target_arch = "x86_64"))] + fn test_x86_extensions() { + let cpu_info = CpuStaticInfo::new(); + + // On x86/x86_64, we should always have at least FPU + assert!(cpu_info.extensions.contains(&"fpu".to_string())); + + // Check that all extensions are valid x86 feature names + let valid_extensions = [ + "fpu", "mmx", "sse", "sse2", "sse3", "ssse3", "sse4_1", "sse4_2", + "pclmulqdq", "avx", "avx2", "avx512_f", "avx512_dq", "avx512_ifma", + "avx512_pf", "avx512_er", "avx512_cd", "avx512_bw", "avx512_vl", + "avx512_vbmi", "avx512_vbmi2", "avx512_vnni", "avx512_bitalg", + "avx512_vpopcntdq", "avx512_vp2intersect", "aes", "f16c" + ]; + + for ext in &cpu_info.extensions { + assert!( + valid_extensions.contains(&ext.as_str()), + "Unknown extension: {}", + ext + ); + } + } + + #[test] + #[cfg(not(any(target_arch = "x86", target_arch = "x86_64")))] + fn test_non_x86_extensions() { + let cpu_info = CpuStaticInfo::new(); + + // On non-x86 architectures, extensions should be empty + assert!(cpu_info.extensions.is_empty()); + } + + #[test] + fn test_arch_detection() { + let cpu_info = CpuStaticInfo::new(); + + // Architecture should be a valid string + assert!(!cpu_info.arch.is_empty()); + + // Should be one of the common architectures + let common_archs = ["x86_64", "aarch64", "arm", "arm64", "x86"]; + let is_common_arch = common_archs.iter().any(|&arch| cpu_info.arch == arch); + let is_compile_time_arch = cpu_info.arch == std::env::consts::ARCH; + + assert!( + is_common_arch || is_compile_time_arch, + "Unexpected architecture: {}", + cpu_info.arch + ); + } + + #[test] + fn test_cpu_info_serialization() { + let cpu_info = CpuStaticInfo::new(); + + // Test that the struct can be serialized (since it derives Serialize) + let serialized = serde_json::to_string(&cpu_info); + assert!(serialized.is_ok()); + + let json_str = serialized.unwrap(); + assert!(json_str.contains("name")); + assert!(json_str.contains("core_count")); + assert!(json_str.contains("arch")); + assert!(json_str.contains("extensions")); + } +}