1use crate::{Benchmark, CacheClearableFilesystem, Filesystem, OperationDuration, OperationTimer};
6use async_trait::async_trait;
7use rand::seq::SliceRandom as _;
8use rand::{Rng, SeedableRng as _};
9use rand_xorshift::XorShiftRng;
10use std::fs::OpenOptions;
11use std::io::{Seek, SeekFrom, Write};
12use std::os::unix::fs::FileExt;
13use std::os::unix::io::AsRawFd;
14
15const RNG_SEED: u64 = 0xda782a0c3ce1819a;
16const BLOCK_SKIP: usize = 255;
20
21#[derive(Clone)]
24pub struct ReadSequentialCold {
25 op_size: usize,
26 op_count: usize,
27 read_only: bool,
28}
29
30impl ReadSequentialCold {
31 pub fn new(op_size: usize, op_count: usize) -> Self {
32 Self { op_size, op_count, read_only: false }
33 }
34
35 pub fn new_read_only(op_size: usize, op_count: usize) -> Self {
36 Self { op_size, op_count, read_only: true }
37 }
38}
39
40#[async_trait]
41impl<T: CacheClearableFilesystem> Benchmark<T> for ReadSequentialCold {
42 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
43 storage_trace::duration!(
44 "benchmark",
45 "ReadSequentialCold",
46 "op_size" => self.op_size,
47 "op_count" => self.op_count
48 );
49 let file_path = fs.benchmark_dir().join("file");
50
51 if !self.read_only {
53 let mut file =
54 OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
55 write_file(&mut file, self.op_size, self.op_count);
56 std::mem::drop(file);
57 }
58 fs.clear_cache().await;
59
60 let mut file = OpenOptions::new().read(true).open(&file_path).unwrap();
62 read_sequential(&mut file, self.op_size, self.op_count)
63 }
64
65 fn name(&self) -> String {
66 format!("ReadSequentialCold/{}", self.op_size)
67 }
68}
69
70#[derive(Clone)]
73pub struct ReadSequentialWarm {
74 op_size: usize,
75 op_count: usize,
76 read_only: bool,
77}
78
79impl ReadSequentialWarm {
80 pub fn new(op_size: usize, op_count: usize) -> Self {
81 Self { op_size, op_count, read_only: false }
82 }
83
84 pub fn new_read_only(op_size: usize, op_count: usize) -> Self {
85 Self { op_size, op_count, read_only: true }
86 }
87}
88
89#[async_trait]
90impl<T: Filesystem> Benchmark<T> for ReadSequentialWarm {
91 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
92 storage_trace::duration!(
93 "benchmark",
94 "ReadSequentialWarm",
95 "op_size" => self.op_size,
96 "op_count" => self.op_count
97 );
98 let file_path = fs.benchmark_dir().join("file");
99
100 let mut file = if self.read_only {
102 let mut file = OpenOptions::new().read(true).open(&file_path).unwrap();
103 let _ = read_sequential(&mut file, self.op_size, self.op_count);
104 file.seek(SeekFrom::Start(0)).unwrap();
105 file
106 } else {
107 let mut file = OpenOptions::new()
108 .write(true)
109 .read(true)
110 .create_new(true)
111 .open(&file_path)
112 .unwrap();
113 write_file(&mut file, self.op_size, self.op_count);
114 file.seek(SeekFrom::Start(0)).unwrap();
115 file
116 };
117
118 read_sequential(&mut file, self.op_size, self.op_count)
120 }
121
122 fn name(&self) -> String {
123 format!("ReadSequentialWarm/{}", self.op_size)
124 }
125}
126
127#[derive(Clone)]
130pub struct ReadRandomCold {
131 op_size: usize,
132 op_count: usize,
133 read_only: bool,
134}
135
136impl ReadRandomCold {
137 pub fn new(op_size: usize, op_count: usize) -> Self {
138 Self { op_size, op_count, read_only: false }
139 }
140
141 pub fn new_read_only(op_size: usize, op_count: usize) -> Self {
142 Self { op_size, op_count, read_only: true }
143 }
144}
145
146#[async_trait]
147impl<T: CacheClearableFilesystem> Benchmark<T> for ReadRandomCold {
148 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
149 storage_trace::duration!(
150 "benchmark",
151 "ReadRandomCold",
152 "op_size" => self.op_size,
153 "op_count" => self.op_count
154 );
155 let file_path = fs.benchmark_dir().join("file");
156
157 if !self.read_only {
159 let mut file =
160 OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
161 write_file(&mut file, self.op_size, self.op_count);
162 std::mem::drop(file);
163 }
164 fs.clear_cache().await;
165
166 let mut rng = XorShiftRng::seed_from_u64(RNG_SEED);
168 let mut file = OpenOptions::new().read(true).open(&file_path).unwrap();
169 read_random(&mut file, self.op_size, self.op_count, &mut rng)
170 }
171
172 fn name(&self) -> String {
173 format!("ReadRandomCold/{}", self.op_size)
174 }
175}
176
177#[derive(Clone)]
181pub struct ReadSparseCold {
182 op_size: usize,
183 op_count: usize,
184}
185
186impl ReadSparseCold {
187 pub fn new(op_size: usize, op_count: usize) -> Self {
188 Self { op_size, op_count }
189 }
190}
191
192#[async_trait]
193impl<T: CacheClearableFilesystem> Benchmark<T> for ReadSparseCold {
194 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
195 storage_trace::duration!(
196 "benchmark",
197 "ReadSparseCold",
198 "op_size" => self.op_size,
199 "op_count" => self.op_count
200 );
201 let file_path = fs.benchmark_dir().join("file");
202
203 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
205 write_sparse_file(&mut file, self.op_size, self.op_count, BLOCK_SKIP);
206 std::mem::drop(file);
207 fs.clear_cache().await;
208
209 let mut file = OpenOptions::new().read(true).open(&file_path).unwrap();
211 read_sparse(&mut file, self.op_size, self.op_count, BLOCK_SKIP)
212 }
213
214 fn name(&self) -> String {
215 format!("ReadSparseCold/{}", self.op_size)
216 }
217}
218
219#[derive(Clone)]
222pub struct ReadRandomWarm {
223 op_size: usize,
224 op_count: usize,
225 read_only: bool,
226}
227
228impl ReadRandomWarm {
229 pub fn new(op_size: usize, op_count: usize) -> Self {
230 Self { op_size, op_count, read_only: false }
231 }
232
233 pub fn new_read_only(op_size: usize, op_count: usize) -> Self {
234 Self { op_size, op_count, read_only: true }
235 }
236}
237
238#[async_trait]
239impl<T: Filesystem> Benchmark<T> for ReadRandomWarm {
240 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
241 storage_trace::duration!(
242 "benchmark",
243 "ReadRandomWarm",
244 "op_size" => self.op_size,
245 "op_count" => self.op_count
246 );
247 let file_path = fs.benchmark_dir().join("file");
248
249 let mut file = if self.read_only {
251 let mut file = OpenOptions::new().read(true).open(&file_path).unwrap();
252 let _ = read_sequential(&mut file, self.op_size, self.op_count);
253 file
254 } else {
255 let mut file = OpenOptions::new()
256 .write(true)
257 .read(true)
258 .create_new(true)
259 .open(&file_path)
260 .unwrap();
261 write_file(&mut file, self.op_size, self.op_count);
262 file
263 };
264
265 let mut rng = XorShiftRng::seed_from_u64(RNG_SEED);
267 read_random(&mut file, self.op_size, self.op_count, &mut rng)
268 }
269
270 fn name(&self) -> String {
271 format!("ReadRandomWarm/{}", self.op_size)
272 }
273}
274
275#[derive(Clone)]
277pub struct WriteSequentialCold {
278 op_size: usize,
279 op_count: usize,
280}
281
282impl WriteSequentialCold {
283 pub fn new(op_size: usize, op_count: usize) -> Self {
284 Self { op_size, op_count }
285 }
286}
287
288#[async_trait]
289impl<T: Filesystem> Benchmark<T> for WriteSequentialCold {
290 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
291 storage_trace::duration!(
292 "benchmark",
293 "WriteSequentialCold",
294 "op_size" => self.op_size,
295 "op_count" => self.op_count
296 );
297 let file_path = fs.benchmark_dir().join("file");
298 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
299 write_sequential(&mut file, self.op_size, self.op_count)
300 }
301
302 fn name(&self) -> String {
303 format!("WriteSequentialCold/{}", self.op_size)
304 }
305}
306
307#[derive(Clone)]
310pub struct WriteSequentialWarm {
311 op_size: usize,
312 op_count: usize,
313}
314
315impl WriteSequentialWarm {
316 pub fn new(op_size: usize, op_count: usize) -> Self {
317 Self { op_size, op_count }
318 }
319}
320
321#[async_trait]
322impl<T: Filesystem> Benchmark<T> for WriteSequentialWarm {
323 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
324 storage_trace::duration!(
325 "benchmark",
326 "WriteSequentialWarm",
327 "op_size" => self.op_size,
328 "op_count" => self.op_count
329 );
330 let file_path = fs.benchmark_dir().join("file");
331
332 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
334 write_file(&mut file, self.op_size, self.op_count);
335 file.seek(SeekFrom::Start(0)).unwrap();
336
337 write_sequential(&mut file, self.op_size, self.op_count)
339 }
340
341 fn name(&self) -> String {
342 format!("WriteSequentialWarm/{}", self.op_size)
343 }
344}
345
346#[derive(Clone)]
348pub struct WriteRandomCold {
349 op_size: usize,
350 op_count: usize,
351}
352
353impl WriteRandomCold {
354 pub fn new(op_size: usize, op_count: usize) -> Self {
355 Self { op_size, op_count }
356 }
357}
358
359#[async_trait]
360impl<T: Filesystem> Benchmark<T> for WriteRandomCold {
361 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
362 storage_trace::duration!(
363 "benchmark",
364 "WriteRandomCold",
365 "op_size" => self.op_size,
366 "op_count" => self.op_count
367 );
368 let file_path = fs.benchmark_dir().join("file");
369 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
370 let mut rng = XorShiftRng::seed_from_u64(RNG_SEED);
371 write_random(&mut file, self.op_size, self.op_count, &mut rng)
372 }
373
374 fn name(&self) -> String {
375 format!("WriteRandomCold/{}", self.op_size)
376 }
377}
378
379#[derive(Clone)]
382pub struct WriteRandomWarm {
383 op_size: usize,
384 op_count: usize,
385}
386
387impl WriteRandomWarm {
388 pub fn new(op_size: usize, op_count: usize) -> Self {
389 Self { op_size, op_count }
390 }
391}
392
393#[async_trait]
394impl<T: Filesystem> Benchmark<T> for WriteRandomWarm {
395 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
396 storage_trace::duration!(
397 "benchmark",
398 "WriteRandomWarm",
399 "op_size" => self.op_size,
400 "op_count" => self.op_count
401 );
402 let file_path = fs.benchmark_dir().join("file");
403
404 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
406 write_sequential(&mut file, self.op_size, self.op_count);
407
408 let mut rng = XorShiftRng::seed_from_u64(RNG_SEED);
410 write_random(&mut file, self.op_size, self.op_count, &mut rng)
411 }
412
413 fn name(&self) -> String {
414 format!("WriteRandomWarm/{}", self.op_size)
415 }
416}
417
418#[derive(Clone)]
420pub struct WriteSequentialFsyncCold {
421 op_size: usize,
422 op_count: usize,
423}
424
425impl WriteSequentialFsyncCold {
426 pub fn new(op_size: usize, op_count: usize) -> Self {
427 Self { op_size, op_count }
428 }
429}
430
431#[async_trait]
432impl<T: Filesystem> Benchmark<T> for WriteSequentialFsyncCold {
433 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
434 storage_trace::duration!(
435 "benchmark",
436 "WriteSequentialFsyncCold",
437 "op_size" => self.op_size,
438 "op_count" => self.op_count
439 );
440 let file_path = fs.benchmark_dir().join("file");
441 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
442 write_sequential_fsync(&mut file, self.op_size, self.op_count)
443 }
444
445 fn name(&self) -> String {
446 format!("WriteSequentialFsyncCold/{}", self.op_size)
447 }
448}
449
450#[derive(Clone)]
453pub struct WriteSequentialFsyncWarm {
454 op_size: usize,
455 op_count: usize,
456}
457
458impl WriteSequentialFsyncWarm {
459 pub fn new(op_size: usize, op_count: usize) -> Self {
460 Self { op_size, op_count }
461 }
462}
463
464#[async_trait]
465impl<T: Filesystem> Benchmark<T> for WriteSequentialFsyncWarm {
466 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
467 storage_trace::duration!(
468 "benchmark",
469 "WriteSequentialFsyncWarm",
470 "op_size" => self.op_size,
471 "op_count" => self.op_count
472 );
473 let file_path = fs.benchmark_dir().join("file");
474
475 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
477 write_sequential(&mut file, self.op_size, self.op_count);
478 assert_eq!(unsafe { libc::fsync(file.as_raw_fd()) }, 0);
480 file.seek(SeekFrom::Start(0)).unwrap();
481
482 write_sequential_fsync(&mut file, self.op_size, self.op_count)
484 }
485
486 fn name(&self) -> String {
487 format!("WriteSequentialFsyncWarm/{}", self.op_size)
488 }
489}
490
491#[derive(Clone)]
493pub struct WriteRandomFsyncCold {
494 op_size: usize,
495 op_count: usize,
496}
497
498impl WriteRandomFsyncCold {
499 pub fn new(op_size: usize, op_count: usize) -> Self {
500 Self { op_size, op_count }
501 }
502}
503
504#[async_trait]
505impl<T: Filesystem> Benchmark<T> for WriteRandomFsyncCold {
506 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
507 storage_trace::duration!(
508 "benchmark",
509 "WriteRandomFsyncCold",
510 "op_size" => self.op_size,
511 "op_count" => self.op_count
512 );
513 let file_path = fs.benchmark_dir().join("file");
514 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
515 let mut rng = XorShiftRng::seed_from_u64(RNG_SEED);
516 write_random_fsync(&mut file, self.op_size, self.op_count, &mut rng)
517 }
518
519 fn name(&self) -> String {
520 format!("WriteRandomFsyncCold/{}", self.op_size)
521 }
522}
523
524#[derive(Clone)]
527pub struct WriteRandomFsyncWarm {
528 op_size: usize,
529 op_count: usize,
530}
531
532impl WriteRandomFsyncWarm {
533 pub fn new(op_size: usize, op_count: usize) -> Self {
534 Self { op_size, op_count }
535 }
536}
537
538#[async_trait]
539impl<T: Filesystem> Benchmark<T> for WriteRandomFsyncWarm {
540 async fn run(&self, fs: &mut T) -> Vec<OperationDuration> {
541 storage_trace::duration!(
542 "benchmark",
543 "WriteRandomFsyncWarm",
544 "op_size" => self.op_size,
545 "op_count" => self.op_count
546 );
547 let file_path = fs.benchmark_dir().join("file");
548
549 let mut file = OpenOptions::new().write(true).create_new(true).open(&file_path).unwrap();
551 write_sequential(&mut file, self.op_size, self.op_count);
552 assert_eq!(unsafe { libc::fsync(file.as_raw_fd()) }, 0);
554 file.seek(SeekFrom::Start(0)).unwrap();
555 let mut rng = XorShiftRng::seed_from_u64(RNG_SEED);
556
557 write_random_fsync(&mut file, self.op_size, self.op_count, &mut rng)
559 }
560
561 fn name(&self) -> String {
562 format!("WriteRandomFsyncWarm/{}", self.op_size)
563 }
564}
565
566fn write_file<F: Write + FileExt>(file: &mut F, op_size: usize, op_count: usize) {
567 write_sparse_file(file, op_size, op_count, 0);
568}
569
570fn write_sparse_file<F: Write + FileExt>(
571 file: &mut F,
572 op_size: usize,
573 op_count: usize,
574 block_skip: usize,
575) {
576 let data = vec![0xAB; op_size];
577 let mut offset: u64 = 0;
578 for _ in 0..op_count {
579 assert_eq!(file.write_at(&data, offset).unwrap(), op_size);
580 offset += (op_size * (block_skip + 1)) as u64;
581 }
582}
583
584fn read_sequential<F: AsRawFd>(
586 file: &mut F,
587 op_size: usize,
588 op_count: usize,
589) -> Vec<OperationDuration> {
590 let mut data = vec![0; op_size];
591 let mut durations = Vec::new();
592 let fd = file.as_raw_fd();
593 for i in 0..op_count {
594 storage_trace::duration!("benchmark", "read", "op_number" => i);
595 let timer = OperationTimer::start();
596 let result = unsafe { libc::read(fd, data.as_mut_ptr() as *mut libc::c_void, data.len()) };
597 durations.push(timer.stop());
598 assert_eq!(result, op_size as isize);
599 }
600 durations
601}
602
603fn read_sparse<F: AsRawFd>(
606 file: &mut F,
607 op_size: usize,
608 op_count: usize,
609 block_skip: usize,
610) -> Vec<OperationDuration> {
611 let mut data = vec![0; op_size];
612 let mut durations = Vec::new();
613 let fd = file.as_raw_fd();
614 let sparse_offset = ((1 + block_skip) * op_size) as i64;
615 for i in 0..op_count as i64 {
616 storage_trace::duration!("benchmark", "pread", "op_number" => i);
617 let timer = OperationTimer::start();
618 let result = unsafe {
619 libc::pread(fd, data.as_mut_ptr() as *mut libc::c_void, data.len(), i * sparse_offset)
620 };
621 durations.push(timer.stop());
622 assert_eq!(result, op_size as isize);
623 }
624 durations
625}
626
627fn write_sequential<F: AsRawFd>(
629 file: &mut F,
630 op_size: usize,
631 op_count: usize,
632) -> Vec<OperationDuration> {
633 let data = vec![0xAB; op_size];
634 let mut durations = Vec::new();
635 let fd = file.as_raw_fd();
636 for i in 0..op_count {
637 storage_trace::duration!("benchmark", "write", "op_number" => i);
638 let timer = OperationTimer::start();
639 let result = unsafe { libc::write(fd, data.as_ptr() as *const libc::c_void, data.len()) };
640 durations.push(timer.stop());
641 assert_eq!(result, op_size as isize);
642 }
643 durations
644}
645
646fn write_sequential_fsync<F: AsRawFd>(
649 file: &mut F,
650 op_size: usize,
651 op_count: usize,
652) -> Vec<OperationDuration> {
653 let data = vec![0xAB; op_size];
654 let mut durations = Vec::new();
655 let fd = file.as_raw_fd();
656 for i in 0..op_count {
657 storage_trace::duration!("benchmark", "write", "op_number" => i);
658 let timer = OperationTimer::start();
659 let write_result =
660 unsafe { libc::write(fd, data.as_ptr() as *const libc::c_void, data.len()) };
661 let fsync_result = unsafe { libc::fsync(fd) };
662 durations.push(timer.stop());
663 assert_eq!(write_result, op_size as isize);
664 assert_eq!(fsync_result, 0);
665 }
666 durations
667}
668
669fn create_random_offsets<R: Rng>(op_size: usize, op_count: usize, rng: &mut R) -> Vec<libc::off_t> {
670 let op_count = op_count as libc::off_t;
671 let op_size = op_size as libc::off_t;
672 let mut offsets: Vec<libc::off_t> = (0..op_count).map(|offset| offset * op_size).collect();
673 offsets.shuffle(rng);
674 offsets
675}
676
677fn read_random<F: AsRawFd, R: Rng>(
681 file: &mut F,
682 op_size: usize,
683 op_count: usize,
684 rng: &mut R,
685) -> Vec<OperationDuration> {
686 let offsets = create_random_offsets(op_size, op_count, rng);
687 let mut data = vec![0xAB; op_size];
688 let mut durations = Vec::new();
689 let fd = file.as_raw_fd();
690 for (i, offset) in offsets.iter().enumerate() {
691 storage_trace::duration!("benchmark", "pread", "op_number" => i, "offset" => *offset);
692 let timer = OperationTimer::start();
693 let result =
694 unsafe { libc::pread(fd, data.as_mut_ptr() as *mut libc::c_void, data.len(), *offset) };
695 durations.push(timer.stop());
696 assert_eq!(result, op_size as isize);
697 }
698 durations
699}
700
701fn write_random<F: AsRawFd, R: Rng>(
705 file: &mut F,
706 op_size: usize,
707 op_count: usize,
708 rng: &mut R,
709) -> Vec<OperationDuration> {
710 let offsets = create_random_offsets(op_size, op_count, rng);
711 let data = vec![0xAB; op_size];
712 let mut durations = Vec::new();
713 let fd = file.as_raw_fd();
714 for (i, offset) in offsets.iter().enumerate() {
715 storage_trace::duration!("benchmark", "pwrite", "op_number" => i, "offset" => *offset);
716 let timer = OperationTimer::start();
717 let result =
718 unsafe { libc::pwrite(fd, data.as_ptr() as *const libc::c_void, data.len(), *offset) };
719 durations.push(timer.stop());
720 assert_eq!(result, op_size as isize);
721 }
722 durations
723}
724
725fn write_random_fsync<F: AsRawFd, R: Rng>(
729 file: &mut F,
730 op_size: usize,
731 op_count: usize,
732 rng: &mut R,
733) -> Vec<OperationDuration> {
734 let offsets = create_random_offsets(op_size, op_count, rng);
735 let data = vec![0xAB; op_size];
736 let mut durations = Vec::new();
737 let fd = file.as_raw_fd();
738 for (i, offset) in offsets.iter().enumerate() {
739 storage_trace::duration!("benchmark", "pwrite", "op_number" => i, "offset" => *offset);
740 let timer = OperationTimer::start();
741 let result =
742 unsafe { libc::pwrite(fd, data.as_ptr() as *const libc::c_void, data.len(), *offset) };
743 let fsync_result = unsafe { libc::fsync(fd) };
744 durations.push(timer.stop());
745 assert_eq!(result, op_size as isize);
746 assert_eq!(fsync_result, 0);
747 }
748 durations
749}
750
751#[cfg(test)]
752mod tests {
753 use super::*;
754 use crate::testing::TestFilesystem;
755
756 const OP_SIZE: usize = 8;
757 const OP_COUNT: usize = 2;
758
759 async fn check_benchmark<T>(benchmark: T, op_count: usize, clear_cache_count: u64)
760 where
761 T: Benchmark<TestFilesystem>,
762 {
763 let mut test_fs = Box::new(TestFilesystem::new());
764 let results = benchmark.run(test_fs.as_mut()).await;
765
766 assert_eq!(results.len(), op_count);
767 assert_eq!(test_fs.clear_cache_count().await, clear_cache_count);
768 test_fs.shutdown().await;
769 }
770
771 #[fuchsia::test]
772 async fn read_sequential_cold_test() {
773 check_benchmark(
774 ReadSequentialCold::new(OP_SIZE, OP_COUNT),
775 OP_COUNT,
776 1,
777 )
778 .await;
779 }
780
781 #[fuchsia::test]
782 async fn read_sequential_warm_test() {
783 check_benchmark(
784 ReadSequentialWarm::new(OP_SIZE, OP_COUNT),
785 OP_COUNT,
786 0,
787 )
788 .await;
789 }
790
791 #[fuchsia::test]
792 async fn read_random_cold_test() {
793 check_benchmark(
794 ReadRandomCold::new(OP_SIZE, OP_COUNT),
795 OP_COUNT,
796 1,
797 )
798 .await;
799 }
800
801 #[fuchsia::test]
802 async fn read_sparse_cold_test() {
803 check_benchmark(
804 ReadSparseCold::new(OP_SIZE, OP_COUNT),
805 OP_COUNT,
806 1,
807 )
808 .await;
809 }
810
811 #[fuchsia::test]
812 async fn read_random_warm_test() {
813 check_benchmark(
814 ReadRandomWarm::new(OP_SIZE, OP_COUNT),
815 OP_COUNT,
816 0,
817 )
818 .await;
819 }
820
821 #[fuchsia::test]
822 async fn write_sequential_cold_test() {
823 check_benchmark(
824 WriteSequentialCold::new(OP_SIZE, OP_COUNT),
825 OP_COUNT,
826 0,
827 )
828 .await;
829 }
830
831 #[fuchsia::test]
832 async fn write_sequential_warm_test() {
833 check_benchmark(
834 WriteSequentialWarm::new(OP_SIZE, OP_COUNT),
835 OP_COUNT,
836 0,
837 )
838 .await;
839 }
840
841 #[fuchsia::test]
842 async fn write_random_cold_test() {
843 check_benchmark(
844 WriteRandomCold::new(OP_SIZE, OP_COUNT),
845 OP_COUNT,
846 0,
847 )
848 .await;
849 }
850
851 #[fuchsia::test]
852 async fn write_random_warm_test() {
853 check_benchmark(
854 WriteRandomWarm::new(OP_SIZE, OP_COUNT),
855 OP_COUNT,
856 0,
857 )
858 .await;
859 }
860
861 #[fuchsia::test]
862 async fn write_sequential_fsync_cold_test() {
863 check_benchmark(
864 WriteSequentialFsyncCold::new(OP_SIZE, OP_COUNT),
865 OP_COUNT,
866 0,
867 )
868 .await;
869 }
870
871 #[fuchsia::test]
872 async fn write_sequential_fsync_warm_test() {
873 check_benchmark(
874 WriteSequentialFsyncWarm::new(OP_SIZE, OP_COUNT),
875 OP_COUNT,
876 0,
877 )
878 .await;
879 }
880
881 #[fuchsia::test]
882 async fn write_random_fsync_cold_test() {
883 check_benchmark(
884 WriteRandomFsyncCold::new(OP_SIZE, OP_COUNT),
885 OP_COUNT,
886 0,
887 )
888 .await;
889 }
890
891 #[fuchsia::test]
892 async fn write_random_fsync_warm_test() {
893 check_benchmark(
894 WriteRandomFsyncWarm::new(OP_SIZE, OP_COUNT),
895 OP_COUNT,
896 0,
897 )
898 .await;
899 }
900}