From eecbe837500270f530e943a1b6bb718031156dd6 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Fri, 29 Jun 2018 23:27:31 +0200 Subject: [PATCH] Add ./mach test-android-startup --- python/servo/command_base.py | 7 +++ python/servo/post_build_commands.py | 6 +- python/servo/testing_commands.py | 87 ++++++++++++++++++++++++++++- 3 files changed, 93 insertions(+), 7 deletions(-) diff --git a/python/servo/command_base.py b/python/servo/command_base.py index 70f19203ec6..0963242226b 100644 --- a/python/servo/command_base.py +++ b/python/servo/command_base.py @@ -623,6 +623,13 @@ class CommandBase(object): return sdk_adb return "adb" + def android_emulator_path(self, env): + if "ANDROID_SDK" in env: + sdk_adb = path.join(env["ANDROID_SDK"], "emulator", "emulator") + if path.exists(sdk_adb): + return sdk_adb + return "emulator" + def handle_android_target(self, target): if target == "arm-linux-androideabi": self.config["android"]["platform"] = "android-18" diff --git a/python/servo/post_build_commands.py b/python/servo/post_build_commands.py index 30c59f417f5..0132d2ea4b0 100644 --- a/python/servo/post_build_commands.py +++ b/python/servo/post_build_commands.py @@ -177,10 +177,8 @@ class PostBuildCommands(CommandBase): help="Command-line arguments to be passed through to the emulator") def android_emulator(self, args=None): if not args: - print("Pass at least an AVD name such as @servo-arm or @servo-x86") - return 1 - env = self.build_env() - emulator = path.join(env["ANDROID_SDK"], "emulator", "emulator") + print("AVDs created by `./mach bootstrap-android` are servo-arm and servo-x86.") + emulator = self.android_emulator_path(self.build_env()) return subprocess.call([emulator] + args) @Command('rr-record', diff --git a/python/servo/testing_commands.py b/python/servo/testing_commands.py index 545fa19f3b0..f705939ba53 100644 --- a/python/servo/testing_commands.py +++ b/python/servo/testing_commands.py @@ -17,7 +17,7 @@ import os.path as path import platform import copy from collections import OrderedDict -from time import time +import time import json import urllib2 import urllib @@ -157,7 +157,7 @@ class MachCommands(CommandBase): print("%s is not a valid test path or suite name" % arg) return 1 - test_start = time() + test_start = time.time() for suite, tests in selected_suites.iteritems(): props = suites[suite] kwargs = props.get("kwargs", {}) @@ -166,7 +166,7 @@ class MachCommands(CommandBase): Registrar.dispatch("test-%s" % suite, context=self.context, **kwargs) - elapsed = time() - test_start + elapsed = time.time() - test_start print("Tests completed in %0.2fs" % elapsed) @@ -551,6 +551,87 @@ class MachCommands(CommandBase): output.close() return 1 + @Command('test-android-startup', + description='Extremely minimal testing of Servo for Android', + category='testing') + @CommandArgument('--release', '-r', action='store_true', + help='Run the release build') + @CommandArgument('--dev', '-d', action='store_true', + help='Run the dev build') + def test_android_startup(self, release, dev): + if (release and dev) or not (release or dev): + print("Please specify one of --dev or --release.") + return 1 + target = "i686-linux-android" + print("Assuming --target " + target) + env = self.build_env(target=target) + assert self.handle_android_target(target) + + emulator_port = "5580" + adb = [self.android_adb_path(env), "-s", "emulator-" + emulator_port] + emulator_process = subprocess.Popen([ + self.android_emulator_path(env), + "@servo-x86", + "-no-window", + "-gpu", "guest", + "-port", emulator_port, + ]) + try: + # This is hopefully enough time for the emulator to exit + # if it cannot start because of a configuration problem, + # and probably more time than it needs to boot anyway + time.sleep(1) + if emulator_process.poll() is not None: + # The process has terminated already, wait-for-device would block indefinitely + return 1 + + subprocess.call(adb + ["wait-for-device"]) + + # https://stackoverflow.com/a/38896494/1162888 + while 1: + stdout, stderr = subprocess.Popen( + adb + ["shell", "getprop", "sys.boot_completed"], + stdout=subprocess.PIPE, + ).communicate() + if "1" in stdout: + break + print("Waiting for the emulator to boot") + time.sleep(1) + + binary_path = self.get_binary_path(release, dev, android=True) + result = subprocess.call(adb + ["install", "-r", binary_path + ".apk"]) + if result != 0: + return result + + html = """ + + """ + url = "data:text/html;base64," + html.encode("base64").replace("\n", "") + result = subprocess.call(adb + ["shell", """ + mkdir -p /sdcard/Android/data/com.mozilla.servo/files/ + echo 'servo' > /sdcard/Android/data/com.mozilla.servo/files/android_params + echo '%s' >> /sdcard/Android/data/com.mozilla.servo/files/android_params + am start com.mozilla.servo/com.mozilla.servo.MainActivity + """ % url]) + if result != 0: + return result + + logcat = adb + ["logcat", "RustAndroidGlueStdouterr:D", "*:S", "-v", "raw"] + logcat_process = subprocess.Popen(logcat, stdout=subprocess.PIPE) + while 1: + line = logcat_process.stdout.readline() + if "JavaScript is running!" in line: + print(line) + break + logcat_process.kill() + finally: + try: + emulator_process.kill() + except OSError: + pass + @Command('test-jquery', description='Run the jQuery test suite', category='testing')