Capture stdin for roc and roc run tests

This commit is contained in:
Richard Feldman 2022-05-05 23:30:40 -04:00
parent e7ac4dac96
commit 6f35d1891a
No known key found for this signature in database
GPG key ID: 7E4127D1E4241798
5 changed files with 58 additions and 18 deletions

1
Cargo.lock generated
View file

@ -507,6 +507,7 @@ name = "cli_utils"
version = "0.1.0"
dependencies = [
"bumpalo",
"const_format",
"criterion 0.3.5 (git+https://github.com/Anton-4/criterion.rs)",
"rlimit",
"roc_cli",

View file

@ -84,7 +84,7 @@ mod cli_run {
}
fn check_compile_error(file: &Path, flags: &[&str], expected: &str) {
let compile_out = run_roc(["check", file.to_str().unwrap()].iter().chain(flags));
let compile_out = run_roc(["check", file.to_str().unwrap()].iter().chain(flags), &[]);
let err = compile_out.stdout.trim();
let err = strip_colors(err);
@ -96,7 +96,7 @@ mod cli_run {
}
fn check_format_check_as_expected(file: &Path, expects_success_exit_code: bool) {
let out = run_roc(["format", file.to_str().unwrap(), CHECK_FLAG]);
let out = run_roc(["format", file.to_str().unwrap(), CHECK_FLAG], &[]);
if expects_success_exit_code {
assert!(out.status.success());
} else {
@ -104,10 +104,22 @@ mod cli_run {
}
}
fn run_roc_on<'a, I: IntoIterator<Item = &'a str>>(file: &'a Path, args: I) -> Out {
let compile_out = run_roc(args.into_iter().chain(iter::once(file.to_str().unwrap())));
if !compile_out.stderr.is_empty() {
panic!("roc build had stderr: {}", compile_out.stderr);
fn run_roc_on<'a, I: IntoIterator<Item = &'a str>>(
file: &'a Path,
args: I,
stdin: &[&str],
) -> Out {
let compile_out = run_roc(
args.into_iter().chain(iter::once(file.to_str().unwrap())),
stdin,
);
if !compile_out.stderr.is_empty() &&
// If there is any stderr, it should be reporting the runtime and that's it!
!(compile_out.stderr.starts_with("runtime: ")
&& compile_out.stderr.ends_with("ms\n"))
{
panic!("roc build had unexpected stderr: {}", compile_out.stderr);
}
assert!(compile_out.status.success(), "bad status {:?}", compile_out);
@ -137,7 +149,7 @@ mod cli_run {
let out = match cli_mode {
CliMode::RocBuild => {
run_roc_on(file, iter::once(CMD_BUILD).chain(flags.clone()));
run_roc_on(file, iter::once(CMD_BUILD).chain(flags.clone()), &[]);
if use_valgrind && ALLOW_VALGRIND {
let (valgrind_out, raw_xml) = if let Some(ref input_file) = input_file {
@ -204,8 +216,10 @@ mod cli_run {
)
}
}
CliMode::Roc => run_roc_on(file, flags.clone()),
CliMode::RocRun => run_roc_on(file, iter::once(CMD_RUN).chain(flags.clone())),
CliMode::Roc => run_roc_on(file, flags.clone(), stdin),
CliMode::RocRun => {
run_roc_on(file, iter::once(CMD_RUN).chain(flags.clone()), stdin)
}
};
if !&out.stdout.ends_with(expected_ending) {
@ -293,7 +307,7 @@ mod cli_run {
}
"hello-gui" | "breakout" => {
// Since these require opening a window, we do `roc build` on them but don't run them.
run_roc_on(&file_name, [CMD_BUILD, OPTIMIZE_FLAG]);
run_roc_on(&file_name, [CMD_BUILD, OPTIMIZE_FLAG], &[]);
return;
}
@ -318,7 +332,7 @@ mod cli_run {
&file_name,
example.stdin,
example.executable_filename,
[OPTIMIZE_FLAG],
&[OPTIMIZE_FLAG],
example.input_file.and_then(|file| Some(example_file(dir_name, file))),
example.expected_ending,
example.use_valgrind,
@ -590,7 +604,7 @@ mod cli_run {
&file_name,
benchmark.stdin,
benchmark.executable_filename,
[OPTIMIZE_FLAG],
&[OPTIMIZE_FLAG],
benchmark.input_file.and_then(|file| Some(examples_dir("benchmarks").join(file))),
benchmark.expected_ending,
);

View file

@ -20,6 +20,7 @@ serde = { version = "1.0.130", features = ["derive"] }
serde-xml-rs = "0.5.1"
strip-ansi-escapes = "0.1.1"
tempfile = "3.2.0"
const_format = "0.2.22"
[target.'cfg(unix)'.dependencies]
rlimit = "0.6.2"

View file

@ -1,9 +1,13 @@
use crate::helpers::{example_file, run_cmd, run_roc};
use const_format::concatcp;
use criterion::{black_box, measurement::Measurement, BenchmarkGroup};
use roc_cli::CMD_BUILD;
use std::{path::Path, thread};
const CFOLD_STACK_SIZE: usize = 8192 * 100000;
const OPTIMIZE_FLAG: &str = concatcp!("--", roc_cli::FLAG_OPTIMIZE);
fn exec_bench_w_input<T: Measurement>(
file: &Path,
stdin_str: &'static str,
@ -11,7 +15,10 @@ fn exec_bench_w_input<T: Measurement>(
expected_ending: &str,
bench_group_opt: Option<&mut BenchmarkGroup<T>>,
) {
let compile_out = run_roc(["build", "--optimize", file.to_str().unwrap()]);
let compile_out = run_roc(
[CMD_BUILD, OPTIMIZE_FLAG, file.to_str().unwrap()],
&[stdin_str],
);
if !compile_out.stderr.is_empty() {
panic!("{}", compile_out.stderr);

View file

@ -45,17 +45,34 @@ pub fn path_to_roc_binary() -> PathBuf {
path
}
pub fn run_roc<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I) -> Out {
pub fn run_roc<I: IntoIterator<Item = S>, S: AsRef<OsStr>>(args: I, stdin_vals: &[&str]) -> Out {
let mut cmd = Command::new(path_to_roc_binary());
for arg in args {
cmd.arg(arg);
}
let output = cmd
.output()
let mut child = cmd
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.stderr(Stdio::piped())
.spawn()
.expect("failed to execute compiled `roc` binary in CLI test");
{
let stdin = child.stdin.as_mut().expect("Failed to open stdin");
for stdin_str in stdin_vals.iter() {
stdin
.write_all(stdin_str.as_bytes())
.expect("Failed to write to stdin");
}
}
let output = child
.wait_with_output()
.expect("failed to get output for compiled `roc` binary in CLI test");
Out {
stdout: String::from_utf8(output.stdout).unwrap(),
stderr: String::from_utf8(output.stderr).unwrap(),