Skip to content

rustpkg: Set exit codes properly and make tests take advantage of that #9799

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 12, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustpkg/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,11 @@ impl RustcFlags {
}

/// Returns true if any of the flags given are incompatible with the cmd
pub fn flags_ok_for_cmd(flags: &RustcFlags,
pub fn flags_forbidden_for_cmd(flags: &RustcFlags,
cfgs: &[~str],
cmd: &str, user_supplied_opt_level: bool) -> bool {
let complain = |s| {
println!("The {} option can only be used with the build command:
println!("The {} option can only be used with the `build` command:
rustpkg [options..] build {} [package-ID]", s, s);
};

Expand Down
3 changes: 3 additions & 0 deletions src/librustpkg/exit_codes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,6 @@
// except according to those terms.

pub static COPY_FAILED_CODE: int = 65;
pub static BAD_FLAG_CODE: int = 67;
pub static NONEXISTENT_PACKAGE_CODE: int = 68;

18 changes: 13 additions & 5 deletions src/librustpkg/rustpkg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ use package_source::PkgSrc;
use target::{WhatToBuild, Everything, is_lib, is_main, is_test, is_bench, Tests};
// use workcache_support::{discover_outputs, digest_only_date};
use workcache_support::digest_only_date;
use exit_codes::COPY_FAILED_CODE;
use exit_codes::{COPY_FAILED_CODE, BAD_FLAG_CODE};

pub mod api;
mod conditions;
Expand Down Expand Up @@ -701,7 +701,7 @@ pub fn main_args(args: &[~str]) -> int {
return 1;
}
};
let mut help = matches.opt_present("h") ||
let help = matches.opt_present("h") ||
matches.opt_present("help");
let no_link = matches.opt_present("no-link");
let no_trans = matches.opt_present("no-trans");
Expand Down Expand Up @@ -798,8 +798,11 @@ pub fn main_args(args: &[~str]) -> int {
return 0;
}
Some(cmd) => {
help |= context::flags_ok_for_cmd(&rustc_flags, cfgs, *cmd, user_supplied_opt_level);
if help {
let bad_option = context::flags_forbidden_for_cmd(&rustc_flags,
cfgs,
*cmd,
user_supplied_opt_level);
if help || bad_option {
match *cmd {
~"build" => usage::build(),
~"clean" => usage::clean(),
Expand All @@ -814,7 +817,12 @@ pub fn main_args(args: &[~str]) -> int {
~"unprefer" => usage::unprefer(),
_ => usage::general()
};
return 0;
if bad_option {
return BAD_FLAG_CODE;
}
else {
return 0;
}
} else {
cmd
}
Expand Down
74 changes: 54 additions & 20 deletions src/librustpkg/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ use syntax::diagnostic;
use target::*;
use package_source::PkgSrc;
use source_control::{CheckedOutSources, DirToUse, safe_git_clone};
use exit_codes::{BAD_FLAG_CODE, COPY_FAILED_CODE};
use util::datestamp;

fn fake_ctxt(sysroot: Path, workspace: &Path) -> BuildContext {
Expand Down Expand Up @@ -244,14 +245,26 @@ fn rustpkg_exec() -> Path {
fn command_line_test(args: &[~str], cwd: &Path) -> ProcessOutput {
match command_line_test_with_env(args, cwd, None) {
Success(r) => r,
_ => fail2!("Command line test failed")
Fail(error) => fail2!("Command line test failed with error {}", error)
}
}

fn command_line_test_partial(args: &[~str], cwd: &Path) -> ProcessResult {
command_line_test_with_env(args, cwd, None)
}

fn command_line_test_expect_fail(args: &[~str],
cwd: &Path,
env: Option<~[(~str, ~str)]>,
expected_exitcode: int) {
match command_line_test_with_env(args, cwd, env) {
Success(_) => fail2!("Should have failed with {}, but it succeeded", expected_exitcode),
Fail(error) if error == expected_exitcode => (), // ok
Fail(other) => fail2!("Expected to fail with {}, but failed with {} instead",
expected_exitcode, other)
}
}

enum ProcessResult {
Success(ProcessOutput),
Fail(int) // exit code
Expand Down Expand Up @@ -1448,11 +1461,11 @@ fn compile_flag_fail() {
let p_id = PkgId::new("foo");
let workspace = create_local_package(&p_id);
let workspace = workspace.path();
command_line_test([test_sysroot().to_str(),
command_line_test_expect_fail([test_sysroot().to_str(),
~"install",
~"--no-link",
~"foo"],
workspace);
workspace, None, BAD_FLAG_CODE);
assert!(!built_executable_exists(workspace, "foo"));
assert!(!object_file_exists(workspace, "foo"));
}
Expand Down Expand Up @@ -1488,14 +1501,11 @@ fn notrans_flag_fail() {
let flags_to_test = [~"--no-trans", ~"--parse-only",
~"--pretty", ~"-S"];
for flag in flags_to_test.iter() {
command_line_test([test_sysroot().to_str(),
command_line_test_expect_fail([test_sysroot().to_str(),
~"install",
flag.clone(),
~"foo"],
workspace);
// Ideally we'd test that rustpkg actually fails, but
// since task failure doesn't set the exit code properly,
// we can't tell
workspace, None, BAD_FLAG_CODE);
assert!(!built_executable_exists(workspace, "foo"));
assert!(!object_file_exists(workspace, "foo"));
assert!(!lib_exists(workspace, &Path("foo"), NoVersion));
Expand All @@ -1522,11 +1532,11 @@ fn dash_S_fail() {
let p_id = PkgId::new("foo");
let workspace = create_local_package(&p_id);
let workspace = workspace.path();
command_line_test([test_sysroot().to_str(),
command_line_test_expect_fail([test_sysroot().to_str(),
~"install",
~"-S",
~"foo"],
workspace);
workspace, None, BAD_FLAG_CODE);
assert!(!built_executable_exists(workspace, "foo"));
assert!(!object_file_exists(workspace, "foo"));
assert!(!assembly_file_exists(workspace, "foo"));
Expand Down Expand Up @@ -1587,11 +1597,13 @@ fn test_emit_llvm_S_fail() {
let p_id = PkgId::new("foo");
let workspace = create_local_package(&p_id);
let workspace = workspace.path();
command_line_test([test_sysroot().to_str(),
command_line_test_expect_fail([test_sysroot().to_str(),
~"install",
~"-S", ~"--emit-llvm",
~"foo"],
workspace);
workspace,
None,
BAD_FLAG_CODE);
assert!(!built_executable_exists(workspace, "foo"));
assert!(!object_file_exists(workspace, "foo"));
assert!(!llvm_assembly_file_exists(workspace, "foo"));
Expand Down Expand Up @@ -1620,11 +1632,13 @@ fn test_emit_llvm_fail() {
let p_id = PkgId::new("foo");
let workspace = create_local_package(&p_id);
let workspace = workspace.path();
command_line_test([test_sysroot().to_str(),
command_line_test_expect_fail([test_sysroot().to_str(),
~"install",
~"--emit-llvm",
~"foo"],
workspace);
workspace,
None,
BAD_FLAG_CODE);
assert!(!built_executable_exists(workspace, "foo"));
assert!(!object_file_exists(workspace, "foo"));
assert!(!llvm_bitcode_file_exists(workspace, "foo"));
Expand Down Expand Up @@ -1665,11 +1679,10 @@ fn test_build_install_flags_fail() {
~[~"--target", host_triple()],
~[~"--target-cpu", ~"generic"],
~[~"-Z", ~"--time-passes"]];
let cwd = os::getcwd();
for flag in forbidden.iter() {
let output = command_line_test_output([test_sysroot().to_str(),
~"list"] + *flag);
assert!(output.len() > 1);
assert!(output[1].find_str("can only be used with").is_some());
command_line_test_expect_fail([test_sysroot().to_str(),
~"list"] + *flag, &cwd, None, BAD_FLAG_CODE);
}
}

Expand All @@ -1686,6 +1699,7 @@ fn test_optimized_build() {
assert!(built_executable_exists(workspace, "foo"));
}

#[test]
fn pkgid_pointing_to_subdir() {
// The actual repo is mockgithub.com/mozilla/some_repo
// rustpkg should recognize that and treat the part after some_repo/ as a subdir
Expand Down Expand Up @@ -1717,6 +1731,7 @@ fn pkgid_pointing_to_subdir() {
assert_executable_exists(workspace, "testpkg");
}

#[test]
fn test_recursive_deps() {
let a_id = PkgId::new("a");
let b_id = PkgId::new("b");
Expand Down Expand Up @@ -1762,6 +1777,7 @@ fn test_install_to_rust_path() {
assert!(!executable_exists(second_workspace, "foo"));
}

#[test]
fn test_target_specific_build_dir() {
let p_id = PkgId::new("foo");
let workspace = create_local_package(&p_id);
Expand Down Expand Up @@ -1870,8 +1886,9 @@ fn correct_package_name_with_rust_path_hack() {
let rust_path = Some(~[(~"RUST_PATH", format!("{}:{}", dest_workspace.to_str(),
foo_workspace.push_many(["src", "foo-0.1"]).to_str()))]);
// bar doesn't exist, but we want to make sure rustpkg doesn't think foo is bar
command_line_test_with_env([~"install", ~"--rust-path-hack", ~"bar"],
dest_workspace, rust_path);
command_line_test_expect_fail([~"install", ~"--rust-path-hack", ~"bar"],
// FIXME #3408: Should be NONEXISTENT_PACKAGE_CODE
dest_workspace, rust_path, COPY_FAILED_CODE);
assert!(!executable_exists(dest_workspace, "bar"));
assert!(!lib_exists(dest_workspace, &bar_id.path.clone(), bar_id.version.clone()));
assert!(!executable_exists(dest_workspace, "foo"));
Expand Down Expand Up @@ -2050,6 +2067,23 @@ fn test_7402() {
assert_executable_exists(dest_workspace, "foo");
}

#[test]
fn test_compile_error() {
let foo_id = PkgId::new("foo");
let foo_workspace = create_local_package(&foo_id);
let foo_workspace = foo_workspace.path();
let main_crate = foo_workspace.push_many(["src", "foo-0.1", "main.rs"]);
// Write something bogus
writeFile(&main_crate, "pub fn main() { if 42 != ~\"the answer\" { fail!(); } }");
let result = command_line_test_partial([~"build", ~"foo"], foo_workspace);
match result {
Success(*) => fail2!("Failed by succeeding!"), // should be a compile error
Fail(status) => {
debug2!("Failed with status {:?}... that's good, right?", status);
}
}
}

/// Returns true if p exists and is executable
fn is_executable(p: &Path) -> bool {
use std::libc::consts::os::posix88::{S_IXUSR};
Expand Down