Added integration tests for run2

This commit is contained in:
Michael-F-Bryan
2023-03-08 15:19:53 +08:00
parent 6b624af5d4
commit ab2f65c143
5 changed files with 309 additions and 6 deletions

58
Cargo.lock generated
View File

@@ -55,6 +55,12 @@ dependencies = [
"winapi", "winapi",
] ]
[[package]]
name = "anstyle"
version = "0.3.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23ea9e81bd02e310c216d080f6223c179012256e5151c41db88d12c88a1684d2"
[[package]] [[package]]
name = "any_ascii" name = "any_ascii"
version = "0.1.7" version = "0.1.7"
@@ -106,9 +112,24 @@ version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe" checksum = "c98233c6673d8601ab23e77eb38f999c51100d46c5703b17288c57fddf3a1ffe"
dependencies = [ dependencies = [
"bstr", "bstr 0.2.17",
"doc-comment", "doc-comment",
"predicates", "predicates 2.1.5",
"predicates-core",
"predicates-tree",
"wait-timeout",
]
[[package]]
name = "assert_cmd"
version = "2.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0b2340f55d9661d76793b2bfc2eb0e62689bd79d067a95707ea762afd5e9dd"
dependencies = [
"anstyle",
"bstr 1.3.0",
"doc-comment",
"predicates 3.0.1",
"predicates-core", "predicates-core",
"predicates-tree", "predicates-tree",
"wait-timeout", "wait-timeout",
@@ -242,6 +263,18 @@ dependencies = [
"regex-automata", "regex-automata",
] ]
[[package]]
name = "bstr"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ffdb39cb703212f3c11973452c2861b972f757b021158f3516ba10f2fa8b2c1"
dependencies = [
"memchr",
"once_cell",
"regex-automata",
"serde",
]
[[package]] [[package]]
name = "build-deps" name = "build-deps"
version = "0.1.4" version = "0.1.4"
@@ -1897,11 +1930,11 @@ version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "340dd3d6102fa919bd20987024a6d84954c36ec691ac1efea37742ee983c8dd5" checksum = "340dd3d6102fa919bd20987024a6d84954c36ec691ac1efea37742ee983c8dd5"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd 1.0.8",
"cc", "cc",
"inline-c-macro", "inline-c-macro",
"lazy_static", "lazy_static",
"predicates", "predicates 2.1.5",
"regex", "regex",
"rustc_version 0.3.3", "rustc_version 0.3.3",
"target-lexicon 0.11.2", "target-lexicon 0.11.2",
@@ -2802,6 +2835,18 @@ dependencies = [
"regex", "regex",
] ]
[[package]]
name = "predicates"
version = "3.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ba7d6ead3e3966038f68caa9fc1f860185d95a793180bbcfe0d0da47b3961ed"
dependencies = [
"anstyle",
"difflib",
"itertools",
"predicates-core",
]
[[package]] [[package]]
name = "predicates-core" name = "predicates-core"
version = "1.0.6" version = "1.0.6"
@@ -5243,10 +5288,10 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c4e7a2a3363ceeb2ee60371af9460748f2bf53569b58627f1f640284ab07778" checksum = "7c4e7a2a3363ceeb2ee60371af9460748f2bf53569b58627f1f640284ab07778"
dependencies = [ dependencies = [
"assert_cmd", "assert_cmd 1.0.8",
"cc", "cc",
"lazy_static", "lazy_static",
"predicates", "predicates 2.1.5",
"regex", "regex",
"rustc_version 0.3.3", "rustc_version 0.3.3",
"target-lexicon 0.11.2", "target-lexicon 0.11.2",
@@ -5270,6 +5315,7 @@ name = "wasmer-integration-tests-cli"
version = "3.2.0-alpha.1" version = "3.2.0-alpha.1"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"assert_cmd 2.0.10",
"derivative", "derivative",
"dirs", "dirs",
"flate2", "flate2",

Binary file not shown.

View File

@@ -274,6 +274,7 @@ impl wasmer_cache::Cache for WasmerHome {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
enum TargetOnDisk { enum TargetOnDisk {
WebAssemblyBinary(PathBuf), WebAssemblyBinary(PathBuf),
Wat(PathBuf),
Webc(PathBuf), Webc(PathBuf),
Directory(PathBuf), Directory(PathBuf),
Artifact(PathBuf), Artifact(PathBuf),
@@ -297,6 +298,8 @@ impl TargetOnDisk {
Ok(TargetOnDisk::Webc(path)) Ok(TargetOnDisk::Webc(path))
} else if ArtifactBuild::is_deserializable(leading_bytes) { } else if ArtifactBuild::is_deserializable(leading_bytes) {
Ok(TargetOnDisk::Artifact(path)) Ok(TargetOnDisk::Artifact(path))
} else if path.extension() == Some("wat".as_ref()) {
Ok(TargetOnDisk::Wat(path))
} else { } else {
anyhow::bail!("Unable to determine how to execute \"{}\"", path.display()); anyhow::bail!("Unable to determine how to execute \"{}\"", path.display());
} }
@@ -306,6 +309,7 @@ impl TargetOnDisk {
match self { match self {
TargetOnDisk::WebAssemblyBinary(p) TargetOnDisk::WebAssemblyBinary(p)
| TargetOnDisk::Webc(p) | TargetOnDisk::Webc(p)
| TargetOnDisk::Wat(p)
| TargetOnDisk::Directory(p) | TargetOnDisk::Directory(p)
| TargetOnDisk::Artifact(p) => p, | TargetOnDisk::Artifact(p) => p,
} }
@@ -344,6 +348,15 @@ impl TargetOnDisk {
.context("Unable to load the module from a file")?; .context("Unable to load the module from a file")?;
Ok(ExecutableTarget::WebAssembly(module)) Ok(ExecutableTarget::WebAssembly(module))
} }
TargetOnDisk::Wat(wat) => {
let wat = std::fs::read(wat)
.with_context(|| format!("Unable to read \"{}\"", wat.display()))?;
let wasm =
wasmer::wat2wasm(&wat).context("Unable to convert the WAT to WebAssembly")?;
let module =
Module::new(store, wasm).context("Unable to load the module from a file")?;
Ok(ExecutableTarget::WebAssembly(module))
}
TargetOnDisk::Artifact(artifact) => { TargetOnDisk::Artifact(artifact) => {
let module = unsafe { let module = unsafe {
Module::deserialize_from_file(store, artifact) Module::deserialize_from_file(store, artifact)

View File

@@ -18,6 +18,7 @@ pretty_assertions = "1.3.0"
object = "0.30.0" object = "0.30.0"
reqwest = { version = "0.11.14", features = ["json"] } reqwest = { version = "0.11.14", features = ["json"] }
tokio = { version = "1", features = [ "rt", "rt-multi-thread", "macros" ] } tokio = { version = "1", features = [ "rt", "rt-multi-thread", "macros" ] }
assert_cmd = "2.0.8"
[dependencies] [dependencies]
anyhow = "1" anyhow = "1"

View File

@@ -0,0 +1,243 @@
use assert_cmd::{assert::Assert, prelude::OutputAssertExt, Command};
use tempfile::TempDir;
use wasmer_integration_tests_cli::get_wasmer_path;
fn wasmer_cli() -> Command {
Command::new(get_wasmer_path())
}
mod webc_on_disk {
use super::*;
#[test]
fn wasi_runner() {
let assert = wasmer_cli()
.arg("run2")
.arg(fixtures::python())
.arg("--")
.arg("--version")
.assert();
assert.success().stdout("Hello, World!");
}
#[test]
fn wasi_runner_with_mounted_directories() {
let temp = TempDir::new().unwrap();
std::fs::write(temp.path().join("main.py"), "print('Hello, World!')").unwrap();
let assert = wasmer_cli()
.arg("run2")
.arg(fixtures::python())
.arg("--mapdir")
.arg(format!("/app:{}", temp.path().display()))
.arg("--")
.arg("/app/main.py")
.assert();
assert.success().stdout("Hello, World!");
}
#[test]
fn wasi_runner_with_env_vars() {
let temp = TempDir::new().unwrap();
std::fs::write(temp.path().join("main.py"), "print('Hello, World!')").unwrap();
let assert = wasmer_cli()
.arg("run2")
.arg(fixtures::python())
.arg("--env")
.arg("SOME_VAR=Hello, World!")
.arg("--")
.arg("-c")
.arg("import os; print(os.environ['SOME_VAR'])")
.assert();
assert.success().stdout("Hello, World!");
}
#[test]
fn wcgi_runner() {
// Start the WCGI server in the background
let child = std::process::Command::new(get_wasmer_path())
.arg("run2")
.arg(fixtures::static_server())
.spawn()
.map(Child::new)
.unwrap();
let assert = child.join();
assert.stdout("Hello, World!");
}
}
mod wasm_on_disk {
use super::*;
#[test]
fn wasi_executable() {
let assert = wasmer_cli()
.arg("run2")
.arg(fixtures::qjs())
.arg("--")
.arg("--eval")
.arg("console.log('Hello, World!')")
.assert();
assert.success().stdout("Hello, World!");
}
#[test]
fn no_abi() {
let assert = wasmer_cli().arg("run2").arg(fixtures::fib()).assert();
assert.success();
}
#[test]
fn error_if_no_start_function_found() {
let assert = wasmer_cli()
.arg("run2")
.arg(fixtures::wat_no_start())
.assert();
assert
.failure()
.stderr("Can not find any export functions.");
}
}
#[test]
fn wasmer_package_directory() {
let temp = TempDir::new().unwrap();
std::fs::copy(fixtures::qjs(), temp.path().join("qjs.wasm")).unwrap();
std::fs::copy(fixtures::qjs_wasmer_toml(), temp.path().join("wasmer.toml")).unwrap();
let assert = wasmer_cli()
.arg("run2")
.arg(temp.path())
.arg("--")
.arg("--eval")
.arg("console.log('Hello, World!')")
.assert();
assert.success().stdout("Hello, World!");
}
#[test]
fn pre_compiled_wasm() {
let temp = TempDir::new().unwrap();
let dest = temp.path().join("qjs.wasmu");
let qjs = fixtures::qjs();
// Make sure it is compiled
wasmer_cli()
.arg("compile")
.arg("-o")
.arg(&dest)
.arg(&qjs)
.assert()
.success();
assert!(dest.exists());
// Now we can try to run the compiled artifact
let assert = wasmer_cli()
.arg("run2")
.arg(&dest)
.arg("--")
.arg("--eval")
.arg("console.log('Hello, World!')")
.assert();
assert.success().stdout("Hello, World!");
}
mod remote_webc {
use super::*;
#[test]
fn quickjs_as_package_name() {
let assert = wasmer_cli()
.arg("run2")
.arg("saghul/quickjs")
.arg("--registry=https://wapm.io/")
.arg("--")
.arg("--eval")
.arg("console.log('Hello, World!')")
.assert();
assert.success().stdout("Hello, World!");
}
#[test]
fn quickjs_as_url() {
let assert = wasmer_cli()
.arg("run2")
.arg("https://wapm.io/saghul/quickjs")
.arg("--")
.arg("--eval")
.arg("console.log('Hello, World!')")
.assert();
assert.success().stdout("Hello, World!");
}
}
mod fixtures {
use std::path::{Path, PathBuf};
use wasmer_integration_tests_cli::{ASSET_PATH, C_ASSET_PATH};
/// A WEBC file containing the Python interpreter, compiled to WASI.
pub fn python() -> PathBuf {
Path::new(C_ASSET_PATH).join("python-0.1.0.wasmer")
}
/// A WEBC file containing the WCGI static server.
pub fn static_server() -> PathBuf {
Path::new(C_ASSET_PATH).join("staticserver.webc")
}
/// The QuickJS interpreter, compiled to a WASI module.
pub fn qjs() -> PathBuf {
Path::new(C_ASSET_PATH).join("qjs.wasm")
}
/// The `wasmer.toml` file for QuickJS.
pub fn qjs_wasmer_toml() -> PathBuf {
Path::new(C_ASSET_PATH).join("qjs-wasmer.toml")
}
/// An executable which calculates fib(40) and exits with no output.
pub fn fib() -> PathBuf {
Path::new(ASSET_PATH).join("fib.wat")
}
pub fn wat_no_start() -> PathBuf {
Path::new(ASSET_PATH).join("no_start.wat")
}
}
/// A helper that wraps [`std::process::Child`] to make sure it gets terminated
/// when it is no longer needed.
struct Child(Option<std::process::Child>);
impl Child {
fn new(child: std::process::Child) -> Self {
Child(Some(child))
}
fn join(mut self) -> Assert {
let mut child = self.0.take().unwrap();
child.kill().unwrap();
child.wait_with_output().unwrap().assert()
}
}
impl Drop for Child {
fn drop(&mut self) {
if let Some(mut child) = self.0.take() {
let _ = child.kill();
}
}
}