#![cfg(all(feature = "fs", target_os = "linux"))]
use std::time::SystemTime;
use xpct::{be_ge, be_le, be_ok, be_some, equal, expect, match_pattern, pattern};
use crate::{
Connection, Error,
file_metadata::{FileKind, FileMode, Gid, Owner, Uid},
settings::Settings,
};
fn open() -> crate::Result<Connection> {
Connection::open_for_testing(&Settings::default())
}
#[test]
fn creates_a_regular_file() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let file = fs.create_temp(Owner::ROOT)?;
expect!(file.kind()).to(equal(&FileKind::Regular));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn has_no_path() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create_temp(Owner::ROOT)?;
expect!(file.link_count()).to(be_ok()).to(equal(0u32));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn owner_is_set() -> crate::Result<()> {
let mut conn = open()?;
let owner = Owner {
user: Uid::from(1000),
group: Gid::from(1001),
};
conn.exec(|fs| {
let mut file = fs.create_temp(owner)?;
let metadata = file.metadata()?;
expect!(metadata.user()).to(equal(Uid::from(1000)));
expect!(metadata.group()).to(equal(Gid::from(1001)));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn mode_respects_default_umask() -> crate::Result<()> {
let mut conn = open()?;
let expected = FileMode::OWNER_R
| FileMode::OWNER_W
| FileMode::GROUP_R
| FileMode::GROUP_W
| FileMode::OTHER_R;
conn.exec(|fs| {
let mut file = fs.create_temp(Owner::ROOT)?;
let metadata = file.metadata()?;
expect!(metadata.mode()).to(equal(expected));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn mode_respects_custom_umask() -> crate::Result<()> {
let mut conn = open()?;
let expected = FileMode::OWNER_R | FileMode::OWNER_W | FileMode::GROUP_R | FileMode::OTHER_R;
conn.exec(|fs| {
fs.set_umask(FileMode::GROUP_W | FileMode::OTHER_W);
let mut file = fs.create_temp(Owner::ROOT)?;
let metadata = file.metadata()?;
expect!(metadata.mode()).to(equal(expected));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn timestamps_are_set_to_now() -> crate::Result<()> {
let mut conn = open()?;
let before = SystemTime::now();
conn.exec(|fs| {
let mut file = fs.create_temp(Owner::ROOT)?;
let metadata = file.metadata()?;
let after = SystemTime::now();
expect!(metadata.accessed()).to(be_ge(before));
expect!(metadata.accessed()).to(be_le(after));
expect!(metadata.modified()).to(be_ge(before));
expect!(metadata.modified()).to(be_le(after));
expect!(metadata.changed()).to(be_ge(before));
expect!(metadata.changed()).to(be_le(after));
expect!(metadata.created()).to(be_some()).to(be_ge(before));
expect!(metadata.created()).to(be_some()).to(be_le(after));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn deleted_when_dropped() -> crate::Result<()> {
let mut conn = open()?;
let file_id = conn.exec(|fs| {
let file = fs.create_temp(Owner::ROOT)?;
crate::Result::Ok(file.file_id())
})?;
conn.exec(|fs| {
expect!(fs.open(file_id)).to(match_pattern(pattern!(Err(Error::FileNotFound { .. }))));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn multiple_calls_return_distinct_file_ids() -> crate::Result<()> {
let mut conn = open()?;
let file_id_1 = conn.exec(|fs| crate::Result::Ok(fs.create_temp(Owner::ROOT)?.file_id()))?;
let file_id_2 = conn.exec(|fs| crate::Result::Ok(fs.create_temp(Owner::ROOT)?.file_id()))?;
expect!(file_id_1).to_not(equal(file_id_2));
Ok(())
}