use core::convert::TryInto;
use generic_array::typenum::consts;
use crate::{
fs::{
Attribute,
File,
Filesystem,
},
io::{
Error,
Result,
Read,
SeekFrom,
},
driver,
};
ram_storage!(
name=OtherRamStorage,
backend=OtherRam,
trait=driver::Storage,
erase_value=0xff,
read_size=1,
write_size=32,
cache_size_ty=consts::U32,
block_size=256,
block_count=512,
lookaheadwords_size_ty=consts::U1,
filename_max_plus_one_ty=consts::U256,
path_max_plus_one_ty=consts::U256,
result=Result,
);
ram_storage!(
name=RamStorage,
backend=Ram,
trait=driver::Storage,
erase_value=0xff,
read_size=20*5,
write_size=20*7,
cache_size_ty=consts::U700,
block_size=20*35,
block_count=32,
lookaheadwords_size_ty=consts::U16,
filename_max_plus_one_ty=consts::U256,
path_max_plus_one_ty=consts::U256,
result=Result,
);
#[test]
fn version() {
assert_eq!(crate::version().format, (2, 0));
assert_eq!(crate::version().backend, (2, 2));
}
#[test]
fn format() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
let mut alloc = Filesystem::allocate();
assert_eq!(
Filesystem::mount(&mut alloc, &mut storage)
.map(drop).unwrap_err(),
Error::Corruption
);
assert!(Filesystem::format(&mut storage).is_ok());
let fs = Filesystem::mount(&mut alloc, &mut storage).unwrap();
drop(fs);
drop(storage);
}
#[test]
fn borrow_fs_allocation() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
let mut alloc_fs = Filesystem::allocate();
Filesystem::format(&mut storage).unwrap();
let _fs = Filesystem::mount(&mut alloc_fs, &mut storage).unwrap();
let fs = Filesystem::mount(&mut alloc_fs, &mut storage).unwrap();
fs.create_file_and_then(b"data.bin\0".try_into().unwrap(), |_| { Ok(()) }).unwrap();
fs.create_file_and_then(b"data.bin\0".try_into().unwrap(), |_| { Ok(()) }).unwrap();
}
#[test]
fn borrow_fs_allocation2() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
let mut alloc_fs = Filesystem::allocate();
Filesystem::format(&mut storage).unwrap();
let _fs = Filesystem::mount(&mut alloc_fs, &mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
fs.create_file_and_then(b"data.bin\0".try_into().unwrap(), |_| { Ok(()) }).unwrap();
fs.create_file_and_then(b"data.bin\0".try_into().unwrap(), |_| { Ok(()) }).unwrap();
Ok(())
}).unwrap();
}
#[test]
fn borrow_fs_allocation3() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |_| {
Ok(())
}).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
fs.create_file_and_then(b"data.bin\0".try_into().unwrap(), |_| { Ok(()) }).unwrap();
fs.create_file_and_then(b"data.bin\0".try_into().unwrap(), |_| { Ok(()) }).unwrap();
Ok(())
}).unwrap();
}
#[test]
fn test_fs_with() -> Result<()> {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
assert_eq!(fs.total_blocks(), 512);
assert_eq!(fs.total_space(), 256*512);
assert_eq!(fs.available_blocks()?, 512 - 2);
assert_eq!(fs.available_space()?, 130_560);
fs.create_dir(b"/tmp\0".try_into().unwrap())?; assert_eq!(fs.available_blocks()?, 512 - 4);
fs.create_dir(b"/mnt\0".try_into().unwrap())?; assert_eq!(fs.available_blocks()?, 512 - 6);
fs.rename(
b"tmp\0".try_into().unwrap(),
b"mnt/tmp\0".try_into().unwrap())?; assert_eq!(fs.available_blocks()?, 512 - 6);
fs.remove(b"/mnt/tmp\0".try_into().unwrap())?; assert_eq!(fs.available_blocks()?, 512 - 4);
fs.remove(b"/mnt\0".try_into().unwrap())?; assert_eq!(fs.available_blocks()?, 512 - 2);
fs.create_file_and_then(b"/test_with.txt\0".try_into().unwrap(), |file| {
assert!(file.write(&[0u8, 1, 2])? == 3);
Ok(())
}).unwrap();
let mut buf = [0u8; 3];
fs.open_file_and_then(b"/test_with.txt\0".try_into().unwrap(), |file| {
assert_eq!(fs.available_blocks()?, 510);
assert!(file.read_exact(&mut buf).is_ok());
assert_eq!(&buf, &[0, 1, 2]);
Ok(())
}).unwrap();
assert_eq!(fs.available_blocks()?, 512 - 2);
Ok(())
})
}
#[test]
fn test_create() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
assert_eq!(fs.total_blocks(), 512);
assert_eq!(fs.total_space(), 256*512);
assert_eq!(fs.available_blocks().unwrap(), 512 - 2);
assert_eq!(fs.available_space().unwrap(), 130_560);
assert!(!crate::path::PathBuf::from(b"/test_open.txt").exists(&fs));
assert_eq!(
File::open_and_then(fs, b"/test_open.txt\0".try_into().unwrap(), |_| { Ok(()) })
.map(drop)
.unwrap_err(), Error::NoSuchEntry
);
assert!(!crate::path::PathBuf::from(b"/test_open.txt").exists(&fs));
fs.create_dir(b"/tmp\0".try_into().unwrap()).unwrap();
assert_eq!(fs.available_blocks().unwrap(), 512 - 2 - 2);
assert!(!crate::path::PathBuf::from(b"/tmp/test_open.txt").exists(&fs));
fs.create_file_and_then(b"/tmp/test_open.txt\0".try_into().unwrap(), |file| {
assert!(file.write(&[0u8, 1, 2]).unwrap() == 3);
file.sync()?;
assert_eq!(fs.available_blocks()?, 512 - 2 - 2);
Ok(())
})?;
assert!(crate::path::PathBuf::from(b"/tmp/test_open.txt").exists(&fs));
assert_eq!(fs.remove(b"/tmp\0".try_into().unwrap()).unwrap_err(), Error::DirNotEmpty);
let metadata = fs.metadata(b"/tmp\0".try_into().unwrap())?;
assert!(metadata.is_dir());
assert_eq!(metadata.len(), 0);
fs.rename(b"/tmp/test_open.txt\0".try_into().unwrap(), b"moved.txt\0".try_into().unwrap())?;
assert_eq!(fs.available_blocks().unwrap(), 512 - 2 - 2);
let metadata = fs.metadata(b"/moved.txt\0".try_into().unwrap())?;
assert!(metadata.is_file());
assert_eq!(metadata.len(), 3);
fs.remove(b"/tmp/../tmp/.\0".try_into().unwrap()).unwrap();
assert_eq!(fs.available_blocks().unwrap(), 512 - 2);
fs.open_file_and_then(b"/moved.txt\0".try_into().unwrap(), |file| {
assert!(file.len().unwrap() == 3);
let mut contents: [u8; 3] = Default::default();
assert!(file.read(&mut contents).unwrap() == 3);
assert_eq!(contents, [0u8, 1, 2]);
file.seek(SeekFrom::Start(0))?;
let mut contents_vec = heapless::Vec::<u8, 3>::new();
assert!(file.read_to_end(&mut contents_vec).unwrap() == 3);
Ok(())
})?;
Ok(())
}).unwrap();
}
#[test]
fn test_unbind() {
let mut backend = Ram::default();
{
let mut storage = RamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
fs.create_file_and_then(b"test_unbind.txt\0".try_into().unwrap(), |file| {
file.write(b"hello world")?;
assert_eq!(file.len()?, 11);
Ok(())
})
}).unwrap();
}
let mut storage = RamStorage::new(&mut backend);
Filesystem::mount_and_then(&mut storage, |fs| {
let contents: heapless::Vec<_, 37> = fs.read(b"test_unbind.txt\0".try_into().unwrap())?;
assert_eq!(contents, b"hello world");
Ok(())
}).unwrap();
}
#[test]
fn test_seek() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
fs.write(b"test_seek.txt\0".try_into().unwrap(), b"hello world")?;
fs.open_file_and_then(b"test_seek.txt\0".try_into().unwrap(), |file| {
file.seek(SeekFrom::End(-5))?;
let mut buf = [0u8; 5];
assert_eq!(file.len()?, 11);
file.read(&mut buf)?;
assert_eq!(&buf, b"world");
Ok(())
})
}).unwrap();
}
#[test]
fn test_file_set_len() {
let mut backend = OtherRam::default();
let mut storage = OtherRamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
fs.create_file_and_then(b"test_set_len.txt\0".try_into().unwrap(), |file| {
file.write(b"hello littlefs")?;
assert_eq!(file.len()?, 14);
file.set_len(10).unwrap();
assert_eq!(file.len()?, 10);
assert_eq!(file.seek(SeekFrom::Current(0))?, 14);
Ok(())
})
}).unwrap();
}
#[test]
fn test_fancy_open() {
let mut backend = Ram::default();
let mut storage = RamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
let mut buf = [0u8; 5];
Filesystem::mount_and_then(&mut storage, |fs| {
fs.open_file_with_options_and_then(
|options| options.read(true).write(true).create_new(true),
b"test_fancy_open.txt\0".try_into().unwrap(),
|file| {
file.write(b"hello world")?;
assert_eq!(file.len()?, 11);
file.seek(SeekFrom::Start(6))?;
file.read(&mut buf)
}
)
}).unwrap();
assert_eq!(&buf, b"world");
}
#[test]
fn attributes() {
let mut backend = Ram::default();
let mut storage = RamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
let filename = b"some.file\0".try_into().unwrap();
fs.write(filename, &[])?;
assert!(fs.attribute(filename, 37)?.is_none());
let mut attribute = Attribute::new(37);
attribute.set_data(b"top secret");
fs.set_attribute(filename, &attribute).unwrap();
assert_eq!(
b"top secret",
fs.attribute(filename, 37)?.unwrap().data()
);
fs.remove_attribute(filename, 37)?;
assert!(fs.attribute(filename, 37)?.is_none());
let tmp_dir = b"/tmp\0".try_into().unwrap();
fs.create_dir(tmp_dir)?;
attribute.set_data(b"temporary directory");
fs.set_attribute(tmp_dir, &attribute)?;
assert_eq!(
b"temporary directory",
fs.attribute(tmp_dir, 37)?.unwrap().data()
);
fs.remove_attribute(tmp_dir, 37)?;
assert!(fs.attribute(tmp_dir, 37)?.is_none());
Ok(())
}).unwrap();
}
#[test]
fn test_iter_dirs() {
let mut backend = Ram::default();
let mut storage = RamStorage::new(&mut backend);
Filesystem::format(&mut storage).unwrap();
Filesystem::mount_and_then(&mut storage, |fs| {
fs.create_dir(b"/tmp\0".try_into()?)?;
fs.create_file_and_then(b"/tmp/file.a\0".try_into()?, |file| {
file.set_len(37)?;
fs.create_file_and_then(b"/tmp/file.b\0".try_into()?, |file| {
file.set_len(42)
})
})?;
fs.read_dir_and_then(b"/tmp\0".try_into()?, |dir| {
let mut found_files: usize = 0;
let mut sizes = [0usize; 4];
for (i, entry) in dir.enumerate() {
let entry = entry?;
sizes[i] = entry.metadata().len();
found_files += 1;
}
assert_eq!(sizes, [0, 0, 37, 42]);
assert_eq!(found_files, 4);
Ok(())
})
}).unwrap();
}