1 #![deny(rust_2018_idioms)]
2 
3 use std::io::{Read, Seek, SeekFrom, Write};
4 
5 use tempfile::{spooled_tempfile, SpooledTempFile};
6 
7 #[test]
test_automatic_rollover()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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).unwrap(), 15);
28     assert!(t.is_rolled());
29 }
30 
31 #[test]
test_explicit_rollover()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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).unwrap(), 26);
52 }
53 
54 // called by test_seek_{buffer, file}
55 // assumes t is empty and offset is 0 to start
test_seek(t: &mut SpooledTempFile)56 fn test_seek(t: &mut SpooledTempFile) {
57     assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
58 
59     assert_eq!(t.seek(SeekFrom::Current(0)).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]
test_seek_buffer()85 fn test_seek_buffer() {
86     let mut t = spooled_tempfile(100);
87     test_seek(&mut t);
88 }
89 
90 #[test]
test_seek_file()91 fn test_seek_file() {
92     let mut t = SpooledTempFile::new(10);
93     test_seek(&mut t);
94 }
95 
test_seek_read(t: &mut SpooledTempFile)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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).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]
test_seek_read_buffer()139 fn test_seek_read_buffer() {
140     let mut t = spooled_tempfile(100);
141     test_seek_read(&mut t);
142 }
143 
144 #[test]
test_seek_read_file()145 fn test_seek_read_file() {
146     let mut t = SpooledTempFile::new(10);
147     test_seek_read(&mut t);
148 }
149 
test_overwrite_middle(t: &mut SpooledTempFile)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]
test_overwrite_middle_of_buffer()163 fn test_overwrite_middle_of_buffer() {
164     let mut t = spooled_tempfile(100);
165     test_overwrite_middle(&mut t);
166 }
167 
168 #[test]
test_overwrite_middle_of_file()169 fn test_overwrite_middle_of_file() {
170     let mut t = SpooledTempFile::new(10);
171     test_overwrite_middle(&mut t);
172 }
173 
174 #[test]
test_overwrite_and_extend_buffer()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]
test_overwrite_and_extend_rollover()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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).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 
test_sparse(t: &mut SpooledTempFile)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]
test_sparse_buffer()215 fn test_sparse_buffer() {
216     let mut t = spooled_tempfile(100);
217     test_sparse(&mut t);
218 }
219 
220 #[test]
test_sparse_file()221 fn test_sparse_file() {
222     let mut t = SpooledTempFile::new(1);
223     test_sparse(&mut t);
224 }
225 
226 #[test]
test_sparse_write_rollover()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 
test_set_len(t: &mut SpooledTempFile)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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).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]
test_set_len_buffer()275 fn test_set_len_buffer() {
276     let mut t = spooled_tempfile(100);
277     test_set_len(&mut t);
278 }
279 
280 #[test]
test_set_len_file()281 fn test_set_len_file() {
282     let mut t = spooled_tempfile(100);
283     test_set_len(&mut t);
284 }
285 
286 #[test]
test_set_len_rollover()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.seek(SeekFrom::Current(0)).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.seek(SeekFrom::Current(0)).unwrap(), 5); // tell()
299     buf.clear();
300 
301     assert!(t.set_len(20).is_ok());
302     assert!(t.is_rolled());
303     assert_eq!(t.seek(SeekFrom::Current(0)).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