Auto merge of #498 - learnopengles:run-ios-tests, r=alexcrichton

Run ios tests

This WIP PR runs the tests on the iOS simulator. I've tested it locally using macOS Sierra and XCode 8.2.1. I get this output:

RUNNING ALL TESTS
PASSED 6756 tests

The python script probably needs to be customized for the specific failure output from this test runner (update: newest commit should have this).
This commit is contained in:
bors 2017-01-18 18:21:23 +00:00
commit 4eb6bf9cc9
4 changed files with 184 additions and 2 deletions

View file

@ -17,7 +17,6 @@ script:
sh ci/run.sh $TARGET; sh ci/run.sh $TARGET;
fi fi
- rustc ci/style.rs && ./style src - rustc ci/style.rs && ./style src
osx_image: xcode7.3
env: env:
global: global:
secure: "e2/3QjgRN9atOuSHp22TrYG7QVKcYUWY48Hi9b60w+r1+BhPkTseIJLte7WefRhdXtqpjjUJTooKDhnurFOeHaCT+nmBgiv+FPU893sBl4bhesY4m0vgUJVbNZcs6lTImYekWVb+aqjGdgV/XAgCw7c3kPmrZV0MzGDWL64Xaps=" secure: "e2/3QjgRN9atOuSHp22TrYG7QVKcYUWY48Hi9b60w+r1+BhPkTseIJLte7WefRhdXtqpjjUJTooKDhnurFOeHaCT+nmBgiv+FPU893sBl4bhesY4m0vgUJVbNZcs6lTImYekWVb+aqjGdgV/XAgCw7c3kPmrZV0MzGDWL64Xaps="
@ -65,9 +64,11 @@ matrix:
env: TARGET=aarch64-unknown-linux-gnu env: TARGET=aarch64-unknown-linux-gnu
rust: stable rust: stable
- os: osx - os: osx
osx_image: xcode8.2
env: TARGET=i386-apple-ios env: TARGET=i386-apple-ios
rust: stable rust: stable
- os: osx - os: osx
osx_image: xcode8.2
env: TARGET=x86_64-apple-ios env: TARGET=x86_64-apple-ios
rust: stable rust: stable
- os: linux - os: linux

View file

@ -111,7 +111,7 @@ Tested:
* [`i686-apple-darwin`](https://doc.rust-lang.org/libc/i686-apple-darwin/libc/) * [`i686-apple-darwin`](https://doc.rust-lang.org/libc/i686-apple-darwin/libc/)
* [`x86_64-apple-darwin`](https://doc.rust-lang.org/libc/x86_64-apple-darwin/libc/) * [`x86_64-apple-darwin`](https://doc.rust-lang.org/libc/x86_64-apple-darwin/libc/)
(OSX) (OSX)
* `i686-apple-ios` * `i386-apple-ios`
* `x86_64-apple-ios` * `x86_64-apple-ios`
* [`i686-unknown-linux-gnu`](https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/) * [`i686-unknown-linux-gnu`](https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/)
* [`x86_64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/) * [`x86_64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/)

View file

@ -0,0 +1,171 @@
// Copyright 2017 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.
// This is a script to deploy and execute a binary on an iOS simulator.
// The primary use of this is to be able to run unit tests on the simulator and
// retrieve the results.
//
// To do this through Cargo instead, use Dinghy
// (https://github.com/snipsco/dinghy): cargo dinghy install, then cargo dinghy
// test.
use std::env;
use std::fs::{self, File};
use std::io::Write;
use std::path::Path;
use std::process;
use std::process::Command;
macro_rules! t {
($e:expr) => (match $e {
Ok(e) => e,
Err(e) => panic!("{} failed with: {}", stringify!($e), e),
})
}
// Step one: Wrap as an app
fn package_as_simulator_app(crate_name: &str, test_binary_path: &Path) {
println!("Packaging simulator app");
drop(fs::remove_dir_all("ios_simulator_app"));
t!(fs::create_dir("ios_simulator_app"));
t!(fs::copy(test_binary_path,
Path::new("ios_simulator_app").join(crate_name)));
let mut f = t!(File::create("ios_simulator_app/Info.plist"));
t!(f.write_all(format!(r#"
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC
"-//Apple//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleExecutable</key>
<string>{}</string>
<key>CFBundleIdentifier</key>
<string>com.rust.unittests</string>
</dict>
</plist>
"#, crate_name).as_bytes()));
}
// Step two: Start the iOS simulator
fn start_simulator() {
println!("Looking for iOS simulator");
let output = t!(Command::new("xcrun").arg("simctl").arg("list").output());
assert!(output.status.success());
let mut simulator_exists = false;
let mut simulator_booted = false;
let mut found_rust_sim = false;
let stdout = t!(String::from_utf8(output.stdout));
for line in stdout.lines() {
if line.contains("rust_ios") {
if found_rust_sim {
panic!("Duplicate rust_ios simulators found. Please \
double-check xcrun simctl list.");
}
simulator_exists = true;
simulator_booted = line.contains("(Booted)");
found_rust_sim = true;
}
}
if simulator_exists == false {
println!("Creating iOS simulator");
Command::new("xcrun")
.arg("simctl")
.arg("create")
.arg("rust_ios")
.arg("com.apple.CoreSimulator.SimDeviceType.iPhone-SE")
.arg("com.apple.CoreSimulator.SimRuntime.iOS-10-2")
.check_status();
} else if simulator_booted == true {
println!("Shutting down already-booted simulator");
Command::new("xcrun")
.arg("simctl")
.arg("shutdown")
.arg("rust_ios")
.check_status();
}
println!("Starting iOS simulator");
// We can't uninstall the app (if present) as that will hang if the
// simulator isn't completely booted; just erase the simulator instead.
Command::new("xcrun").arg("simctl").arg("erase").arg("rust_ios").check_status();
Command::new("xcrun").arg("simctl").arg("boot").arg("rust_ios").check_status();
}
// Step three: Install the app
fn install_app_to_simulator() {
println!("Installing app to simulator");
Command::new("xcrun")
.arg("simctl")
.arg("install")
.arg("booted")
.arg("ios_simulator_app/")
.check_status();
}
// Step four: Run the app
fn run_app_on_simulator() {
println!("Running app");
let output = t!(Command::new("xcrun")
.arg("simctl")
.arg("launch")
.arg("--console")
.arg("booted")
.arg("com.rust.unittests")
.output());
println!("stdout --\n{}\n", String::from_utf8_lossy(&output.stdout));
println!("stderr --\n{}\n", String::from_utf8_lossy(&output.stderr));
let stdout = String::from_utf8_lossy(&output.stdout);
let passed = stdout.lines()
.find(|l| l.contains("PASSED"))
.map(|l| l.contains("tests"))
.unwrap_or(false);
println!("Shutting down simulator");
Command::new("xcrun")
.arg("simctl")
.arg("shutdown")
.arg("rust_ios")
.check_status();
if !passed {
panic!("tests didn't pass");
}
}
trait CheckStatus {
fn check_status(&mut self);
}
impl CheckStatus for Command {
fn check_status(&mut self) {
println!("\trunning: {:?}", self);
assert!(t!(self.status()).success());
}
}
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Usage: {} <executable>", args[0]);
process::exit(-1);
}
let test_binary_path = Path::new(&args[1]);
let crate_name = test_binary_path.file_name().unwrap();
package_as_simulator_app(crate_name.to_str().unwrap(), test_binary_path);
start_simulator();
install_app_to_simulator();
run_app_on_simulator();
}

View file

@ -113,6 +113,16 @@ case "$TARGET" in
grep "^PASSED .* tests" /tmp/out grep "^PASSED .* tests" /tmp/out
;; ;;
i386-apple-ios)
rustc -O ./ci/ios/deploy_and_run_on_ios_simulator.rs
./deploy_and_run_on_ios_simulator $CARGO_TARGET_DIR/$TARGET/debug/libc-test
;;
x86_64-apple-ios)
rustc -O ./ci/ios/deploy_and_run_on_ios_simulator.rs
./deploy_and_run_on_ios_simulator $CARGO_TARGET_DIR/$TARGET/debug/libc-test
;;
arm-unknown-linux-gnueabihf) arm-unknown-linux-gnueabihf)
qemu-arm -L /usr/arm-linux-gnueabihf $CARGO_TARGET_DIR/$TARGET/debug/libc-test qemu-arm -L /usr/arm-linux-gnueabihf $CARGO_TARGET_DIR/$TARGET/debug/libc-test
;; ;;