1 #![warn(rust_2018_idioms)]
2 #![cfg(all(feature = "full", not(target_os = "wasi")))] // WASI does not support all fs operations
3
4 use std::io::prelude::*;
5 use tempfile::NamedTempFile;
6 use tokio::fs::File;
7 use tokio::io::{AsyncReadExt, AsyncSeekExt, AsyncWriteExt, SeekFrom};
8 use tokio_test::task;
9
10 const HELLO: &[u8] = b"hello world...";
11
12 #[tokio::test]
basic_read()13 async fn basic_read() {
14 let mut tempfile = tempfile();
15 tempfile.write_all(HELLO).unwrap();
16
17 let mut file = File::open(tempfile.path()).await.unwrap();
18
19 let mut buf = [0; 1024];
20 let n = file.read(&mut buf).await.unwrap();
21
22 assert_eq!(n, HELLO.len());
23 assert_eq!(&buf[..n], HELLO);
24 }
25
26 #[tokio::test]
basic_write()27 async fn basic_write() {
28 let tempfile = tempfile();
29
30 let mut file = File::create(tempfile.path()).await.unwrap();
31
32 file.write_all(HELLO).await.unwrap();
33 file.flush().await.unwrap();
34
35 let file = std::fs::read(tempfile.path()).unwrap();
36 assert_eq!(file, HELLO);
37 }
38
39 #[tokio::test]
basic_write_and_shutdown()40 async fn basic_write_and_shutdown() {
41 let tempfile = tempfile();
42
43 let mut file = File::create(tempfile.path()).await.unwrap();
44
45 file.write_all(HELLO).await.unwrap();
46 file.shutdown().await.unwrap();
47
48 let file = std::fs::read(tempfile.path()).unwrap();
49 assert_eq!(file, HELLO);
50 }
51
52 #[tokio::test]
rewind_seek_position()53 async fn rewind_seek_position() {
54 let tempfile = tempfile();
55
56 let mut file = File::create(tempfile.path()).await.unwrap();
57
58 file.seek(SeekFrom::Current(10)).await.unwrap();
59
60 file.rewind().await.unwrap();
61
62 assert_eq!(file.stream_position().await.unwrap(), 0);
63 }
64
65 #[tokio::test]
coop()66 async fn coop() {
67 let mut tempfile = tempfile();
68 tempfile.write_all(HELLO).unwrap();
69
70 let mut task = task::spawn(async {
71 let mut file = File::open(tempfile.path()).await.unwrap();
72
73 let mut buf = [0; 1024];
74
75 loop {
76 let _ = file.read(&mut buf).await.unwrap();
77 file.seek(std::io::SeekFrom::Start(0)).await.unwrap();
78 }
79 });
80
81 for _ in 0..1_000 {
82 if task.poll().is_pending() {
83 return;
84 }
85 }
86
87 panic!("did not yield");
88 }
89
90 #[tokio::test]
write_to_clone()91 async fn write_to_clone() {
92 let tempfile = tempfile();
93
94 let file = File::create(tempfile.path()).await.unwrap();
95 let mut clone = file.try_clone().await.unwrap();
96
97 clone.write_all(HELLO).await.unwrap();
98 clone.flush().await.unwrap();
99
100 let contents = std::fs::read(tempfile.path()).unwrap();
101 assert_eq!(contents, HELLO);
102 }
103
104 #[tokio::test]
write_into_std()105 async fn write_into_std() {
106 let tempfile = tempfile();
107
108 let file = File::create(tempfile.path()).await.unwrap();
109 let mut std_file = file.into_std().await;
110
111 std_file.write_all(HELLO).unwrap();
112
113 let contents = std::fs::read(tempfile.path()).unwrap();
114 assert_eq!(contents, HELLO);
115 }
116
117 #[tokio::test]
write_into_std_immediate()118 async fn write_into_std_immediate() {
119 let tempfile = tempfile();
120
121 let file = File::create(tempfile.path()).await.unwrap();
122 let mut std_file = file.try_into_std().unwrap();
123
124 std_file.write_all(HELLO).unwrap();
125
126 let contents = std::fs::read(tempfile.path()).unwrap();
127 assert_eq!(contents, HELLO);
128 }
129
130 #[tokio::test]
read_file_from_std()131 async fn read_file_from_std() {
132 let mut tempfile = tempfile();
133 tempfile.write_all(HELLO).unwrap();
134
135 let std_file = std::fs::File::open(tempfile.path()).unwrap();
136 let mut file = File::from(std_file);
137
138 let mut buf = [0; 1024];
139 let n = file.read(&mut buf).await.unwrap();
140 assert_eq!(n, HELLO.len());
141 assert_eq!(&buf[..n], HELLO);
142 }
143
tempfile() -> NamedTempFile144 fn tempfile() -> NamedTempFile {
145 NamedTempFile::new().unwrap()
146 }
147
148 #[tokio::test]
149 #[cfg(unix)]
file_debug_fmt()150 async fn file_debug_fmt() {
151 let tempfile = tempfile();
152
153 let file = File::open(tempfile.path()).await.unwrap();
154
155 assert_eq!(
156 &format!("{:?}", file)[0..33],
157 "tokio::fs::File { std: File { fd:"
158 );
159 }
160
161 #[tokio::test]
162 #[cfg(windows)]
file_debug_fmt()163 async fn file_debug_fmt() {
164 let tempfile = tempfile();
165
166 let file = File::open(tempfile.path()).await.unwrap();
167
168 assert_eq!(
169 &format!("{:?}", file)[0..37],
170 "tokio::fs::File { std: File { handle:"
171 );
172 }
173
174 #[tokio::test]
175 #[cfg(unix)]
unix_fd_is_valid()176 async fn unix_fd_is_valid() {
177 use std::os::unix::io::AsRawFd;
178 let tempfile = tempfile();
179
180 let file = File::create(tempfile.path()).await.unwrap();
181 assert!(file.as_raw_fd() as u64 > 0);
182 }
183
184 #[tokio::test]
185 #[cfg(unix)]
read_file_from_unix_fd()186 async fn read_file_from_unix_fd() {
187 use std::os::unix::io::{FromRawFd, IntoRawFd};
188
189 let mut tempfile = tempfile();
190 tempfile.write_all(HELLO).unwrap();
191
192 let file1 = File::open(tempfile.path()).await.unwrap();
193 let raw_fd = file1.into_std().await.into_raw_fd();
194 assert!(raw_fd > 0);
195
196 let mut file2 = unsafe { File::from_raw_fd(raw_fd) };
197
198 let mut buf = [0; 1024];
199 let n = file2.read(&mut buf).await.unwrap();
200 assert_eq!(n, HELLO.len());
201 assert_eq!(&buf[..n], HELLO);
202 }
203
204 #[tokio::test]
205 #[cfg(windows)]
windows_handle()206 async fn windows_handle() {
207 use std::os::windows::io::AsRawHandle;
208 let tempfile = tempfile();
209
210 let file = File::create(tempfile.path()).await.unwrap();
211 assert!(file.as_raw_handle() as u64 > 0);
212 }
213