提交qiming-mcp-proxy

This commit is contained in:
Codex
2026-06-01 13:03:20 +08:00
parent 9e9486b7c2
commit afb3d9f4e6
394 changed files with 124494 additions and 0 deletions

View File

@@ -0,0 +1,302 @@
//! 集成测试
//!
//! 注意这些测试需要有效的OSS凭证才能运行
//! 设置环境变量 OSS_ACCESS_KEY_ID 和 OSS_ACCESS_KEY_SECRET 来运行实际的OSS操作测试
use oss_client::{
OssClientTrait, OssConfig, OssError, PrivateOssClient, PublicOssClient, defaults,
};
use std::time::Duration;
fn create_private_client_from_env() -> Result<PrivateOssClient, OssError> {
let access_key_id = std::env::var("OSS_ACCESS_KEY_ID").unwrap_or_default();
let access_key_secret = std::env::var("OSS_ACCESS_KEY_SECRET").unwrap_or_default();
if access_key_id.is_empty() || access_key_secret.is_empty() {
return Err(OssError::config("缺少OSS凭证环境变量"));
}
let bucket =
std::env::var("OSS_BUCKET").unwrap_or_else(|_| defaults::PRIVATE_BUCKET.to_string());
let endpoint = std::env::var("OSS_ENDPOINT").unwrap_or_else(|_| defaults::ENDPOINT.to_string());
let region = std::env::var("OSS_REGION").unwrap_or_else(|_| defaults::REGION.to_string());
let upload_directory =
std::env::var("OSS_UPLOAD_DIR").unwrap_or_else(|_| defaults::UPLOAD_DIRECTORY.to_string());
let config = OssConfig::new(
endpoint,
bucket,
access_key_id,
access_key_secret,
region,
upload_directory,
);
PrivateOssClient::new(config)
}
fn create_public_client_from_env() -> Result<PublicOssClient, OssError> {
let access_key_id = std::env::var("OSS_ACCESS_KEY_ID").unwrap_or_default();
let access_key_secret = std::env::var("OSS_ACCESS_KEY_SECRET").unwrap_or_default();
if access_key_id.is_empty() || access_key_secret.is_empty() {
return Err(OssError::config("缺少OSS凭证环境变量"));
}
let bucket =
std::env::var("OSS_PUBLIC_BUCKET").unwrap_or_else(|_| defaults::PUBLIC_BUCKET.to_string());
let endpoint = std::env::var("OSS_ENDPOINT").unwrap_or_else(|_| defaults::ENDPOINT.to_string());
let region = std::env::var("OSS_REGION").unwrap_or_else(|_| defaults::REGION.to_string());
let upload_directory =
std::env::var("OSS_UPLOAD_DIR").unwrap_or_else(|_| defaults::UPLOAD_DIRECTORY.to_string());
let config = OssConfig::new(
endpoint,
bucket,
access_key_id,
access_key_secret,
region,
upload_directory,
);
PublicOssClient::new(config)
}
/// 测试客户端创建
#[test]
fn test_client_creation() {
// 测试从环境变量创建私有客户端
match create_private_client_from_env() {
Ok(client) => {
let config = client.get_config();
assert!(!config.access_key_id.is_empty());
assert!(!config.access_key_secret.is_empty());
assert!(!config.endpoint.is_empty());
assert!(!config.bucket.is_empty());
}
Err(e) => {
assert!(e.is_config_error());
}
}
// 测试从环境变量创建公有客户端
match create_public_client_from_env() {
Ok(client) => {
let config = client.get_config();
assert!(!config.access_key_id.is_empty());
assert!(!config.access_key_secret.is_empty());
assert!(!config.endpoint.is_empty());
assert!(!config.bucket.is_empty());
}
Err(e) => {
assert!(e.is_config_error());
}
}
// 测试使用自定义配置创建公有客户端
let config = OssConfig::new(
defaults::ENDPOINT.to_string(),
defaults::PUBLIC_BUCKET.to_string(),
"test_key_id".to_string(),
"test_key_secret".to_string(),
defaults::REGION.to_string(),
defaults::UPLOAD_DIRECTORY.to_string(),
);
let client = PublicOssClient::new(config).unwrap();
assert_eq!(client.get_config().access_key_id, "test_key_id");
assert_eq!(client.get_config().access_key_secret, "test_key_secret");
}
/// 测试配置验证
#[test]
fn test_config_validation() {
// 测试空的access_key_id
let config = OssConfig::new(
defaults::ENDPOINT.to_string(),
defaults::PUBLIC_BUCKET.to_string(),
"".to_string(),
"secret".to_string(),
defaults::REGION.to_string(),
defaults::UPLOAD_DIRECTORY.to_string(),
);
let result = PublicOssClient::new(config);
assert!(result.is_err());
assert!(result.unwrap_err().is_config_error());
// 测试空的access_key_secret
let config = OssConfig::new(
defaults::ENDPOINT.to_string(),
defaults::PUBLIC_BUCKET.to_string(),
"key_id".to_string(),
"".to_string(),
defaults::REGION.to_string(),
defaults::UPLOAD_DIRECTORY.to_string(),
);
let result = PublicOssClient::new(config);
assert!(result.is_err());
assert!(result.unwrap_err().is_config_error());
}
/// 测试签名URL生成不需要实际OSS连接
#[test]
fn test_signed_url_generation() {
// 私有客户端:签名上传/下载链接
let private_config = OssConfig::new(
defaults::ENDPOINT.to_string(),
defaults::PRIVATE_BUCKET.to_string(),
"test_key_id".to_string(),
"test_key_secret".to_string(),
defaults::REGION.to_string(),
defaults::UPLOAD_DIRECTORY.to_string(),
);
let private_client = PrivateOssClient::new(private_config).unwrap();
let upload_url = private_client.generate_upload_url(
"test/file.txt",
Duration::from_secs(3600),
Some("text/plain"),
);
assert!(upload_url.is_ok());
let url = upload_url.unwrap();
assert!(
url.contains("nuwa-packages.oss-rg-china-mainland.aliyuncs.com")
|| url.contains("edu-nuwa-packages.oss-rg-china-mainland.aliyuncs.com")
);
assert!(url.contains("edu/test/file.txt"));
assert!(url.contains("Expires=") || url.contains("x-oss-expires"));
assert!(url.contains("Signature=") || url.contains("x-oss-signature"));
let download_url =
private_client.generate_download_url("test/file.txt", Some(Duration::from_secs(3600)));
assert!(download_url.is_ok());
let url = download_url.unwrap();
assert!(url.contains("edu/test/file.txt"));
assert!(url.contains("Expires=") || url.contains("x-oss-expires"));
assert!(url.contains("Signature=") || url.contains("x-oss-signature"));
// 公有客户端:下载链接不应包含签名
let public_config = OssConfig::new(
defaults::ENDPOINT.to_string(),
defaults::PUBLIC_BUCKET.to_string(),
"test_key_id".to_string(),
"test_key_secret".to_string(),
defaults::REGION.to_string(),
defaults::UPLOAD_DIRECTORY.to_string(),
);
let public_client = PublicOssClient::new(public_config.clone()).unwrap();
let public_download_url = public_client.generate_download_url("test/file.txt", None);
let url = public_download_url.unwrap();
// 验证URL包含正确的路径但域名可能被替换为自定义域名
assert!(url.contains("edu/test/file.txt"));
// 由于 replace_oss_domain 可能替换域名,我们只验证路径部分
assert!(!url.contains("Expires="));
assert!(!url.contains("Signature="));
}
/// 测试object key生成
#[test]
fn test_object_key_generation() {
let config = OssConfig::new(
defaults::ENDPOINT.to_string(),
defaults::PUBLIC_BUCKET.to_string(),
"test_key_id".to_string(),
"test_key_secret".to_string(),
defaults::REGION.to_string(),
defaults::UPLOAD_DIRECTORY.to_string(),
);
let client = PublicOssClient::new(config).unwrap();
// 测试带文件名的object key生成
let key1 = client.generate_object_key("uploads", Some("document.pdf"));
assert!(key1.starts_with("uploads/"));
assert!(key1.contains("document"));
assert!(key1.ends_with(".pdf"));
// 测试不带文件名的object key生成
let key2 = client.generate_object_key("temp", None);
assert!(key2.starts_with("temp/"));
assert!(key2.contains("file_"));
// 确保生成的key是唯一的
let key3 = client.generate_object_key("uploads", Some("document.pdf"));
assert_ne!(key1, key3);
}
/// 测试错误处理
#[test]
fn test_error_handling() {
// 测试配置错误
let config_err = OssError::config("test config error");
assert!(config_err.is_config_error());
assert!(!config_err.is_network_error());
// 测试网络错误
let network_err = OssError::network("test network error");
assert!(network_err.is_network_error());
assert!(!network_err.is_config_error());
// 测试文件不存在错误
let file_err = OssError::file_not_found("test.txt");
assert!(file_err.is_file_not_found());
// 测试权限错误
let perm_err = OssError::permission("access denied");
assert!(perm_err.is_permission_error());
}
// 以下测试需要有效的OSS凭证只有在设置了环境变量时才会运行
#[tokio::test]
async fn test_actual_oss_operations() -> oss_client::Result<()> {
// 只有在设置了环境变量时才运行
let client = match create_private_client_from_env() {
Ok(client) => client,
Err(_) => {
println!("Skip actual OSS operation test: environment variables not set");
return Ok(());
}
};
println!("Run actual OSS operation test...");
// 测试文件存在性检查(对一个不存在的文件)
let test_key = format!("test/non-existent-{}.txt", chrono::Utc::now().timestamp());
match client.file_exists(&test_key).await {
Ok(exists) => {
assert!(!exists, "不存在的文件应该返回false");
println!("✓ File existence check test passed");
}
Err(e) => {
println!("File existence check failed: {e}");
}
}
// 测试上传小文件
let test_content = b"Hello, OSS!";
let test_key = format!(
"test/integration-test-{}.txt",
chrono::Utc::now().timestamp()
);
match client
.upload_content(test_content, &test_key, Some("text/plain"))
.await
{
Ok(url) => {
println!("✓ File uploaded successfully: {url}");
// 测试文件存在性
match client.file_exists(&test_key).await {
Ok(exists) => {
assert!(exists, "上传的文件应该存在");
println!("✓ The file existence check passes after uploading");
}
Err(e) => println!("File existence check failed: {e}"),
}
// 清理测试文件
match client.delete_file(&test_key).await {
Ok(_) => println!("✓ Test file cleanup successful"),
Err(e) => println!("Test file cleanup failed: {e}"),
}
}
Err(e) => {
println!("File upload failed: {e}");
println!("This may be caused by invalid OSS credentials or insufficient permissions");
}
}
Ok(())
}