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 mut contents: Vec<DBKeyValue> = Vec::new();
98 let out = db
99 .iter(0, None, |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 mut contents: Vec<DBKeyValue> = Vec::new();
113 let out = db
114 .iter(0, None, |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 mut contents: Vec<DBKey> = Vec::new();
137 let out = db
138 .iter_keys(0, None, |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 mut contents: Vec<DBKey> = Vec::new();
150 let out = db
151 .iter_keys(0, None, |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 mut contents: Vec<DBKeyValue> = Vec::new();
179 let out = db
180 .iter(0, Some(b""), |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 mut contents: Vec<DBKeyValue> = Vec::new();
194 let out = db
195 .iter(0, Some(b""), |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 mut contents: Vec<DBKeyValue> = Vec::new();
206 db.iter(0, Some(b"a"), |kv: DBKeyValueRef| {
207 contents.push((kv.0.clone(), kv.1.clone()));
208 Ok(Option::<()>::None)
209 })
210 .await?;
211 assert_eq!(contents.len(), 3);
212 assert_eq!(contents[0].0, key2);
213 assert_eq!(contents[1].0, key3);
214 assert_eq!(contents[2].0, key4);
215
216 let mut contents: Vec<DBKeyValue> = Vec::new();
218 db.iter(0, Some(b"abc"), |kv: DBKeyValueRef| {
219 contents.push((kv.0.clone(), kv.1.clone()));
220 Ok(Option::<()>::None)
221 })
222 .await?;
223 assert_eq!(contents.len(), 2);
224 assert_eq!(contents[0].0, key3);
225 assert_eq!(contents[1].0, key4);
226
227 let mut contents: Vec<DBKeyValue> = Vec::new();
229 db.iter(0, Some(b"abcde"), |kv: DBKeyValueRef| {
230 contents.push((kv.0.clone(), kv.1.clone()));
231 Ok(Option::<()>::None)
232 })
233 .await?;
234 assert_eq!(contents.len(), 0);
235
236 let mut contents: Vec<DBKeyValue> = Vec::new();
238 db.iter(0, Some(b"0"), |kv: DBKeyValueRef| {
239 contents.push((kv.0.clone(), kv.1.clone()));
240 Ok(Option::<()>::None)
241 })
242 .await?;
243 assert_eq!(contents.len(), 1);
244 assert_eq!(contents[0].0, key1);
245 Ok(())
246}
247
248pub const IO_STATS_NUM_COLUMNS: u32 = 3;
250
251pub async fn test_io_stats<DB: KeyValueDB>(db: DB) -> io::Result<()> {
254 let key1 = b"kkk";
255 let mut batch = db.transaction();
256 batch.put(0, key1, key1);
257 batch.put(1, key1, key1);
258 batch.put(2, key1, key1);
259
260 for _ in 0..10 {
261 db.get(0, key1).await?;
262 }
263
264 db.write(batch).await.map_err(|e| e.error)?;
265
266 let io_stats = db.io_stats(IoStatsKind::SincePrevious);
267 assert_eq!(io_stats.transactions, 1);
268 assert_eq!(io_stats.writes, 3);
269 assert_eq!(io_stats.bytes_written, 18);
270 assert_eq!(io_stats.reads, 10);
271 assert_eq!(io_stats.bytes_read, 30);
272
273 let new_io_stats = db.io_stats(IoStatsKind::SincePrevious);
274 assert_eq!(new_io_stats.transactions, 0);
277
278 let new_io_stats = db.io_stats(IoStatsKind::Overall);
280 assert_eq!(new_io_stats.bytes_written, 18);
281
282 let mut batch = db.transaction();
283 batch.delete(0, key1);
284 batch.delete(1, key1);
285 batch.delete(2, key1);
286
287 assert_eq!(db.io_stats(IoStatsKind::SincePrevious).writes, 0);
289
290 db.write(batch).await.map_err(|e| e.error)?;
291 assert_eq!(db.io_stats(IoStatsKind::SincePrevious).writes, 3);
293 Ok(())
294}
295
296pub const DELETE_PREFIX_NUM_COLUMNS: u32 = 7;
298
299pub async fn test_delete_prefix<DB: KeyValueDB + 'static>(db: DB) -> io::Result<()> {
301 let keys = [
302 &[][..],
303 &[0u8][..],
304 &[0, 1][..],
305 &[1][..],
306 &[1, 0][..],
307 &[1, 255][..],
308 &[1, 255, 255][..],
309 &[2][..],
310 &[2, 0][..],
311 &[2, 255][..],
312 &[255; 16][..],
313 ];
314 let tests: [_; DELETE_PREFIX_NUM_COLUMNS as usize] = [
315 (
317 &[1u8][..],
318 [
319 true, true, true, false, false, false, false, true, true, true, true,
320 ],
321 ),
322 (
324 &[1u8, 255, 255][..],
325 [
326 true, true, true, true, true, true, false, true, true, true, true,
327 ],
328 ),
329 (
331 &[1, 2][..],
332 [
333 true, true, true, true, true, true, true, true, true, true, true,
334 ],
335 ),
336 (
338 &[8][..],
339 [
340 true, true, true, true, true, true, true, true, true, true, true,
341 ],
342 ),
343 (
345 &[255, 255][..],
346 [
347 true, true, true, true, true, true, true, true, true, true, false,
348 ],
349 ),
350 (
352 &[255][..],
353 [
354 true, true, true, true, true, true, true, true, true, true, false,
355 ],
356 ),
357 (
359 &[][..],
360 [
361 false, false, false, false, false, false, false, false, false, false, false,
362 ],
363 ),
364 ];
365 for (ix, test) in tests.iter().enumerate() {
366 let ix = ix as u32;
367
368 let mut batch = db.transaction();
370 for (i, key) in keys.iter().enumerate() {
371 batch.put(ix, key, [i as u8]);
372 }
373 db.write(batch).await.map_err(|e| e.error)?;
374
375 let mut batch = db.transaction();
377 batch.delete_prefix(ix, test.0);
378 db.write(batch).await.map_err(|e| e.error)?;
379
380 let mut state = [true; 11];
382 for (c, key) in keys.iter().enumerate() {
383 state[c] = db.get(ix, key).await?.is_some();
384 }
385 assert_eq!(state, test.1, "at {}", ix);
386 }
387
388 Ok(())
389}
390
391pub async fn test_complex<DB: KeyValueDB>(db: DB) -> io::Result<()> {
393 let key1 = b"02c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
394 let key2 = b"03c69be41d0b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
395 let key3 = b"04c00000000b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
396 let key4 = b"04c01111110b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
397 let key5 = b"04c02222220b7e40352fc85be1cd65eb03d40ef8427a0ca4596b1ead9a00e9fc";
398
399 let mut batch = db.transaction();
400 batch.put(0, key1, b"cat");
401 batch.put(0, key2, b"dog");
402 batch.put(0, key3, b"caterpillar");
403 batch.put(0, key4, b"beef");
404 batch.put(0, key5, b"fish");
405 db.write(batch).await.map_err(|e| e.error)?;
406
407 assert_eq!(db.get(0, key1).await?.unwrap(), b"cat");
408
409 let mut contents: Vec<DBKeyValue> = Vec::new();
410 db.iter(0, None, |kv: DBKeyValueRef| {
411 contents.push((kv.0.clone(), kv.1.clone()));
412 Ok(Option::<()>::None)
413 })
414 .await?;
415 assert_eq!(contents.len(), 5);
416 assert_eq!(contents[0].0, key1.to_vec());
417 assert_eq!(contents[0].1, b"cat");
418 assert_eq!(contents[1].0, key2.to_vec());
419 assert_eq!(contents[1].1, b"dog");
420
421 let mut contents: Vec<DBKeyValue> = Vec::new();
422 db.iter(0, Some(b"04c0"), |kv: DBKeyValueRef| {
423 contents.push((kv.0.clone(), kv.1.clone()));
424 Ok(Option::<()>::None)
425 })
426 .await?;
427 assert_eq!(contents[0].1, b"caterpillar");
428 assert_eq!(contents[1].1, b"beef");
429 assert_eq!(contents[2].1, b"fish");
430
431 let mut batch = db.transaction();
432 batch.delete(0, key1);
433 db.write(batch).await.map_err(|e| e.error)?;
434
435 assert!(db.get(0, key1).await?.is_none());
436
437 let mut batch = db.transaction();
438 batch.put(0, key1, b"cat");
439 db.write(batch).await.map_err(|e| e.error)?;
440
441 let mut transaction = db.transaction();
442 transaction.put(0, key3, b"elephant");
443 transaction.delete(0, key1);
444 db.write(transaction).await.map_err(|e| e.error)?;
445 assert!(db.get(0, key1).await?.is_none());
446 assert_eq!(db.get(0, key3).await?.unwrap(), b"elephant");
447
448 assert_eq!(
449 db.first_with_prefix(0, key3).await?.unwrap(),
450 (key3.to_vec(), b"elephant".to_vec())
451 );
452 assert_eq!(
453 db.first_with_prefix(0, key2).await?.unwrap(),
454 (key2.to_vec(), b"dog".to_vec())
455 );
456
457 let mut transaction = db.transaction();
458 transaction.put(0, key1, b"horse");
459 transaction.delete(0, key3);
460 db.write(transaction).await.map_err(|e| e.error)?;
461 assert!(db.get(0, key3).await?.is_none());
462 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
463
464 assert!(db.get(0, key3).await?.is_none());
465 assert_eq!(db.get(0, key1).await?.unwrap(), b"horse");
466 Ok(())
467}