1#![deny(rust_2018_idioms)]
2
3use std::io::{Read, Seek, SeekFrom, Write};
4
5use tempfile::{spooled_tempfile, SpooledTempFile};
6
7#[test]
8fn 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]
32fn 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
56fn 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]
85fn test_seek_buffer() {
86 let mut t = spooled_tempfile(100);
87 test_seek(&mut t);
88}
89
90#[test]
91fn test_seek_file() {
92 let mut t = SpooledTempFile::new(10);
93 test_seek(&mut t);
94}
95
96fn 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]
139fn test_seek_read_buffer() {
140 let mut t = spooled_tempfile(100);
141 test_seek_read(&mut t);
142}
143
144#[test]
145fn test_seek_read_file() {
146 let mut t = SpooledTempFile::new(10);
147 test_seek_read(&mut t);
148}
149
150fn 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]
163fn test_overwrite_middle_of_buffer() {
164 let mut t = spooled_tempfile(100);
165 test_overwrite_middle(&mut t);
166}
167
168#[test]
169fn test_overwrite_middle_of_file() {
170 let mut t = SpooledTempFile::new(10);
171 test_overwrite_middle(&mut t);
172}
173
174#[test]
175fn 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]
188fn 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
204fn 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]
215fn test_sparse_buffer() {
216 let mut t = spooled_tempfile(100);
217 test_sparse(&mut t);
218}
219
220#[test]
221fn test_sparse_file() {
222 let mut t = SpooledTempFile::new(1);
223 test_sparse(&mut t);
224}
225
226#[test]
227fn 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
241fn 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]
275fn test_set_len_buffer() {
276 let mut t = spooled_tempfile(100);
277 test_set_len(&mut t);
278}
279
280#[test]
281fn test_set_len_file() {
282 let mut t = spooled_tempfile(100);
283 test_set_len(&mut t);
284}
285
286#[test]
287fn 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