blob: 75aa79c03d7892c32ef140500c621484bc83eb29 [file] [log] [blame]
"""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)