Skip to content

Commit

Permalink
add proper output tests
Browse files Browse the repository at this point in the history
  • Loading branch information
scootermon committed Jan 16, 2024
1 parent a3b4614 commit c8c61a2
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 7 deletions.
66 changes: 59 additions & 7 deletions cc-test/build.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
use std::env;
use std::fs;
use std::path::PathBuf;
use std::path::{Path, PathBuf};
use std::process::Command;
use std::{env, fs};

fn main() {
// if we are being executed from a `fork_run_action` call (i.e. this is a
// "fork"), perform the requested action and then return.
if run_action_if_forked() {
return;
}

let out = PathBuf::from(env::var_os("OUT_DIR").unwrap());
fs::remove_dir_all(&out).unwrap();
fs::create_dir(&out).unwrap();

// The following are builds where we want to capture the output (i.e. stdout and
// stderr). We do that by re-running _this_ executable and passing in the
// action as the first argument.
run_forked_capture_output(&out, "metadata-on");
run_forked_capture_output(&out, "metadata-off");
run_forked_capture_output(&out, "warnings-on");
run_forked_capture_output(&out, "warnings-off");

cc::Build::new()
.file("src/foo.c")
.flag_if_supported("-Wall")
Expand Down Expand Up @@ -103,12 +117,50 @@ fn main() {
let out = cc::Build::new().file("src/expand.c").expand();
let out = String::from_utf8(out).unwrap();
assert!(out.contains("hello world"));
}

#[track_caller]
fn run_forked_capture_output(out: &Path, action: &str) {
let program = env::current_exe().unwrap();
let output = Command::new(&program).arg(action).output().unwrap();
assert!(output.status.success());
// we've captured the output and now we write it to a dedicated directory in the
// build output so our tests can access the output.
let action_dir = out.join(action);
fs::create_dir_all(&action_dir).unwrap();
fs::write(action_dir.join("stdout"), output.stdout).unwrap();
fs::write(action_dir.join("stderr"), output.stderr).unwrap();
}

// Compilations _should_ fail, but we don't want it to show up as a warning.
fn run_action_if_forked() -> bool {
let mut args = env::args();
let _program = args.next().unwrap();
let action = args.next();
match action.as_deref() {
Some("metadata-on") => build_cargo_metadata(true),
Some("metadata-off") => build_cargo_metadata(false),
Some("warnings-on") => build_cargo_warnings(true),
Some("warnings-off") => build_cargo_warnings(false),
// No action requested, we're being called from cargo. Proceed with build.
_ => return false,
}
true
}

fn build_cargo_warnings(warnings: bool) {
cc::Build::new()
.cargo_metadata(false)
.cargo_warnings(false)
.file("src/suppress_warnings.c")
.try_compile("suppress_warnings")
.cargo_warnings(warnings)
.file("src/compile_error.c")
.try_compile("compile_error")
// we expect the compilation to fail in this case
.unwrap_err();
}

fn build_cargo_metadata(metadata: bool) {
cc::Build::new()
.cargo_metadata(metadata)
.file("src/dummy.c")
.try_compile("dummy")
.unwrap();
}
File renamed without changes.
1 change: 1 addition & 0 deletions cc-test/src/dummy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/* just an empty file */
42 changes: 42 additions & 0 deletions cc-test/tests/output.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use std::fs;
use std::path::PathBuf;

#[test]
fn cargo_warnings_on() {
let (stdout, stderr) = load_output("warnings-on");
assert!(stderr.is_empty());
assert!(stdout.contains("cargo:warning="));
}

#[test]
fn cargo_warnings_off() {
let (stdout, stderr) = load_output("warnings-off");
assert!(stderr.is_empty());
assert!(!stdout.contains("cargo:warning="));
}

#[test]
fn cargo_metadata_on() {
let (stdout, stderr) = load_output("metadata-on");
assert!(stderr.is_empty());
assert!(stdout.contains("rustc-link-lib="));
assert!(stdout.contains("rustc-link-search="));
}

#[test]
fn cargo_metadata_off() {
let (stdout, stderr) = load_output("metadata-off");
assert!(stderr.is_empty());
assert!(!stdout.contains("rustc-link-lib="));
assert!(!stdout.contains("rustc-link-search="));
}

#[track_caller]
fn load_output(action: &str) -> (String, String) {
// these files are written by the `run_forked_capture_output` function in the
// build script.
let action_dir = PathBuf::from(env!("OUT_DIR")).join(action);
let stdout = fs::read_to_string(action_dir.join("stdout")).unwrap();
let stderr = fs::read_to_string(action_dir.join("stderr")).unwrap();
(stdout, stderr)
}

0 comments on commit c8c61a2

Please sign in to comment.