hotfix_store/
test_utils.rs1use crate::MessageStore;
7
8#[async_trait::async_trait]
14pub trait TestStoreFactory: Send + Sync {
15 async fn create_store(&self) -> Box<dyn MessageStore>;
20
21 fn is_persistent(&self) -> bool {
25 true
26 }
27}
28
29pub async fn test_new_store_initialization(factory: &dyn TestStoreFactory) {
31 let store = factory.create_store().await;
32
33 assert_eq!(store.next_sender_seq_number(), 1);
34 assert_eq!(store.next_target_seq_number(), 1);
35}
36
37pub async fn test_add_and_get_messages(factory: &dyn TestStoreFactory) {
39 let mut store = factory.create_store().await;
40
41 let message1 = b"test message 1";
42 let message2 = b"test message 2";
43 let message3 = b"test message 3";
44
45 store
46 .add(1, message1)
47 .await
48 .expect("Failed to add message 1");
49 store
50 .add(2, message2)
51 .await
52 .expect("Failed to add message 2");
53 store
54 .add(3, message3)
55 .await
56 .expect("Failed to add message 3");
57
58 let messages = store.get_slice(1, 3).await.expect("Failed to get messages");
59 assert_eq!(messages.len(), 3);
60 assert_eq!(messages[0], message1);
61 assert_eq!(messages[1], message2);
62 assert_eq!(messages[2], message3);
63}
64
65pub async fn test_get_slice_partial_range(factory: &dyn TestStoreFactory) {
67 let mut store = factory.create_store().await;
68
69 let message1 = b"message 1";
70 let message2 = b"message 2";
71 let message3 = b"message 3";
72 let message4 = b"message 4";
73
74 store
75 .add(1, message1)
76 .await
77 .expect("Failed to add message 1");
78 store
79 .add(2, message2)
80 .await
81 .expect("Failed to add message 2");
82 store
83 .add(3, message3)
84 .await
85 .expect("Failed to add message 3");
86 store
87 .add(4, message4)
88 .await
89 .expect("Failed to add message 4");
90
91 let messages = store.get_slice(2, 3).await.expect("Failed to get messages");
92 assert_eq!(messages.len(), 2);
93 assert_eq!(messages[0], message2);
94 assert_eq!(messages[1], message3);
95}
96
97pub async fn test_get_slice_empty_range(factory: &dyn TestStoreFactory) {
99 let store = factory.create_store().await;
100
101 let messages = store.get_slice(1, 3).await.expect("Failed to get messages");
102 assert_eq!(messages.len(), 0);
103}
104
105pub async fn test_increment_sender_seq_number(factory: &dyn TestStoreFactory) {
107 let mut store = factory.create_store().await;
108
109 assert_eq!(store.next_sender_seq_number(), 1);
110
111 store
112 .increment_sender_seq_number()
113 .await
114 .expect("Failed to increment sender seq number");
115 assert_eq!(store.next_sender_seq_number(), 2);
116
117 store
118 .increment_sender_seq_number()
119 .await
120 .expect("Failed to increment sender seq number");
121 assert_eq!(store.next_sender_seq_number(), 3);
122}
123
124pub async fn test_increment_target_seq_number(factory: &dyn TestStoreFactory) {
126 let mut store = factory.create_store().await;
127
128 assert_eq!(store.next_target_seq_number(), 1);
129
130 store
131 .increment_target_seq_number()
132 .await
133 .expect("Failed to increment target seq number");
134 assert_eq!(store.next_target_seq_number(), 2);
135
136 store
137 .increment_target_seq_number()
138 .await
139 .expect("Failed to increment target seq number");
140 assert_eq!(store.next_target_seq_number(), 3);
141}
142
143pub async fn test_set_target_seq_number(factory: &dyn TestStoreFactory) {
145 let mut store = factory.create_store().await;
146
147 assert_eq!(store.next_target_seq_number(), 1);
148
149 store
150 .set_target_seq_number(10)
151 .await
152 .expect("Failed to set target seq number");
153 assert_eq!(store.next_target_seq_number(), 11);
154
155 store
156 .set_target_seq_number(5)
157 .await
158 .expect("Failed to set target seq number");
159 assert_eq!(store.next_target_seq_number(), 6);
160}
161
162pub async fn test_reset_store(factory: &dyn TestStoreFactory) {
164 let mut store = factory.create_store().await;
165
166 store
168 .add(1, b"message 1")
169 .await
170 .expect("Failed to add message");
171 store
172 .add(2, b"message 2")
173 .await
174 .expect("Failed to add message");
175 store
176 .increment_sender_seq_number()
177 .await
178 .expect("Failed to increment sender seq number");
179 store
180 .increment_target_seq_number()
181 .await
182 .expect("Failed to increment target seq number");
183
184 assert_eq!(store.next_sender_seq_number(), 2);
185 assert_eq!(store.next_target_seq_number(), 2);
186
187 let messages_before_reset = store.get_slice(1, 2).await.expect("Failed to get messages");
188 assert_eq!(messages_before_reset.len(), 2);
189
190 store.reset().await.expect("Failed to reset store");
192
193 assert_eq!(store.next_sender_seq_number(), 1);
195 assert_eq!(store.next_target_seq_number(), 1);
196
197 let messages_after_reset = store.get_slice(1, 2).await.expect("Failed to get messages");
199 assert_eq!(messages_after_reset.len(), 0);
200}
201
202pub async fn test_persistence_across_store_instances(factory: &dyn TestStoreFactory) {
204 if !factory.is_persistent() {
205 return;
206 }
207
208 {
210 let mut store1 = factory.create_store().await;
211 store1
212 .add(1, b"persistent message")
213 .await
214 .expect("Failed to add message");
215 store1
216 .increment_sender_seq_number()
217 .await
218 .expect("Failed to increment sender seq number");
219 store1
220 .set_target_seq_number(5)
221 .await
222 .expect("Failed to set target seq number");
223 }
224
225 {
227 let store2 = factory.create_store().await;
228
229 assert_eq!(store2.next_sender_seq_number(), 2);
230 assert_eq!(store2.next_target_seq_number(), 6);
231
232 let messages = store2
233 .get_slice(1, 1)
234 .await
235 .expect("Failed to get messages");
236 assert_eq!(messages.len(), 1);
237 assert_eq!(messages[0], b"persistent message");
238 }
239}
240
241pub async fn test_get_slice_beyond_available_messages(factory: &dyn TestStoreFactory) {
243 let mut store = factory.create_store().await;
244
245 store
246 .add(1, b"only message")
247 .await
248 .expect("Failed to add message");
249
250 let messages = store
251 .get_slice(1, 10)
252 .await
253 .expect("Failed to get messages");
254 assert_eq!(messages.len(), 1);
255 assert_eq!(messages[0], b"only message");
256}
257
258pub async fn test_overwrite_existing_message(factory: &dyn TestStoreFactory) {
260 let mut store = factory.create_store().await;
261
262 store
263 .add(1, b"original message")
264 .await
265 .expect("Failed to add original message");
266 store
267 .add(1, b"updated message")
268 .await
269 .expect("Failed to add updated message");
270
271 let messages = store.get_slice(1, 1).await.expect("Failed to get messages");
272 assert_eq!(messages.len(), 1);
273 assert_eq!(messages[0], b"updated message");
274}
275
276pub async fn test_creation_time_is_set(factory: &dyn TestStoreFactory) {
278 use chrono::Utc;
279
280 let before = Utc::now();
281 let store = factory.create_store().await;
282 let after = Utc::now();
283
284 assert!(before <= store.creation_time());
285 assert!(store.creation_time() <= after);
286}
287
288pub async fn test_creation_time_is_preserved(factory: &dyn TestStoreFactory) {
290 if !factory.is_persistent() {
291 return;
292 }
293
294 let store = factory.create_store().await;
295 let creation_time1 = store.creation_time();
296 drop(store);
297
298 tokio::time::sleep(std::time::Duration::from_millis(10)).await;
299
300 let store = factory.create_store().await;
301 let creation_time2 = store.creation_time();
302
303 assert_eq!(creation_time1, creation_time2);
304}
305
306pub async fn test_creation_time_gets_reset_correctly(factory: &dyn TestStoreFactory) {
308 use chrono::Utc;
309
310 let mut store = factory.create_store().await;
311
312 tokio::time::sleep(std::time::Duration::from_millis(2)).await;
313 let after_sleep = Utc::now();
314 tokio::time::sleep(std::time::Duration::from_millis(2)).await;
315
316 store.reset().await.expect("failed to reset store");
317 let reset_creation_time = store.creation_time();
318 assert!(reset_creation_time > after_sleep);
319
320 if !factory.is_persistent() {
321 return;
322 }
323
324 drop(store);
325 let store = factory.create_store().await;
326 assert_eq!(reset_creation_time, store.creation_time());
327}
328
329#[macro_export]
359macro_rules! conformance_tests {
360 ($mod_name:ident, $factory:expr) => {
361 mod $mod_name {
362 use super::*;
363
364 #[tokio::test]
365 async fn test_new_store_initialization() {
366 let factory = $factory;
367 $crate::test_utils::test_new_store_initialization(&factory).await;
368 }
369
370 #[tokio::test]
371 async fn test_add_and_get_messages() {
372 let factory = $factory;
373 $crate::test_utils::test_add_and_get_messages(&factory).await;
374 }
375
376 #[tokio::test]
377 async fn test_get_slice_partial_range() {
378 let factory = $factory;
379 $crate::test_utils::test_get_slice_partial_range(&factory).await;
380 }
381
382 #[tokio::test]
383 async fn test_get_slice_empty_range() {
384 let factory = $factory;
385 $crate::test_utils::test_get_slice_empty_range(&factory).await;
386 }
387
388 #[tokio::test]
389 async fn test_increment_sender_seq_number() {
390 let factory = $factory;
391 $crate::test_utils::test_increment_sender_seq_number(&factory).await;
392 }
393
394 #[tokio::test]
395 async fn test_increment_target_seq_number() {
396 let factory = $factory;
397 $crate::test_utils::test_increment_target_seq_number(&factory).await;
398 }
399
400 #[tokio::test]
401 async fn test_set_target_seq_number() {
402 let factory = $factory;
403 $crate::test_utils::test_set_target_seq_number(&factory).await;
404 }
405
406 #[tokio::test]
407 async fn test_reset_store() {
408 let factory = $factory;
409 $crate::test_utils::test_reset_store(&factory).await;
410 }
411
412 #[tokio::test]
413 async fn test_persistence_across_store_instances() {
414 let factory = $factory;
415 $crate::test_utils::test_persistence_across_store_instances(&factory).await;
416 }
417
418 #[tokio::test]
419 async fn test_get_slice_beyond_available_messages() {
420 let factory = $factory;
421 $crate::test_utils::test_get_slice_beyond_available_messages(&factory).await;
422 }
423
424 #[tokio::test]
425 async fn test_overwrite_existing_message() {
426 let factory = $factory;
427 $crate::test_utils::test_overwrite_existing_message(&factory).await;
428 }
429
430 #[tokio::test]
431 async fn test_creation_time_is_set() {
432 let factory = $factory;
433 $crate::test_utils::test_creation_time_is_set(&factory).await;
434 }
435
436 #[tokio::test]
437 async fn test_creation_time_is_preserved() {
438 let factory = $factory;
439 $crate::test_utils::test_creation_time_is_preserved(&factory).await;
440 }
441
442 #[tokio::test]
443 async fn test_creation_time_gets_reset_correctly() {
444 let factory = $factory;
445 $crate::test_utils::test_creation_time_gets_reset_correctly(&factory).await;
446 }
447 }
448 };
449}