Skip to content

Commit 4eb6bf9

Browse files
committed
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).
2 parents 6ec4f81 + d4a5fce commit 4eb6bf9

File tree

4 files changed

+184
-2
lines changed

4 files changed

+184
-2
lines changed

.travis.yml

+2-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ script:
1717
sh ci/run.sh $TARGET;
1818
fi
1919
- rustc ci/style.rs && ./style src
20-
osx_image: xcode7.3
2120
env:
2221
global:
2322
secure: "e2/3QjgRN9atOuSHp22TrYG7QVKcYUWY48Hi9b60w+r1+BhPkTseIJLte7WefRhdXtqpjjUJTooKDhnurFOeHaCT+nmBgiv+FPU893sBl4bhesY4m0vgUJVbNZcs6lTImYekWVb+aqjGdgV/XAgCw7c3kPmrZV0MzGDWL64Xaps="
@@ -65,9 +64,11 @@ matrix:
6564
env: TARGET=aarch64-unknown-linux-gnu
6665
rust: stable
6766
- os: osx
67+
osx_image: xcode8.2
6868
env: TARGET=i386-apple-ios
6969
rust: stable
7070
- os: osx
71+
osx_image: xcode8.2
7172
env: TARGET=x86_64-apple-ios
7273
rust: stable
7374
- os: linux

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ Tested:
111111
* [`i686-apple-darwin`](https://doc.rust-lang.org/libc/i686-apple-darwin/libc/)
112112
* [`x86_64-apple-darwin`](https://doc.rust-lang.org/libc/x86_64-apple-darwin/libc/)
113113
(OSX)
114-
* `i686-apple-ios`
114+
* `i386-apple-ios`
115115
* `x86_64-apple-ios`
116116
* [`i686-unknown-linux-gnu`](https://doc.rust-lang.org/libc/i686-unknown-linux-gnu/libc/)
117117
* [`x86_64-unknown-linux-gnu`](https://doc.rust-lang.org/libc/x86_64-unknown-linux-gnu/libc/)
+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
// This is a script to deploy and execute a binary on an iOS simulator.
12+
// The primary use of this is to be able to run unit tests on the simulator and
13+
// retrieve the results.
14+
//
15+
// To do this through Cargo instead, use Dinghy
16+
// (https://github.com/snipsco/dinghy): cargo dinghy install, then cargo dinghy
17+
// test.
18+
19+
use std::env;
20+
use std::fs::{self, File};
21+
use std::io::Write;
22+
use std::path::Path;
23+
use std::process;
24+
use std::process::Command;
25+
26+
macro_rules! t {
27+
($e:expr) => (match $e {
28+
Ok(e) => e,
29+
Err(e) => panic!("{} failed with: {}", stringify!($e), e),
30+
})
31+
}
32+
33+
// Step one: Wrap as an app
34+
fn package_as_simulator_app(crate_name: &str, test_binary_path: &Path) {
35+
println!("Packaging simulator app");
36+
drop(fs::remove_dir_all("ios_simulator_app"));
37+
t!(fs::create_dir("ios_simulator_app"));
38+
t!(fs::copy(test_binary_path,
39+
Path::new("ios_simulator_app").join(crate_name)));
40+
41+
let mut f = t!(File::create("ios_simulator_app/Info.plist"));
42+
t!(f.write_all(format!(r#"
43+
<?xml version="1.0" encoding="UTF-8"?>
44+
<!DOCTYPE plist PUBLIC
45+
"-//Apple//DTD PLIST 1.0//EN"
46+
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
47+
<plist version="1.0">
48+
<dict>
49+
<key>CFBundleExecutable</key>
50+
<string>{}</string>
51+
<key>CFBundleIdentifier</key>
52+
<string>com.rust.unittests</string>
53+
</dict>
54+
</plist>
55+
"#, crate_name).as_bytes()));
56+
}
57+
58+
// Step two: Start the iOS simulator
59+
fn start_simulator() {
60+
println!("Looking for iOS simulator");
61+
let output = t!(Command::new("xcrun").arg("simctl").arg("list").output());
62+
assert!(output.status.success());
63+
let mut simulator_exists = false;
64+
let mut simulator_booted = false;
65+
let mut found_rust_sim = false;
66+
let stdout = t!(String::from_utf8(output.stdout));
67+
for line in stdout.lines() {
68+
if line.contains("rust_ios") {
69+
if found_rust_sim {
70+
panic!("Duplicate rust_ios simulators found. Please \
71+
double-check xcrun simctl list.");
72+
}
73+
simulator_exists = true;
74+
simulator_booted = line.contains("(Booted)");
75+
found_rust_sim = true;
76+
}
77+
}
78+
79+
if simulator_exists == false {
80+
println!("Creating iOS simulator");
81+
Command::new("xcrun")
82+
.arg("simctl")
83+
.arg("create")
84+
.arg("rust_ios")
85+
.arg("com.apple.CoreSimulator.SimDeviceType.iPhone-SE")
86+
.arg("com.apple.CoreSimulator.SimRuntime.iOS-10-2")
87+
.check_status();
88+
} else if simulator_booted == true {
89+
println!("Shutting down already-booted simulator");
90+
Command::new("xcrun")
91+
.arg("simctl")
92+
.arg("shutdown")
93+
.arg("rust_ios")
94+
.check_status();
95+
}
96+
97+
println!("Starting iOS simulator");
98+
// We can't uninstall the app (if present) as that will hang if the
99+
// simulator isn't completely booted; just erase the simulator instead.
100+
Command::new("xcrun").arg("simctl").arg("erase").arg("rust_ios").check_status();
101+
Command::new("xcrun").arg("simctl").arg("boot").arg("rust_ios").check_status();
102+
}
103+
104+
// Step three: Install the app
105+
fn install_app_to_simulator() {
106+
println!("Installing app to simulator");
107+
Command::new("xcrun")
108+
.arg("simctl")
109+
.arg("install")
110+
.arg("booted")
111+
.arg("ios_simulator_app/")
112+
.check_status();
113+
}
114+
115+
// Step four: Run the app
116+
fn run_app_on_simulator() {
117+
println!("Running app");
118+
let output = t!(Command::new("xcrun")
119+
.arg("simctl")
120+
.arg("launch")
121+
.arg("--console")
122+
.arg("booted")
123+
.arg("com.rust.unittests")
124+
.output());
125+
126+
println!("stdout --\n{}\n", String::from_utf8_lossy(&output.stdout));
127+
println!("stderr --\n{}\n", String::from_utf8_lossy(&output.stderr));
128+
129+
let stdout = String::from_utf8_lossy(&output.stdout);
130+
let passed = stdout.lines()
131+
.find(|l| l.contains("PASSED"))
132+
.map(|l| l.contains("tests"))
133+
.unwrap_or(false);
134+
135+
println!("Shutting down simulator");
136+
Command::new("xcrun")
137+
.arg("simctl")
138+
.arg("shutdown")
139+
.arg("rust_ios")
140+
.check_status();
141+
if !passed {
142+
panic!("tests didn't pass");
143+
}
144+
}
145+
146+
trait CheckStatus {
147+
fn check_status(&mut self);
148+
}
149+
150+
impl CheckStatus for Command {
151+
fn check_status(&mut self) {
152+
println!("\trunning: {:?}", self);
153+
assert!(t!(self.status()).success());
154+
}
155+
}
156+
157+
fn main() {
158+
let args: Vec<String> = env::args().collect();
159+
if args.len() != 2 {
160+
println!("Usage: {} <executable>", args[0]);
161+
process::exit(-1);
162+
}
163+
164+
let test_binary_path = Path::new(&args[1]);
165+
let crate_name = test_binary_path.file_name().unwrap();
166+
167+
package_as_simulator_app(crate_name.to_str().unwrap(), test_binary_path);
168+
start_simulator();
169+
install_app_to_simulator();
170+
run_app_on_simulator();
171+
}

ci/run.sh

+10
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,16 @@ case "$TARGET" in
113113
grep "^PASSED .* tests" /tmp/out
114114
;;
115115

116+
i386-apple-ios)
117+
rustc -O ./ci/ios/deploy_and_run_on_ios_simulator.rs
118+
./deploy_and_run_on_ios_simulator $CARGO_TARGET_DIR/$TARGET/debug/libc-test
119+
;;
120+
121+
x86_64-apple-ios)
122+
rustc -O ./ci/ios/deploy_and_run_on_ios_simulator.rs
123+
./deploy_and_run_on_ios_simulator $CARGO_TARGET_DIR/$TARGET/debug/libc-test
124+
;;
125+
116126
arm-unknown-linux-gnueabihf)
117127
qemu-arm -L /usr/arm-linux-gnueabihf $CARGO_TARGET_DIR/$TARGET/debug/libc-test
118128
;;

0 commit comments

Comments
 (0)