extern crate tempdir;
use crate::*;
use std::fs;
use std::io::{Read, Seek, SeekFrom, Write};
use std::path::PathBuf;
pub(crate) fn tmpdir() -> tempdir::TempDir {
tempdir::TempDir::new("fs3").unwrap()
}
pub(crate) fn tmpfile() -> (tempdir::TempDir, PathBuf) {
let dir = tmpdir();
let path = dir.path().join("file");
(dir, path)
}
#[test]
fn duplicate() {
let (_dir, path) = tmpfile();
let mut file1 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
let mut file2 = file1.duplicate().unwrap();
file1.write_all(b"foo").unwrap();
drop(file1);
let mut buf = vec![];
file2.read_to_end(&mut buf).unwrap();
assert_eq!(0, buf.len());
file2.seek(SeekFrom::Start(0)).unwrap();
file2.read_to_end(&mut buf).unwrap();
assert_eq!(&buf, &b"foo");
}
#[test]
fn lock_shared() {
let (_dir, path) = tmpfile();
let file1 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
let file2 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
let file3 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
file1.lock_shared().unwrap();
file2.lock_shared().unwrap();
assert_eq!(
file3.try_lock_exclusive().unwrap_err().kind(),
lock_contended_error().kind()
);
file1.unlock().unwrap();
assert_eq!(
file3.try_lock_exclusive().unwrap_err().kind(),
lock_contended_error().kind()
);
file2.unlock().unwrap();
file3.lock_exclusive().unwrap();
}
#[test]
fn lock_exclusive() {
let (_dir, path) = tmpfile();
let file1 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
let file2 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
file1.lock_exclusive().unwrap();
assert_eq!(
file2.try_lock_exclusive().unwrap_err().kind(),
lock_contended_error().kind()
);
assert_eq!(
file2.try_lock_shared().unwrap_err().kind(),
lock_contended_error().kind()
);
file1.unlock().unwrap();
file2.lock_exclusive().unwrap();
}
#[test]
fn lock_cleanup() {
let (_dir, path) = tmpfile();
let file1 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
let file2 = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
file1.lock_exclusive().unwrap();
assert_eq!(
file2.try_lock_shared().unwrap_err().kind(),
lock_contended_error().kind()
);
drop(file1);
file2.lock_shared().unwrap();
}
#[test]
fn allocate() {
let (_dir, path) = tmpfile();
let file = fs::OpenOptions::new()
.write(true)
.create(true)
.open(&path)
.unwrap();
let blksize = allocation_granularity(&path).unwrap();
assert_eq!(0, file.allocated_size().unwrap());
assert_eq!(0, file.metadata().unwrap().len());
file.allocate(2 * blksize - 1).unwrap();
assert_eq!(2 * blksize, file.allocated_size().unwrap());
assert_eq!(2 * blksize - 1, file.metadata().unwrap().len());
file.set_len(blksize + 1).unwrap();
assert_eq!(2 * blksize, file.allocated_size().unwrap());
assert_eq!(blksize + 1, file.metadata().unwrap().len());
}
#[test]
fn filesystem_space() {
let tempdir = tmpdir();
let total_space = total_space(&tempdir.path()).unwrap();
let free_space = free_space(&tempdir.path()).unwrap();
let available_space = available_space(&tempdir.path()).unwrap();
assert!(total_space > free_space);
assert!(total_space > available_space);
assert!(available_space <= free_space);
}
#[cfg(nightly)]
mod bench {
extern crate test;
use super::{tmpdir, tmpfile};
use crate::*;
use std::fs;
#[bench]
fn bench_file_create(b: &mut test::Bencher) {
let (_dir, path) = tmpfile();
b.iter(|| {
fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
fs::remove_file(&path).unwrap();
});
}
#[bench]
fn bench_file_truncate(b: &mut test::Bencher) {
let (_dir, path) = tmpfile();
let size = 32 * 1024 * 1024;
b.iter(|| {
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
file.set_len(size).unwrap();
fs::remove_file(&path).unwrap();
});
}
#[bench]
fn bench_file_allocate(b: &mut test::Bencher) {
let (_dir, path) = tmpfile();
let size = 32 * 1024 * 1024;
b.iter(|| {
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
file.allocate(size).unwrap();
fs::remove_file(&path).unwrap();
});
}
#[cfg(nightly)]
#[bench]
fn bench_allocated_size(b: &mut test::Bencher) {
let (_dir, path) = tmpfile();
let size = 32 * 1024 * 1024;
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
file.allocate(size).unwrap();
b.iter(|| {
file.allocated_size().unwrap();
});
}
#[bench]
fn bench_duplicate(b: &mut test::Bencher) {
let (_dir, path) = tmpfile();
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
b.iter(|| test::black_box(file.duplicate().unwrap()));
}
#[bench]
fn bench_lock_unlock(b: &mut test::Bencher) {
let (_dir, path) = tmpfile();
let file = fs::OpenOptions::new()
.read(true)
.write(true)
.create(true)
.open(&path)
.unwrap();
b.iter(|| {
file.lock_exclusive().unwrap();
file.unlock().unwrap();
});
}
#[bench]
fn bench_free_space(b: &mut test::Bencher) {
let dir = tmpdir();
b.iter(|| {
test::black_box(free_space(&dir.path()).unwrap());
});
}
#[bench]
fn bench_available_space(b: &mut test::Bencher) {
let dir = tmpdir();
b.iter(|| {
test::black_box(available_space(&dir.path()).unwrap());
});
}
#[bench]
fn bench_total_space(b: &mut test::Bencher) {
let dir = tmpdir();
b.iter(|| {
test::black_box(total_space(&dir.path()).unwrap());
});
}
}