1 #![warn(rust_2018_idioms)]
2 #![cfg(feature = "full")]
3
4 macro_rules! ready {
5 ($e:expr $(,)?) => {
6 match $e {
7 std::task::Poll::Ready(t) => t,
8 std::task::Poll::Pending => return std::task::Poll::Pending,
9 }
10 };
11 }
12
13 #[macro_export]
14 macro_rules! cfg_fs {
15 ($($item:item)*) => { $($item)* }
16 }
17
18 #[macro_export]
19 macro_rules! cfg_io_std {
20 ($($item:item)*) => { $($item)* }
21 }
22
23 use futures::future;
24
25 // Load source
26 #[allow(warnings)]
27 #[path = "../src/fs/file.rs"]
28 mod file;
29 use file::File;
30
31 #[allow(warnings)]
32 #[path = "../src/io/blocking.rs"]
33 mod blocking;
34
35 // Load mocked types
36 mod support {
37 pub(crate) mod mock_file;
38 pub(crate) mod mock_pool;
39 }
40 pub(crate) use support::mock_pool as pool;
41
42 // Place them where the source expects them
43 pub(crate) mod io {
44 pub(crate) use tokio::io::*;
45
46 pub(crate) use crate::blocking;
47
48 pub(crate) mod sys {
49 pub(crate) use crate::support::mock_pool::{run, Blocking};
50 }
51 }
52 pub(crate) mod fs {
53 pub(crate) mod sys {
54 pub(crate) use crate::support::mock_file::File;
55 pub(crate) use crate::support::mock_pool::{run, Blocking};
56 }
57
58 pub(crate) use crate::support::mock_pool::asyncify;
59 }
60 use fs::sys;
61
62 use tokio::prelude::*;
63 use tokio_test::{assert_pending, assert_ready, assert_ready_err, assert_ready_ok, task};
64
65 use std::io::SeekFrom;
66
67 const HELLO: &[u8] = b"hello world...";
68 const FOO: &[u8] = b"foo bar baz...";
69
70 #[test]
open_read()71 fn open_read() {
72 let (mock, file) = sys::File::mock();
73 mock.read(HELLO);
74
75 let mut file = File::from_std(file);
76
77 let mut buf = [0; 1024];
78 let mut t = task::spawn(file.read(&mut buf));
79
80 assert_eq!(0, pool::len());
81 assert_pending!(t.poll());
82
83 assert_eq!(1, mock.remaining());
84 assert_eq!(1, pool::len());
85
86 pool::run_one();
87
88 assert_eq!(0, mock.remaining());
89 assert!(t.is_woken());
90
91 let n = assert_ready_ok!(t.poll());
92 assert_eq!(n, HELLO.len());
93 assert_eq!(&buf[..n], HELLO);
94 }
95
96 #[test]
read_twice_before_dispatch()97 fn read_twice_before_dispatch() {
98 let (mock, file) = sys::File::mock();
99 mock.read(HELLO);
100
101 let mut file = File::from_std(file);
102
103 let mut buf = [0; 1024];
104 let mut t = task::spawn(file.read(&mut buf));
105
106 assert_pending!(t.poll());
107 assert_pending!(t.poll());
108
109 assert_eq!(pool::len(), 1);
110 pool::run_one();
111
112 assert!(t.is_woken());
113
114 let n = assert_ready_ok!(t.poll());
115 assert_eq!(&buf[..n], HELLO);
116 }
117
118 #[test]
read_with_smaller_buf()119 fn read_with_smaller_buf() {
120 let (mock, file) = sys::File::mock();
121 mock.read(HELLO);
122
123 let mut file = File::from_std(file);
124
125 {
126 let mut buf = [0; 32];
127 let mut t = task::spawn(file.read(&mut buf));
128 assert_pending!(t.poll());
129 }
130
131 pool::run_one();
132
133 {
134 let mut buf = [0; 4];
135 let mut t = task::spawn(file.read(&mut buf));
136 let n = assert_ready_ok!(t.poll());
137 assert_eq!(n, 4);
138 assert_eq!(&buf[..], &HELLO[..n]);
139 }
140
141 // Calling again immediately succeeds with the rest of the buffer
142 let mut buf = [0; 32];
143 let mut t = task::spawn(file.read(&mut buf));
144 let n = assert_ready_ok!(t.poll());
145 assert_eq!(n, 10);
146 assert_eq!(&buf[..n], &HELLO[4..]);
147
148 assert_eq!(0, pool::len());
149 }
150
151 #[test]
read_with_bigger_buf()152 fn read_with_bigger_buf() {
153 let (mock, file) = sys::File::mock();
154 mock.read(&HELLO[..4]).read(&HELLO[4..]);
155
156 let mut file = File::from_std(file);
157
158 {
159 let mut buf = [0; 4];
160 let mut t = task::spawn(file.read(&mut buf));
161 assert_pending!(t.poll());
162 }
163
164 pool::run_one();
165
166 {
167 let mut buf = [0; 32];
168 let mut t = task::spawn(file.read(&mut buf));
169 let n = assert_ready_ok!(t.poll());
170 assert_eq!(n, 4);
171 assert_eq!(&buf[..n], &HELLO[..n]);
172 }
173
174 // Calling again immediately succeeds with the rest of the buffer
175 let mut buf = [0; 32];
176 let mut t = task::spawn(file.read(&mut buf));
177
178 assert_pending!(t.poll());
179
180 assert_eq!(1, pool::len());
181 pool::run_one();
182
183 assert!(t.is_woken());
184
185 let n = assert_ready_ok!(t.poll());
186 assert_eq!(n, 10);
187 assert_eq!(&buf[..n], &HELLO[4..]);
188
189 assert_eq!(0, pool::len());
190 }
191
192 #[test]
read_err_then_read_success()193 fn read_err_then_read_success() {
194 let (mock, file) = sys::File::mock();
195 mock.read_err().read(&HELLO);
196
197 let mut file = File::from_std(file);
198
199 {
200 let mut buf = [0; 32];
201 let mut t = task::spawn(file.read(&mut buf));
202 assert_pending!(t.poll());
203
204 pool::run_one();
205
206 assert_ready_err!(t.poll());
207 }
208
209 {
210 let mut buf = [0; 32];
211 let mut t = task::spawn(file.read(&mut buf));
212 assert_pending!(t.poll());
213
214 pool::run_one();
215
216 let n = assert_ready_ok!(t.poll());
217
218 assert_eq!(n, HELLO.len());
219 assert_eq!(&buf[..n], HELLO);
220 }
221 }
222
223 #[test]
open_write()224 fn open_write() {
225 let (mock, file) = sys::File::mock();
226 mock.write(HELLO);
227
228 let mut file = File::from_std(file);
229
230 let mut t = task::spawn(file.write(HELLO));
231
232 assert_eq!(0, pool::len());
233 assert_ready_ok!(t.poll());
234
235 assert_eq!(1, mock.remaining());
236 assert_eq!(1, pool::len());
237
238 pool::run_one();
239
240 assert_eq!(0, mock.remaining());
241 assert!(!t.is_woken());
242
243 let mut t = task::spawn(file.flush());
244 assert_ready_ok!(t.poll());
245 }
246
247 #[test]
flush_while_idle()248 fn flush_while_idle() {
249 let (_mock, file) = sys::File::mock();
250
251 let mut file = File::from_std(file);
252
253 let mut t = task::spawn(file.flush());
254 assert_ready_ok!(t.poll());
255 }
256
257 #[test]
read_with_buffer_larger_than_max()258 fn read_with_buffer_larger_than_max() {
259 // Chunks
260 let a = 16 * 1024;
261 let b = a * 2;
262 let c = a * 3;
263 let d = a * 4;
264
265 assert_eq!(d / 1024, 64);
266
267 let mut data = vec![];
268 for i in 0..(d - 1) {
269 data.push((i % 151) as u8);
270 }
271
272 let (mock, file) = sys::File::mock();
273 mock.read(&data[0..a])
274 .read(&data[a..b])
275 .read(&data[b..c])
276 .read(&data[c..]);
277
278 let mut file = File::from_std(file);
279
280 let mut actual = vec![0; d];
281 let mut pos = 0;
282
283 while pos < data.len() {
284 let mut t = task::spawn(file.read(&mut actual[pos..]));
285
286 assert_pending!(t.poll());
287 pool::run_one();
288 assert!(t.is_woken());
289
290 let n = assert_ready_ok!(t.poll());
291 assert!(n <= a);
292
293 pos += n;
294 }
295
296 assert_eq!(mock.remaining(), 0);
297 assert_eq!(data, &actual[..data.len()]);
298 }
299
300 #[test]
write_with_buffer_larger_than_max()301 fn write_with_buffer_larger_than_max() {
302 // Chunks
303 let a = 16 * 1024;
304 let b = a * 2;
305 let c = a * 3;
306 let d = a * 4;
307
308 assert_eq!(d / 1024, 64);
309
310 let mut data = vec![];
311 for i in 0..(d - 1) {
312 data.push((i % 151) as u8);
313 }
314
315 let (mock, file) = sys::File::mock();
316 mock.write(&data[0..a])
317 .write(&data[a..b])
318 .write(&data[b..c])
319 .write(&data[c..]);
320
321 let mut file = File::from_std(file);
322
323 let mut rem = &data[..];
324
325 let mut first = true;
326
327 while !rem.is_empty() {
328 let mut t = task::spawn(file.write(rem));
329
330 if !first {
331 assert_pending!(t.poll());
332 pool::run_one();
333 assert!(t.is_woken());
334 }
335
336 first = false;
337
338 let n = assert_ready_ok!(t.poll());
339
340 rem = &rem[n..];
341 }
342
343 pool::run_one();
344
345 assert_eq!(mock.remaining(), 0);
346 }
347
348 #[test]
write_twice_before_dispatch()349 fn write_twice_before_dispatch() {
350 let (mock, file) = sys::File::mock();
351 mock.write(HELLO).write(FOO);
352
353 let mut file = File::from_std(file);
354
355 let mut t = task::spawn(file.write(HELLO));
356 assert_ready_ok!(t.poll());
357
358 let mut t = task::spawn(file.write(FOO));
359 assert_pending!(t.poll());
360
361 assert_eq!(pool::len(), 1);
362 pool::run_one();
363
364 assert!(t.is_woken());
365
366 assert_ready_ok!(t.poll());
367
368 let mut t = task::spawn(file.flush());
369 assert_pending!(t.poll());
370
371 assert_eq!(pool::len(), 1);
372 pool::run_one();
373
374 assert!(t.is_woken());
375 assert_ready_ok!(t.poll());
376 }
377
378 #[test]
incomplete_read_followed_by_write()379 fn incomplete_read_followed_by_write() {
380 let (mock, file) = sys::File::mock();
381 mock.read(HELLO)
382 .seek_current_ok(-(HELLO.len() as i64), 0)
383 .write(FOO);
384
385 let mut file = File::from_std(file);
386
387 let mut buf = [0; 32];
388
389 let mut t = task::spawn(file.read(&mut buf));
390 assert_pending!(t.poll());
391
392 pool::run_one();
393
394 let mut t = task::spawn(file.write(FOO));
395 assert_ready_ok!(t.poll());
396
397 assert_eq!(pool::len(), 1);
398 pool::run_one();
399
400 let mut t = task::spawn(file.flush());
401 assert_ready_ok!(t.poll());
402 }
403
404 #[test]
incomplete_partial_read_followed_by_write()405 fn incomplete_partial_read_followed_by_write() {
406 let (mock, file) = sys::File::mock();
407 mock.read(HELLO).seek_current_ok(-10, 0).write(FOO);
408
409 let mut file = File::from_std(file);
410
411 let mut buf = [0; 32];
412 let mut t = task::spawn(file.read(&mut buf));
413 assert_pending!(t.poll());
414
415 pool::run_one();
416
417 let mut buf = [0; 4];
418 let mut t = task::spawn(file.read(&mut buf));
419 assert_ready_ok!(t.poll());
420
421 let mut t = task::spawn(file.write(FOO));
422 assert_ready_ok!(t.poll());
423
424 assert_eq!(pool::len(), 1);
425 pool::run_one();
426
427 let mut t = task::spawn(file.flush());
428 assert_ready_ok!(t.poll());
429 }
430
431 #[test]
incomplete_read_followed_by_flush()432 fn incomplete_read_followed_by_flush() {
433 let (mock, file) = sys::File::mock();
434 mock.read(HELLO)
435 .seek_current_ok(-(HELLO.len() as i64), 0)
436 .write(FOO);
437
438 let mut file = File::from_std(file);
439
440 let mut buf = [0; 32];
441
442 let mut t = task::spawn(file.read(&mut buf));
443 assert_pending!(t.poll());
444
445 pool::run_one();
446
447 let mut t = task::spawn(file.flush());
448 assert_ready_ok!(t.poll());
449
450 let mut t = task::spawn(file.write(FOO));
451 assert_ready_ok!(t.poll());
452
453 pool::run_one();
454 }
455
456 #[test]
incomplete_flush_followed_by_write()457 fn incomplete_flush_followed_by_write() {
458 let (mock, file) = sys::File::mock();
459 mock.write(HELLO).write(FOO);
460
461 let mut file = File::from_std(file);
462
463 let mut t = task::spawn(file.write(HELLO));
464 let n = assert_ready_ok!(t.poll());
465 assert_eq!(n, HELLO.len());
466
467 let mut t = task::spawn(file.flush());
468 assert_pending!(t.poll());
469
470 // TODO: Move under write
471 pool::run_one();
472
473 let mut t = task::spawn(file.write(FOO));
474 assert_ready_ok!(t.poll());
475
476 pool::run_one();
477
478 let mut t = task::spawn(file.flush());
479 assert_ready_ok!(t.poll());
480 }
481
482 #[test]
read_err()483 fn read_err() {
484 let (mock, file) = sys::File::mock();
485 mock.read_err();
486
487 let mut file = File::from_std(file);
488
489 let mut buf = [0; 1024];
490 let mut t = task::spawn(file.read(&mut buf));
491
492 assert_pending!(t.poll());
493
494 pool::run_one();
495 assert!(t.is_woken());
496
497 assert_ready_err!(t.poll());
498 }
499
500 #[test]
write_write_err()501 fn write_write_err() {
502 let (mock, file) = sys::File::mock();
503 mock.write_err();
504
505 let mut file = File::from_std(file);
506
507 let mut t = task::spawn(file.write(HELLO));
508 assert_ready_ok!(t.poll());
509
510 pool::run_one();
511
512 let mut t = task::spawn(file.write(FOO));
513 assert_ready_err!(t.poll());
514 }
515
516 #[test]
write_read_write_err()517 fn write_read_write_err() {
518 let (mock, file) = sys::File::mock();
519 mock.write_err().read(HELLO);
520
521 let mut file = File::from_std(file);
522
523 let mut t = task::spawn(file.write(HELLO));
524 assert_ready_ok!(t.poll());
525
526 pool::run_one();
527
528 let mut buf = [0; 1024];
529 let mut t = task::spawn(file.read(&mut buf));
530
531 assert_pending!(t.poll());
532
533 pool::run_one();
534
535 let mut t = task::spawn(file.write(FOO));
536 assert_ready_err!(t.poll());
537 }
538
539 #[test]
write_read_flush_err()540 fn write_read_flush_err() {
541 let (mock, file) = sys::File::mock();
542 mock.write_err().read(HELLO);
543
544 let mut file = File::from_std(file);
545
546 let mut t = task::spawn(file.write(HELLO));
547 assert_ready_ok!(t.poll());
548
549 pool::run_one();
550
551 let mut buf = [0; 1024];
552 let mut t = task::spawn(file.read(&mut buf));
553
554 assert_pending!(t.poll());
555
556 pool::run_one();
557
558 let mut t = task::spawn(file.flush());
559 assert_ready_err!(t.poll());
560 }
561
562 #[test]
write_seek_write_err()563 fn write_seek_write_err() {
564 let (mock, file) = sys::File::mock();
565 mock.write_err().seek_start_ok(0);
566
567 let mut file = File::from_std(file);
568
569 let mut t = task::spawn(file.write(HELLO));
570 assert_ready_ok!(t.poll());
571
572 pool::run_one();
573
574 {
575 let mut t = task::spawn(file.seek(SeekFrom::Start(0)));
576 assert_pending!(t.poll());
577 }
578
579 pool::run_one();
580
581 let mut t = task::spawn(file.write(FOO));
582 assert_ready_err!(t.poll());
583 }
584
585 #[test]
write_seek_flush_err()586 fn write_seek_flush_err() {
587 let (mock, file) = sys::File::mock();
588 mock.write_err().seek_start_ok(0);
589
590 let mut file = File::from_std(file);
591
592 let mut t = task::spawn(file.write(HELLO));
593 assert_ready_ok!(t.poll());
594
595 pool::run_one();
596
597 {
598 let mut t = task::spawn(file.seek(SeekFrom::Start(0)));
599 assert_pending!(t.poll());
600 }
601
602 pool::run_one();
603
604 let mut t = task::spawn(file.flush());
605 assert_ready_err!(t.poll());
606 }
607
608 #[test]
sync_all_ordered_after_write()609 fn sync_all_ordered_after_write() {
610 let (mock, file) = sys::File::mock();
611 mock.write(HELLO).sync_all();
612
613 let mut file = File::from_std(file);
614 let mut t = task::spawn(file.write(HELLO));
615 assert_ready_ok!(t.poll());
616
617 let mut t = task::spawn(file.sync_all());
618 assert_pending!(t.poll());
619
620 assert_eq!(1, pool::len());
621 pool::run_one();
622
623 assert!(t.is_woken());
624 assert_pending!(t.poll());
625
626 assert_eq!(1, pool::len());
627 pool::run_one();
628
629 assert!(t.is_woken());
630 assert_ready_ok!(t.poll());
631 }
632
633 #[test]
sync_all_err_ordered_after_write()634 fn sync_all_err_ordered_after_write() {
635 let (mock, file) = sys::File::mock();
636 mock.write(HELLO).sync_all_err();
637
638 let mut file = File::from_std(file);
639 let mut t = task::spawn(file.write(HELLO));
640 assert_ready_ok!(t.poll());
641
642 let mut t = task::spawn(file.sync_all());
643 assert_pending!(t.poll());
644
645 assert_eq!(1, pool::len());
646 pool::run_one();
647
648 assert!(t.is_woken());
649 assert_pending!(t.poll());
650
651 assert_eq!(1, pool::len());
652 pool::run_one();
653
654 assert!(t.is_woken());
655 assert_ready_err!(t.poll());
656 }
657
658 #[test]
sync_data_ordered_after_write()659 fn sync_data_ordered_after_write() {
660 let (mock, file) = sys::File::mock();
661 mock.write(HELLO).sync_data();
662
663 let mut file = File::from_std(file);
664 let mut t = task::spawn(file.write(HELLO));
665 assert_ready_ok!(t.poll());
666
667 let mut t = task::spawn(file.sync_data());
668 assert_pending!(t.poll());
669
670 assert_eq!(1, pool::len());
671 pool::run_one();
672
673 assert!(t.is_woken());
674 assert_pending!(t.poll());
675
676 assert_eq!(1, pool::len());
677 pool::run_one();
678
679 assert!(t.is_woken());
680 assert_ready_ok!(t.poll());
681 }
682
683 #[test]
sync_data_err_ordered_after_write()684 fn sync_data_err_ordered_after_write() {
685 let (mock, file) = sys::File::mock();
686 mock.write(HELLO).sync_data_err();
687
688 let mut file = File::from_std(file);
689 let mut t = task::spawn(file.write(HELLO));
690 assert_ready_ok!(t.poll());
691
692 let mut t = task::spawn(file.sync_data());
693 assert_pending!(t.poll());
694
695 assert_eq!(1, pool::len());
696 pool::run_one();
697
698 assert!(t.is_woken());
699 assert_pending!(t.poll());
700
701 assert_eq!(1, pool::len());
702 pool::run_one();
703
704 assert!(t.is_woken());
705 assert_ready_err!(t.poll());
706 }
707
708 #[test]
open_set_len_ok()709 fn open_set_len_ok() {
710 let (mock, file) = sys::File::mock();
711 mock.set_len(123);
712
713 let mut file = File::from_std(file);
714 let mut t = task::spawn(file.set_len(123));
715
716 assert_pending!(t.poll());
717 assert_eq!(1, mock.remaining());
718
719 pool::run_one();
720 assert_eq!(0, mock.remaining());
721
722 assert!(t.is_woken());
723 assert_ready_ok!(t.poll());
724 }
725
726 #[test]
open_set_len_err()727 fn open_set_len_err() {
728 let (mock, file) = sys::File::mock();
729 mock.set_len_err(123);
730
731 let mut file = File::from_std(file);
732 let mut t = task::spawn(file.set_len(123));
733
734 assert_pending!(t.poll());
735 assert_eq!(1, mock.remaining());
736
737 pool::run_one();
738 assert_eq!(0, mock.remaining());
739
740 assert!(t.is_woken());
741 assert_ready_err!(t.poll());
742 }
743
744 #[test]
partial_read_set_len_ok()745 fn partial_read_set_len_ok() {
746 let (mock, file) = sys::File::mock();
747 mock.read(HELLO)
748 .seek_current_ok(-14, 0)
749 .set_len(123)
750 .read(FOO);
751
752 let mut buf = [0; 32];
753 let mut file = File::from_std(file);
754
755 {
756 let mut t = task::spawn(file.read(&mut buf));
757 assert_pending!(t.poll());
758 }
759
760 pool::run_one();
761
762 {
763 let mut t = task::spawn(file.set_len(123));
764
765 assert_pending!(t.poll());
766 pool::run_one();
767 assert_ready_ok!(t.poll());
768 }
769
770 let mut t = task::spawn(file.read(&mut buf));
771 assert_pending!(t.poll());
772 pool::run_one();
773 let n = assert_ready_ok!(t.poll());
774
775 assert_eq!(n, FOO.len());
776 assert_eq!(&buf[..n], FOO);
777 }
778