Skip to content

Commit

Permalink
tests: add integration tests for OCI seccomp and devices support.
Browse files Browse the repository at this point in the history
Signed-off-by: Ismo Puustinen <[email protected]>
  • Loading branch information
ipuustin committed Aug 2, 2023
1 parent 1209bdb commit c89099f
Show file tree
Hide file tree
Showing 6 changed files with 422 additions and 0 deletions.
20 changes: 20 additions & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ members = [
"crates/containerd-shim-wasmedge",
"crates/containerd-shim-wasmtime",
"test/wasi-modules-for-testing",
"test/oci-tests",
]

[workspace.package]
Expand Down
31 changes: 31 additions & 0 deletions test/oci-tests/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[package]
name = "oci-tests"
version = "0.1.0"
edition = "2021"

[dependencies]
anyhow = { workspace = true }
chrono = { workspace = true }
containerd-shim-wasm = { path = "../../crates/containerd-shim-wasm" }
containerd-shim-wasmedge = { path = "../../crates/containerd-shim-wasmedge" }
containerd-shim-wasmtime = { path = "../../crates/containerd-shim-wasmtime" }
libc = { workspace = true }
oci-spec = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tempfile = "3.0"
wasmedge-sdk = { version = "0.10.1", features = [ "standalone", "static" ] }
wasmtime = { version = "11.0", default-features = false, features = [
'cache',
'wat',
'jitdump',
'parallel-compilation',
'cranelift',
'pooling-allocator',
'vtune',
]}

[dev-dependencies]
tempfile = "3.0"
pretty_assertions = "1"
serial_test = "*"
100 changes: 100 additions & 0 deletions test/oci-tests/tests/common/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use std::fs::{create_dir, read_to_string, File, OpenOptions};
use std::io::prelude::*;
use std::os::unix::fs::OpenOptionsExt;
use std::path::{Path, PathBuf};
use std::sync::mpsc::channel;
use std::time::Duration;

use libc::SIGKILL;
use oci_spec::runtime::Spec;
use serde::{Deserialize, Serialize};
use tempfile::tempdir;

use containerd_shim_wasm::sandbox::instance::Wait;
use containerd_shim_wasm::sandbox::{EngineGetter, Error, Instance, InstanceConfig};

#[derive(Serialize, Deserialize)]
struct Options {
root: Option<PathBuf>,
}

pub static WASM_FILENAME: &str = "./file.wasm";

pub(crate) fn get_external_wasm_module(name: String) -> Result<Vec<u8>, Error> {
let manifest_dir = env!("CARGO_MANIFEST_DIR");
let target = Path::new(manifest_dir)
.join("../../target/wasm32-wasi/debug")
.join(name.clone());
std::fs::read(target).map_err(|e| {
Error::Others(format!(
"failed to read requested Wasm module ({}): {}. Perhaps you need to run 'make test/wasm-modules' first.",
name, e
))
})
}

pub(crate) fn run_test_with_spec<I, E>(spec: &Spec, bytes: &[u8]) -> Result<(String, u32), Error>
where
I: Instance<E = E> + EngineGetter<E = E>,
E: Sync + Send + Clone,
{
let dir = tempdir().unwrap();
create_dir(dir.path().join("rootfs"))?;
let rootdir = dir.path().join("runwasi");
create_dir(&rootdir)?;
let opts = Options {
root: Some(rootdir),
};
let opts_file = OpenOptions::new()
.read(true)
.create(true)
.truncate(true)
.write(true)
.open(dir.path().join("options.json"))?;
write!(&opts_file, "{}", serde_json::to_string(&opts)?)?;

let wasm_path = dir.path().join("rootfs").join(WASM_FILENAME);
let mut f = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.mode(0o755)
.open(wasm_path)?;
f.write_all(bytes)?;

let stdout = File::create(dir.path().join("stdout"))?;
drop(stdout);

spec.save(dir.path().join("config.json"))?;

let mut cfg = InstanceConfig::new(
I::new_engine()?,
"test_namespace".into(),
"/containerd/address".into(),
);
let cfg = cfg
.set_bundle(dir.path().to_str().unwrap().to_string())
.set_stdout(dir.path().join("stdout").to_str().unwrap().to_string());

let wasi = I::new("test".to_string(), Some(cfg));

wasi.start()?;

let (tx, rx) = channel();
let waiter = Wait::new(tx);
wasi.wait(&waiter).unwrap();

let res = match rx.recv_timeout(Duration::from_secs(600)) {
Ok(res) => res,
Err(e) => {
wasi.kill(SIGKILL as u32).unwrap();
return Err(Error::Others(format!(
"error waiting for module to finish: {0}",
e
)));
}
};
wasi.delete()?;
let output = read_to_string(dir.path().join("stdout"))?;
Ok((output, res.0))
}
53 changes: 53 additions & 0 deletions test/oci-tests/tests/devices.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use std::borrow::Cow;
use std::path::PathBuf;

use serde::{Deserialize, Serialize};
use serial_test::serial;
use oci_spec::runtime::{ProcessBuilder, RootBuilder, SpecBuilder};
use wasmedge_sdk::Vm as WasmEdgeVm;
use wasmtime::Engine as WasmtimeVm;

use containerd_shim_wasm::function;
use containerd_shim_wasm::sandbox::testutil::{has_cap_sys_admin, run_test_with_sudo};
use containerd_shim_wasm::sandbox::Error;

use containerd_shim_wasmedge::instance::Wasi as WasmEdgeWasi;
use containerd_shim_wasmtime::instance::Wasi as WasmtimeWasi;

#[derive(Serialize, Deserialize)]
struct Options {
root: Option<PathBuf>,
}

mod common;

#[test]
#[serial]
fn test_has_default_devices() -> Result<(), Error> {
if !has_cap_sys_admin() {
println!("running test with sudo: {}", function!());
return run_test_with_sudo("test_has_default_devices");
}

let wasmbytes = common::get_external_wasm_module("has-default-devices.wasm".to_string())?;

let spec = SpecBuilder::default()
.root(RootBuilder::default().path("rootfs").build()?)
.process(
ProcessBuilder::default()
.cwd("/")
.args(vec![common::WASM_FILENAME.to_string()])
.build()?,
)
.build()?;

let bytes = Cow::from(wasmbytes);

let (output, retval) = common::run_test_with_spec::<WasmtimeWasi, WasmtimeVm>(&spec, &bytes)?;
assert_eq!(retval, 0, "error: {}", output);

let (output, retval) = common::run_test_with_spec::<WasmEdgeWasi, WasmEdgeVm>(&spec, &bytes)?;
assert_eq!(retval, 0, "error: {}", output);

Ok(())
}
Loading

0 comments on commit c89099f

Please sign in to comment.