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