1 | #![deny (rust_2018_idioms)] |
2 | |
3 | use std::io::{Read, Seek, SeekFrom, Write}; |
4 | |
5 | use tempfile::{spooled_tempfile, SpooledTempFile}; |
6 | |
7 | #[test] |
8 | fn test_automatic_rollover() { |
9 | let mut t = spooled_tempfile(10); |
10 | let mut buf = Vec::new(); |
11 | |
12 | assert!(!t.is_rolled()); |
13 | assert_eq!(t.stream_position().unwrap(), 0); |
14 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); |
15 | assert_eq!(buf.as_slice(), b"" ); |
16 | buf.clear(); |
17 | |
18 | assert_eq!(t.write(b"abcde" ).unwrap(), 5); |
19 | |
20 | assert!(!t.is_rolled()); |
21 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
22 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 5); |
23 | assert_eq!(buf.as_slice(), b"abcde" ); |
24 | |
25 | assert_eq!(t.write(b"fghijklmno" ).unwrap(), 10); |
26 | |
27 | assert_eq!(t.stream_position().unwrap(), 15); |
28 | assert!(t.is_rolled()); |
29 | } |
30 | |
31 | #[test] |
32 | fn test_explicit_rollover() { |
33 | let mut t = SpooledTempFile::new(100); |
34 | assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz" ).unwrap(), 26); |
35 | assert_eq!(t.stream_position().unwrap(), 26); |
36 | assert!(!t.is_rolled()); |
37 | |
38 | // roll over explicitly |
39 | assert!(t.roll().is_ok()); |
40 | assert!(t.is_rolled()); |
41 | assert_eq!(t.stream_position().unwrap(), 26); |
42 | |
43 | let mut buf = Vec::new(); |
44 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); |
45 | assert_eq!(buf.as_slice(), b"" ); |
46 | buf.clear(); |
47 | |
48 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
49 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 26); |
50 | assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz" ); |
51 | assert_eq!(t.stream_position().unwrap(), 26); |
52 | } |
53 | |
54 | // called by test_seek_{buffer, file} |
55 | // assumes t is empty and offset is 0 to start |
56 | fn test_seek(t: &mut SpooledTempFile) { |
57 | assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz" ).unwrap(), 26); |
58 | |
59 | assert_eq!(t.stream_position().unwrap(), 26); // tell() |
60 | assert_eq!(t.seek(SeekFrom::Current(-1)).unwrap(), 25); |
61 | assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 26); |
62 | assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 27); |
63 | assert_eq!(t.seek(SeekFrom::Current(-27)).unwrap(), 0); |
64 | assert!(t.seek(SeekFrom::Current(-1)).is_err()); |
65 | assert!(t.seek(SeekFrom::Current(-1245)).is_err()); |
66 | |
67 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
68 | assert_eq!(t.seek(SeekFrom::Start(1)).unwrap(), 1); |
69 | assert_eq!(t.seek(SeekFrom::Start(26)).unwrap(), 26); |
70 | assert_eq!(t.seek(SeekFrom::Start(27)).unwrap(), 27); |
71 | // // these are build errors |
72 | // assert!(t.seek(SeekFrom::Start(-1)).is_err()); |
73 | // assert!(t.seek(SeekFrom::Start(-1000)).is_err()); |
74 | |
75 | assert_eq!(t.seek(SeekFrom::End(0)).unwrap(), 26); |
76 | assert_eq!(t.seek(SeekFrom::End(-1)).unwrap(), 25); |
77 | assert_eq!(t.seek(SeekFrom::End(-26)).unwrap(), 0); |
78 | assert!(t.seek(SeekFrom::End(-27)).is_err()); |
79 | assert!(t.seek(SeekFrom::End(-99)).is_err()); |
80 | assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27); |
81 | assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27); |
82 | } |
83 | |
84 | #[test] |
85 | fn test_seek_buffer() { |
86 | let mut t = spooled_tempfile(100); |
87 | test_seek(&mut t); |
88 | } |
89 | |
90 | #[test] |
91 | fn test_seek_file() { |
92 | let mut t = SpooledTempFile::new(10); |
93 | test_seek(&mut t); |
94 | } |
95 | |
96 | fn test_seek_read(t: &mut SpooledTempFile) { |
97 | assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz" ).unwrap(), 26); |
98 | |
99 | let mut buf = Vec::new(); |
100 | |
101 | // we're at the end |
102 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); |
103 | assert_eq!(buf.as_slice(), b"" ); |
104 | buf.clear(); |
105 | |
106 | // seek to start, read whole thing |
107 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
108 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 26); |
109 | assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz" ); |
110 | buf.clear(); |
111 | |
112 | // now we're at the end again |
113 | assert_eq!(t.stream_position().unwrap(), 26); // tell() |
114 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); |
115 | assert_eq!(buf.as_slice(), b"" ); |
116 | buf.clear(); |
117 | |
118 | // seek to somewhere in the middle, read a bit |
119 | assert_eq!(t.seek(SeekFrom::Start(5)).unwrap(), 5); |
120 | let mut buf = [0; 5]; |
121 | assert!(t.read_exact(&mut buf).is_ok()); |
122 | assert_eq!(buf, *b"fghij" ); |
123 | |
124 | // read again from current spot |
125 | assert_eq!(t.stream_position().unwrap(), 10); // tell() |
126 | assert!(t.read_exact(&mut buf).is_ok()); |
127 | assert_eq!(buf, *b"klmno" ); |
128 | |
129 | let mut buf = [0; 15]; |
130 | // partial read |
131 | assert_eq!(t.read(&mut buf).unwrap(), 11); |
132 | assert_eq!(buf[0..11], *b"pqrstuvwxyz" ); |
133 | |
134 | // try to read off the end: UnexpectedEof |
135 | assert!(t.read_exact(&mut buf).is_err()); |
136 | } |
137 | |
138 | #[test] |
139 | fn test_seek_read_buffer() { |
140 | let mut t = spooled_tempfile(100); |
141 | test_seek_read(&mut t); |
142 | } |
143 | |
144 | #[test] |
145 | fn test_seek_read_file() { |
146 | let mut t = SpooledTempFile::new(10); |
147 | test_seek_read(&mut t); |
148 | } |
149 | |
150 | fn test_overwrite_middle(t: &mut SpooledTempFile) { |
151 | assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz" ).unwrap(), 26); |
152 | |
153 | assert_eq!(t.seek(SeekFrom::Start(10)).unwrap(), 10); |
154 | assert_eq!(t.write(b"0123456789" ).unwrap(), 10); |
155 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
156 | |
157 | let mut buf = Vec::new(); |
158 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 26); |
159 | assert_eq!(buf.as_slice(), b"abcdefghij0123456789uvwxyz" ); |
160 | } |
161 | |
162 | #[test] |
163 | fn test_overwrite_middle_of_buffer() { |
164 | let mut t = spooled_tempfile(100); |
165 | test_overwrite_middle(&mut t); |
166 | } |
167 | |
168 | #[test] |
169 | fn test_overwrite_middle_of_file() { |
170 | let mut t = SpooledTempFile::new(10); |
171 | test_overwrite_middle(&mut t); |
172 | } |
173 | |
174 | #[test] |
175 | fn test_overwrite_and_extend_buffer() { |
176 | let mut t = spooled_tempfile(100); |
177 | assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz" ).unwrap(), 26); |
178 | assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 21); |
179 | assert_eq!(t.write(b"0123456789" ).unwrap(), 10); |
180 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
181 | let mut buf = Vec::new(); |
182 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 31); |
183 | assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstu0123456789" ); |
184 | assert!(!t.is_rolled()); |
185 | } |
186 | |
187 | #[test] |
188 | fn test_overwrite_and_extend_rollover() { |
189 | let mut t = SpooledTempFile::new(20); |
190 | assert_eq!(t.write(b"abcdefghijklmno" ).unwrap(), 15); |
191 | assert!(!t.is_rolled()); |
192 | assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 10); |
193 | assert_eq!(t.stream_position().unwrap(), 10); // tell() |
194 | assert!(!t.is_rolled()); |
195 | assert_eq!(t.write(b"0123456789)!@#$%^&*(" ).unwrap(), 20); |
196 | assert!(t.is_rolled()); |
197 | assert_eq!(t.stream_position().unwrap(), 30); // tell() |
198 | let mut buf = Vec::new(); |
199 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
200 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 30); |
201 | assert_eq!(buf.as_slice(), b"abcdefghij0123456789)!@#$%^&*(" ); |
202 | } |
203 | |
204 | fn test_sparse(t: &mut SpooledTempFile) { |
205 | assert_eq!(t.write(b"abcde" ).unwrap(), 5); |
206 | assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10); |
207 | assert_eq!(t.write(b"klmno" ).unwrap(), 5); |
208 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
209 | let mut buf = Vec::new(); |
210 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 15); |
211 | assert_eq!(buf.as_slice(), b"abcde \0\0\0\0\0klmno" ); |
212 | } |
213 | |
214 | #[test] |
215 | fn test_sparse_buffer() { |
216 | let mut t = spooled_tempfile(100); |
217 | test_sparse(&mut t); |
218 | } |
219 | |
220 | #[test] |
221 | fn test_sparse_file() { |
222 | let mut t = SpooledTempFile::new(1); |
223 | test_sparse(&mut t); |
224 | } |
225 | |
226 | #[test] |
227 | fn test_sparse_write_rollover() { |
228 | let mut t = spooled_tempfile(10); |
229 | assert_eq!(t.write(b"abcde" ).unwrap(), 5); |
230 | assert!(!t.is_rolled()); |
231 | assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10); |
232 | assert!(!t.is_rolled()); |
233 | assert_eq!(t.write(b"klmno" ).unwrap(), 5); |
234 | assert!(t.is_rolled()); |
235 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
236 | let mut buf = Vec::new(); |
237 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 15); |
238 | assert_eq!(buf.as_slice(), b"abcde \0\0\0\0\0klmno" ); |
239 | } |
240 | |
241 | fn test_set_len(t: &mut SpooledTempFile) { |
242 | let mut buf: Vec<u8> = Vec::new(); |
243 | |
244 | assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz" ).unwrap(), 26); |
245 | |
246 | // truncate to 10 bytes |
247 | assert!(t.set_len(10).is_ok()); |
248 | |
249 | // position should not have moved |
250 | assert_eq!(t.stream_position().unwrap(), 26); // tell() |
251 | |
252 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 0); |
253 | assert_eq!(buf.as_slice(), b"" ); |
254 | assert_eq!(t.stream_position().unwrap(), 26); // tell() |
255 | buf.clear(); |
256 | |
257 | // read whole thing |
258 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
259 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 10); |
260 | assert_eq!(buf.as_slice(), b"abcdefghij" ); |
261 | buf.clear(); |
262 | |
263 | // set_len to expand beyond the end |
264 | assert!(t.set_len(40).is_ok()); |
265 | assert_eq!(t.stream_position().unwrap(), 10); // tell() |
266 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
267 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 40); |
268 | assert_eq!( |
269 | buf.as_slice(), |
270 | &b"abcdefghij \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" [..] |
271 | ); |
272 | } |
273 | |
274 | #[test] |
275 | fn test_set_len_buffer() { |
276 | let mut t = spooled_tempfile(100); |
277 | test_set_len(&mut t); |
278 | } |
279 | |
280 | #[test] |
281 | fn test_set_len_file() { |
282 | let mut t = spooled_tempfile(100); |
283 | test_set_len(&mut t); |
284 | } |
285 | |
286 | #[test] |
287 | fn test_set_len_rollover() { |
288 | let mut buf: Vec<u8> = Vec::new(); |
289 | |
290 | let mut t = spooled_tempfile(10); |
291 | assert_eq!(t.write(b"abcde" ).unwrap(), 5); |
292 | assert!(!t.is_rolled()); |
293 | assert_eq!(t.stream_position().unwrap(), 5); // tell() |
294 | |
295 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
296 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 5); |
297 | assert_eq!(buf.as_slice(), b"abcde" ); |
298 | assert_eq!(t.stream_position().unwrap(), 5); // tell() |
299 | buf.clear(); |
300 | |
301 | assert!(t.set_len(20).is_ok()); |
302 | assert!(t.is_rolled()); |
303 | assert_eq!(t.stream_position().unwrap(), 5); // tell() |
304 | assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0); |
305 | assert_eq!(t.read_to_end(&mut buf).unwrap(), 20); |
306 | assert_eq!(buf.as_slice(), b"abcde \0\0\0\0\0\0\0\0\0\0\0\0\0\0\0" ); |
307 | } |
308 | |