Rust · 7013 bytes Raw Blame History
1 use anyhow::Result;
2 use std::path::PathBuf;
3 use std::time::Duration;
4 use tempfile::TempDir;
5 use tokio::fs;
6 use zephyrfs_cli::{Config, ZephyrClient};
7
8 struct TestEnvironment {
9 temp_dir: TempDir,
10 config: Config,
11 }
12
13 impl TestEnvironment {
14 fn new() -> Result<Self> {
15 let temp_dir = tempfile::tempdir()?;
16 let mut config = Config::default();
17 config.node.data_dir = temp_dir.path().join("data");
18 config.node.listen_port = 0; // Let OS choose port for tests
19
20 Ok(Self { temp_dir, config })
21 }
22
23 async fn create_test_file(&self, name: &str, content: &[u8]) -> Result<PathBuf> {
24 let file_path = self.temp_dir.path().join(name);
25 fs::write(&file_path, content).await?;
26 Ok(file_path)
27 }
28 }
29
30 #[tokio::test]
31 async fn test_config_load_default() -> Result<()> {
32 let config = Config::load(None)?;
33 assert!(!config.node.data_dir.as_os_str().is_empty());
34 assert!(config.node.listen_port > 0);
35 assert!(!config.coordinator.endpoint.is_empty());
36 Ok(())
37 }
38
39 #[tokio::test]
40 async fn test_config_save_load_yaml() -> Result<()> {
41 let env = TestEnvironment::new()?;
42 let config_path = env.temp_dir.path().join("test_config.yaml");
43
44 // Save config
45 env.config.save(Some(config_path.to_str().unwrap()))?;
46
47 // Load config
48 let loaded_config = Config::load(Some(config_path.to_str().unwrap()))?;
49
50 assert_eq!(env.config.node.listen_port, loaded_config.node.listen_port);
51 assert_eq!(env.config.storage.max_storage_gb, loaded_config.storage.max_storage_gb);
52 assert_eq!(env.config.coordinator.endpoint, loaded_config.coordinator.endpoint);
53
54 Ok(())
55 }
56
57 #[tokio::test]
58 async fn test_config_save_load_toml() -> Result<()> {
59 let env = TestEnvironment::new()?;
60 let config_path = env.temp_dir.path().join("test_config.toml");
61
62 // Save config
63 env.config.save(Some(config_path.to_str().unwrap()))?;
64
65 // Load config
66 let loaded_config = Config::load(Some(config_path.to_str().unwrap()))?;
67
68 assert_eq!(env.config.node.listen_port, loaded_config.node.listen_port);
69 assert_eq!(env.config.storage.max_storage_gb, loaded_config.storage.max_storage_gb);
70
71 Ok(())
72 }
73
74 #[tokio::test]
75 async fn test_config_ensure_data_dir() -> Result<()> {
76 let env = TestEnvironment::new()?;
77
78 // Data dir shouldn't exist yet
79 assert!(!env.config.node.data_dir.exists());
80
81 // Ensure data dir
82 env.config.ensure_data_dir()?;
83
84 // Data dir should exist now
85 assert!(env.config.node.data_dir.exists());
86 assert!(env.config.node.data_dir.is_dir());
87
88 Ok(())
89 }
90
91 #[tokio::test]
92 async fn test_client_creation() -> Result<()> {
93 let env = TestEnvironment::new()?;
94 let _client = ZephyrClient::new(&env.config);
95 Ok(())
96 }
97
98 // Mock server tests would go here if we had a test server
99 // For now, these test the client creation and basic config handling
100
101 #[tokio::test]
102 async fn test_file_operations_offline() -> Result<()> {
103 let env = TestEnvironment::new()?;
104
105 // Create a test file
106 let test_content = b"Hello, ZephyrFS!";
107 let test_file = env.create_test_file("test.txt", test_content).await?;
108
109 // Verify file was created correctly
110 let read_content = fs::read(&test_file).await?;
111 assert_eq!(read_content, test_content);
112
113 Ok(())
114 }
115
116 #[tokio::test]
117 async fn test_large_file_handling() -> Result<()> {
118 let env = TestEnvironment::new()?;
119
120 // Create a 10MB test file
121 let test_content = vec![0u8; 10 * 1024 * 1024];
122 let test_file = env.create_test_file("large.bin", &test_content).await?;
123
124 // Verify file size
125 let metadata = fs::metadata(&test_file).await?;
126 assert_eq!(metadata.len(), test_content.len() as u64);
127
128 Ok(())
129 }
130
131 #[tokio::test]
132 async fn test_invalid_config_handling() -> Result<()> {
133 let temp_dir = tempfile::tempdir()?;
134 let invalid_config_path = temp_dir.path().join("invalid.yaml");
135
136 // Write invalid YAML
137 fs::write(&invalid_config_path, "invalid: yaml: content: [").await?;
138
139 // Should return error
140 let result = Config::load(Some(invalid_config_path.to_str().unwrap()));
141 assert!(result.is_err());
142
143 Ok(())
144 }
145
146 #[tokio::test]
147 async fn test_nonexistent_config_uses_defaults() -> Result<()> {
148 let temp_dir = tempfile::tempdir()?;
149 let nonexistent_path = temp_dir.path().join("nonexistent.yaml");
150
151 // Should return default config
152 let config = Config::load(Some(nonexistent_path.to_str().unwrap()))?;
153 let default_config = Config::default();
154
155 assert_eq!(config.node.listen_port, default_config.node.listen_port);
156 assert_eq!(config.storage.max_storage_gb, default_config.storage.max_storage_gb);
157
158 Ok(())
159 }
160
161 // Performance tests
162 #[tokio::test]
163 async fn test_config_load_performance() -> Result<()> {
164 let env = TestEnvironment::new()?;
165 let config_path = env.temp_dir.path().join("perf_test.yaml");
166 env.config.save(Some(config_path.to_str().unwrap()))?;
167
168 let start = std::time::Instant::now();
169 for _ in 0..100 {
170 let _config = Config::load(Some(config_path.to_str().unwrap()))?;
171 }
172 let duration = start.elapsed();
173
174 // Should load 100 configs in under 1 second
175 assert!(duration < Duration::from_secs(1));
176
177 Ok(())
178 }
179
180 // Network simulation tests (would require mock server)
181 // These are placeholders for future implementation
182
183 #[ignore] // Requires running node
184 #[tokio::test]
185 async fn test_node_status_integration() -> Result<()> {
186 let env = TestEnvironment::new()?;
187 let client = ZephyrClient::new(&env.config);
188
189 // This would test against a running node
190 let _status = client.get_node_status().await?;
191
192 Ok(())
193 }
194
195 #[ignore] // Requires running node and network
196 #[tokio::test]
197 async fn test_file_upload_download_integration() -> Result<()> {
198 let env = TestEnvironment::new()?;
199 let client = ZephyrClient::new(&env.config);
200
201 // Create test file
202 let test_content = b"Integration test content";
203 let test_file = env.create_test_file("integration_test.txt", test_content).await?;
204
205 // Upload file
206 let upload_result = client.upload_file(&test_file).await?;
207 assert!(!upload_result.file_hash.is_empty());
208
209 // Download file
210 let download_path = env.temp_dir.path().join("downloaded.txt");
211 client.download_file(&upload_result.file_hash, &download_path).await?;
212
213 // Verify content
214 let downloaded_content = fs::read(&download_path).await?;
215 assert_eq!(downloaded_content, test_content);
216
217 Ok(())
218 }
219
220 #[ignore] // Requires multiple running nodes
221 #[tokio::test]
222 async fn test_network_join_integration() -> Result<()> {
223 let env = TestEnvironment::new()?;
224 let client = ZephyrClient::new(&env.config);
225
226 // Join network
227 client.join_network("127.0.0.1:8081").await?;
228
229 // Verify connection
230 let status = client.get_node_status().await?;
231 assert!(status.peers_connected > 0);
232
233 Ok(())
234 }