rust/src/compiletest/runtest.rs
Daniel Micay d2e9912aea vec: remove BaseIter implementation
I removed the `static-method-test.rs` test because it was heavily based
on `BaseIter` and there are plenty of other more complex uses of static
methods anyway.
2013-06-23 02:05:20 -04:00

842 lines
27 KiB
Rust

// Copyright 2012-2013 The Rust Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use core::prelude::*;
use common::mode_run_pass;
use common::mode_run_fail;
use common::mode_compile_fail;
use common::mode_pretty;
use common::config;
use errors;
use header::load_props;
use header::TestProps;
use procsrv;
use util;
use util::logv;
use core::io;
use core::os;
use core::uint;
use core::vec;
pub fn run(config: config, testfile: ~str) {
if config.verbose {
// We're going to be dumping a lot of info. Start on a new line.
io::stdout().write_str("\n\n");
}
let testfile = Path(testfile);
debug!("running %s", testfile.to_str());
let props = load_props(&testfile);
debug!("loaded props");
match config.mode {
mode_compile_fail => run_cfail_test(&config, &props, &testfile),
mode_run_fail => run_rfail_test(&config, &props, &testfile),
mode_run_pass => run_rpass_test(&config, &props, &testfile),
mode_pretty => run_pretty_test(&config, &props, &testfile),
mode_debug_info => run_debuginfo_test(&config, &props, &testfile)
}
}
fn run_cfail_test(config: &config, props: &TestProps, testfile: &Path) {
let ProcRes = compile_test(config, props, testfile);
if ProcRes.status == 0 {
fatal_ProcRes(~"compile-fail test compiled successfully!", &ProcRes);
}
check_correct_failure_status(&ProcRes);
let expected_errors = errors::load_errors(testfile);
if !expected_errors.is_empty() {
if !props.error_patterns.is_empty() {
fatal(~"both error pattern and expected errors specified");
}
check_expected_errors(expected_errors, testfile, &ProcRes);
} else {
check_error_patterns(props, testfile, &ProcRes);
}
}
fn run_rfail_test(config: &config, props: &TestProps, testfile: &Path) {
let ProcRes = if !config.jit {
let ProcRes = compile_test(config, props, testfile);
if ProcRes.status != 0 {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}
exec_compiled_test(config, props, testfile)
} else {
jit_test(config, props, testfile)
};
// The value our Makefile configures valgrind to return on failure
static valgrind_err: int = 100;
if ProcRes.status == valgrind_err {
fatal_ProcRes(~"run-fail test isn't valgrind-clean!", &ProcRes);
}
match config.target {
~"arm-linux-androideabi" => {
if (config.adb_device_status) {
check_correct_failure_status(&ProcRes);
check_error_patterns(props, testfile, &ProcRes);
}
}
_=> {
check_correct_failure_status(&ProcRes);
check_error_patterns(props, testfile, &ProcRes);
}
}
}
fn check_correct_failure_status(ProcRes: &ProcRes) {
// The value the rust runtime returns on failure
static rust_err: int = 101;
if ProcRes.status != rust_err {
fatal_ProcRes(
fmt!("failure produced the wrong error code: %d",
ProcRes.status),
ProcRes);
}
}
fn run_rpass_test(config: &config, props: &TestProps, testfile: &Path) {
if !config.jit {
let mut ProcRes = compile_test(config, props, testfile);
if ProcRes.status != 0 {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}
ProcRes = exec_compiled_test(config, props, testfile);
if ProcRes.status != 0 {
fatal_ProcRes(~"test run failed!", &ProcRes);
}
} else {
let ProcRes = jit_test(config, props, testfile);
if ProcRes.status != 0 { fatal_ProcRes(~"jit failed!", &ProcRes); }
}
}
fn run_pretty_test(config: &config, props: &TestProps, testfile: &Path) {
if props.pp_exact.is_some() {
logv(config, ~"testing for exact pretty-printing");
} else { logv(config, ~"testing for converging pretty-printing"); }
let rounds =
match props.pp_exact { Some(_) => 1, None => 2 };
let mut srcs = ~[io::read_whole_file_str(testfile).get()];
let mut round = 0;
while round < rounds {
logv(config, fmt!("pretty-printing round %d", round));
let ProcRes = print_source(config, testfile, copy srcs[round]);
if ProcRes.status != 0 {
fatal_ProcRes(fmt!("pretty-printing failed in round %d", round),
&ProcRes);
}
let ProcRes{ stdout, _ } = ProcRes;
srcs.push(stdout);
round += 1;
}
let mut expected =
match props.pp_exact {
Some(ref file) => {
let filepath = testfile.dir_path().push_rel(file);
io::read_whole_file_str(&filepath).get()
}
None => { copy srcs[srcs.len() - 2u] }
};
let mut actual = copy srcs[srcs.len() - 1u];
if props.pp_exact.is_some() {
// Now we have to care about line endings
let cr = ~"\r";
actual = actual.replace(cr, "");
expected = expected.replace(cr, "");
}
compare_source(expected, actual);
// Finally, let's make sure it actually appears to remain valid code
let ProcRes = typecheck_source(config, props, testfile, actual);
if ProcRes.status != 0 {
fatal_ProcRes(~"pretty-printed source does not typecheck", &ProcRes);
}
return;
fn print_source(config: &config, testfile: &Path, src: ~str) -> ProcRes {
compose_and_run(config, testfile, make_pp_args(config, testfile),
~[], config.compile_lib_path, Some(src))
}
fn make_pp_args(config: &config, _testfile: &Path) -> ProcArgs {
let args = ~[~"-", ~"--pretty", ~"normal"];
return ProcArgs {prog: config.rustc_path.to_str(), args: args};
}
fn compare_source(expected: &str, actual: &str) {
if expected != actual {
error(~"pretty-printed source does not match expected source");
let msg =
fmt!("\n\
expected:\n\
------------------------------------------\n\
%s\n\
------------------------------------------\n\
actual:\n\
------------------------------------------\n\
%s\n\
------------------------------------------\n\
\n",
expected, actual);
io::stdout().write_str(msg);
fail!();
}
}
fn typecheck_source(config: &config, props: &TestProps,
testfile: &Path, src: ~str) -> ProcRes {
let args = make_typecheck_args(config, props, testfile);
compose_and_run_compiler(config, props, testfile, args, Some(src))
}
fn make_typecheck_args(config: &config, props: &TestProps, testfile: &Path) -> ProcArgs {
let mut args = ~[~"-",
~"--no-trans", ~"--lib",
~"-L", config.build_base.to_str(),
~"-L",
aux_output_dir_name(config, testfile).to_str()];
args += split_maybe_args(&config.rustcflags);
args += split_maybe_args(&props.compile_flags);
return ProcArgs {prog: config.rustc_path.to_str(), args: args};
}
}
fn run_debuginfo_test(config: &config, props: &TestProps, testfile: &Path) {
// do not optimize debuginfo tests
let mut config = match config.rustcflags {
Some(ref flags) => config {
rustcflags: Some(flags.replace("-O", "")),
.. copy *config
},
None => copy *config
};
let config = &mut config;
let cmds = props.debugger_cmds.connect("\n");
let check_lines = copy props.check_lines;
// compile test file (it shoud have 'compile-flags:-g' in the header)
let mut ProcRes = compile_test(config, props, testfile);
if ProcRes.status != 0 {
fatal_ProcRes(~"compilation failed!", &ProcRes);
}
// write debugger script
let script_str = cmds.append("\nquit\n");
debug!("script_str = %s", script_str);
dump_output_file(config, testfile, script_str, "debugger.script");
// run debugger script with gdb
#[cfg(windows)]
fn debugger() -> ~str { ~"gdb.exe" }
#[cfg(unix)]
fn debugger() -> ~str { ~"gdb" }
let debugger_script = make_out_name(config, testfile, "debugger.script");
let debugger_opts = ~[~"-quiet", ~"-batch", ~"-nx",
~"-command=" + debugger_script.to_str(),
make_exe_name(config, testfile).to_str()];
let ProcArgs = ProcArgs {prog: debugger(), args: debugger_opts};
ProcRes = compose_and_run(config, testfile, ProcArgs, ~[], "", None);
if ProcRes.status != 0 {
fatal(~"gdb failed to execute");
}
let num_check_lines = check_lines.len();
if num_check_lines > 0 {
// check if each line in props.check_lines appears in the
// output (in order)
let mut i = 0u;
for ProcRes.stdout.line_iter().advance |line| {
if check_lines[i].trim() == line.trim() {
i += 1u;
}
if i == num_check_lines {
// all lines checked
break;
}
}
if i != num_check_lines {
fatal_ProcRes(fmt!("line not found in debugger output: %s"
check_lines[i]), &ProcRes);
}
}
}
fn check_error_patterns(props: &TestProps,
testfile: &Path,
ProcRes: &ProcRes) {
if props.error_patterns.is_empty() {
fatal(~"no error pattern specified in " + testfile.to_str());
}
if ProcRes.status == 0 {
fatal(~"process did not return an error status");
}
let mut next_err_idx = 0u;
let mut next_err_pat = &props.error_patterns[next_err_idx];
let mut done = false;
for ProcRes.stderr.line_iter().advance |line| {
if line.contains(*next_err_pat) {
debug!("found error pattern %s", *next_err_pat);
next_err_idx += 1u;
if next_err_idx == props.error_patterns.len() {
debug!("found all error patterns");
done = true;
break;
}
next_err_pat = &props.error_patterns[next_err_idx];
}
}
if done { return; }
let missing_patterns =
vec::slice(props.error_patterns, next_err_idx,
props.error_patterns.len());
if missing_patterns.len() == 1u {
fatal_ProcRes(fmt!("error pattern '%s' not found!",
missing_patterns[0]), ProcRes);
} else {
for missing_patterns.iter().advance |pattern| {
error(fmt!("error pattern '%s' not found!", *pattern));
}
fatal_ProcRes(~"multiple error patterns not found", ProcRes);
}
}
fn check_expected_errors(expected_errors: ~[errors::ExpectedError],
testfile: &Path,
ProcRes: &ProcRes) {
// true if we found the error in question
let mut found_flags = vec::from_elem(
expected_errors.len(), false);
if ProcRes.status == 0 {
fatal(~"process did not return an error status");
}
let prefixes = vec::map(expected_errors, |ee| {
fmt!("%s:%u:", testfile.to_str(), ee.line)
});
// Scan and extract our error/warning messages,
// which look like:
// filename:line1:col1: line2:col2: *error:* msg
// filename:line1:col1: line2:col2: *warning:* msg
// where line1:col1: is the starting point, line2:col2:
// is the ending point, and * represents ANSI color codes.
for ProcRes.stderr.line_iter().advance |line| {
let mut was_expected = false;
for expected_errors.iter().enumerate().advance |(i, ee)| {
if !found_flags[i] {
debug!("prefix=%s ee.kind=%s ee.msg=%s line=%s",
prefixes[i], ee.kind, ee.msg, line);
if (line.starts_with(prefixes[i]) &&
line.contains(ee.kind) &&
line.contains(ee.msg)) {
found_flags[i] = true;
was_expected = true;
break;
}
}
}
// ignore this msg which gets printed at the end
if line.contains("aborting due to") {
was_expected = true;
}
if !was_expected && is_compiler_error_or_warning(line) {
fatal_ProcRes(fmt!("unexpected compiler error or warning: '%s'",
line),
ProcRes);
}
}
for uint::range(0u, found_flags.len()) |i| {
if !found_flags[i] {
let ee = &expected_errors[i];
fatal_ProcRes(fmt!("expected %s on line %u not found: %s",
ee.kind, ee.line, ee.msg), ProcRes);
}
}
}
fn is_compiler_error_or_warning(line: &str) -> bool {
let mut i = 0u;
return
scan_until_char(line, ':', &mut i) &&
scan_char(line, ':', &mut i) &&
scan_integer(line, &mut i) &&
scan_char(line, ':', &mut i) &&
scan_integer(line, &mut i) &&
scan_char(line, ':', &mut i) &&
scan_char(line, ' ', &mut i) &&
scan_integer(line, &mut i) &&
scan_char(line, ':', &mut i) &&
scan_integer(line, &mut i) &&
scan_char(line, ' ', &mut i) &&
(scan_string(line, "error", &mut i) ||
scan_string(line, "warning", &mut i));
}
fn scan_until_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
if *idx >= haystack.len() {
return false;
}
let opt = haystack.slice_from(*idx).find(needle);
if opt.is_none() {
return false;
}
*idx = opt.get();
return true;
}
fn scan_char(haystack: &str, needle: char, idx: &mut uint) -> bool {
if *idx >= haystack.len() {
return false;
}
let range = haystack.char_range_at(*idx);
if range.ch != needle {
return false;
}
*idx = range.next;
return true;
}
fn scan_integer(haystack: &str, idx: &mut uint) -> bool {
let mut i = *idx;
while i < haystack.len() {
let range = haystack.char_range_at(i);
if range.ch < '0' || '9' < range.ch {
break;
}
i = range.next;
}
if i == *idx {
return false;
}
*idx = i;
return true;
}
fn scan_string(haystack: &str, needle: &str, idx: &mut uint) -> bool {
let mut haystack_i = *idx;
let mut needle_i = 0u;
while needle_i < needle.len() {
if haystack_i >= haystack.len() {
return false;
}
let range = haystack.char_range_at(haystack_i);
haystack_i = range.next;
if !scan_char(needle, range.ch, &mut needle_i) {
return false;
}
}
*idx = haystack_i;
return true;
}
struct ProcArgs {prog: ~str, args: ~[~str]}
struct ProcRes {status: int, stdout: ~str, stderr: ~str, cmdline: ~str}
fn compile_test(config: &config, props: &TestProps,
testfile: &Path) -> ProcRes {
compile_test_(config, props, testfile, [])
}
fn jit_test(config: &config, props: &TestProps, testfile: &Path) -> ProcRes {
compile_test_(config, props, testfile, [~"--jit"])
}
fn compile_test_(config: &config, props: &TestProps,
testfile: &Path, extra_args: &[~str]) -> ProcRes {
let link_args = ~[~"-L", aux_output_dir_name(config, testfile).to_str()];
let args = make_compile_args(config, props, link_args + extra_args,
make_exe_name, testfile);
compose_and_run_compiler(config, props, testfile, args, None)
}
fn exec_compiled_test(config: &config, props: &TestProps,
testfile: &Path) -> ProcRes {
// If testing the new runtime then set the RUST_NEWRT env var
let env = copy props.exec_env;
let env = if config.newrt { env + &[(~"RUST_NEWRT", ~"1")] } else { env };
match config.target {
~"arm-linux-androideabi" => {
if (config.adb_device_status) {
_arm_exec_compiled_test(config, props, testfile)
} else {
_dummy_exec_compiled_test(config, props, testfile)
}
}
_=> {
compose_and_run(config, testfile,
make_run_args(config, props, testfile),
env,
config.run_lib_path, None)
}
}
}
fn compose_and_run_compiler(
config: &config,
props: &TestProps,
testfile: &Path,
args: ProcArgs,
input: Option<~str>) -> ProcRes {
if !props.aux_builds.is_empty() {
ensure_dir(&aux_output_dir_name(config, testfile));
}
let extra_link_args = ~[~"-L",
aux_output_dir_name(config, testfile).to_str()];
for vec::each(props.aux_builds) |rel_ab| {
let abs_ab = config.aux_base.push_rel(&Path(*rel_ab));
let aux_args =
make_compile_args(config, props, ~[~"--lib"] + extra_link_args,
|a,b| make_lib_name(a, b, testfile), &abs_ab);
let auxres = compose_and_run(config, &abs_ab, aux_args, ~[],
config.compile_lib_path, None);
if auxres.status != 0 {
fatal_ProcRes(
fmt!("auxiliary build of %s failed to compile: ",
abs_ab.to_str()),
&auxres);
}
match config.target {
~"arm-linux-androideabi" => {
if (config.adb_device_status) {
_arm_push_aux_shared_library(config, testfile);
}
}
_=> { }
}
}
compose_and_run(config, testfile, args, ~[],
config.compile_lib_path, input)
}
fn ensure_dir(path: &Path) {
if os::path_is_dir(path) { return; }
if !os::make_dir(path, 0x1c0i32) {
fail!("can't make dir %s", path.to_str());
}
}
fn compose_and_run(config: &config, testfile: &Path,
ProcArgs{ args, prog }: ProcArgs,
procenv: ~[(~str, ~str)],
lib_path: &str,
input: Option<~str>) -> ProcRes {
return program_output(config, testfile, lib_path,
prog, args, procenv, input);
}
fn make_compile_args(config: &config, props: &TestProps, extras: ~[~str],
xform: &fn(&config, (&Path)) -> Path,
testfile: &Path) -> ProcArgs {
let mut args = ~[testfile.to_str(),
~"-o", xform(config, testfile).to_str(),
~"-L", config.build_base.to_str()]
+ extras;
args += split_maybe_args(&config.rustcflags);
args += split_maybe_args(&props.compile_flags);
return ProcArgs {prog: config.rustc_path.to_str(), args: args};
}
fn make_lib_name(config: &config, auxfile: &Path, testfile: &Path) -> Path {
// what we return here is not particularly important, as it
// happens; rustc ignores everything except for the directory.
let auxname = output_testname(auxfile);
aux_output_dir_name(config, testfile).push_rel(&auxname)
}
fn make_exe_name(config: &config, testfile: &Path) -> Path {
Path(output_base_name(config, testfile).to_str() + os::EXE_SUFFIX)
}
fn make_run_args(config: &config, _props: &TestProps, testfile: &Path) ->
ProcArgs {
// If we've got another tool to run under (valgrind),
// then split apart its command
let toolargs = split_maybe_args(&config.runtool);
let mut args = toolargs + [make_exe_name(config, testfile).to_str()];
let prog = args.shift();
return ProcArgs {prog: prog, args: args};
}
fn split_maybe_args(argstr: &Option<~str>) -> ~[~str] {
match *argstr {
Some(ref s) => {
s.split_iter(' ')
.filter_map(|s| if s.is_whitespace() {None} else {Some(s.to_owned())})
.collect()
}
None => ~[]
}
}
fn program_output(config: &config, testfile: &Path, lib_path: &str, prog: ~str,
args: ~[~str], env: ~[(~str, ~str)],
input: Option<~str>) -> ProcRes {
let cmdline =
{
let cmdline = make_cmdline(lib_path, prog, args);
logv(config, fmt!("executing %s", cmdline));
cmdline
};
let procsrv::Result{ out, err, status } =
procsrv::run(lib_path, prog, args, env, input);
dump_output(config, testfile, out, err);
return ProcRes {status: status,
stdout: out,
stderr: err,
cmdline: cmdline};
}
// Linux and mac don't require adjusting the library search path
#[cfg(target_os = "linux")]
#[cfg(target_os = "macos")]
#[cfg(target_os = "freebsd")]
fn make_cmdline(_libpath: &str, prog: &str, args: &[~str]) -> ~str {
fmt!("%s %s", prog, args.connect(" "))
}
#[cfg(target_os = "win32")]
fn make_cmdline(libpath: &str, prog: &str, args: &[~str]) -> ~str {
fmt!("%s %s %s", lib_path_cmd_prefix(libpath), prog,
args.connect(" "))
}
// Build the LD_LIBRARY_PATH variable as it would be seen on the command line
// for diagnostic purposes
fn lib_path_cmd_prefix(path: &str) -> ~str {
fmt!("%s=\"%s\"", util::lib_path_env_var(), util::make_new_path(path))
}
fn dump_output(config: &config, testfile: &Path, out: &str, err: &str) {
dump_output_file(config, testfile, out, "out");
dump_output_file(config, testfile, err, "err");
maybe_dump_to_stdout(config, out, err);
}
fn dump_output_file(config: &config, testfile: &Path,
out: &str, extension: &str) {
let outfile = make_out_name(config, testfile, extension);
let writer =
io::file_writer(&outfile, [io::Create, io::Truncate]).get();
writer.write_str(out);
}
fn make_out_name(config: &config, testfile: &Path, extension: &str) -> Path {
output_base_name(config, testfile).with_filetype(extension)
}
fn aux_output_dir_name(config: &config, testfile: &Path) -> Path {
output_base_name(config, testfile).with_filetype("libaux")
}
fn output_testname(testfile: &Path) -> Path {
Path(testfile.filestem().get())
}
fn output_base_name(config: &config, testfile: &Path) -> Path {
config.build_base
.push_rel(&output_testname(testfile))
.with_filetype(config.stage_id)
}
fn maybe_dump_to_stdout(config: &config, out: &str, err: &str) {
if config.verbose {
let sep1 = fmt!("------%s------------------------------", "stdout");
let sep2 = fmt!("------%s------------------------------", "stderr");
let sep3 = ~"------------------------------------------";
io::stdout().write_line(sep1);
io::stdout().write_line(out);
io::stdout().write_line(sep2);
io::stdout().write_line(err);
io::stdout().write_line(sep3);
}
}
fn error(err: ~str) { io::stdout().write_line(fmt!("\nerror: %s", err)); }
fn fatal(err: ~str) -> ! { error(err); fail!(); }
fn fatal_ProcRes(err: ~str, ProcRes: &ProcRes) -> ! {
let msg =
fmt!("\n\
error: %s\n\
command: %s\n\
stdout:\n\
------------------------------------------\n\
%s\n\
------------------------------------------\n\
stderr:\n\
------------------------------------------\n\
%s\n\
------------------------------------------\n\
\n",
err, ProcRes.cmdline, ProcRes.stdout, ProcRes.stderr);
io::stdout().write_str(msg);
fail!();
}
fn _arm_exec_compiled_test(config: &config, props: &TestProps,
testfile: &Path) -> ProcRes {
let args = make_run_args(config, props, testfile);
let cmdline = make_cmdline("", args.prog, args.args);
// get bare program string
let mut tvec: ~[~str] = args.prog.split_iter('/').transform(|ts| ts.to_owned()).collect();
let prog_short = tvec.pop();
// copy to target
let copy_result = procsrv::run("", config.adb_path,
[~"push", copy args.prog, copy config.adb_test_dir],
~[(~"",~"")], Some(~""));
if config.verbose {
io::stdout().write_str(fmt!("push (%s) %s %s %s",
config.target, args.prog,
copy_result.out, copy_result.err));
}
logv(config, fmt!("executing (%s) %s", config.target, cmdline));
let mut runargs = ~[];
// run test via adb_run_wrapper
runargs.push(~"shell");
runargs.push(fmt!("%s/adb_run_wrapper.sh", config.adb_test_dir));
runargs.push(fmt!("%s", config.adb_test_dir));
runargs.push(fmt!("%s", prog_short));
for args.args.iter().advance |tv| {
runargs.push(tv.to_owned());
}
procsrv::run("", config.adb_path, runargs, ~[(~"",~"")], Some(~""));
// get exitcode of result
runargs = ~[];
runargs.push(~"shell");
runargs.push(~"cat");
runargs.push(fmt!("%s/%s.exitcode", config.adb_test_dir, prog_short));
let procsrv::Result{ out: exitcode_out, err: _, status: _ } =
procsrv::run("", config.adb_path, runargs, ~[(~"",~"")],
Some(~""));
let mut exitcode : int = 0;
for exitcode_out.iter().advance |c| {
if !c.is_digit() { break; }
exitcode = exitcode * 10 + match c {
'0' .. '9' => c as int - ('0' as int),
_ => 101,
}
}
// get stdout of result
runargs = ~[];
runargs.push(~"shell");
runargs.push(~"cat");
runargs.push(fmt!("%s/%s.stdout", config.adb_test_dir, prog_short));
let procsrv::Result{ out: stdout_out, err: _, status: _ } =
procsrv::run("", config.adb_path, runargs, ~[(~"",~"")], Some(~""));
// get stderr of result
runargs = ~[];
runargs.push(~"shell");
runargs.push(~"cat");
runargs.push(fmt!("%s/%s.stderr", config.adb_test_dir, prog_short));
let procsrv::Result{ out: stderr_out, err: _, status: _ } =
procsrv::run("", config.adb_path, runargs, ~[(~"",~"")], Some(~""));
dump_output(config, testfile, stdout_out, stderr_out);
ProcRes {status: exitcode, stdout: stdout_out, stderr: stderr_out, cmdline: cmdline }
}
fn _dummy_exec_compiled_test(config: &config, props: &TestProps,
testfile: &Path) -> ProcRes {
let args = make_run_args(config, props, testfile);
let cmdline = make_cmdline("", args.prog, args.args);
match config.mode {
mode_run_fail => ProcRes {status: 101, stdout: ~"",
stderr: ~"", cmdline: cmdline},
_ => ProcRes {status: 0, stdout: ~"",
stderr: ~"", cmdline: cmdline}
}
}
fn _arm_push_aux_shared_library(config: &config, testfile: &Path) {
let tstr = aux_output_dir_name(config, testfile).to_str();
let dirs = os::list_dir_path(&Path(tstr));
for dirs.iter().advance |file| {
if (file.filetype() == Some(~".so")) {
let copy_result = procsrv::run("", config.adb_path,
[~"push", file.to_str(), copy config.adb_test_dir],
~[(~"",~"")], Some(~""));
if config.verbose {
io::stdout().write_str(fmt!("push (%s) %s %s %s",
config.target, file.to_str(),
copy_result.out, copy_result.err));
}
}
}
}