Skip to content

Commit 2b719d4

Browse files
committed
Add test suite to redb store
1 parent 741ce0a commit 2b719d4

1 file changed

Lines changed: 332 additions & 0 deletions

File tree

crates/hotfix/src/store/redb.rs

Lines changed: 332 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,3 +118,335 @@ impl MessageStore for RedbMessageStore {
118118
Ok(())
119119
}
120120
}
121+
122+
#[cfg(test)]
123+
mod tests {
124+
use super::*;
125+
use std::env;
126+
use std::fs;
127+
use std::path::PathBuf;
128+
use tokio;
129+
130+
struct TestStore {
131+
store: RedbMessageStore,
132+
db_path: PathBuf,
133+
}
134+
135+
impl TestStore {
136+
fn new() -> Self {
137+
let mut temp_path = env::temp_dir();
138+
temp_path.push(format!("redb_test_{}", uuid::Uuid::new_v4()));
139+
temp_path.set_extension("db");
140+
141+
let store = RedbMessageStore::new(&temp_path).expect("Failed to create store");
142+
143+
Self {
144+
store,
145+
db_path: temp_path,
146+
}
147+
}
148+
149+
fn store(&self) -> &RedbMessageStore {
150+
&self.store
151+
}
152+
153+
fn store_mut(&mut self) -> &mut RedbMessageStore {
154+
&mut self.store
155+
}
156+
157+
fn db_path(&self) -> &PathBuf {
158+
&self.db_path
159+
}
160+
}
161+
162+
impl Drop for TestStore {
163+
fn drop(&mut self) {
164+
// Clean up the database file when the test store is dropped
165+
let _ = fs::remove_file(&self.db_path);
166+
}
167+
}
168+
169+
#[tokio::test]
170+
async fn test_new_store_initialization() {
171+
let test_store = TestStore::new();
172+
let store = test_store.store();
173+
174+
assert_eq!(store.next_sender_seq_number(), 1);
175+
assert_eq!(store.next_target_seq_number(), 1);
176+
}
177+
178+
#[tokio::test]
179+
async fn test_add_and_get_messages() {
180+
let mut test_store = TestStore::new();
181+
let store = test_store.store_mut();
182+
183+
let message1 = b"test message 1";
184+
let message2 = b"test message 2";
185+
let message3 = b"test message 3";
186+
187+
store
188+
.add(1, message1)
189+
.await
190+
.expect("Failed to add message 1");
191+
store
192+
.add(2, message2)
193+
.await
194+
.expect("Failed to add message 2");
195+
store
196+
.add(3, message3)
197+
.await
198+
.expect("Failed to add message 3");
199+
200+
let messages = store.get_slice(1, 3).await.expect("Failed to get messages");
201+
assert_eq!(messages.len(), 3);
202+
assert_eq!(messages[0], message1);
203+
assert_eq!(messages[1], message2);
204+
assert_eq!(messages[2], message3);
205+
}
206+
207+
#[tokio::test]
208+
async fn test_get_slice_partial_range() {
209+
let mut test_store = TestStore::new();
210+
let store = test_store.store_mut();
211+
212+
let message1 = b"message 1";
213+
let message2 = b"message 2";
214+
let message3 = b"message 3";
215+
let message4 = b"message 4";
216+
217+
store
218+
.add(1, message1)
219+
.await
220+
.expect("Failed to add message 1");
221+
store
222+
.add(2, message2)
223+
.await
224+
.expect("Failed to add message 2");
225+
store
226+
.add(3, message3)
227+
.await
228+
.expect("Failed to add message 3");
229+
store
230+
.add(4, message4)
231+
.await
232+
.expect("Failed to add message 4");
233+
234+
let messages = store.get_slice(2, 3).await.expect("Failed to get messages");
235+
assert_eq!(messages.len(), 2);
236+
assert_eq!(messages[0], message2);
237+
assert_eq!(messages[1], message3);
238+
}
239+
240+
#[tokio::test]
241+
async fn test_get_slice_empty_range() {
242+
let test_store = TestStore::new();
243+
let store = test_store.store();
244+
245+
let messages = store.get_slice(1, 3).await.expect("Failed to get messages");
246+
assert_eq!(messages.len(), 0);
247+
}
248+
249+
#[tokio::test]
250+
async fn test_increment_sender_seq_number() {
251+
let mut test_store = TestStore::new();
252+
let store = test_store.store_mut();
253+
254+
assert_eq!(store.next_sender_seq_number(), 1);
255+
256+
store
257+
.increment_sender_seq_number()
258+
.await
259+
.expect("Failed to increment sender seq number");
260+
assert_eq!(store.next_sender_seq_number(), 2);
261+
262+
store
263+
.increment_sender_seq_number()
264+
.await
265+
.expect("Failed to increment sender seq number");
266+
assert_eq!(store.next_sender_seq_number(), 3);
267+
}
268+
269+
#[tokio::test]
270+
async fn test_increment_target_seq_number() {
271+
let mut test_store = TestStore::new();
272+
let store = test_store.store_mut();
273+
274+
assert_eq!(store.next_target_seq_number(), 1);
275+
276+
store
277+
.increment_target_seq_number()
278+
.await
279+
.expect("Failed to increment target seq number");
280+
assert_eq!(store.next_target_seq_number(), 2);
281+
282+
store
283+
.increment_target_seq_number()
284+
.await
285+
.expect("Failed to increment target seq number");
286+
assert_eq!(store.next_target_seq_number(), 3);
287+
}
288+
289+
#[tokio::test]
290+
async fn test_set_target_seq_number() {
291+
let mut test_store = TestStore::new();
292+
let store = test_store.store_mut();
293+
294+
assert_eq!(store.next_target_seq_number(), 1);
295+
296+
store
297+
.set_target_seq_number(10)
298+
.await
299+
.expect("Failed to set target seq number");
300+
assert_eq!(store.next_target_seq_number(), 11);
301+
302+
store
303+
.set_target_seq_number(5)
304+
.await
305+
.expect("Failed to set target seq number");
306+
assert_eq!(store.next_target_seq_number(), 6);
307+
}
308+
309+
#[tokio::test]
310+
async fn test_reset_store() {
311+
let mut test_store = TestStore::new();
312+
let store = test_store.store_mut();
313+
314+
// Add some messages and increment sequence numbers
315+
store
316+
.add(1, b"message 1")
317+
.await
318+
.expect("Failed to add message");
319+
store
320+
.add(2, b"message 2")
321+
.await
322+
.expect("Failed to add message");
323+
store
324+
.increment_sender_seq_number()
325+
.await
326+
.expect("Failed to increment sender seq number");
327+
store
328+
.increment_target_seq_number()
329+
.await
330+
.expect("Failed to increment target seq number");
331+
332+
assert_eq!(store.next_sender_seq_number(), 2);
333+
assert_eq!(store.next_target_seq_number(), 2);
334+
335+
let messages_before_reset = store.get_slice(1, 2).await.expect("Failed to get messages");
336+
assert_eq!(messages_before_reset.len(), 2);
337+
338+
// Reset the store
339+
store.reset().await.expect("Failed to reset store");
340+
341+
// Verify sequence numbers are reset
342+
assert_eq!(store.next_sender_seq_number(), 1);
343+
assert_eq!(store.next_target_seq_number(), 1);
344+
345+
// Verify messages are cleared
346+
let messages_after_reset = store.get_slice(1, 2).await.expect("Failed to get messages");
347+
assert_eq!(messages_after_reset.len(), 0);
348+
}
349+
350+
#[tokio::test]
351+
async fn test_persistence_across_store_instances() {
352+
let test_store = TestStore::new();
353+
let db_path = test_store.db_path().clone();
354+
355+
// Create first store instance and add data
356+
{
357+
let mut store1 = RedbMessageStore::new(&db_path).expect("Failed to create store1");
358+
store1
359+
.add(1, b"persistent message")
360+
.await
361+
.expect("Failed to add message");
362+
store1
363+
.increment_sender_seq_number()
364+
.await
365+
.expect("Failed to increment sender seq number");
366+
store1
367+
.set_target_seq_number(5)
368+
.await
369+
.expect("Failed to set target seq number");
370+
}
371+
372+
// Create second store instance and verify data persists
373+
{
374+
let store2 = RedbMessageStore::new(&db_path).expect("Failed to create store2");
375+
376+
assert_eq!(store2.next_sender_seq_number(), 2);
377+
assert_eq!(store2.next_target_seq_number(), 6);
378+
379+
let messages = store2
380+
.get_slice(1, 1)
381+
.await
382+
.expect("Failed to get messages");
383+
assert_eq!(messages.len(), 1);
384+
assert_eq!(messages[0], b"persistent message");
385+
}
386+
387+
// TestStore will clean up the file when it goes out of scope
388+
}
389+
390+
#[tokio::test]
391+
async fn test_add_messages_non_sequential() {
392+
let mut test_store = TestStore::new();
393+
let store = test_store.store_mut();
394+
395+
// Add messages in non-sequential order
396+
store
397+
.add(5, b"message 5")
398+
.await
399+
.expect("Failed to add message 5");
400+
store
401+
.add(1, b"message 1")
402+
.await
403+
.expect("Failed to add message 1");
404+
store
405+
.add(3, b"message 3")
406+
.await
407+
.expect("Failed to add message 3");
408+
409+
let messages = store.get_slice(1, 5).await.expect("Failed to get messages");
410+
assert_eq!(messages.len(), 3);
411+
assert_eq!(messages[0], b"message 1");
412+
assert_eq!(messages[1], b"message 3");
413+
assert_eq!(messages[2], b"message 5");
414+
}
415+
416+
#[tokio::test]
417+
async fn test_get_slice_beyond_available_messages() {
418+
let mut test_store = TestStore::new();
419+
let store = test_store.store_mut();
420+
421+
store
422+
.add(1, b"only message")
423+
.await
424+
.expect("Failed to add message");
425+
426+
let messages = store
427+
.get_slice(1, 10)
428+
.await
429+
.expect("Failed to get messages");
430+
assert_eq!(messages.len(), 1);
431+
assert_eq!(messages[0], b"only message");
432+
}
433+
434+
#[tokio::test]
435+
async fn test_overwrite_existing_message() {
436+
let mut test_store = TestStore::new();
437+
let store = test_store.store_mut();
438+
439+
store
440+
.add(1, b"original message")
441+
.await
442+
.expect("Failed to add original message");
443+
store
444+
.add(1, b"updated message")
445+
.await
446+
.expect("Failed to add updated message");
447+
448+
let messages = store.get_slice(1, 1).await.expect("Failed to get messages");
449+
assert_eq!(messages.len(), 1);
450+
assert_eq!(messages[0], b"updated message");
451+
}
452+
}

0 commit comments

Comments
 (0)