Revision control

Copy as Markdown

Other Tools

#![deny(rust_2018_idioms)]
use std::io::{Read, Seek, SeekFrom, Write};
use tempfile::{spooled_tempfile, SpooledTempFile};
#[test]
fn test_automatic_rollover() {
let mut t = spooled_tempfile(10);
let mut buf = Vec::new();
assert!(!t.is_rolled());
assert_eq!(t.stream_position().unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
assert_eq!(buf.as_slice(), b"");
buf.clear();
assert_eq!(t.write(b"abcde").unwrap(), 5);
assert!(!t.is_rolled());
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 5);
assert_eq!(buf.as_slice(), b"abcde");
assert_eq!(t.write(b"fghijklmno").unwrap(), 10);
assert_eq!(t.stream_position().unwrap(), 15);
assert!(t.is_rolled());
}
#[test]
fn test_explicit_rollover() {
let mut t = SpooledTempFile::new(100);
assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
assert_eq!(t.stream_position().unwrap(), 26);
assert!(!t.is_rolled());
// roll over explicitly
assert!(t.roll().is_ok());
assert!(t.is_rolled());
assert_eq!(t.stream_position().unwrap(), 26);
let mut buf = Vec::new();
assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
assert_eq!(buf.as_slice(), b"");
buf.clear();
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 26);
assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz");
assert_eq!(t.stream_position().unwrap(), 26);
}
// called by test_seek_{buffer, file}
// assumes t is empty and offset is 0 to start
fn test_seek(t: &mut SpooledTempFile) {
assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
assert_eq!(t.stream_position().unwrap(), 26); // tell()
assert_eq!(t.seek(SeekFrom::Current(-1)).unwrap(), 25);
assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 26);
assert_eq!(t.seek(SeekFrom::Current(1)).unwrap(), 27);
assert_eq!(t.seek(SeekFrom::Current(-27)).unwrap(), 0);
assert!(t.seek(SeekFrom::Current(-1)).is_err());
assert!(t.seek(SeekFrom::Current(-1245)).is_err());
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.seek(SeekFrom::Start(1)).unwrap(), 1);
assert_eq!(t.seek(SeekFrom::Start(26)).unwrap(), 26);
assert_eq!(t.seek(SeekFrom::Start(27)).unwrap(), 27);
// // these are build errors
// assert!(t.seek(SeekFrom::Start(-1)).is_err());
// assert!(t.seek(SeekFrom::Start(-1000)).is_err());
assert_eq!(t.seek(SeekFrom::End(0)).unwrap(), 26);
assert_eq!(t.seek(SeekFrom::End(-1)).unwrap(), 25);
assert_eq!(t.seek(SeekFrom::End(-26)).unwrap(), 0);
assert!(t.seek(SeekFrom::End(-27)).is_err());
assert!(t.seek(SeekFrom::End(-99)).is_err());
assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27);
assert_eq!(t.seek(SeekFrom::End(1)).unwrap(), 27);
}
#[test]
fn test_seek_buffer() {
let mut t = spooled_tempfile(100);
test_seek(&mut t);
}
#[test]
fn test_seek_file() {
let mut t = SpooledTempFile::new(10);
test_seek(&mut t);
}
fn test_seek_read(t: &mut SpooledTempFile) {
assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
let mut buf = Vec::new();
// we're at the end
assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
assert_eq!(buf.as_slice(), b"");
buf.clear();
// seek to start, read whole thing
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 26);
assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstuvwxyz");
buf.clear();
// now we're at the end again
assert_eq!(t.stream_position().unwrap(), 26); // tell()
assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
assert_eq!(buf.as_slice(), b"");
buf.clear();
// seek to somewhere in the middle, read a bit
assert_eq!(t.seek(SeekFrom::Start(5)).unwrap(), 5);
let mut buf = [0; 5];
assert!(t.read_exact(&mut buf).is_ok());
assert_eq!(buf, *b"fghij");
// read again from current spot
assert_eq!(t.stream_position().unwrap(), 10); // tell()
assert!(t.read_exact(&mut buf).is_ok());
assert_eq!(buf, *b"klmno");
let mut buf = [0; 15];
// partial read
assert_eq!(t.read(&mut buf).unwrap(), 11);
assert_eq!(buf[0..11], *b"pqrstuvwxyz");
// try to read off the end: UnexpectedEof
assert!(t.read_exact(&mut buf).is_err());
}
#[test]
fn test_seek_read_buffer() {
let mut t = spooled_tempfile(100);
test_seek_read(&mut t);
}
#[test]
fn test_seek_read_file() {
let mut t = SpooledTempFile::new(10);
test_seek_read(&mut t);
}
fn test_overwrite_middle(t: &mut SpooledTempFile) {
assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
assert_eq!(t.seek(SeekFrom::Start(10)).unwrap(), 10);
assert_eq!(t.write(b"0123456789").unwrap(), 10);
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
let mut buf = Vec::new();
assert_eq!(t.read_to_end(&mut buf).unwrap(), 26);
assert_eq!(buf.as_slice(), b"abcdefghij0123456789uvwxyz");
}
#[test]
fn test_overwrite_middle_of_buffer() {
let mut t = spooled_tempfile(100);
test_overwrite_middle(&mut t);
}
#[test]
fn test_overwrite_middle_of_file() {
let mut t = SpooledTempFile::new(10);
test_overwrite_middle(&mut t);
}
#[test]
fn test_overwrite_and_extend_buffer() {
let mut t = spooled_tempfile(100);
assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 21);
assert_eq!(t.write(b"0123456789").unwrap(), 10);
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
let mut buf = Vec::new();
assert_eq!(t.read_to_end(&mut buf).unwrap(), 31);
assert_eq!(buf.as_slice(), b"abcdefghijklmnopqrstu0123456789");
assert!(!t.is_rolled());
}
#[test]
fn test_overwrite_and_extend_rollover() {
let mut t = SpooledTempFile::new(20);
assert_eq!(t.write(b"abcdefghijklmno").unwrap(), 15);
assert!(!t.is_rolled());
assert_eq!(t.seek(SeekFrom::End(-5)).unwrap(), 10);
assert_eq!(t.stream_position().unwrap(), 10); // tell()
assert!(!t.is_rolled());
assert_eq!(t.write(b"0123456789)!@#$%^&*(").unwrap(), 20);
assert!(t.is_rolled());
assert_eq!(t.stream_position().unwrap(), 30); // tell()
let mut buf = Vec::new();
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 30);
assert_eq!(buf.as_slice(), b"abcdefghij0123456789)!@#$%^&*(");
}
fn test_sparse(t: &mut SpooledTempFile) {
assert_eq!(t.write(b"abcde").unwrap(), 5);
assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10);
assert_eq!(t.write(b"klmno").unwrap(), 5);
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
let mut buf = Vec::new();
assert_eq!(t.read_to_end(&mut buf).unwrap(), 15);
assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0klmno");
}
#[test]
fn test_sparse_buffer() {
let mut t = spooled_tempfile(100);
test_sparse(&mut t);
}
#[test]
fn test_sparse_file() {
let mut t = SpooledTempFile::new(1);
test_sparse(&mut t);
}
#[test]
fn test_sparse_write_rollover() {
let mut t = spooled_tempfile(10);
assert_eq!(t.write(b"abcde").unwrap(), 5);
assert!(!t.is_rolled());
assert_eq!(t.seek(SeekFrom::Current(5)).unwrap(), 10);
assert!(!t.is_rolled());
assert_eq!(t.write(b"klmno").unwrap(), 5);
assert!(t.is_rolled());
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
let mut buf = Vec::new();
assert_eq!(t.read_to_end(&mut buf).unwrap(), 15);
assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0klmno");
}
fn test_set_len(t: &mut SpooledTempFile) {
let mut buf: Vec<u8> = Vec::new();
assert_eq!(t.write(b"abcdefghijklmnopqrstuvwxyz").unwrap(), 26);
// truncate to 10 bytes
assert!(t.set_len(10).is_ok());
// position should not have moved
assert_eq!(t.stream_position().unwrap(), 26); // tell()
assert_eq!(t.read_to_end(&mut buf).unwrap(), 0);
assert_eq!(buf.as_slice(), b"");
assert_eq!(t.stream_position().unwrap(), 26); // tell()
buf.clear();
// read whole thing
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 10);
assert_eq!(buf.as_slice(), b"abcdefghij");
buf.clear();
// set_len to expand beyond the end
assert!(t.set_len(40).is_ok());
assert_eq!(t.stream_position().unwrap(), 10); // tell()
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 40);
assert_eq!(
buf.as_slice(),
&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"[..]
);
}
#[test]
fn test_set_len_buffer() {
let mut t = spooled_tempfile(100);
test_set_len(&mut t);
}
#[test]
fn test_set_len_file() {
let mut t = spooled_tempfile(100);
test_set_len(&mut t);
}
#[test]
fn test_set_len_rollover() {
let mut buf: Vec<u8> = Vec::new();
let mut t = spooled_tempfile(10);
assert_eq!(t.write(b"abcde").unwrap(), 5);
assert!(!t.is_rolled());
assert_eq!(t.stream_position().unwrap(), 5); // tell()
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 5);
assert_eq!(buf.as_slice(), b"abcde");
assert_eq!(t.stream_position().unwrap(), 5); // tell()
buf.clear();
assert!(t.set_len(20).is_ok());
assert!(t.is_rolled());
assert_eq!(t.stream_position().unwrap(), 5); // tell()
assert_eq!(t.seek(SeekFrom::Start(0)).unwrap(), 0);
assert_eq!(t.read_to_end(&mut buf).unwrap(), 20);
assert_eq!(buf.as_slice(), b"abcde\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
}
#[test]
fn test_write_overflow() {
let mut t = spooled_tempfile(10);
t.seek(SeekFrom::Start(u64::MAX)).unwrap();
assert!(t.write(b"abcde").is_err());
}
#[cfg(target_pointer_width = "32")]
#[test]
fn test_set_len_truncation() {
let mut t = spooled_tempfile(100);
assert!(t.set_len(usize::MAX as u64 + 5).is_ok());
assert!(t.is_rolled());
}