Replace Python script with Rust script.

This commit is contained in:
Kevin Brothaler 2017-01-17 21:17:46 -04:00
parent 938955c0f4
commit f8e12769ca
3 changed files with 136 additions and 116 deletions

View File

@ -1,114 +0,0 @@
#!/usr/bin/env python
#
# 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 x86-64 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.
import os.path
import subprocess
import sys
import time
# Step one: Wrap as an app
def package_as_simulator_app(crate_name, test_binary_path):
print 'Packaging simulator app'
subprocess.call(['rm', '-rf', 'ios_simulator_app'])
subprocess.check_call(['mkdir', 'ios_simulator_app'])
subprocess.check_call(['cp', test_binary_path, 'ios_simulator_app/' + crate_name])
f = open('ios_simulator_app/Info.plist', 'w')
f.write('<?xml version="1.0" encoding="UTF-8"?>\n'
'<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">\n'
'<plist version="1.0">\n'
' <dict>\n'
' <key>CFBundleExecutable</key>\n'
' <string>' + crate_name + '</string>\n'
' <key>CFBundleIdentifier</key>\n'
' <string>com.rust.unittests</string>\n'
' <key>UIRequiredDeviceCapabilities</key>\n'
' <array>\n'
' <string>x86_64</string>\n'
' </array>\n'
' </dict>\n'
'</plist>\n')
# Step two: Start the iOS simulator
def start_simulator():
print 'Looking for iOS simulator'
xcrun_list = subprocess.Popen(['xcrun', 'simctl', 'list'], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)
simulator_exists = False
simulator_booted = False
found_rust_sim = False
for line in xcrun_list.stdout:
if "rust_ios" in line:
if found_rust_sim == True:
raise Exception("Duplicate rust_ios simulators found. Please double-check xcrun simctl list.")
simulator_exists = True
simulator_booted = "(Booted)" in line
found_rust_sim = True
if simulator_exists == False:
print 'Creating iOS simulator'
subprocess.check_output(['xcrun', 'simctl', 'create', 'rust_ios', 'com.apple.CoreSimulator.SimDeviceType.iPhone-SE', 'com.apple.CoreSimulator.SimRuntime.iOS-10-2'])
elif simulator_booted == True:
print 'Shutting down already-booted simulator'
subprocess.call(['xcrun', 'simctl', 'shutdown', 'rust_ios'])
print '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.
subprocess.check_call(['xcrun', 'simctl', 'erase', 'rust_ios'])
subprocess.check_call(['xcrun', 'simctl', 'boot', 'rust_ios'])
# Step three: Install the app
def install_app_to_simulator():
print 'Installing app to simulator'
subprocess.check_call(['xcrun', 'simctl', 'install', 'booted', 'ios_simulator_app/'])
# Step four: Run the app
def run_app_on_simulator():
print 'Running app'
try:
test_run = subprocess.Popen(['xcrun', 'simctl', 'launch', '--console', 'booted', 'com.rust.unittests'], stdout=subprocess.PIPE, bufsize=1, universal_newlines=True)
test_run_passed = False
for line in test_run.stdout:
sys.stdout.write(line)
if test_run_passed == False:
# Based on all.rs test output
test_run_passed = 'PASSED' in line and 'tests' in line
sys.stdout.flush()
if test_run_passed == False:
raise Exception('Some tests failed')
finally:
print 'Shutting down simulator'
subprocess.call(['xcrun', 'simctl', 'shutdown', 'rust_ios'])
# Run all steps in sequence
# TODO 1: Use a /tmp place for the app instead of current dir?
def main():
if len(sys.argv) != 2:
print 'usage: ' + os.path.basename(sys.argv[0]) + ' executable'
sys.exit(-1)
crate_name = os.path.basename(sys.argv[1])
test_binary_path = sys.argv[1]
package_as_simulator_app(crate_name, test_binary_path)
start_simulator()
install_app_to_simulator()
run_app_on_simulator()
# Entry point
if __name__ == '__main__':
main()

View File

@ -0,0 +1,132 @@
// 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 x86-64 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::File;
use std::io::Write;
use std::path::Path;
use std::process;
use std::process::Command;
// Step one: Wrap as an app
fn package_as_simulator_app(crate_name: &str, test_binary_path: &Path) {
println!("Packaging simulator app");
Command::new("rm").arg("-rf").arg("ios_simulator_app").status().unwrap();
Command::new("mkdir").arg("ios_simulator_app").check_status();
Command::new("cp").arg(test_binary_path).arg(["ios_simulator_app/", crate_name].join("")).check_status();
let mut f = File::create("ios_simulator_app/Info.plist").unwrap();
f.write_all(&[
"<?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>", crate_name, "</string>"].join(""),
" <key>CFBundleIdentifier</key>",
" <string>com.rust.unittests</string>",
" <key>UIRequiredDeviceCapabilities</key>",
" <array>",
" <string>x86_64</string>",
" </array>",
" </dict>",
"</plist>"].join("\n").into_bytes()).unwrap();
}
// Step two: Start the iOS simulator
fn start_simulator() {
println!("Looking for iOS simulator");
let output = Command::new("xcrun").arg("simctl").arg("list").output().unwrap();
let mut simulator_exists = false;
let mut simulator_booted = false;
let mut found_rust_sim = false;
let stdout = String::from_utf8(output.stdout).unwrap();
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 = Command::new("xcrun").arg("simctl").arg("launch").arg("--console").arg("booted").arg("com.rust.unittests").output().unwrap();
let mut test_run_passed = false;
let stdout = String::from_utf8(output.stdout).unwrap();
for line in stdout.lines() {
println!("{}", line);
if test_run_passed == false {
// Based on all.rs test output
test_run_passed = line.contains("PASSED") && line.contains("tests");
}
}
println!("Shutting down simulator");
Command::new("xcrun").arg("simctl").arg("shutdown").arg("rust_ios").check_status();
assert!(test_run_passed);
}
trait CheckStatus {
fn check_status(&mut self);
}
impl CheckStatus for Command {
fn check_status(&mut self) {
assert!(self.status().unwrap().success());
}
}
pub fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 2 {
println!("Usage: {:?} executable", Path::new(&args[0]).file_name().unwrap());
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

@ -114,11 +114,13 @@ case "$TARGET" in
;;
i386-apple-ios)
python ./ci/ios/deploy_and_run_ios_binary_on_ios_simulator.py $CARGO_TARGET_DIR/$TARGET/debug/libc-test
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)
python ./ci/ios/deploy_and_run_ios_binary_on_ios_simulator.py $CARGO_TARGET_DIR/$TARGET/debug/libc-test
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)