1#![deny(clippy::all)]
4
5use keyvaluedb::{DBKey, DBKeyRef, DBKeyValue, DBKeyValueRef, IoStatsKind, KeyValueDB};
6use std::io;
7
8pub async fn test_put_and_get<DB: KeyValueDB>(db: DB) -> io::Result<()> {
10 let key1 = b"key1";
11
12 let mut transaction = db.transaction();
13 transaction.put(0, key1, b"horse");
14 db.write(transaction).await.map_err(|e| e.error)?;
15 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
16 Ok(())
17}
18
19pub async fn test_num_keys<DB: KeyValueDB>(db: DB) -> io::Result<()> {
21 let key1 = b"key1";
22 let key2 = b"key2";
23
24 let mut transaction = db.transaction();
25 transaction.put(0, key1, b"horse");
26 transaction.put(0, key2, b"horse2");
27 db.write(transaction).await.map_err(|e| e.error)?;
28 assert_eq!(db.num_keys(0).await?, 2);
29 Ok(())
30}
31
32pub async fn test_delete_and_get<DB: KeyValueDB>(db: DB) -> io::Result<()> {
34 let key1 = b"key1";
35
36 let mut transaction = db.transaction();
37 transaction.put(0, key1, b"horse");
38 db.write(transaction).await.map_err(|e| e.error)?;
39 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
40
41 let mut transaction = db.transaction();
42 transaction.delete(0, key1);
43 db.write(transaction).await.map_err(|e| e.error)?;
44 assert!(db.get(0, key1).await?.is_none());
45 Ok(())
46}
47
48pub async fn test_delete_and_get_single<DB: KeyValueDB>(db: DB) -> io::Result<()> {
50 let key1 = b"key1";
51
52 let mut transaction = db.transaction();
53 transaction.put(0, key1, b"horse");
54 db.write(transaction).await.map_err(|e| e.error)?;
55 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
56
57 assert_eq!(db.delete(0, key1).await?, Some(b"horse".to_vec()));
58 assert!(db.get(0, key1).await?.is_none());
59 assert_eq!(db.delete(0, key1).await?, None);
60
61 Ok(())
62}
63
64pub async fn test_get_fails_with_non_existing_column<DB: KeyValueDB>(db: DB) -> io::Result<()> {
67 assert!(db.get(1, b"").await.is_err());
68 Ok(())
69}
70
71pub async fn test_write_clears_buffered_ops<DB: KeyValueDB>(db: DB) -> io::Result<()> {
73 let mut batch = db.transaction();
74 batch.put(0, b"foo", b"bar");
75 db.write(batch).await.map_err(|e| e.error)?;
76
77 assert_eq!(db.get(0, b"foo").await?.unwrap(), b"bar");
78
79 let mut batch = db.transaction();
80 batch.put(0, b"foo", b"baz");
81 db.write(batch).await.map_err(|e| e.error)?;
82
83 assert_eq!(db.get(0, b"foo").await?.unwrap(), b"baz");
84 Ok(())
85}
86
87pub async fn test_iter<DB: KeyValueDB>(db: DB) -> io::Result<()> {
89 let key1 = b"key1";
90 let key2 = b"key2";
91
92 let mut transaction = db.transaction();
93 transaction.put(0, key1, key1);
94 transaction.put(0, key2, key2);
95 db.write(transaction).await.map_err(|e| e.error)?;
96
97 let contents: Vec<DBKeyValue> = Vec::new();
98 let (contents, out) = db
99 .iter(0, None, contents, |contents, kv: DBKeyValueRef| {
100 contents.push((kv.0.clone(), kv.1.clone()));
101 Ok(Option::<()>::None)
102 })
103 .await?;
104 assert!(out.is_none());
105 assert_eq!(contents.len(), 2);
106 assert_eq!(contents[0].0, key1);
107 assert_eq!(contents[0].1, key1);
108 assert_eq!(contents[1].0, key2);
109 assert_eq!(contents[1].1, key2);
110
111 let contents: Vec<DBKeyValue> = Vec::new();
113 let (contents, out) = db
114 .iter(0, None, contents, |contents, kv: DBKeyValueRef| {
115 contents.push((kv.0.clone(), kv.1.clone()));
116 Ok(Option::<()>::Some(()))
117 })
118 .await?;
119 assert!(out.is_some());
120 assert_eq!(contents.len(), 1);
121 assert_eq!(contents[0].0, key1);
122 assert_eq!(contents[0].1, key1);
123 Ok(())
124}
125
126pub async fn test_iter_keys<DB: KeyValueDB>(db: DB) -> io::Result<()> {
128 let key1 = b"key1";
129 let key2 = b"key2";
130
131 let mut transaction = db.transaction();
132 transaction.put(0, key1, key1);
133 transaction.put(0, key2, key2);
134 db.write(transaction).await.map_err(|e| e.error)?;
135
136 let contents: Vec<DBKey> = Vec::new();
137 let (contents, out) = db
138 .iter_keys(0, None, contents, |contents, k: DBKeyRef| {
139 contents.push(k.clone());
140 Ok(Option::<()>::None)
141 })
142 .await?;
143 assert!(out.is_none());
144 assert_eq!(contents.len(), 2);
145 assert_eq!(contents[0], key1);
146 assert_eq!(contents[1], key2);
147
148 let contents: Vec<DBKey> = Vec::new();
150 let (contents, out) = db
151 .iter_keys(0, None, contents, |contents, k: DBKeyRef| {
152 contents.push(k.clone());
153 Ok(Option::<()>::Some(()))
154 })
155 .await?;
156 assert!(out.is_some());
157 assert_eq!(contents.len(), 1);
158 assert_eq!(contents[0], key1);
159
160 Ok(())
161}
162
163pub async fn test_iter_with_prefix<DB: KeyValueDB>(db: DB) -> io::Result<()> {
165 let key1 = b"0";
166 let key2 = b"ab";
167 let key3 = b"abc";
168 let key4 = b"abcd";
169
170 let mut batch = db.transaction();
171 batch.put(0, key1, key1);
172 batch.put(0, key2, key2);
173 batch.put(0, key3, key3);
174 batch.put(0, key4, key4);
175 db.write(batch).await.map_err(|e| e.error)?;
176
177 let contents: Vec<DBKeyValue> = Vec::new();
179 let (contents, out) = db
180 .iter(0, Some(b""), contents, |contents, kv: DBKeyValueRef| {
181 contents.push((kv.0.clone(), kv.1.clone()));
182 Ok(Option::<()>::None)
183 })
184 .await?;
185 assert!(out.is_none());
186 assert_eq!(contents.len(), 4);
187 assert_eq!(contents[0].0, key1);
188 assert_eq!(contents[1].0, key2);
189 assert_eq!(contents[2].0, key3);
190 assert_eq!(contents[3].0, key4);
191
192 let contents: Vec<DBKeyValue> = Vec::new();
194 let (contents, out) = db
195 .iter(0, Some(b""), contents, |contents, kv: DBKeyValueRef| {
196 contents.push((kv.0.clone(), kv.1.clone()));
197 Ok(Option::<()>::Some(()))
198 })
199 .await?;
200 assert!(out.is_some());
201 assert_eq!(contents.len(), 1);
202 assert_eq!(contents[0].0, key1);
203
204 let contents: Vec<DBKeyValue> = Vec::new();
206 let (contents, _) = db
207 .iter(0, Some(b"a"), contents, |contents, kv: DBKeyValueRef| {
208 contents.push((kv.0.clone(), kv.1.clone()));
209 Ok(Option::<()>::None)
210 })
211 .await?;
212 assert_eq!(contents.len(), 3);
213 assert_eq!(contents[0].0, key2);
214 assert_eq!(contents[1].0, key3);
215 assert_eq!(contents[2].0, key4);
216
217 let contents: Vec<DBKeyValue> = Vec::new();
219 let (contents, _) = db
220 .iter(0, Some(b"abc"), contents, |contents, kv: DBKeyValueRef| {
221 contents.push((kv.0.clone(), kv.1.clone()));
222 Ok(Option::<()>::None)
223 })
224 .await?;
225 assert_eq!(contents.len(), 2);
226 assert_eq!(contents[0].0, key3);
227 assert_eq!(contents[1].0, key4);
228
229 let contents: Vec<DBKeyValue> = Vec::new();
231 let (contents, _) = db
232 .iter(
233 0,
234 Some(b"abcde"),
235 contents,
236 |contents, kv: DBKeyValueRef| {
237 contents.push((kv.0.clone(), kv.1.clone()));
238 Ok(Option::<()>::None)
239 },
240 )
241 .await?;
242 assert_eq!(contents.len(), 0);
243
244 let contents: Vec<DBKeyValue> = Vec::new();
246 let (contents, _) = db
247 .iter(0, Some(b"0"), contents, |contents, kv: DBKeyValueRef| {
248 contents.push((kv.0.clone(), kv.1.clone()));
249 Ok(Option::<()>::None)
250 })
251 .await?;
252 assert_eq!(contents.len(), 1);
253 assert_eq!(contents[0].0, key1);
254 Ok(())
255}
256
257pub const IO_STATS_NUM_COLUMNS: u32 = 3;
259
260pub async fn test_io_stats<DB: KeyValueDB>(db: DB) -> io::Result<()> {
263 let key1 = b"kkk";
264 let mut batch = db.transaction();
265 batch.put(0, key1, key1);
266 batch.put(1, key1, key1);
267 batch.put(2, key1, key1);
268
269 for _ in 0..10 {
270 db.get(0, key1).await?;
271 }
272
273 db.write(batch).await.map_err(|e| e.error)?;
274
275 let io_stats = db.io_stats(IoStatsKind::SincePrevious);
276 assert_eq!(io_stats.transactions, 1);
277 assert_eq!(io_stats.writes, 3);
278 assert_eq!(io_stats.bytes_written, 18);
279 assert_eq!(io_stats.reads, 10);
280 assert_eq!(io_stats.bytes_read, 30);
281
282 let new_io_stats = db.io_stats(IoStatsKind::SincePrevious);
283 assert_eq!(new_io_stats.transactions, 0);
286
287 let new_io_stats = db.io_stats(IoStatsKind::Overall);
289 assert_eq!(new_io_stats.bytes_written, 18);
290
291 let mut batch = db.transaction();
292 batch.delete(0, key1);
293 batch.delete(1, key1);
294 batch.delete(2, key1);
295
296 assert_eq!(db.io_stats(IoStatsKind::SincePrevious).writes, 0);
298
299 db.write(batch).await.map_err(|e| e.error)?;
300 assert_eq!(db.io_stats(IoStatsKind::SincePrevious).writes, 3);
302 Ok(())
303}
304
305pub const DELETE_PREFIX_NUM_COLUMNS: u32 = 7;
307
308pub async fn test_delete_prefix<DB: KeyValueDB + 'static>(db: DB) -> io::Result<()> {
310 let keys = [
311 &[][..],
312 &[0u8][..],
313 &[0, 1][..],
314 &[1][..],
315 &[1, 0][..],
316 &[1, 255][..],
317 &[1, 255, 255][..],
318 &[2][..],
319 &[2, 0][..],
320 &[2, 255][..],
321 &[255; 16][..],
322 ];
323 let tests: [_; DELETE_PREFIX_NUM_COLUMNS as usize] = [
324 (
326 &[1u8][..],
327 [
328 true, true, true, false, false, false, false, true, true, true, true,
329 ],
330 ),
331 (
333 &[1u8, 255, 255][..],
334 [
335 true, true, true, true, true, true, false, true, true, true, true,
336 ],
337 ),
338 (
340 &[1, 2][..],
341 [
342 true, true, true, true, true, true, true, true, true, true, true,
343 ],
344 ),
345 (
347 &[8][..],
348 [
349 true, true, true, true, true, true, true, true, true, true, true,
350 ],
351 ),
352 (
354 &[255, 255][..],
355 [
356 true, true, true, true, true, true, true, true, true, true, false,
357 ],
358 ),
359 (
361 &[255][..],
362 [
363 true, true, true, true, true, true, true, true, true, true, false,
364 ],
365 ),
366 (
368 &[][..],
369 [
370 false, false, false, false, false, false, false, false, false, false, false,
371 ],
372 ),
373 ];
374 for (ix, test) in tests.iter().enumerate() {
375 let ix = ix as u32;
376
377 let mut batch = db.transaction();
379 for (i, key) in keys.iter().enumerate() {
380 batch.put(ix, key, [i as u8]);
381 }
382 db.write(batch).await.map_err(|e| e.error)?;
383
384 let mut batch = db.transaction();
386 batch.delete_prefix(ix, test.0);
387 db.write(batch).await.map_err(|e| e.error)?;
388
389 let mut state = [true; 11];
391 for (c, key) in keys.iter().enumerate() {
392 state[c] = db.get(ix, key).await?.is_some();
393 }
394 assert_eq!(state, test.1, "at {}", ix);
395 }
396
397 Ok(())
398}
399
400pub async fn test_complex<DB: KeyValueDB>(db: DB) -> io::Result<()> {
402 let key1 = b"02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
403 let key2 = b"03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
404 let key3 = b"04c00000000b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
405 let key4 = b"04c01111110b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
406 let key5 = b"04c02222220b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
407
408 let mut batch = db.transaction();
409 batch.put(0, key1, b"cat");
410 batch.put(0, key2, b"dog");
411 batch.put(0, key3, b"caterpillar");
412 batch.put(0, key4, b"beef");
413 batch.put(0, key5, b"fish");
414 db.write(batch).await.map_err(|e| e.error)?;
415
416 assert_eq!(db.get(0, key1).await?.unwrap(), b"cat");
417
418 let contents: Vec<DBKeyValue> = Vec::new();
419 let (contents, _) = db
420 .iter(0, None, contents, |contents, kv: DBKeyValueRef| {
421 contents.push((kv.0.clone(), kv.1.clone()));
422 Ok(Option::<()>::None)
423 })
424 .await?;
425 assert_eq!(contents.len(), 5);
426 assert_eq!(contents[0].0, key1.to_vec());
427 assert_eq!(contents[0].1, b"cat");
428 assert_eq!(contents[1].0, key2.to_vec());
429 assert_eq!(contents[1].1, b"dog");
430
431 let contents: Vec<DBKeyValue> = Vec::new();
432 let (contents, _) = db
433 .iter(0, Some(b"04c0"), contents, |contents, kv: DBKeyValueRef| {
434 contents.push((kv.0.clone(), kv.1.clone()));
435 Ok(Option::<()>::None)
436 })
437 .await?;
438 assert_eq!(contents[0].1, b"caterpillar");
439 assert_eq!(contents[1].1, b"beef");
440 assert_eq!(contents[2].1, b"fish");
441
442 let mut batch = db.transaction();
443 batch.delete(0, key1);
444 db.write(batch).await.map_err(|e| e.error)?;
445
446 assert!(db.get(0, key1).await?.is_none());
447
448 let mut batch = db.transaction();
449 batch.put(0, key1, b"cat");
450 db.write(batch).await.map_err(|e| e.error)?;
451
452 let mut transaction = db.transaction();
453 transaction.put(0, key3, b"elephant");
454 transaction.delete(0, key1);
455 db.write(transaction).await.map_err(|e| e.error)?;
456 assert!(db.get(0, key1).await?.is_none());
457 assert_eq!(db.get(0, key3).await?.unwrap(), b"elephant");
458
459 assert_eq!(
460 db.first_with_prefix(0, key3).await?.unwrap(),
461 (key3.to_vec(), b"elephant".to_vec())
462 );
463 assert_eq!(
464 db.first_with_prefix(0, key2).await?.unwrap(),
465 (key2.to_vec(), b"dog".to_vec())
466 );
467
468 let mut transaction = db.transaction();
469 transaction.put(0, key1, b"horse");
470 transaction.delete(0, key3);
471 db.write(transaction).await.map_err(|e| e.error)?;
472 assert!(db.get(0, key3).await?.is_none());
473 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
474
475 assert!(db.get(0, key3).await?.is_none());
476 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
477 Ok(())
478}
479
480pub async fn test_cleanup<DB: KeyValueDB>(db: DB) -> io::Result<()> {
481 db.cleanup().await
482}