mongodb_integration/
mongodb_integration.rs1use rust_test_harness::{test, run_tests_with_config, TestConfig, ContainerConfig, before_each};
10use std::time::Duration;
11
12struct MongoClient {
14 container_id: String,
15 connected: bool,
16}
17
18impl MongoClient {
19 fn new(container_id: String) -> Self {
20 Self {
21 container_id,
22 connected: false,
23 }
24 }
25
26 fn connect(&mut self) -> Result<(), String> {
27 std::thread::sleep(Duration::from_millis(20));
29 self.connected = true;
30 Ok(())
31 }
32
33 fn disconnect(&mut self) -> Result<(), String> {
34 std::thread::sleep(Duration::from_millis(10));
36 self.connected = false;
37 Ok(())
38 }
39
40 fn insert_document(&self, collection: &str, document: &str) -> Result<(), String> {
41 if !self.connected {
42 return Err("Not connected to MongoDB".to_string());
43 }
44
45 std::thread::sleep(Duration::from_millis(5));
47 println!("๐ Inserted document into collection '{}': {}", collection, document);
48 Ok(())
49 }
50
51 fn find_documents(&self, collection: &str, query: &str) -> Result<Vec<String>, String> {
52 if !self.connected {
53 return Err("Not connected to MongoDB".to_string());
54 }
55
56 std::thread::sleep(Duration::from_millis(3));
58 println!("๐ Found documents in collection '{}' with query: {}", collection, query);
59
60 Ok(vec![
62 format!("Document 1 matching: {}", query),
63 format!("Document 2 matching: {}", query),
64 ])
65 }
66}
67
68fn main() {
69 println!("๐ณ MongoDB Integration Example with Container Hooks");
70 println!("==================================================");
71 println!();
72
73 let mongo_container = ContainerConfig::new("mongo:5.0")
75 .port(27017, 27017)
76 .env("MONGO_INITDB_ROOT_USERNAME", "admin")
77 .env("MONGO_INITDB_ROOT_PASSWORD", "password")
78 .name("test_mongodb")
79 .ready_timeout(Duration::from_secs(30));
80
81 println!("๐ Container Configuration:");
82 println!(" Image: {}", mongo_container.image);
83 println!(" Ports: {:?}", mongo_container.ports);
84 println!(" Environment: {:?}", mongo_container.env);
85 println!(" Name: {:?}", mongo_container.name);
86 println!(" Ready Timeout: {:?}", mongo_container.ready_timeout);
87 println!();
88
89 let mongo_container_before = mongo_container.clone();
91
92 before_each(move |ctx| {
94 println!("๐ before_each: Starting MongoDB container...");
95
96 let container_id = mongo_container_before.start()
98 .map_err(|e| format!("Failed to start container: {}", e))?;
99 ctx.set_data("mongo_container_id", container_id.clone());
100
101 println!("โ
before_each: MongoDB container {} started", container_id);
102 Ok(())
103 });
104
105 let mongo_container_after = mongo_container.clone();
107 rust_test_harness::after_each(move |ctx| {
108 println!("๐ after_each: Stopping MongoDB container...");
109
110 let container_id = ctx.get_data::<String>("mongo_container_id")
112 .expect("Container ID should be available");
113
114 mongo_container_after.stop(&container_id)
116 .map_err(|e| format!("Failed to stop container: {}", e))?;
117
118 println!("โ
after_each: MongoDB container {} stopped", container_id);
119 Ok(())
120 });
121
122 test("test_mongodb_basic_operations", |ctx| {
124 println!("๐งช Running test: test_mongodb_basic_operations");
125
126 let container_id = ctx.get_data::<String>("mongo_container_id")
128 .expect("Container ID should be available")
129 .to_string();
130
131 let mut client = MongoClient::new(container_id);
133
134 client.connect()?;
136
137 client.insert_document("users", r#"{"name": "John Doe", "email": "john@example.com"}"#)?;
139
140 let documents = client.find_documents("users", r#"{"name": "John Doe"}"#)?;
142 assert_eq!(documents.len(), 2);
143
144 client.disconnect()?;
146
147 println!("โ
test_mongodb_basic_operations passed");
148 Ok(())
149 });
150
151 test("test_mongodb_multiple_operations", |ctx| {
153 println!("๐งช Running test: test_mongodb_multiple_operations");
154
155 let container_id = ctx.get_data::<String>("mongo_container_id")
157 .expect("Container ID should be available")
158 .to_string();
159
160 let mut client = MongoClient::new(container_id);
162
163 client.connect()?;
165
166 client.insert_document("products", r#"{"name": "Laptop", "price": 999.99}"#)?;
168 client.insert_document("products", r#"{"name": "Mouse", "price": 29.99}"#)?;
169 client.insert_document("products", r#"{"name": "Keyboard", "price": 79.99}"#)?;
170
171 let documents = client.find_documents("products", r#"{"price": {"$gt": 50}}"#)?;
173 assert_eq!(documents.len(), 2); client.disconnect()?;
177
178 println!("โ
test_mongodb_multiple_operations passed");
179 Ok(())
180 });
181
182 test("test_mongodb_error_handling", |ctx| {
184 println!("๐งช Running test: test_mongodb_error_handling");
185
186 let container_id = ctx.get_data::<String>("mongo_container_id")
188 .expect("Container ID should be available")
189 .to_string();
190
191 let client = MongoClient::new(container_id);
193
194 let result = client.insert_document("users", r#"{"name": "Test"}"#);
196 assert!(result.is_err());
197 assert_eq!(result.unwrap_err(), "Not connected to MongoDB");
198
199 println!("โ
test_mongodb_error_handling passed");
200 Ok(())
201 });
202
203 test("test_mongodb_performance", |ctx| {
205 println!("๐งช Running test: test_mongodb_performance");
206
207 let container_id = ctx.get_data::<String>("mongo_container_id")
209 .expect("Container ID should be available")
210 .to_string();
211
212 let mut client = MongoClient::new(container_id);
214
215 client.connect()?;
217
218 for i in 0..100 {
220 client.insert_document("bulk_data", &format!(r#"{{"index": {}, "data": "bulk_item_{}"}}"#, i, i))?;
221 }
222
223 let documents = client.find_documents("bulk_data", r#"{"index": {"$lt": 50}}"#)?;
225 assert_eq!(documents.len(), 2); client.disconnect()?;
229
230 println!("โ
test_mongodb_performance passed");
231 Ok(())
232 });
233
234 println!("\n๐ Running MongoDB integration tests...");
235 println!(" Each test will get a fresh MongoDB container via before_each");
236 println!(" Each test will clean up its container via after_each");
237 println!();
238
239 let config = TestConfig {
241 skip_hooks: Some(false),
242 ..Default::default()
243 };
244
245 let result = run_tests_with_config(config);
246
247 println!("\n๐ Test Results:");
248 if result == 0 {
249 println!("โ
All MongoDB integration tests passed!");
250 println!("๐ฏ Container lifecycle management working correctly");
251 println!("๐ณ Each test got its own MongoDB container");
252 println!("๐งน Each test cleaned up its container properly");
253 } else {
254 println!("โ Some tests failed");
255 }
256
257 println!("\n๐ก Key Benefits of this approach:");
258 println!(" โข Clean separation of concerns");
259 println!(" โข Each test gets a fresh container");
260 println!(" โข Automatic cleanup via after_each");
261 println!(" โข Easy to configure containers");
262 println!(" โข No complex global state management");
263}