2304b13ec4
Dir methods do not change Dir object itself. They usually clone inner stream so no change really happens self struct. Underlying partition is modified but it does not have to affect API. For example see std::fs::File::set_len. This change greatly simplifies rename API usage.
254 lines
7.5 KiB
Rust
254 lines
7.5 KiB
Rust
extern crate fatfs;
|
|
extern crate env_logger;
|
|
|
|
use std::fs;
|
|
use std::io::SeekFrom;
|
|
use std::io::prelude::*;
|
|
use std::str;
|
|
|
|
use fatfs::{FileSystem, FsOptions, FatType, DirEntry, BufStream};
|
|
|
|
const TEST_TEXT: &str = "Rust is cool!\n";
|
|
const FAT12_IMG: &str = "resources/fat12.img";
|
|
const FAT16_IMG: &str = "resources/fat16.img";
|
|
const FAT32_IMG: &str = "resources/fat32.img";
|
|
|
|
fn call_with_fs(f: &Fn(FileSystem) -> (), filename: &str) {
|
|
let _ = env_logger::try_init();
|
|
let file = fs::File::open(filename).unwrap();
|
|
let mut buf_file = BufStream::new(file);
|
|
let fs = FileSystem::new(&mut buf_file, FsOptions::new()).unwrap();
|
|
f(fs);
|
|
}
|
|
|
|
fn test_root_dir(fs: FileSystem) {
|
|
let root_dir = fs.root_dir();
|
|
let entries = root_dir.iter().map(|r| r.unwrap()).collect::<Vec<DirEntry>>();
|
|
let short_names = entries.iter().map(|e| e.short_file_name()).collect::<Vec<String>>();
|
|
assert_eq!(short_names, ["LONG.TXT", "SHORT.TXT", "VERY", "VERY-L~1"]);
|
|
let names = entries.iter().map(|e| e.file_name()).collect::<Vec<String>>();
|
|
assert_eq!(names, ["long.txt", "short.txt", "very", "very-long-dir-name"]);
|
|
// Try read again
|
|
let names2 = root_dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
|
assert_eq!(names2, names);
|
|
}
|
|
|
|
#[test]
|
|
fn test_root_dir_fat12() {
|
|
call_with_fs(&test_root_dir, FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_root_dir_fat16() {
|
|
call_with_fs(&test_root_dir, FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_root_dir_fat32() {
|
|
call_with_fs(&test_root_dir, FAT32_IMG)
|
|
}
|
|
|
|
fn test_read_seek_short_file(fs: FileSystem) {
|
|
let root_dir = fs.root_dir();
|
|
let mut short_file = root_dir.open_file("short.txt").unwrap();
|
|
let mut buf = Vec::new();
|
|
short_file.read_to_end(&mut buf).unwrap();
|
|
assert_eq!(str::from_utf8(&buf).unwrap(), TEST_TEXT);
|
|
|
|
assert_eq!(short_file.seek(SeekFrom::Start(5)).unwrap(), 5);
|
|
let mut buf2 = [0; 5];
|
|
short_file.read_exact(&mut buf2).unwrap();
|
|
assert_eq!(str::from_utf8(&buf2).unwrap(), &TEST_TEXT[5..10]);
|
|
|
|
assert_eq!(short_file.seek(SeekFrom::Start(1000)).unwrap(), TEST_TEXT.len() as u64);
|
|
let mut buf2 = [0; 5];
|
|
assert_eq!(short_file.read(&mut buf2).unwrap(), 0);
|
|
}
|
|
|
|
#[test]
|
|
fn test_read_seek_short_file_fat12() {
|
|
call_with_fs(&test_read_seek_short_file, FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_read_seek_short_file_fat16() {
|
|
call_with_fs(&test_read_seek_short_file, FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_read_seek_short_file_fat32() {
|
|
call_with_fs(&test_read_seek_short_file, FAT32_IMG)
|
|
}
|
|
|
|
fn test_read_long_file(fs: FileSystem) {
|
|
let root_dir = fs.root_dir();
|
|
let mut long_file = root_dir.open_file("long.txt").unwrap();
|
|
let mut buf = Vec::new();
|
|
long_file.read_to_end(&mut buf).unwrap();
|
|
assert_eq!(str::from_utf8(&buf).unwrap(), TEST_TEXT.repeat(1000));
|
|
|
|
assert_eq!(long_file.seek(SeekFrom::Start(2017)).unwrap(), 2017);
|
|
buf.clear();
|
|
let mut buf2 = [0; 10];
|
|
long_file.read_exact(&mut buf2).unwrap();
|
|
assert_eq!(str::from_utf8(&buf2).unwrap(), &TEST_TEXT.repeat(1000)[2017..2027]);
|
|
}
|
|
|
|
#[test]
|
|
fn test_read_long_file_fat12() {
|
|
call_with_fs(&test_read_long_file, FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_read_long_file_fat16() {
|
|
call_with_fs(&test_read_long_file, FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_read_long_file_fat32() {
|
|
call_with_fs(&test_read_long_file, FAT32_IMG)
|
|
}
|
|
|
|
fn test_get_dir_by_path(fs: FileSystem) {
|
|
let root_dir = fs.root_dir();
|
|
let dir = root_dir.open_dir("very/long/path/").unwrap();
|
|
let names = dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
|
assert_eq!(names, [".", "..", "test.txt"]);
|
|
|
|
let dir2 = root_dir.open_dir("very/long/path/././.").unwrap();
|
|
let names2 = dir2.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
|
assert_eq!(names2, [".", "..", "test.txt"]);
|
|
|
|
let root_dir2 = root_dir.open_dir("very/long/path/../../..").unwrap();
|
|
let root_names = root_dir2.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
|
let root_names2 = root_dir.iter().map(|r| r.unwrap().file_name()).collect::<Vec<String>>();
|
|
assert_eq!(root_names, root_names2);
|
|
|
|
root_dir.open_dir("VERY-L~1").unwrap();
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_dir_by_path_fat12() {
|
|
call_with_fs(&test_get_dir_by_path, FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_dir_by_path_fat16() {
|
|
call_with_fs(&test_get_dir_by_path, FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_dir_by_path_fat32() {
|
|
call_with_fs(&test_get_dir_by_path, FAT32_IMG)
|
|
}
|
|
|
|
fn test_get_file_by_path(fs: FileSystem) {
|
|
let root_dir = fs.root_dir();
|
|
let mut file = root_dir.open_file("very/long/path/test.txt").unwrap();
|
|
let mut buf = Vec::new();
|
|
file.read_to_end(&mut buf).unwrap();
|
|
assert_eq!(str::from_utf8(&buf).unwrap(), TEST_TEXT);
|
|
|
|
let mut file = root_dir.open_file("very-long-dir-name/very-long-file-name.txt").unwrap();
|
|
let mut buf = Vec::new();
|
|
file.read_to_end(&mut buf).unwrap();
|
|
assert_eq!(str::from_utf8(&buf).unwrap(), TEST_TEXT);
|
|
|
|
root_dir.open_file("VERY-L~1/VERY-L~1.TXT").unwrap();
|
|
|
|
// try opening dir as file
|
|
assert!(root_dir.open_file("very/long/path").is_err());
|
|
// try opening file as dir
|
|
assert!(root_dir.open_dir("very/long/path/test.txt").is_err());
|
|
// try using invalid path containing file as non-last component
|
|
assert!(root_dir.open_file("very/long/path/test.txt/abc").is_err());
|
|
assert!(root_dir.open_dir("very/long/path/test.txt/abc").is_err());
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_file_by_path_fat12() {
|
|
call_with_fs(&test_get_file_by_path, FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_file_by_path_fat16() {
|
|
call_with_fs(&test_get_file_by_path, FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_get_file_by_path_fat32() {
|
|
call_with_fs(&test_get_file_by_path, FAT32_IMG)
|
|
}
|
|
|
|
fn test_volume_metadata(fs: FileSystem, fat_type: FatType) {
|
|
assert_eq!(fs.volume_id(), 0x12345678);
|
|
assert_eq!(fs.volume_label(), "Test!");
|
|
assert_eq!(fs.fat_type(), fat_type);
|
|
}
|
|
|
|
#[test]
|
|
fn test_volume_metadata_fat12() {
|
|
call_with_fs(&|fs| test_volume_metadata(fs, FatType::Fat12), FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_volume_metadata_fat16() {
|
|
call_with_fs(&|fs| test_volume_metadata(fs, FatType::Fat16), FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_volume_metadata_fat32() {
|
|
call_with_fs(&|fs| test_volume_metadata(fs, FatType::Fat32), FAT32_IMG)
|
|
}
|
|
|
|
fn test_status_flags(fs: FileSystem) {
|
|
let status_flags = fs.read_status_flags().unwrap();
|
|
assert_eq!(status_flags.dirty(), false);
|
|
assert_eq!(status_flags.io_error(), false);
|
|
}
|
|
|
|
#[test]
|
|
fn test_status_flags_fat12() {
|
|
call_with_fs(&|fs| test_status_flags(fs), FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_status_flags_fat16() {
|
|
call_with_fs(&|fs| test_status_flags(fs), FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_status_flags_fat32() {
|
|
call_with_fs(&|fs| test_status_flags(fs), FAT32_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_stats_fat12() {
|
|
call_with_fs(&|fs| {
|
|
let stats = fs.stats().unwrap();
|
|
assert_eq!(stats.cluster_size(), 512);
|
|
assert_eq!(stats.total_clusters(), 1955); // 1000 * 1024 / 512 = 2000
|
|
assert_eq!(stats.free_clusters(), 1920);
|
|
}, FAT12_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_stats_fat16() {
|
|
call_with_fs(&|fs| {
|
|
let stats = fs.stats().unwrap();
|
|
assert_eq!(stats.cluster_size(), 512);
|
|
assert_eq!(stats.total_clusters(), 4927); // 2500 * 1024 / 512 = 5000
|
|
assert_eq!(stats.free_clusters(), 4892);
|
|
}, FAT16_IMG)
|
|
}
|
|
|
|
#[test]
|
|
fn test_stats_fat32() {
|
|
call_with_fs(&|fs| {
|
|
let stats = fs.stats().unwrap();
|
|
assert_eq!(stats.cluster_size(), 512);
|
|
assert_eq!(stats.total_clusters(), 66922); // 34000 * 1024 / 512 = 68000
|
|
assert_eq!(stats.free_clusters(), 66886);
|
|
}, FAT32_IMG)
|
|
}
|