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 let stats = db.io_stats(IoStatsKind::SincePrevious);
298 assert_eq!(stats.writes, 0);
299 assert_eq!(stats.deletes, 0);
300
301 db.write(batch).await.map_err(|e| e.error)?;
302 let stats = db.io_stats(IoStatsKind::SincePrevious);
303 assert_eq!(stats.writes, 0);
304 assert_eq!(stats.deletes, 3);
305 Ok(())
306}
307
308pub const DELETE_PREFIX_NUM_COLUMNS: u32 = 7;
310
311pub async fn test_delete_prefix<DB: KeyValueDB + 'static>(db: DB) -> io::Result<()> {
313 let keys = [
314 &[][..],
315 &[0u8][..],
316 &[0, 1][..],
317 &[1][..],
318 &[1, 0][..],
319 &[1, 255][..],
320 &[1, 255, 255][..],
321 &[2][..],
322 &[2, 0][..],
323 &[2, 255][..],
324 &[255; 16][..],
325 ];
326 let tests: [_; DELETE_PREFIX_NUM_COLUMNS as usize] = [
327 (
329 &[1u8][..],
330 [
331 true, true, true, false, false, false, false, true, true, true, true,
332 ],
333 ),
334 (
336 &[1u8, 255, 255][..],
337 [
338 true, true, true, true, true, true, false, true, true, true, true,
339 ],
340 ),
341 (
343 &[1, 2][..],
344 [
345 true, true, true, true, true, true, true, true, true, true, true,
346 ],
347 ),
348 (
350 &[8][..],
351 [
352 true, true, true, true, true, true, true, true, true, true, true,
353 ],
354 ),
355 (
357 &[255, 255][..],
358 [
359 true, true, true, true, true, true, true, true, true, true, false,
360 ],
361 ),
362 (
364 &[255][..],
365 [
366 true, true, true, true, true, true, true, true, true, true, false,
367 ],
368 ),
369 (
371 &[][..],
372 [
373 false, false, false, false, false, false, false, false, false, false, false,
374 ],
375 ),
376 ];
377 for (ix, test) in tests.iter().enumerate() {
378 let ix = ix as u32;
379
380 let mut batch = db.transaction();
382 for (i, key) in keys.iter().enumerate() {
383 batch.put(ix, key, [i as u8]);
384 }
385 db.write(batch).await.map_err(|e| e.error)?;
386
387 let mut batch = db.transaction();
389 batch.delete_prefix(ix, test.0);
390 db.write(batch).await.map_err(|e| e.error)?;
391
392 let mut state = [true; 11];
394 for (c, key) in keys.iter().enumerate() {
395 state[c] = db.get(ix, key).await?.is_some();
396 }
397 assert_eq!(state, test.1, "at {}", ix);
398 }
399
400 Ok(())
401}
402
403pub async fn test_complex<DB: KeyValueDB>(db: DB) -> io::Result<()> {
405 let key1 = b"02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
406 let key2 = b"03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
407 let key3 = b"04c00000000b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
408 let key4 = b"04c01111110b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
409 let key5 = b"04c02222220b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
410
411 let mut batch = db.transaction();
412 batch.put(0, key1, b"cat");
413 batch.put(0, key2, b"dog");
414 batch.put(0, key3, b"caterpillar");
415 batch.put(0, key4, b"beef");
416 batch.put(0, key5, b"fish");
417 db.write(batch).await.map_err(|e| e.error)?;
418
419 assert_eq!(db.get(0, key1).await?.unwrap(), b"cat");
420
421 let contents: Vec<DBKeyValue> = Vec::new();
422 let (contents, _) = db
423 .iter(0, None, contents, |contents, kv: DBKeyValueRef| {
424 contents.push((kv.0.clone(), kv.1.clone()));
425 Ok(Option::<()>::None)
426 })
427 .await?;
428 assert_eq!(contents.len(), 5);
429 assert_eq!(contents[0].0, key1.to_vec());
430 assert_eq!(contents[0].1, b"cat");
431 assert_eq!(contents[1].0, key2.to_vec());
432 assert_eq!(contents[1].1, b"dog");
433
434 let contents: Vec<DBKeyValue> = Vec::new();
435 let (contents, _) = db
436 .iter(0, Some(b"04c0"), contents, |contents, kv: DBKeyValueRef| {
437 contents.push((kv.0.clone(), kv.1.clone()));
438 Ok(Option::<()>::None)
439 })
440 .await?;
441 assert_eq!(contents[0].1, b"caterpillar");
442 assert_eq!(contents[1].1, b"beef");
443 assert_eq!(contents[2].1, b"fish");
444
445 let mut batch = db.transaction();
446 batch.delete(0, key1);
447 db.write(batch).await.map_err(|e| e.error)?;
448
449 assert!(db.get(0, key1).await?.is_none());
450
451 let mut batch = db.transaction();
452 batch.put(0, key1, b"cat");
453 db.write(batch).await.map_err(|e| e.error)?;
454
455 let mut transaction = db.transaction();
456 transaction.put(0, key3, b"elephant");
457 transaction.delete(0, key1);
458 db.write(transaction).await.map_err(|e| e.error)?;
459 assert!(db.get(0, key1).await?.is_none());
460 assert_eq!(db.get(0, key3).await?.unwrap(), b"elephant");
461
462 assert_eq!(
463 db.first_with_prefix(0, key3).await?.unwrap(),
464 (key3.to_vec(), b"elephant".to_vec())
465 );
466 assert_eq!(
467 db.first_with_prefix(0, key2).await?.unwrap(),
468 (key2.to_vec(), b"dog".to_vec())
469 );
470
471 let mut transaction = db.transaction();
472 transaction.put(0, key1, b"horse");
473 transaction.delete(0, key3);
474 db.write(transaction).await.map_err(|e| e.error)?;
475 assert!(db.get(0, key3).await?.is_none());
476 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
477
478 assert!(db.get(0, key3).await?.is_none());
479 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
480 Ok(())
481}
482
483pub async fn test_cleanup<DB: KeyValueDB>(db: DB) -> io::Result<()> {
484 db.cleanup().await
485}