mod testing;
use std::{io::prelude::*, path::Path};
use liteboxfs::{Connection, CreateOptions, Error, FileBy, FileKind, FileOrigin, Owner};
use testing::{Case, random_string};
use xpct::{be_err, be_ok, equal, expect, match_pattern, pattern};
#[test]
fn link_target_not_found() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
expect!(fs.open("original.txt")).to(be_err()).to(match_pattern(
pattern!(Error::FileNotFound { file: FileOrigin::Litebox { locator, .. }, .. } if locator == &FileBy::from("/original.txt")),
));
let mut file = fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.link("link.txt")).to(be_ok());
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn file_already_exists_at_link() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.create("link.txt", FileKind::Regular, Owner::ROOT)?;
let mut file = fs.open("original.txt")?;
expect!(file.link("link.txt"))
.to(be_err())
.to(match_pattern(
pattern!(Error::FileAlreadyExists { path: FileOrigin::Litebox { locator, .. }, .. } if locator == Path::new("/link.txt")),
));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_has_no_parent_directory() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
let mut file = fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.link("/nonexistent/link.txt"))
.to(be_err())
.to(match_pattern(
pattern!(Error::NoParentDirectory { file: FileOrigin::Litebox { locator, .. }, .. } if locator == &FileBy::from("/nonexistent/link.txt")),
));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_parent_is_not_a_directory() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.create("regular.txt", FileKind::Regular, Owner::ROOT)?;
let mut file = fs.open("original.txt")?;
expect!(file.link("regular.txt/link.txt"))
.to(be_err())
.to(match_pattern(
pattern!(Error::NotADirectory { file: FileOrigin::Litebox { locator, .. }, .. } if locator == &FileBy::from("/regular.txt")),
));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn links_have_same_file_id() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
let original_id = fs.open("original.txt")?.file_id();
let link_id = fs.open("link.txt")?.file_id();
expect!(original_id).to(equal(link_id));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn links_have_same_content() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
let expected = random_string(32, Case::Lower);
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
let mut original_file = fs.open("original.txt")?;
original_file.write_all(expected.as_bytes())?;
drop(original_file);
let mut link_file = fs.open("link.txt")?;
let mut actual = String::new();
link_file.read_to_string(&mut actual)?;
expect!(actual).to(equal(expected));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn links_have_same_content_id() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
let expected = random_string(32, Case::Lower);
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
let mut original_file = fs.open("original.txt")?;
original_file.write_all(expected.as_bytes())?;
drop(original_file);
let original_content_id = fs.open("original.txt")?.content_id()?;
let link_content_id = fs.open("link.txt")?.content_id()?;
expect!(original_content_id).to(equal(link_content_id));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_count_of_file_with_no_links() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("file.txt", FileKind::Regular, Owner::ROOT)?;
expect!(fs.open("file.txt")?.link_count())
.to(be_ok())
.to(equal(1));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_count_increases_with_each_link() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
expect!(fs.open("original.txt")?.link_count())
.to(be_ok())
.to(equal(1));
fs.open("original.txt")?.link("link1.txt")?;
expect!(fs.open("original.txt")?.link_count())
.to(be_ok())
.to(equal(2));
fs.open("original.txt")?.link("link2.txt")?;
expect!(fs.open("original.txt")?.link_count())
.to(be_ok())
.to(equal(3));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_count_is_same_from_any_path() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
let original_count = fs.open("original.txt")?.link_count()?;
let link_count = fs.open("link.txt")?.link_count()?;
expect!(original_count).to(equal(link_count));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_count_decreases_after_delete() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
expect!(fs.open("link.txt")?.link_count())
.to(be_ok())
.to(equal(2));
fs.delete("original.txt")?;
expect!(fs.open("link.txt")?.link_count())
.to(be_ok())
.to(equal(1));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_count_by_file_id() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
let file_id = fs.open("original.txt")?.file_id();
expect!(fs.open(file_id)?.link_count())
.to(be_ok())
.to(equal(2));
liteboxfs::Result::Ok(())
})?;
Ok(())
}
#[test]
fn open_by_id_on_hard_linked_file() -> liteboxfs::Result<()> {
let mut conn = Connection::open_in_memory(&CreateOptions::new())?;
conn.exec(|fs| {
fs.create("original.txt", FileKind::Regular, Owner::ROOT)?;
fs.open("original.txt")?.link("link.txt")?;
let file_id = fs.open("original.txt")?.file_id();
expect!(fs.open(file_id)).to(be_ok());
liteboxfs::Result::Ok(())
})?;
Ok(())
}