Skip to main content

wae_testing/
environment.rs

1//! 测试环境管理模块
2
3use crate::error::{TestingError, TestingResult};
4use parking_lot::RwLock;
5use std::{collections::HashMap, sync::Arc, time::Duration};
6
7/// 测试环境配置
8#[derive(Debug, Clone)]
9pub struct TestEnvConfig {
10    /// 环境名称
11    pub name: String,
12    /// 是否启用日志
13    pub enable_logging: bool,
14    /// 是否启用追踪
15    pub enable_tracing: bool,
16    /// 超时时间
17    pub default_timeout: Duration,
18    /// 自定义配置
19    pub custom: HashMap<String, String>,
20}
21
22impl Default for TestEnvConfig {
23    fn default() -> Self {
24        Self {
25            name: "test".to_string(),
26            enable_logging: true,
27            enable_tracing: false,
28            default_timeout: Duration::from_secs(30),
29            custom: HashMap::new(),
30        }
31    }
32}
33
34impl TestEnvConfig {
35    /// 创建新的测试环境配置
36    pub fn new() -> Self {
37        Self::default()
38    }
39
40    /// 设置环境名称
41    pub fn name(mut self, name: impl Into<String>) -> Self {
42        self.name = name.into();
43        self
44    }
45
46    /// 启用日志
47    pub fn with_logging(mut self, enable: bool) -> Self {
48        self.enable_logging = enable;
49        self
50    }
51
52    /// 启用追踪
53    pub fn with_tracing(mut self, enable: bool) -> Self {
54        self.enable_tracing = enable;
55        self
56    }
57
58    /// 设置超时时间
59    pub fn timeout(mut self, timeout: Duration) -> Self {
60        self.default_timeout = timeout;
61        self
62    }
63
64    /// 添加自定义配置
65    pub fn custom(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
66        self.custom.insert(key.into(), value.into());
67        self
68    }
69}
70
71/// 测试环境状态
72#[derive(Debug, Clone, PartialEq)]
73pub enum TestEnvState {
74    /// 未初始化
75    Uninitialized,
76    /// 已初始化
77    Initialized,
78    /// 已销毁
79    Destroyed,
80}
81
82/// 测试环境管理器
83pub struct TestEnv {
84    /// 配置
85    config: TestEnvConfig,
86    /// 状态
87    state: Arc<RwLock<TestEnvState>>,
88    /// 清理函数列表
89    #[allow(clippy::type_complexity)]
90    cleanup_handlers: Arc<RwLock<Vec<Box<dyn Fn() + Send + Sync>>>>,
91    /// 存储的数据
92    storage: Arc<RwLock<HashMap<String, Box<dyn std::any::Any + Send + Sync>>>>,
93}
94
95impl TestEnv {
96    /// 创建新的测试环境
97    pub fn new(config: TestEnvConfig) -> Self {
98        Self {
99            config,
100            state: Arc::new(RwLock::new(TestEnvState::Uninitialized)),
101            cleanup_handlers: Arc::new(RwLock::new(Vec::new())),
102            storage: Arc::new(RwLock::new(HashMap::new())),
103        }
104    }
105
106    /// 创建默认测试环境
107    pub fn default_env() -> Self {
108        Self::new(TestEnvConfig::default())
109    }
110
111    /// 初始化测试环境
112    pub fn setup(&self) -> TestingResult<()> {
113        let mut state = self.state.write();
114        if *state != TestEnvState::Uninitialized {
115            return Err(TestingError::EnvironmentError("Environment already initialized".to_string()));
116        }
117
118        *state = TestEnvState::Initialized;
119        Ok(())
120    }
121
122    /// 清理测试环境
123    pub fn teardown(&self) -> TestingResult<()> {
124        let mut state = self.state.write();
125        if *state != TestEnvState::Initialized {
126            return Err(TestingError::EnvironmentError("Environment not initialized".to_string()));
127        }
128
129        let handlers = self.cleanup_handlers.write();
130        for handler in handlers.iter() {
131            handler();
132        }
133
134        self.storage.write().clear();
135
136        *state = TestEnvState::Destroyed;
137        Ok(())
138    }
139
140    /// 获取环境状态
141    pub fn state(&self) -> TestEnvState {
142        self.state.read().clone()
143    }
144
145    /// 注册清理函数
146    pub fn on_cleanup<F>(&self, handler: F)
147    where
148        F: Fn() + Send + Sync + 'static,
149    {
150        self.cleanup_handlers.write().push(Box::new(handler));
151    }
152
153    /// 存储数据
154    pub fn set<T: 'static + Send + Sync>(&self, key: &str, value: T) {
155        self.storage.write().insert(key.to_string(), Box::new(value));
156    }
157
158    /// 获取数据
159    pub fn get<T: 'static + Clone>(&self, key: &str) -> Option<T> {
160        let storage = self.storage.read();
161        storage.get(key).and_then(|v| v.downcast_ref::<T>().cloned())
162    }
163
164    /// 获取配置
165    pub fn config(&self) -> &TestEnvConfig {
166        &self.config
167    }
168
169    /// 使用 fixture 运行测试
170    pub async fn with_fixture<F, R>(&self, fixture: F) -> TestingResult<R>
171    where
172        F: FnOnce() -> TestingResult<R>,
173    {
174        self.setup()?;
175
176        let fixture_data = fixture()?;
177
178        self.teardown()?;
179
180        Ok(fixture_data)
181    }
182
183    /// 运行异步测试
184    pub async fn run_test<F, Fut>(&self, test: F) -> TestingResult<()>
185    where
186        F: FnOnce() -> Fut,
187        Fut: std::future::Future<Output = TestingResult<()>>,
188    {
189        self.setup()?;
190
191        let result = test().await;
192
193        self.teardown()?;
194
195        result
196    }
197}
198
199/// 测试环境构建器
200pub struct TestEnvBuilder {
201    config: TestEnvConfig,
202}
203
204impl TestEnvBuilder {
205    /// 创建新的构建器
206    pub fn new() -> Self {
207        Self { config: TestEnvConfig::default() }
208    }
209
210    /// 设置环境名称
211    pub fn name(mut self, name: impl Into<String>) -> Self {
212        self.config.name = name.into();
213        self
214    }
215
216    /// 启用日志
217    pub fn with_logging(mut self, enable: bool) -> Self {
218        self.config.enable_logging = enable;
219        self
220    }
221
222    /// 启用追踪
223    pub fn with_tracing(mut self, enable: bool) -> Self {
224        self.config.enable_tracing = enable;
225        self
226    }
227
228    /// 设置超时时间
229    pub fn timeout(mut self, timeout: Duration) -> Self {
230        self.config.default_timeout = timeout;
231        self
232    }
233
234    /// 添加自定义配置
235    pub fn custom(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
236        self.config.custom.insert(key.into(), value.into());
237        self
238    }
239
240    /// 构建测试环境
241    pub fn build(self) -> TestEnv {
242        TestEnv::new(self.config)
243    }
244}
245
246impl Default for TestEnvBuilder {
247    fn default() -> Self {
248        Self::new()
249    }
250}
251
252/// 创建测试环境
253pub fn create_test_env() -> TestEnv {
254    TestEnv::default_env()
255}
256
257/// 使用配置创建测试环境
258pub fn create_test_env_with_config(config: TestEnvConfig) -> TestEnv {
259    TestEnv::new(config)
260}