From f7ef71d491fe432eab3c3c9d2ee80a6678ebb952 Mon Sep 17 00:00:00 2001 From: Young-il Choi Date: Wed, 1 May 2013 18:52:08 +0900 Subject: [PATCH] compiletest: expanded to ARM test automation --- src/compiletest/common.rs | 12 ++++ src/compiletest/compiletest.rc | 26 ++++++- src/compiletest/runtest.rs | 127 +++++++++++++++++++++++++++++++-- 3 files changed, 158 insertions(+), 7 deletions(-) diff --git a/src/compiletest/common.rs b/src/compiletest/common.rs index e515ef302f65..73322fe1bdea 100644 --- a/src/compiletest/common.rs +++ b/src/compiletest/common.rs @@ -64,6 +64,18 @@ pub struct config { // Run tests using the new runtime newrt: bool, + // Host System to be built + host: ~str, + + // Target System to be executed + target: ~str, + + // Extra parameter to run arm-linux-androideabi + adb_path: ~str, + + // check if can be run or not + flag_runnable: bool, + // Explain what's going on verbose: bool diff --git a/src/compiletest/compiletest.rc b/src/compiletest/compiletest.rc index 4392ce7ba289..70e09fc7bab7 100644 --- a/src/compiletest/compiletest.rc +++ b/src/compiletest/compiletest.rc @@ -60,7 +60,11 @@ pub fn parse_config(args: ~[~str]) -> config { getopts::optflag(~"verbose"), getopts::optopt(~"logfile"), getopts::optflag(~"jit"), - getopts::optflag(~"newrt")]; + getopts::optflag(~"newrt"), + getopts::optopt(~"host"), + getopts::optopt(~"target"), + getopts::optopt(~"adb-path") + ]; assert!(!args.is_empty()); let args_ = vec::tail(args); @@ -93,6 +97,22 @@ pub fn parse_config(args: ~[~str]) -> config { rustcflags: getopts::opt_maybe_str(matches, ~"rustcflags"), jit: getopts::opt_present(matches, ~"jit"), newrt: getopts::opt_present(matches, ~"newrt"), + host: opt_str(getopts::opt_maybe_str(matches, ~"host")), + target: opt_str(getopts::opt_maybe_str(matches, ~"target")), + adb_path: opt_str(getopts::opt_maybe_str(matches, ~"adb-path")), + flag_runnable: + if (getopts::opt_maybe_str(matches, ~"host") == + getopts::opt_maybe_str(matches, ~"target")) { true } + else { + match getopts::opt_maybe_str(matches, ~"target") { + Some(~"arm-linux-androideabi") => { + if (getopts::opt_maybe_str(matches, ~"adb-path") != + option::None) { true } + else { false } + } + _ => { false } + } + }, verbose: getopts::opt_present(matches, ~"verbose") } } @@ -113,6 +133,10 @@ pub fn log_config(config: config) { logv(c, fmt!("rustcflags: %s", opt_str(config.rustcflags))); logv(c, fmt!("jit: %b", config.jit)); logv(c, fmt!("newrt: %b", config.newrt)); + logv(c, fmt!("host: %s", config.host)); + logv(c, fmt!("target: %s", config.target)); + logv(c, fmt!("adb_path: %s", config.adb_path)); + logv(c, fmt!("flag_runnable: %b", config.flag_runnable)); logv(c, fmt!("verbose: %b", config.verbose)); logv(c, fmt!("\n")); } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index fef4cabf7fd6..4b07835163c0 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -77,8 +77,10 @@ fn run_rfail_test(config: config, props: TestProps, testfile: &Path) { fatal_ProcRes(~"run-fail test isn't valgrind-clean!", ProcRes); } - check_correct_failure_status(ProcRes); - check_error_patterns(props, testfile, ProcRes); + if (config.flag_runnable) { + check_correct_failure_status(ProcRes); + check_error_patterns(props, testfile, ProcRes); + } } fn check_correct_failure_status(ProcRes: ProcRes) { @@ -483,10 +485,96 @@ fn exec_compiled_test(config: config, props: TestProps, props.exec_env }; - compose_and_run(config, testfile, - make_run_args(config, props, testfile), - env, - config.run_lib_path, None) + if (config.host == config.target) { + compose_and_run(config, testfile, + make_run_args(config, props, testfile), + env, + config.run_lib_path, None) + } + else { + let args = make_run_args(config, props, testfile); + let cmdline = make_cmdline(~"", args.prog, args.args); + + let defaultRes = match config.mode { + mode_run_fail => ProcRes {status: 101, stdout: ~"", stderr: ~"", cmdline: cmdline}, + _ => ProcRes {status: 0, stdout: ~"", stderr: ~"", cmdline: cmdline} + }; + + match (config.target, config.flag_runnable) { + + (~"arm-linux-androideabi", true) => { + + // get bare program string + let mut tvec = ~[]; + let tstr = args.prog; + for str::each_split_char(tstr, '/') |ts| { tvec.push(ts.to_owned()) } + let prog_short = tvec.pop(); + + // copy to target + let copy_result = procsrv::run(~"", config.adb_path, + ~[~"push", args.prog, ~"/system/tmp"], + ~[(~"",~"")], Some(~"")); + + if config.verbose { + io::stdout().write_str(fmt!("push (%s) %s %s %s", + config.target, args.prog, + copy_result.out, copy_result.err)); + } + + // execute program + logv(config, fmt!("executing (%s) %s", config.target, cmdline)); + + // NOTE : adb shell dose not forward to each stdout and stderr of internal result + // but forward to stdout only + let mut newargs_out = ~[]; + let mut newargs_err = ~[]; + let subargs = args.args; + newargs_out.push(~"shell"); + newargs_err.push(~"shell"); + + let mut newcmd_out = ~""; + let mut newcmd_err = ~""; + newcmd_out.push_str(~"LD_LIBRARY_PATH=/system/tmp; "); + newcmd_err.push_str(~"LD_LIBRARY_PATH=/system/tmp; "); + newcmd_out.push_str(~"export LD_LIBRARY_PATH; "); + newcmd_err.push_str(~"export LD_LIBRARY_PATH; "); + newcmd_out.push_str(~"cd /system/tmp; "); + newcmd_err.push_str(~"cd /system/tmp; "); + newcmd_out.push_str("./"); + newcmd_err.push_str("./"); + newcmd_out.push_str(prog_short); + newcmd_err.push_str(prog_short); + + for vec::each(subargs) |tv| { + newcmd_out.push_str(" "); + newcmd_err.push_str(" "); + newcmd_out.push_str(tv.to_owned()); + newcmd_err.push_str(tv.to_owned()); + } + + newcmd_out.push_str(" 2>/dev/null"); + newcmd_err.push_str(" 1>/dev/null"); + + newargs_out.push(newcmd_out); + newargs_err.push(newcmd_err); + + let exe_result_out = procsrv::run(~"", config.adb_path, + newargs_out, ~[(~"",~"")], Some(~"")); + let exe_result_err = procsrv::run(~"", config.adb_path, + newargs_err, ~[(~"",~"")], Some(~"")); + + dump_output(config, testfile, exe_result_out.out, exe_result_err.out); + + match exe_result_err.out { + ~"" => ProcRes {status: exe_result_out.status, stdout: exe_result_out.out, + stderr: exe_result_err.out, cmdline: cmdline }, + _ => ProcRes {status: 101, stdout: exe_result_out.out, + stderr: exe_result_err.out, cmdline: cmdline } + } + } + _=> defaultRes + } + } } fn compose_and_run_compiler( @@ -516,6 +604,33 @@ fn compose_and_run_compiler( abs_ab.to_str()), auxres); } + if (config.host != config.target) + { + match (config.target, config.flag_runnable) { + + (~"arm-linux-androideabi", true) => { + + let tstr = aux_output_dir_name(config, testfile).to_str(); + + for os::list_dir_path(&Path(tstr)).each |file| { + + if (file.filetype() == Some(~".so")) { + + let copy_result = procsrv::run(~"", config.adb_path, + ~[~"push", file.to_str(), ~"/system/tmp"], + ~[(~"",~"")], 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)); + } + } + } + } + _=> () + } + } } compose_and_run(config, testfile, args, ~[],