Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat add rdiratime/rnodiratime recursive mount test #1616

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -243,16 +243,67 @@ fn check_recursive_noexec() -> TestResult {
result
}

/// rdiratime If set in attr_clr, removes the restriction that prevented updating access time for directories.
fn check_recursive_rdiratime() -> TestResult {
let rdiratime_base_dir = PathBuf::from_str("/tmp/rdiratime").unwrap();
let mount_dest_path = PathBuf::from_str("/rdiratime").unwrap();
fs::create_dir(rdiratime_base_dir.clone()).unwrap();

let mount_options = vec!["rbind".to_string(), "rdiratime".to_string()];
let mut mount_spec = Mount::default();
mount_spec
.set_destination(mount_dest_path)
.set_typ(None)
.set_source(Some(rdiratime_base_dir.clone()))
.set_options(Some(mount_options));
let spec = get_spec(
vec![mount_spec],
vec!["runtimetest".to_string(), "mounts_recursive".to_string()],
);

let result = test_inside_container(spec, &|_| Ok(()));

fs::remove_dir(rdiratime_base_dir).unwrap();
result
}

/// If set in attr_set, prevents updating access time for directories on this mount
fn check_recursive_rnodiratime() -> TestResult {
let rnodiratime_base_dir = PathBuf::from_str("/tmp/rnodiratime").unwrap();
let mount_dest_path = PathBuf::from_str("/rnodiratime").unwrap();
fs::create_dir(rnodiratime_base_dir.clone()).unwrap();

let mount_options = vec!["rbind".to_string(), "rnodiratime".to_string()];
let mut mount_spec = Mount::default();
mount_spec
.set_destination(mount_dest_path)
.set_typ(None)
.set_source(Some(rnodiratime_base_dir.clone()))
.set_options(Some(mount_options));
let spec = get_spec(
vec![mount_spec],
vec!["runtimetest".to_string(), "mounts_recursive".to_string()],
);

let result = test_inside_container(spec, &|_| Ok(()));
fs::remove_dir(rnodiratime_base_dir).unwrap();
result
}

pub fn get_mounts_recursive_test() -> TestGroup {
let rro_test = Test::new("rro_test", Box::new(check_recursive_readonly));
let rnosuid_test = Test::new("rnosuid_test", Box::new(check_recursive_nosuid));
let rnoexec_test = Test::new("rnoexec_test", Box::new(check_recursive_noexec));
let rnodiratime_test = Test::new("rnodiratime_test", Box::new(check_recursive_rnodiratime));
let rdiratime_test = Test::new("rdiratime_test", Box::new(check_recursive_rdiratime));

let mut tg = TestGroup::new("mounts_recursive");
tg.add(vec![
Box::new(rro_test),
Box::new(rnosuid_test),
Box::new(rnoexec_test),
Box::new(rdiratime_test),
Box::new(rnodiratime_test),
]);

tg
Expand Down
18 changes: 18 additions & 0 deletions tests/rust-integration-tests/runtimetest/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,24 @@ pub fn validate_mounts_recursive(spec: &Spec) {
eprintln!("error in testing rnoexec recursive mounting: {e}");
}
}
"rdiratime" => {
println!("test_dir_update_access_time: {:?}", mount);
let rest = utils::test_dir_update_access_time(
mount.destination().to_str().unwrap(),
);
if let Err(e) = rest {
eprintln!("error in testing rdiratime recursive mounting: {e}");
}
}
"rnodiratime" => {
println!("test_dir_not_update_access_time: {:?}", mount);
let rest = utils::test_dir_not_update_access_time(
mount.destination().to_str().unwrap(),
);
if let Err(e) = rest {
eprintln!("error in testing rnodiratime recursive mounting: {e}");
}
}
_ => {}
}
}
Expand Down
68 changes: 65 additions & 3 deletions tests/rust-integration-tests/runtimetest/src/utils.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use std::path::PathBuf;
use std::process::Command;

use nix::sys::stat::stat;
use nix::sys::stat::SFlag;
use std::fs;
use std::path::PathBuf;
use std::process::Command;

fn test_file_read_access(path: &str) -> Result<(), std::io::Error> {
let _ = std::fs::OpenOptions::new()
Expand Down Expand Up @@ -85,3 +85,65 @@ pub fn test_file_executable(path: &str) -> Result<(), std::io::Error> {
format!("{path:?} is directory, so cannot execute"),
))
}

pub fn test_dir_update_access_time(path: &str) -> Result<(), std::io::Error> {
println!("test_dir_update_access_time path: {:?}", path);
let metadata = fs::metadata(PathBuf::from(path))?;
let rest = metadata.accessed();
let first_access_time = rest.unwrap();
println!(
"{:?} dir first access time is {:?}",
path, first_access_time
);
// execute ls command to update access time
Command::new("ls")
.arg(path)
.output()
.expect("execute ls command error");
// second get access time
let metadata = fs::metadata(PathBuf::from(path))?;
let rest = metadata.accessed();
let second_access_time = rest.unwrap();
println!(
"{:?} dir second access time is {:?}",
path, second_access_time
);
if first_access_time == second_access_time {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("cannot update access time for path {:?}", path),
));
}
Ok(())
}

pub fn test_dir_not_update_access_time(path: &str) -> Result<(), std::io::Error> {
println!("test_dir_not_update_access_time path: {:?}", path);
let metadata = fs::metadata(PathBuf::from(path))?;
let rest = metadata.accessed();
let first_access_time = rest.unwrap();
println!(
"{:?} dir first access time is {:?}",
path, first_access_time
);
// execute ls command to update access time
Command::new("ls")
.arg(path)
.output()
.expect("execute ls command error");
// second get access time
let metadata = fs::metadata(PathBuf::from(path))?;
let rest = metadata.accessed();
let second_access_time = rest.unwrap();
println!(
"{:?} dir second access time is {:?}",
path, second_access_time
);
if first_access_time != second_access_time {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
format!("cannot update access time for path {:?}", path),
));
}
Ok(())
}