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 chunk_a = 16 * 1024;
261     let chunk_b = chunk_a * 2;
262     let chunk_c = chunk_a * 3;
263     let chunk_d = chunk_a * 4;
264 
265     assert_eq!(chunk_d / 1024, 64);
266 
267     let mut data = vec![];
268     for i in 0..(chunk_d - 1) {
269         data.push((i % 151) as u8);
270     }
271 
272     let (mock, file) = sys::File::mock();
273     mock.read(&data[0..chunk_a])
274         .read(&data[chunk_a..chunk_b])
275         .read(&data[chunk_b..chunk_c])
276         .read(&data[chunk_c..]);
277 
278     let mut file = File::from_std(file);
279 
280     let mut actual = vec![0; chunk_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 <= chunk_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 chunk_a = 16 * 1024;
304     let chunk_b = chunk_a * 2;
305     let chunk_c = chunk_a * 3;
306     let chunk_d = chunk_a * 4;
307 
308     assert_eq!(chunk_d / 1024, 64);
309 
310     let mut data = vec![];
311     for i in 0..(chunk_d - 1) {
312         data.push((i % 151) as u8);
313     }
314 
315     let (mock, file) = sys::File::mock();
316     mock.write(&data[0..chunk_a])
317         .write(&data[chunk_a..chunk_b])
318         .write(&data[chunk_b..chunk_c])
319         .write(&data[chunk_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 task = task::spawn(file.write(rem));
329 
330         if !first {
331             assert_pending!(task.poll());
332             pool::run_one();
333             assert!(task.is_woken());
334         }
335 
336         first = false;
337 
338         let n = assert_ready_ok!(task.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