Add support for test suites emulated in QEMU

This commit adds support to the build system to execute test suites that cannot
run natively but can instead run inside of a QEMU emulator. A proof-of-concept
builder was added for the `arm-unknown-linux-gnueabihf` target to show off how
this might work.

In general the architecture is to have a server running inside of the emulator
which a local client connects to. The protocol between the server/client
supports compiling tests on the host and running them on the target inside the
emulator.

Closes #33114
This commit is contained in:
Alex Crichton 2017-01-28 13:38:06 -08:00
parent 4be49e1937
commit 1747ce25ad
23 changed files with 3772 additions and 49 deletions

View file

@ -185,6 +185,9 @@ pub struct Config {
// Print one character per test instead of one line
pub quiet: bool,
// where to find the qemu test client process, if we're using it
pub qemu_test_client: Option<PathBuf>,
// Configuration for various run-make tests frobbing things like C compilers
// or querying about various LLVM component information.
pub cc: String,

View file

@ -116,6 +116,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
reqopt("", "llvm-components", "list of LLVM components built in", "LIST"),
reqopt("", "llvm-cxxflags", "C++ flags for LLVM", "FLAGS"),
optopt("", "nodejs", "the name of nodejs", "PATH"),
optopt("", "qemu-test-client", "path to the qemu test client", "PATH"),
optflag("h", "help", "show this message")];
let (argv0, args_) = args.split_first().unwrap();
@ -196,6 +197,7 @@ pub fn parse_config(args: Vec<String> ) -> Config {
lldb_python_dir: matches.opt_str("lldb-python-dir"),
verbose: matches.opt_present("verbose"),
quiet: matches.opt_present("quiet"),
qemu_test_client: matches.opt_str("qemu-test-client").map(PathBuf::from),
cc: matches.opt_str("cc").unwrap(),
cxx: matches.opt_str("cxx").unwrap(),
@ -302,6 +304,14 @@ pub fn run_tests(config: &Config) {
// time.
env::set_var("RUST_TEST_THREADS", "1");
}
DebugInfoGdb => {
if config.qemu_test_client.is_some() {
println!("WARNING: debuginfo tests are not available when \
testing with QEMU");
return
}
}
_ => { /* proceed */ }
}

View file

@ -1190,7 +1190,45 @@ actual:\n\
"arm-linux-androideabi" | "armv7-linux-androideabi" | "aarch64-linux-android" => {
self._arm_exec_compiled_test(env)
}
_=> {
// This is pretty similar to below, we're transforming:
//
// program arg1 arg2
//
// into
//
// qemu-test-client run program:support-lib.so arg1 arg2
//
// The test-client program will upload `program` to the emulator
// along with all other support libraries listed (in this case
// `support-lib.so`. It will then execute the program on the
// emulator with the arguments specified (in the environment we give
// the process) and then report back the same result.
_ if self.config.qemu_test_client.is_some() => {
let aux_dir = self.aux_output_dir_name();
let mut args = self.make_run_args();
let mut program = args.prog.clone();
if let Ok(entries) = aux_dir.read_dir() {
for entry in entries {
let entry = entry.unwrap();
if !entry.path().is_file() {
continue
}
program.push_str(":");
program.push_str(entry.path().to_str().unwrap());
}
}
args.args.insert(0, program);
args.args.insert(0, "run".to_string());
args.prog = self.config.qemu_test_client.clone().unwrap()
.into_os_string().into_string().unwrap();
self.compose_and_run(args,
env,
self.config.run_lib_path.to_str().unwrap(),
Some(aux_dir.to_str().unwrap()),
None)
}
_ => {
let aux_dir = self.aux_output_dir_name();
self.compose_and_run(self.make_run_args(),
env,