summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordyu <dyu@google.com>2017-03-27 17:39:57 +0000
committerandroid-build-merger <android-build-merger@google.com>2017-03-27 17:39:57 +0000
commit25ec36922685100612a06ea96d9cd0a0c6a1d46a (patch)
tree6741269e8923acc4d139eb80d1aa8415c5ae56e3
parentdd380614e18cd8e6b14800c4ea175767880bbe00 (diff)
parent949d42d16149ce6fbe4944c0b1d79e1e21288073 (diff)
downloadadt-infra-25ec36922685100612a06ea96d9cd0a0c6a1d46a.tar.gz
Merge "Add test to verify emulator launched in AVD can be detected."
am: 949d42d161 Change-Id: I18bb16c18bd2f69cd17a4093c05e29d7d1100051
-rw-r--r--emu_test/test_avd/launch_avd.py160
1 files changed, 160 insertions, 0 deletions
diff --git a/emu_test/test_avd/launch_avd.py b/emu_test/test_avd/launch_avd.py
new file mode 100644
index 00000000..75aa79c0
--- /dev/null
+++ b/emu_test/test_avd/launch_avd.py
@@ -0,0 +1,160 @@
+"""AVD Launch test.
+
+Verify the emulator launched in AVD can be detected.
+
+usage: launch_avd.py [-h] [-t TIMEOUT_IN_SECONDS] --avd AVD
+ [--exec EMULATOR_EXEC]
+"""
+
+import argparse
+import logging
+import multiprocessing.pool
+import subprocess
+from subprocess import PIPE, STDOUT
+import sys
+import time
+import threading
+import unittest
+
+import util
+
+log = logging.getLogger('launch_avd')
+
+def arg_parser():
+ """Return argument parser for launch_avd test"""
+ parser = argparse.ArgumentParser(description='Argument parser for emu test')
+
+ parser.add_argument('-t', '--timeout', type=int, dest='timeout_in_seconds', action='store',
+ default=600,
+ help='an integer for timeout in seconds, default is 600')
+ parser.add_argument('--avd', type=str, dest='avd', action='store',
+ required=True,
+ help='run test for given AVD')
+ parser.add_argument('--exec', type=str, dest='emulator_exec', action='store',
+ default='emulator',
+ help='path of emulator executable, default is system emulator')
+ parser.add_argument('unittest_args', nargs='*')
+ return parser
+
+class TimeoutError(Exception):
+ """Exception raised for timeout
+
+ Attributes:
+ cmd -- cmd which timed out
+ timeout -- value of timeout
+ """
+
+ def __init__(self, cmd, timeout):
+ self.cmd = cmd
+ self.timeout = timeout
+
+def run_with_timeout(cmd, timeout):
+ """Run command with specified timeout.
+
+ Args:
+ cmd - Required : command to run
+ timeout - Required : timeout (in seconds)
+
+ Returns:
+ Tuple of form (returncode, output, err), where:
+ * returncode is the exit code of the command
+ * output is the stdout output of the command, collected into a string
+ * err is the stderr output of the command, collected into a string
+ """
+ vars = {'output': "",
+ 'err': "",
+ 'process': None}
+
+ def run_cmd():
+ vars['process'] = subprocess.Popen(cmd, stdout=PIPE, stderr=PIPE)
+ (vars['output'], vars['err']) = vars['process'].communicate()
+
+ thread = threading.Thread(target=run_cmd)
+ thread.start()
+
+ thread.join(timeout)
+ if thread.is_alive():
+ log.debug('cmd %s timeout, force terminate' % ' '.join(cmd))
+ try:
+ vars['process'].terminate()
+ except Exception as e:
+ log.error('exception terminating adb getprop process: %r' % e)
+ thread.join(timeout)
+ return vars['process'].returncode, vars['output'], vars['err']
+
+
+def launch_emu(avd, emu_args):
+ """Launch given avd and return immediately"""
+ log.debug('call Launching AVD, ...: %s' % str(avd))
+ exec_path = emu_args.emulator_exec
+ launch_cmd = [exec_path, "-avd", str(avd), "-verbose", "-show-kernel"]
+
+ if "emu-master-dev" in exec_path:
+ launch_cmd += ["-skip-adb-auth"]
+
+ log.info('Launching AVD, cmd: %s' % ' '.join(launch_cmd))
+ start_proc = subprocess.Popen(launch_cmd, stdout=PIPE, stderr=STDOUT)
+ log.info('done Launching AVD, cmd: %s' % ' '.join(launch_cmd))
+
+ if start_proc.poll():
+ raise LaunchError(str(avd))
+ log.debug('return Launching AVD, ...: %s' % str(avd))
+ return start_proc
+
+
+def launch_emu_and_wait(avd, emu_args):
+ """Launch given avd and wait for boot completion, return boot time"""
+ run_with_timeout(["adb", "kill-server"], 20)
+ run_with_timeout(["adb", "start-server"], 20)
+ pool = multiprocessing.pool.ThreadPool(processes = 1)
+ launcher_emu = pool.apply_async(launch_emu, [avd, emu_args])
+ start_time = time.time()
+ completed = "0"
+ real_time_out = emu_args.timeout_in_seconds;
+ if 'swiftshader' in str(avd):
+ real_time_out = real_time_out + emu_args.timeout_in_seconds
+ if 'arm' in str(avd):
+ real_time_out = real_time_out + emu_args.timeout_in_seconds;
+ if 'mips' in str(avd):
+ real_time_out = real_time_out + emu_args.timeout_in_seconds;
+ while time.time()-start_time < real_time_out:
+ cmd = ["adb", "shell", "getprop", "sys.boot_completed"]
+ try:
+ (exit_code, output, err) = run_with_timeout(cmd, 10)
+ except Exception as e:
+ log.error('exception run_with_timeout adb getprop: %r' % e)
+ continue
+ if exit_code is 0:
+ completed = output.strip()
+ if completed is "1":
+ log.info('AVD %s is fully booted' % avd)
+ break
+ time.sleep(1)
+ if completed is not "1":
+ log.debug('command output - %s %s' % (output,err))
+ log.error('AVD %s didn\'t boot up within %s seconds' % (avd,real_time_out))
+ raise TimeoutError(avd, real_time_out)
+ boot_time = time.time() - start_time
+ log.debug('AVD %s, boot time is %s' % (avd, boot_time))
+ emu_proc = launcher_emu.get(10)
+ if util.get_connected_devices():
+ success = True
+ else:
+ success = False
+ emu_proc.terminate()
+ return success
+
+
+class LaunchAVDTest(unittest.TestCase):
+ def test_launch_avd(self):
+ args = arg_parser().parse_args()
+ avd = args.avd
+ return launch_emu_and_wait(avd, args)
+
+if __name__ == '__main__':
+ console_handler = logging.StreamHandler(sys.stdout)
+ console_handler.setLevel(logging.DEBUG)
+ log.addHandler(console_handler)
+ log.setLevel(logging.DEBUG)
+ suite = unittest.TestLoader().loadTestsFromTestCase(LaunchAVDTest)
+ unittest.TextTestRunner(verbosity=2).run(suite)