#![cfg(all(feature = "fs", target_os = "linux"))]
use std::time::{Duration, SystemTime};
use xpct::{approx_eq_time, be_ok, be_some, equal, expect};
use crate::{
Connection,
file_metadata::{FileKind, Owner},
settings::Settings,
};
fn open() -> crate::Result<Connection> {
Connection::open_for_testing(&Settings::default())
}
#[test]
fn touch_at_sets_atime_mtime_and_ctime_to_given_time() -> crate::Result<()> {
let mut conn = open()?;
let time = SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000);
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.touch_at(time)).to(be_ok());
let metadata = file.metadata()?;
expect!(metadata.accessed()).to(equal(time));
expect!(metadata.modified()).to(equal(time));
expect!(metadata.changed()).to(equal(time));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn touch_at_does_not_change_btime() -> crate::Result<()> {
let mut conn = open()?;
let touch_time = SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000);
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
let original_btime = file.metadata()?.created();
expect!(file.touch_at(touch_time)).to(be_ok());
expect!(file.metadata()?.created()).to(equal(original_btime));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn touch_at_overwrites_existing_timestamps() -> crate::Result<()> {
let mut conn = open()?;
let earlier = SystemTime::UNIX_EPOCH + Duration::from_secs(1_000_000_000);
let later = SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000);
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
file.touch_at(later)?;
expect!(file.touch_at(earlier)).to(be_ok());
let metadata = file.metadata()?;
expect!(metadata.accessed()).to(equal(earlier));
expect!(metadata.modified()).to(equal(earlier));
expect!(metadata.changed()).to(equal(earlier));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn touch_sets_atime_mtime_and_ctime_to_now() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
expect!(file.touch()).to(be_ok());
let now = SystemTime::now();
let metadata = file.metadata()?;
expect!(metadata.accessed()).to(approx_eq_time(now, Duration::from_secs(1)));
expect!(metadata.modified()).to(approx_eq_time(now, Duration::from_secs(1)));
expect!(metadata.changed()).to(approx_eq_time(now, Duration::from_secs(1)));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn touch_does_not_change_btime() -> crate::Result<()> {
let mut conn = open()?;
conn.exec(|fs| {
let mut file = fs.create("/a.txt", FileKind::Regular, Owner::ROOT)?;
let original_btime = file.metadata()?.created();
expect!(original_btime).to(be_some());
expect!(file.touch()).to(be_ok());
expect!(file.metadata()?.created()).to(equal(original_btime));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn touch_at_works_on_directory() -> crate::Result<()> {
let mut conn = open()?;
let time = SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000);
conn.exec(|fs| {
let mut dir = fs.create("/dir", FileKind::Dir, Owner::ROOT)?;
expect!(dir.touch_at(time)).to(be_ok());
let metadata = dir.metadata()?;
expect!(metadata.accessed()).to(equal(time));
expect!(metadata.modified()).to(equal(time));
expect!(metadata.changed()).to(equal(time));
crate::Result::Ok(())
})?;
Ok(())
}
#[test]
fn touch_at_works_on_symlink() -> crate::Result<()> {
let mut conn = open()?;
let time = SystemTime::UNIX_EPOCH + Duration::from_secs(1_700_000_000);
conn.exec(|fs| {
let mut symlink = fs.create(
"/link",
FileKind::Symlink {
target: "/target".into(),
},
Owner::ROOT,
)?;
expect!(symlink.touch_at(time)).to(be_ok());
let metadata = symlink.metadata()?;
expect!(metadata.accessed()).to(equal(time));
expect!(metadata.modified()).to(equal(time));
expect!(metadata.changed()).to(equal(time));
crate::Result::Ok(())
})?;
Ok(())
}