use std::fs;
use tempfile::TempDir;
use tidepool_version_manager::go::GoManager;
#[tokio::test]
async fn test_hash_verification_functionality() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let test_file = base_dir.join("test_file.txt");
let test_content = "Hello, World!";
fs::write(&test_file, test_content).expect("无法创建测试文件");
let hash_result = manager.calculate_file_hash(&test_file).await;
assert!(hash_result.is_ok(), "哈希计算应该成功");
let hash_value = hash_result.unwrap();
let expected_hash = "dffd6021bb2bd5b0af676290809ec3a53191dd81c7f70a4b28688a362182986f";
assert_eq!(hash_value, expected_hash, "哈希值应该匹配");
}
#[tokio::test]
async fn test_calculate_file_hash() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let large_content = "X".repeat(10000); let test_cases = vec![
("small.txt", "Hello"),
("medium.txt", "This is a medium-sized test file for SHA256 calculation"),
("large.txt", &large_content),
];
for (filename, content) in test_cases {
let test_file = base_dir.join(filename);
fs::write(&test_file, content).expect("无法创建测试文件");
let result = manager.calculate_file_hash(&test_file).await;
assert!(result.is_ok(), "计算 {filename} 的哈希值应该成功");
let hash = result.unwrap();
assert_eq!(hash.len(), 64, "SHA256 哈希值应该是 64 个字符");
assert!(hash.chars().all(|c| c.is_ascii_hexdigit()), "哈希值应该只包含十六进制字符");
}
}
#[tokio::test]
async fn test_empty_file_hash() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let empty_file = base_dir.join("empty.txt");
fs::write(&empty_file, "").expect("无法创建空文件");
let result = manager.calculate_file_hash(&empty_file).await;
assert!(result.is_ok(), "计算空文件的哈希值应该成功");
let hash = result.unwrap();
let expected_empty_hash = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855";
assert_eq!(hash, expected_empty_hash, "空文件的哈希值应该匹配");
}
#[tokio::test]
async fn test_nonexistent_file_hash() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let nonexistent_file = base_dir.join("nonexistent.txt");
let result = manager.calculate_file_hash(&nonexistent_file).await;
assert!(result.is_err(), "计算不存在文件的哈希值应该失败");
let error = result.unwrap_err();
assert!(error.contains("Failed to open file"), "错误信息应该指出无法打开文件");
}
#[tokio::test]
async fn test_large_file_hash_performance() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let large_file = base_dir.join("large.bin");
let large_content = vec![0u8; 1024 * 1024]; fs::write(&large_file, &large_content).expect("无法创建大文件");
let start = std::time::Instant::now();
let result = manager.calculate_file_hash(&large_file).await;
let duration = start.elapsed();
assert!(result.is_ok(), "计算大文件的哈希值应该成功");
println!("计算 1MB 文件哈希耗时: {duration:?}");
let hash = result.unwrap();
assert_eq!(hash.len(), 64, "SHA256 哈希值应该是 64 个字符");
assert!(hash.chars().all(|c| c.is_ascii_hexdigit()), "哈希值应该只包含十六进制字符");
}
#[tokio::test]
async fn test_hash_consistency() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let content = "This is a test for hash consistency";
let file1 = base_dir.join("file1.txt");
let file2 = base_dir.join("file2.txt");
fs::write(&file1, content).expect("无法创建文件1");
fs::write(&file2, content).expect("无法创建文件2");
let hash1 = manager.calculate_file_hash(&file1).await.expect("计算文件1哈希失败");
let hash2 = manager.calculate_file_hash(&file2).await.expect("计算文件2哈希失败");
assert_eq!(hash1, hash2, "相同内容的文件应该有相同的哈希值");
fs::write(&file2, format!("{content} modified")).expect("无法修改文件2");
let hash2_modified =
manager.calculate_file_hash(&file2).await.expect("计算修改后文件2哈希失败");
assert_ne!(hash1, hash2_modified, "不同内容的文件应该有不同的哈希值");
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[tokio::test]
async fn test_file_verification_workflow() {
let temp_dir = TempDir::new().expect("无法创建临时目录");
let base_dir = temp_dir.path().to_path_buf();
let manager = GoManager::new();
let test_file = base_dir.join("go1.21.0.linux-amd64.tar.gz");
let test_content = "This is a mock Go installation package";
fs::write(&test_file, test_content).expect("无法创建测试文件");
let file_hash = manager.calculate_file_hash(&test_file).await;
assert!(file_hash.is_ok(), "文件哈希计算应该成功");
println!("模拟 Go 安装包哈希值: {}", file_hash.unwrap());
}
}