Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
3 changes: 3 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions tests/rust-integration-tests/integration_test/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use crate::tests::hooks::get_hooks_tests;
use crate::tests::hostname::get_hostname_test;
use crate::tests::lifecycle::{ContainerCreate, ContainerLifecycle};
use crate::tests::linux_ns_itype::get_ns_itype_tests;
use crate::tests::mounts_recursive::get_mounts_recursive_test;
use crate::tests::pidfile::get_pidfile_test;
use crate::tests::readonly_paths::get_ro_paths_test;
use crate::tests::seccomp_notify::get_seccomp_notify_test;
Expand Down Expand Up @@ -90,6 +91,7 @@ fn main() -> Result<()> {
let seccomp_notify = get_seccomp_notify_test();
let ro_paths = get_ro_paths_test();
let hostname = get_hostname_test();
let mounts_recursive = get_mounts_recursive_test();

tm.add_test_group(Box::new(cl));
tm.add_test_group(Box::new(cc));
Expand All @@ -106,6 +108,7 @@ fn main() -> Result<()> {
tm.add_test_group(Box::new(seccomp_notify));
tm.add_test_group(Box::new(ro_paths));
tm.add_test_group(Box::new(hostname));
tm.add_test_group(Box::new(mounts_recursive));

tm.add_cleanup(Box::new(cgroups::cleanup_v1));
tm.add_cleanup(Box::new(cgroups::cleanup_v2));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ fn create_spec(hostname: &str) -> Spec {
)
.process(
ProcessBuilder::default()
.args(vec!["runtimetest".to_string()])
.args(vec!["runtimetest".to_string(), "set_host_name".to_string()])
.build()
.expect("error in creating process config"),
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ pub mod hooks;
pub mod hostname;
pub mod lifecycle;
pub mod linux_ns_itype;
pub mod mounts_recursive;
pub mod pidfile;
pub mod readonly_paths;
pub mod seccomp_notify;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
use crate::utils::test_inside_container;
use nix::mount::{mount, umount, MsFlags};
use oci_spec::runtime::{get_default_mounts, Mount, ProcessBuilder, Spec, SpecBuilder};
use std::fs;
use std::path::{Path, PathBuf};
use std::str::FromStr;
use test_framework::{Test, TestGroup, TestResult};

fn get_spec(added_mounts: Vec<Mount>) -> Spec {
let mut mounts = get_default_mounts();
for mount in added_mounts {
mounts.push(mount);
}

SpecBuilder::default()
.mounts(mounts)
.process(
ProcessBuilder::default()
.args(vec![
"runtimetest".to_string(),
"mounts_recursive".to_string(),
])
.build()
.unwrap(),
)
.build()
.unwrap()
}

fn setup_mount(mount_dir: &Path, sub_mount_dir: &Path) {
fs::create_dir(mount_dir).unwrap();
mount::<Path, Path, str, str>(None, mount_dir, Some("tmpfs"), MsFlags::empty(), None).unwrap();
fs::create_dir(sub_mount_dir).unwrap();
mount::<Path, Path, str, str>(None, sub_mount_dir, Some("tmpfs"), MsFlags::empty(), None)
.unwrap();
}

fn clean_mount(mount_dir: &Path, sub_mount_dir: &Path) {
umount(sub_mount_dir).unwrap();
umount(mount_dir).unwrap();
fs::remove_dir_all(mount_dir).unwrap();
}

fn check_recursive_readonly() -> TestResult {
let rro_test_base_dir = PathBuf::from_str("/tmp").unwrap();
let rro_dir_path = rro_test_base_dir.join("rro_dir");
let rro_subdir_path = rro_dir_path.join("rro_subdir");
let mount_dest_path = PathBuf::from_str("/mnt").unwrap();

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

let result = test_inside_container(spec, &|_| {
setup_mount(&rro_dir_path, &rro_subdir_path);
Ok(())
});

clean_mount(&rro_dir_path, &rro_subdir_path);

result
}

pub fn get_mounts_recursive_test() -> TestGroup {
let rro_test = Test::new("rro_test", Box::new(check_recursive_readonly));
let mut tg = TestGroup::new("mounts_recursive");
tg.add(vec![Box::new(rro_test)]);
tg
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@ fn get_spec(readonly_paths: Vec<String>) -> Spec {
)
.process(
ProcessBuilder::default()
.args(vec!["runtimetest".to_string()])
.args(vec![
"runtimetest".to_string(),
"readonly_paths".to_string(),
])
.build()
.unwrap(),
)
Expand Down
10 changes: 10 additions & 0 deletions tests/rust-integration-tests/runtimetest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,13 @@ edition = "2021"
[dependencies]
oci-spec = { version = "0.5.8", features = ["runtime"] }
nix = "0.25.0"
anyhow = "1.0"

[dependencies.clap]
version = "3.2.23"
default-features = false
features = ["std", "suggestions", "derive", "cargo"]

[dependencies.clap_derive]
version = "4.0.21"
default-features = true
29 changes: 27 additions & 2 deletions tests/rust-integration-tests/runtimetest/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,29 @@
mod tests;
mod utils;

use clap::Parser;
use oci_spec::runtime::Spec;
use std::path::PathBuf;

#[derive(Parser, Debug)]
#[clap(version = "0.0.1", author = "youki team")]
struct Opts {
#[clap(subcommand)]
command: SubCommand,
}

#[derive(Parser, Debug)]
enum SubCommand {
#[clap(name = "readonly_paths")]
ReadonlyPaths,

#[clap(name = "set_host_name")]
SetHostName,

#[clap(name = "mounts_recursive")]
MountsRecursive,
}

const SPEC_PATH: &str = "/config.json";

fn get_spec() -> Spec {
Expand All @@ -18,7 +38,12 @@ fn get_spec() -> Spec {
}

fn main() {
let opts: Opts = Opts::parse();
let spec = get_spec();
tests::validate_readonly_paths(&spec);
tests::validate_hostname(&spec);

match opts.command {
SubCommand::ReadonlyPaths => tests::validate_readonly_paths(&spec),
SubCommand::SetHostName => tests::validate_hostname(&spec),
SubCommand::MountsRecursive => tests::validate_mounts_recursive(&spec),
};
}
53 changes: 52 additions & 1 deletion tests/rust-integration-tests/runtimetest/src/tests.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::utils::{test_read_access, test_write_access};
use crate::utils::{self, test_read_access, test_write_access};
use anyhow::{bail, Result};
use nix::errno::Errno;
use oci_spec::runtime::Spec;
use std::fs::read_dir;
use std::path::Path;

pub fn validate_readonly_paths(spec: &Spec) {
let linux = spec.linux().as_ref().unwrap();
Expand Down Expand Up @@ -76,3 +79,51 @@ pub fn validate_hostname(spec: &Spec) {
}
}
}

/// Run argument test recursively for files after base_dir
fn do_test_mounts_recursive(base_dir: &Path, test_fn: &dyn Fn(&Path) -> Result<()>) -> Result<()> {
let rd = read_dir(base_dir).unwrap();
for d in rd {
let d = d.unwrap();
let f_type = d.file_type().unwrap();
if f_type.is_dir() {
do_test_mounts_recursive(d.path().as_path(), test_fn)?;
}

if f_type.is_file() {
test_fn(d.path().as_path())?;
}
}

Ok(())
}

pub fn validate_mounts_recursive(spec: &Spec) {
if let Some(mounts) = spec.mounts() {
for m in mounts {
if let Some(options) = m.options() {
for o in options {
match o.as_str() {
"rro" => {
if let Err(e) =
do_test_mounts_recursive(m.destination(), &|test_file_path| {
if utils::test_write_access(test_file_path.to_str().unwrap())
.is_ok()
{
// Return Err if writeable
bail!("Unexpectedl writeable");
}
Ok(())
})
{
eprintln!("mounts_recursive rro error: {}", e);
}
}
"rrw" => { /* TODO... */ }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Otherwise test looks fine, so please add other tests in this PR as well 👍

_ => {}
}
}
}
}
}
}