Skip to content

Commit

Permalink
add envvar opt, add test, rm binaries from wasitests, clean up
Browse files Browse the repository at this point in the history
  • Loading branch information
Mark McCaskey committed May 30, 2019
1 parent 792ebc0 commit 2a94a69
Show file tree
Hide file tree
Showing 26 changed files with 137 additions and 53 deletions.
57 changes: 38 additions & 19 deletions lib/wasi/build/wasitests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> {
let result = Command::new(&normalized_name)
.output()
.expect("Failed to execute native program");

std::fs::remove_file(&normalized_name).expect("could not delete executable");
let wasm_out_name = format!("{}.wasm", &normalized_name);

Command::new("rustc")
Expand All @@ -76,25 +78,31 @@ pub fn compile(file: &str, ignores: &HashSet<String>) -> Option<String> {
};

let src_code = fs::read_to_string(file).expect("read src file");
let args = extract_args_from_source_file(&src_code);

let mapdir_args = if let Some(a) = args {
if !a.mapdir.is_empty() {
let mut out_str = String::new();
out_str.push_str("vec![");
for (alias, real_dir) in a.mapdir {
out_str.push_str(&format!(
"(\"{}\".to_string(), \"{}\".to_string()),",
alias, real_dir
));
}
out_str.push_str("]");
out_str
} else {
"vec![]".to_string()
let args = extract_args_from_source_file(&src_code).unwrap_or_default();

let mapdir_args = {
let mut out_str = String::new();
out_str.push_str("vec![");
for (alias, real_dir) in args.mapdir {
out_str.push_str(&format!(
"(\"{}\".to_string(), \"{}\".to_string()),",
alias, real_dir
));
}
} else {
"vec![]".to_string()
out_str.push_str("]");
out_str
};

let envvar_args = {
let mut out_str = String::new();
out_str.push_str("vec![");

for entry in args.envvars {
out_str.push_str(&format!("\"{}={}\".to_string(),", entry.0, entry.1));
}

out_str.push_str("]");
out_str
};

let contents = format!(
Expand All @@ -104,6 +112,7 @@ fn test_{rs_module_name}() {{
\"../../{module_path}\",
\"{rs_module_name}\",
{mapdir_args},
{envvar_args},
\"../../{test_output_path}\"
);
}}
Expand All @@ -113,6 +122,7 @@ fn test_{rs_module_name}() {{
rs_module_name = rs_module_name,
test_output_path = format!("{}.out", normalized_name),
mapdir_args = mapdir_args,
envvar_args = envvar_args
);
let rust_test_filepath = format!(
concat!(env!("CARGO_MANIFEST_DIR"), "/tests/{}.rs"),
Expand Down Expand Up @@ -167,14 +177,16 @@ fn read_ignore_list() -> HashSet<String> {
.collect()
}

#[derive(Debug, Default)]
struct Args {
pub mapdir: Vec<(String, String)>,
pub envvars: Vec<(String, String)>,
}

/// Pulls args to the program out of a comment at the top of the file starting with "// Args:"
fn extract_args_from_source_file(source_code: &str) -> Option<Args> {
if source_code.starts_with("// Args:") {
let mut args = Args { mapdir: vec![] };
let mut args = Args::default();
for arg_line in source_code
.lines()
.skip(1)
Expand All @@ -196,6 +208,13 @@ fn extract_args_from_source_file(source_code: &str) -> Option<Args> {
);
}
}
"env" => {
if let [name, val] = &tokenized[2].split('=').collect::<Vec<&str>>()[..] {
args.envvars.push((name.to_string(), val.to_string()));
} else {
eprintln!("Parse error in env {} not parsed correctly", &tokenized[2]);
}
}
e => {
eprintln!("WARN: comment arg: {} is not supported", e);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/wasi/tests/wasitests/_common.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
macro_rules! assert_wasi_output {
($file:expr, $name:expr, $mapdir_args:expr, $expected:expr) => {{
($file:expr, $name:expr, $mapdir_args:expr, $envvar_args:expr, $expected:expr) => {{
use wasmer_dev_utils::stdio::StdioCapturer;
use wasmer_runtime_core::{backend::Compiler, Func};
use wasmer_wasi::generate_import_object;
Expand Down
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/create_dir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ fn test_create_dir() {
"../../wasitests/create_dir.wasm",
"create_dir",
vec![],
vec![],
"../../wasitests/create_dir.out"
);
}
10 changes: 10 additions & 0 deletions lib/wasi/tests/wasitests/envvar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#[test]
fn test_envvar() {
assert_wasi_output!(
"../../wasitests/envvar.wasm",
"envvar",
vec![],
vec![],
"../../wasitests/envvar.out"
);
}
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/file_metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fn test_file_metadata() {
"../../wasitests/file_metadata.wasm",
"file_metadata",
vec![],
vec![],
"../../wasitests/file_metadata.out"
);
}
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/fs_sandbox_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fn test_fs_sandbox_test() {
"../../wasitests/fs_sandbox_test.wasm",
"fs_sandbox_test",
vec![],
vec![],
"../../wasitests/fs_sandbox_test.out"
);
}
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fn test_hello() {
"../../wasitests/hello.wasm",
"hello",
vec![],
vec![],
"../../wasitests/hello.out"
);
}
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/mapdir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fn test_mapdir() {
"../../wasitests/mapdir.wasm",
"mapdir",
vec![],
vec![],
"../../wasitests/mapdir.out"
);
}
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#[macro_use]
mod _common;
mod create_dir;
mod envvar;
mod file_metadata;
mod fs_sandbox_test;
mod hello;
Expand Down
1 change: 1 addition & 0 deletions lib/wasi/tests/wasitests/quine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fn test_quine() {
"../../wasitests/quine.wasm",
"quine",
vec![],
vec![],
"../../wasitests/quine.out"
);
}
Binary file removed lib/wasi/wasitests/create_dir
Binary file not shown.
Binary file modified lib/wasi/wasitests/create_dir.wasm
Binary file not shown.
3 changes: 3 additions & 0 deletions lib/wasi/wasitests/envvar.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Env vars:
CAT=2
DOG=1
21 changes: 21 additions & 0 deletions lib/wasi/wasitests/envvar.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Args:
// env: DOG=1
// env: CAT=2

use std::env;

fn main() {
#[cfg(not(target = "wasi"))]
let mut env_vars = vec!["DOG=1".to_string(), "CAT=2".to_string()];
#[cfg(target = "wasi")]
let mut env_vars = env::vars()
.map(|(key, value)| format!("{}={}", key, value))
.collect::<Vec<String>>();

env_vars.sort();

println!("Env vars:");
for e in env_vars {
println!("{}", e);
}
}
Binary file added lib/wasi/wasitests/envvar.wasm
Binary file not shown.
Binary file removed lib/wasi/wasitests/file_metadata
Binary file not shown.
Binary file modified lib/wasi/wasitests/file_metadata.wasm
Binary file not shown.
Binary file removed lib/wasi/wasitests/fs_sandbox_test
Binary file not shown.
Binary file modified lib/wasi/wasitests/fs_sandbox_test.wasm
Binary file not shown.
Binary file removed lib/wasi/wasitests/hello
Binary file not shown.
Binary file modified lib/wasi/wasitests/hello.wasm
Binary file not shown.
Binary file removed lib/wasi/wasitests/mapdir
Binary file not shown.
Binary file modified lib/wasi/wasitests/mapdir.wasm
Binary file not shown.
Binary file removed lib/wasi/wasitests/quine
Binary file not shown.
Binary file modified lib/wasi/wasitests/quine.wasm
Binary file not shown.
90 changes: 57 additions & 33 deletions src/bin/wasmer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ struct Run {
#[structopt(long = "mapdir", multiple = true)]
mapped_dirs: Vec<String>,

/// Pass custom environment variables
#[structopt(long = "env", multiple = true)]
env_vars: Vec<String>,

/// Custom code loader
#[structopt(
long = "loader",
Expand Down Expand Up @@ -223,6 +227,47 @@ fn get_cache_dir() -> PathBuf {
}
}

fn get_mapped_dirs(input: &[String]) -> Result<Vec<(String, PathBuf)>, String> {
let mut md = vec![];
for entry in input.iter() {
if let [alias, real_dir] = entry.split(':').collect::<Vec<&str>>()[..] {
let pb = PathBuf::from(&real_dir);
if let Ok(pb_metadata) = pb.metadata() {
if !pb_metadata.is_dir() {
return Err(format!(
"\"{}\" exists, but it is not a directory",
&real_dir
));
}
} else {
return Err(format!("Directory \"{}\" does not exist", &real_dir));
}
md.push((alias.to_string(), pb));
continue;
}
return Err(format!(
"Directory mappings must consist of two paths separate by a colon. Found {}",
&entry
));
}
Ok(md)
}

fn get_env_var_args(input: &[String]) -> Result<Vec<(&str, &str)>, String> {
let mut ev = vec![];
for entry in input.iter() {
if let [env_var, value] = entry.split('=').collect::<Vec<&str>>()[..] {
ev.push((env_var, value));
} else {
return Err(format!(
"Env vars must be of the form <var_name>=<value>. Found {}",
&entry
));
}
}
Ok(ev)
}

/// Execute a wasm/wat file
fn execute_wasm(options: &Run) -> Result<(), String> {
// force disable caching on windows
Expand All @@ -231,31 +276,8 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
#[cfg(not(target_os = "windows"))]
let disable_cache = options.disable_cache;

let mapped_dirs = {
let mut md = vec![];
for entry in options.mapped_dirs.iter() {
if let &[alias, real_dir] = &entry.split(':').collect::<Vec<&str>>()[..] {
let pb = PathBuf::from(&real_dir);
if let Ok(pb_metadata) = pb.metadata() {
if !pb_metadata.is_dir() {
return Err(format!(
"\"{}\" exists, but it is not a directory",
&real_dir
));
}
} else {
return Err(format!("Directory \"{}\" does not exist", &real_dir));
}
md.push((alias.to_string(), pb));
continue;
}
return Err(format!(
"Directory mappings must consist of two paths separate by a colon. Found {}",
&entry
));
}
md
};
let mapped_dirs = get_mapped_dirs(&options.mapped_dirs[..])?;
let env_vars = get_env_var_args(&options.env_vars[..])?;
let wasm_path = &options.path;

let mut wasm_binary: Vec<u8> = read_file_contents(wasm_path).map_err(|err| {
Expand All @@ -282,9 +304,10 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
let num_str = if let Some(ns) = split.next() {
ns
} else {
return Err(format!(
return Err(
"Can't parse symbol map (expected each entry to be of the form: `0:func_name`)"
));
.to_string(),
);
};
let num: u32 = num_str.parse::<u32>().map_err(|err| {
format!(
Expand All @@ -295,9 +318,10 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
let name_str: String = if let Some(name_str) = split.next() {
name_str
} else {
return Err(format!(
return Err(
"Can't parse symbol map (expected each entry to be of the form: `0:func_name`)"
));
.to_string(),
);
}
.to_owned();

Expand Down Expand Up @@ -375,7 +399,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
// cache.load will return the Module if it's able to deserialize it properly, and an error if:
// * The file is not found
// * The file exists, but it's corrupted or can't be converted to a module
let module = match cache.load(hash) {
match cache.load(hash) {
Ok(module) => {
// We are able to load the module from cache
module
Expand All @@ -395,8 +419,7 @@ fn execute_wasm(options: &Run) -> Result<(), String> {

module
}
};
module
}
};

if let Some(loader) = options.loader {
Expand Down Expand Up @@ -471,7 +494,8 @@ fn execute_wasm(options: &Run) -> Result<(), String> {
.cloned()
.map(|arg| arg.into_bytes())
.collect(),
env::vars()
env_vars
.into_iter()
.map(|(k, v)| format!("{}={}", k, v).into_bytes())
.collect(),
options.pre_opened_directories.clone(),
Expand Down

0 comments on commit 2a94a69

Please sign in to comment.