mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-04-02 18:12:05 +08:00
The previous cleanup logic only sent a shutdown signal but didn't wait for the proxy server to actually stop. This caused a race condition where the app would exit before cleanup completed, leaving Live configs in an inconsistent state. Changes: - Add `server_handle` field to ProxyServer to track the spawned task - Modify `stop()` to wait for server task completion (5s timeout) - Add 100ms delay before process exit to ensure I/O flush - Export ProxyService and fix test files that were missing proxy_service field
65 lines
2.3 KiB
Rust
65 lines
2.3 KiB
Rust
use std::path::{Path, PathBuf};
|
||
use std::sync::{Arc, Mutex, OnceLock};
|
||
|
||
use cc_switch_lib::{update_settings, AppSettings, AppState, Database, MultiAppConfig, ProxyService};
|
||
|
||
/// 为测试设置隔离的 HOME 目录,避免污染真实用户数据。
|
||
pub fn ensure_test_home() -> &'static Path {
|
||
static HOME: OnceLock<PathBuf> = OnceLock::new();
|
||
HOME.get_or_init(|| {
|
||
let base = std::env::temp_dir().join("cc-switch-test-home");
|
||
if base.exists() {
|
||
let _ = std::fs::remove_dir_all(&base);
|
||
}
|
||
std::fs::create_dir_all(&base).expect("create test home");
|
||
std::env::set_var("HOME", &base);
|
||
#[cfg(windows)]
|
||
std::env::set_var("USERPROFILE", &base);
|
||
base
|
||
})
|
||
.as_path()
|
||
}
|
||
|
||
/// 清理测试目录中生成的配置文件与缓存。
|
||
pub fn reset_test_fs() {
|
||
let home = ensure_test_home();
|
||
for sub in [".claude", ".codex", ".cc-switch", ".gemini"] {
|
||
let path = home.join(sub);
|
||
if path.exists() {
|
||
if let Err(err) = std::fs::remove_dir_all(&path) {
|
||
eprintln!("failed to clean {}: {}", path.display(), err);
|
||
}
|
||
}
|
||
}
|
||
let claude_json = home.join(".claude.json");
|
||
if claude_json.exists() {
|
||
let _ = std::fs::remove_file(&claude_json);
|
||
}
|
||
|
||
// 重置内存中的设置缓存,确保测试环境不受上一次调用影响
|
||
let _ = update_settings(AppSettings::default());
|
||
}
|
||
|
||
/// 全局互斥锁,避免多测试并发写入相同的 HOME 目录。
|
||
pub fn test_mutex() -> &'static Mutex<()> {
|
||
static MUTEX: OnceLock<Mutex<()>> = OnceLock::new();
|
||
MUTEX.get_or_init(|| Mutex::new(()))
|
||
}
|
||
|
||
/// 创建测试用的 AppState,包含一个空的数据库
|
||
pub fn create_test_state() -> Result<AppState, Box<dyn std::error::Error>> {
|
||
let db = Arc::new(Database::init()?);
|
||
let proxy_service = ProxyService::new(db.clone());
|
||
Ok(AppState { db, proxy_service })
|
||
}
|
||
|
||
/// 创建测试用的 AppState,并从 MultiAppConfig 迁移数据
|
||
pub fn create_test_state_with_config(
|
||
config: &MultiAppConfig,
|
||
) -> Result<AppState, Box<dyn std::error::Error>> {
|
||
let db = Arc::new(Database::init()?);
|
||
db.migrate_from_json(config)?;
|
||
let proxy_service = ProxyService::new(db.clone());
|
||
Ok(AppState { db, proxy_service })
|
||
}
|