#![cfg(all(feature = "fs", target_os = "linux"))]
use xpct::{be_ok, equal, expect, match_pattern, pattern};
use crate::{
Connection, Error,
file_metadata::{FileKind, Owner},
settings::Settings,
};
fn open() -> crate::Result<Connection> {
Connection::open_for_testing(&Settings::default())
}
#[test]
fn creates_a_link() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.link("/b.txt")).to(be_ok());
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_count_increases() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.link_count()).to(be_ok()).to(equal(1u32));
file.link("/b.txt")?;
expect!(file.link_count()).to(be_ok()).to(equal(2u32));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn file_is_accessible_at_link_path() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
file.link("/b.txt")?;
drop(file);
expect!(fs.open("/b.txt")).to(be_ok());
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn link_shares_file_id() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut orig = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
orig.link("/b.txt")?;
let orig_id = orig.file_id();
drop(orig);
let linked = fs.open("/b.txt")?;
expect!(linked.file_id()).to(equal(orig_id));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn fails_for_directories() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut dir = fs.create("/a", FileKind::Dir, Owner::ROOT)?;
expect!(dir.link("/b")).to(match_pattern(pattern!(Err(Error::NotARegularFile { .. }))));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn fails_if_link_already_exists() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
drop(file);
let mut file = fs.open("/a.txt")?;
expect!(file.link("/a.txt")).to(match_pattern(pattern!(Err(
Error::FileAlreadyExists { .. }
))));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn fails_if_parent_does_not_exist() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.link("/nonexistent/b.txt")).to(match_pattern(pattern!(Err(
Error::NoParentDirectory { .. }
))));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn temp_file_can_be_linked() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut tmp = fs.create_temp(Owner::ROOT)?;
tmp.link("/permanent.txt")?;
crate::Result::Ok(())
})?;
conn.exec(|fs| {
expect!(fs.open("/permanent.txt")).to(be_ok());
crate::Result::Ok(())
})?;
Ok(())
}