From f8e12769ca92363453587c7f4258cb0603be11f3 Mon Sep 17 00:00:00 2001 From: Kevin Brothaler <admin@digipom.com> Date: Tue, 17 Jan 2017 21:17:46 -0400 Subject: [PATCH] Replace Python script with Rust script. --- ...loy_and_run_ios_binary_on_ios_simulator.py | 114 --------------- ci/ios/deploy_and_run_on_ios_simulator.rs | 132 ++++++++++++++++++ ci/run.sh | 6 +- 3 files changed, 136 insertions(+), 116 deletions(-) delete mode 100755 ci/ios/deploy_and_run_ios_binary_on_ios_simulator.py create mode 100644 ci/ios/deploy_and_run_on_ios_simulator.rs diff --git a/ci/ios/deploy_and_run_ios_binary_on_ios_simulator.py b/ci/ios/deploy_and_run_ios_binary_on_ios_simulator.py deleted file mode 100755 index 40c00bb5..00000000 --- a/ci/ios/deploy_and_run_ios_binary_on_ios_simulator.py +++ /dev/null @@ -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() \ No newline at end of file diff --git a/ci/ios/deploy_and_run_on_ios_simulator.rs b/ci/ios/deploy_and_run_on_ios_simulator.rs new file mode 100644 index 00000000..b36bef8d --- /dev/null +++ b/ci/ios/deploy_and_run_on_ios_simulator.rs @@ -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(); +} \ No newline at end of file diff --git a/ci/run.sh b/ci/run.sh index 3419090f..d33af30f 100755 --- a/ci/run.sh +++ b/ci/run.sh @@ -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) -- GitLab