.dep(|s| s.name("libtest"))
.dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
.dep(|s| s.name("test-helpers"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.default(mode != "pretty") // pretty tests don't run everywhere
.run(move |s| {
check::compiletest(build, &s.compiler(), s.target, mode, dir)
.dep(|s| s.name("tool-compiletest").target(s.host).stage(0))
.dep(|s| s.name("test-helpers"))
.dep(|s| s.name("debugger-scripts"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.run(move |s| check::compiletest(build, &s.compiler(), s.target,
"debuginfo-gdb", "debuginfo"));
let mut rule = rules.test("check-debuginfo", "src/test/debuginfo");
for (krate, path, _default) in krates("std") {
rules.test(&krate.test_step, path)
.dep(|s| s.name("libtest"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Libstd, TestKind::Test,
Some(&krate.name)));
}
rules.test("check-std-all", "path/to/nowhere")
.dep(|s| s.name("libtest"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.default(true)
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Libstd, TestKind::Test, None));
for (krate, path, _default) in krates("std") {
rules.bench(&krate.bench_step, path)
.dep(|s| s.name("libtest"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Libstd, TestKind::Bench,
Some(&krate.name)));
}
rules.bench("bench-std-all", "path/to/nowhere")
.dep(|s| s.name("libtest"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.default(true)
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Libstd, TestKind::Bench, None));
for (krate, path, _default) in krates("test") {
rules.test(&krate.test_step, path)
.dep(|s| s.name("libtest"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Libtest, TestKind::Test,
Some(&krate.name)));
}
rules.test("check-test-all", "path/to/nowhere")
.dep(|s| s.name("libtest"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.default(true)
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Libtest, TestKind::Test, None));
for (krate, path, _default) in krates("rustc-main") {
rules.test(&krate.test_step, path)
.dep(|s| s.name("librustc"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.host(true)
.run(move |s| check::krate(build, &s.compiler(), s.target,
Mode::Librustc, TestKind::Test,
}
rules.test("check-rustc-all", "path/to/nowhere")
.dep(|s| s.name("librustc"))
- .dep(|s| s.name("emulator-copy-libs"))
+ .dep(|s| s.name("remote-copy-libs"))
.default(true)
.host(true)
.run(move |s| check::krate(build, &s.compiler(), s.target,
rules.build("openssl", "path/to/nowhere")
.run(move |s| native::openssl(build, s.target));
- // Some test suites are run inside emulators, and most of our test binaries
- // are linked dynamically which means we need to ship the standard library
- // and such to the emulator ahead of time. This step represents this and is
- // a dependency of all test suites.
+ // Some test suites are run inside emulators or on remote devices, and most
+ // of our test binaries are linked dynamically which means we need to ship
+ // the standard library and such to the emulator ahead of time. This step
+ // represents this and is a dependency of all test suites.
//
// Most of the time this step is a noop (the `check::emulator_copy_libs`
// only does work if necessary). For some steps such as shipping data to
// QEMU we have to build our own tools so we've got conditional dependencies
- // on those programs as well. Note that the QEMU client is built for the
- // build target (us) and the server is built for the target.
- rules.test("emulator-copy-libs", "path/to/nowhere")
+ // on those programs as well. Note that the remote test client is built for
+ // the build target (us) and the server is built for the target.
+ rules.test("remote-copy-libs", "path/to/nowhere")
.dep(|s| s.name("libtest"))
.dep(move |s| {
if build.remote_tested(s.target) {
Step::noop()
}
})
- .run(move |s| check::emulator_copy_libs(build, &s.compiler(), s.target));
+ .run(move |s| check::remote_copy_libs(build, &s.compiler(), s.target));
rules.test("check-bootstrap", "src/bootstrap")
.default(true)
use std::thread;
use std::time::Duration;
+const REMOTE_ADDR_ENV: &'static str = "TEST_DEVICE_ADDR";
+
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
server: &Path,
tmpdir: &Path,
rootfs: Option<PathBuf>) {
- if target.contains("android") {
+ let device_address = env::var(REMOTE_ADDR_ENV).unwrap_or("127.0.0.1:12345".to_string());
+
+ if env::var(REMOTE_ADDR_ENV).is_ok() {
+ println!("Connecting to remote device {} ...", device_address);
+ } else if target.contains("android") {
start_android_emulator(server);
} else {
let rootfs = rootfs.as_ref().expect("need rootfs on non-android");
// Wait for the emulator to come online
loop {
let dur = Duration::from_millis(100);
- if let Ok(mut client) = TcpStream::connect("127.0.0.1:12345") {
+ if let Ok(mut client) = TcpStream::connect(&device_address) {
t!(client.set_read_timeout(Some(dur)));
t!(client.set_write_timeout(Some(dur)));
if client.write_all(b"ping").is_ok() {
}
fn push(path: &Path) {
- let client = t!(TcpStream::connect("127.0.0.1:12345"));
+ let device_address = env::var(REMOTE_ADDR_ENV).unwrap_or("127.0.0.1:12345".to_string());
+ let client = t!(TcpStream::connect(device_address));
let mut client = BufWriter::new(client);
t!(client.write_all(b"push"));
send(path, &mut client);
}
fn run(files: String, args: Vec<String>) {
- let client = t!(TcpStream::connect("127.0.0.1:12345"));
+ let device_address = env::var(REMOTE_ADDR_ENV).unwrap_or("127.0.0.1:12345".to_string());
+ let client = t!(TcpStream::connect(device_address));
let mut client = BufWriter::new(client);
t!(client.write_all(b"run "));
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-/// This is a small server which is intended to run inside of an emulator. This
-/// server pairs with the `remote-test-client` program in this repository. The
-/// `remote-test-client` connects to this server over a TCP socket and performs
-/// work such as:
+/// This is a small server which is intended to run inside of an emulator or
+/// on a remote test device. This server pairs with the `remote-test-client`
+/// program in this repository. The `remote-test-client` connects to this
+/// server over a TCP socket and performs work such as:
///
/// 1. Pushing shared libraries to the server
/// 2. Running tests through the server
/// basically custom format suiting our needs.
use std::cmp;
+use std::env;
use std::fs::{self, File, Permissions};
use std::io::prelude::*;
use std::io::{self, BufReader};
static TEST: AtomicUsize = ATOMIC_USIZE_INIT;
+struct Config {
+ pub remote: bool,
+ pub verbose: bool,
+}
+
+impl Config {
+ pub fn default() -> Config {
+ Config {
+ remote: false,
+ verbose: false,
+ }
+ }
+
+ pub fn parse_args() -> Config {
+ let mut config = Config::default();
+
+ let args = env::args().skip(1);
+ for argument in args {
+ match &argument[..] {
+ "remote" => {
+ config.remote = true;
+ },
+ "verbose" | "-v" => {
+ config.verbose = true;
+ }
+ arg => panic!("unknown argument: {}", arg),
+ }
+ }
+
+ config
+ }
+}
+
fn main() {
println!("starting test server");
+
+ let config = Config::parse_args();
+
+ let bind_addr = if cfg!(target_os = "android") || config.remote {
+ "0.0.0.0:12345"
+ } else {
+ "10.0.2.15:12345"
+ };
+
let (listener, work) = if cfg!(target_os = "android") {
- (t!(TcpListener::bind("0.0.0.0:12345")), "/data/tmp/work")
+ (t!(TcpListener::bind(bind_addr)), "/data/tmp/work")
} else {
- (t!(TcpListener::bind("10.0.2.15:12345")), "/tmp/work")
+ (t!(TcpListener::bind(bind_addr)), "/tmp/work")
};
println!("listening!");