#![cfg(feature = "localfs")]
mod common;
use common::{kernel_at, run};
use std::time::{Duration, SystemTime};
#[tokio::test]
async fn touch_on_existing_directory_succeeds_and_advances_mtime() {
let tmp = tempfile::tempdir().unwrap();
let kernel = kernel_at(tmp.path());
let subdir = tmp.path().join("subdir");
std::fs::create_dir(&subdir).unwrap();
let past = SystemTime::now() - Duration::from_secs(3600);
let past_file = std::fs::File::open(&subdir).unwrap();
past_file.set_modified(past).unwrap();
drop(past_file);
let before = std::fs::metadata(&subdir).unwrap().modified().unwrap();
assert_eq!(before, past, "test setup: mtime pin didn't take");
let (out, code) = run(&kernel, "touch subdir").await;
assert_eq!(code, 0, "touch on an existing directory must succeed: {out}");
let after = std::fs::metadata(&subdir).unwrap().modified().unwrap();
assert!(
after > before,
"touch did not advance the directory's mtime: before={before:?} after={after:?}"
);
}
#[tokio::test]
async fn touch_still_creates_a_missing_file() {
let tmp = tempfile::tempdir().unwrap();
let kernel = kernel_at(tmp.path());
let (out, code) = run(&kernel, "touch newfile.txt").await;
assert_eq!(code, 0, "touch on a missing path must create it: {out}");
assert!(tmp.path().join("newfile.txt").is_file());
}
#[tokio::test]
async fn touch_still_updates_an_existing_file() {
let tmp = tempfile::tempdir().unwrap();
let kernel = kernel_at(tmp.path());
let file = tmp.path().join("existing.txt");
std::fs::write(&file, b"content").unwrap();
let past = SystemTime::now() - Duration::from_secs(3600);
let past_file = std::fs::File::open(&file).unwrap();
past_file.set_modified(past).unwrap();
drop(past_file);
let before = std::fs::metadata(&file).unwrap().modified().unwrap();
let (out, code) = run(&kernel, "touch existing.txt").await;
assert_eq!(code, 0, "touch on an existing file must succeed: {out}");
let after = std::fs::metadata(&file).unwrap().modified().unwrap();
assert!(
after > before,
"touch did not advance the file's mtime: before={before:?} after={after:?}"
);
assert_eq!(std::fs::read(&file).unwrap(), b"content");
}
#[cfg(unix)]
#[tokio::test]
async fn touch_still_updates_a_write_only_file() {
use std::os::unix::fs::PermissionsExt;
let tmp = tempfile::tempdir().unwrap();
let kernel = kernel_at(tmp.path());
let file = tmp.path().join("wonly.txt");
std::fs::write(&file, b"").unwrap();
let past = SystemTime::now() - Duration::from_secs(3600);
let past_file = std::fs::File::open(&file).unwrap();
past_file.set_modified(past).unwrap();
drop(past_file);
let before = std::fs::metadata(&file).unwrap().modified().unwrap();
assert_eq!(before, past, "test setup: mtime pin didn't take");
std::fs::set_permissions(&file, std::fs::Permissions::from_mode(0o200)).unwrap();
let (out, code) = run(&kernel, "touch wonly.txt").await;
assert_eq!(code, 0, "touch on a write-only file must succeed: {out}");
let after = std::fs::metadata(&file).unwrap().modified().unwrap();
assert!(
after > before,
"touch did not advance the write-only file's mtime: before={before:?} after={after:?}"
);
}