blob: f1acf733df944e603eff17db226410da1826c21f [file] [log] [blame]
# Copyright (c) 2015 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for emulator boot tests."""
from recipe_engine.types import freeze
import os
import csv
import collections
from slave.email_watcher import EmailRecipeWatcher
DEPS = [
'adt',
'path',
'platform',
'properties',
'python',
'raw_io',
'step',
'json',
'trigger',
]
MASTER_USER = 'user'
MASTER_IP = '172.27.213.40'
bootStep = collections.namedtuple('bootStep', 'description, filter')
@EmailRecipeWatcher()
def RunSteps(api):
buildername = api.properties['buildername']
project = str(api.properties['project'])
file_list = api.properties.get('file_list')
download_path = api.path['slave_build'].join('')
env_path = ['%(PATH)s']
emulator_branches = ['emu-master-dev', 'emu-2.4-release']
is_cts = 'CTS' in str(buildername)
is_ui = 'UI' in str(buildername)
is_console = "console" in str(api.properties.get('scheduler'))
is_avd = 'AVD' in str(buildername)
# find android sdk root directory
home_dir = os.path.expanduser('~')
if api.platform.is_mac:
android_sdk_home = os.path.join(home_dir, 'Android', 'android-sdk-macosx')
elif api.platform.is_linux:
android_sdk_home = os.path.join(home_dir, 'Android', 'android-sdk-linux')
# On windows, we need cygwin and GnuWin for commands like, rm, scp, unzip
elif api.platform.is_win:
android_sdk_home = os.path.join(home_dir, 'Android', 'android-sdk')
if api.platform.bits == 64:
gnu_path = 'C:\\Program Files (x86)\\GnuWin32\\bin'
else:
gnu_path = 'C:\\Program Files\\GnuWin32\\bin'
cygwin_path = 'C:\\cygwin\\bin'
cygwin_path64 = 'C:\\cygwin64\\bin'
java_path = "C:\\ProgramData\\Oracle\\Java\\javapath"
env_path = [gnu_path, cygwin_path, cygwin_path64, java_path] + env_path
else:
raise # pragma: no cover
is_cross_build = api.properties.get('triggered')
if project in emulator_branches and not is_cross_build and not is_cts:
android_sdk_home += "_public"
else:
android_sdk_home += "_image-builds"
android_tools_dir = os.path.join(android_sdk_home, 'tools')
android_tools_bin_dir = os.path.join(android_sdk_home, 'tools', 'bin')
android_platform_dir = os.path.join(android_sdk_home, 'platform-tools')
android_buildtools_dir = os.path.join(android_sdk_home, 'build-tools', '23.0.2')
env_path += [android_tools_dir, android_tools_bin_dir, android_platform_dir, android_buildtools_dir]
if is_console or is_avd:
env_path += [os.path.join(home_dir, 'bin', 'jdk1.8.0_121', 'bin')]
env = {'PATH': api.path.pathsep.join(env_path),
'ANDROID_SDK_ROOT': android_sdk_home,
'ANDROID_HOME': android_sdk_home}
# Find emulator script based on build directory
# Emulator scripts are located [project root]/emu_test
build_dir = api.path['build']
script_root = api.path.join(build_dir, os.pardir, 'emu_test')
create_cl_list_path = api.path.join(script_root, 'utils', 'create_cl_list.py')
image_util_path = api.path.join(script_root, 'utils', 'download_unzip_image.py')
buildnum = api.properties['buildnumber']
rev = api.properties['revision']
log_util_path = api.path.join(script_root, 'utils', 'zip_upload_logs.py')
init_bot_util_path = api.path.join(script_root, 'utils', 'emu_bot_init.py')
log_dir = 'logs-build_%s-rev_%s' % (buildnum, rev)
bootSteps = {
'emu-master-dev': bootStep('public', '{"ori": "public"}'),
'emu-2.4-release': bootStep('public', '{"ori": "public"}'),
'master': bootStep('master', '{"ori": "master"}'),
'mnc-emu-dev': bootStep('MNC', '{"ori": "mnc"}'),
'lmp-mr1-emu-dev': bootStep('LMP_MR1', '{"ori": "lmp-mr1"}'),
'nyc-mr1-emu-dev': bootStep('NYC_MR1', '{"ori": "nyc-mr1"}'),
'nyc-emu-dev': bootStep('NYC', '{"ori": "nyc"}'),
'oc-emu-dev': bootStep('OC', '{"ori": "oc"}'),
'oc-mr1-emu-dev': bootStep('OC_MR1', '{"ori": "oc-mr1"}'),
'lmp-emu-dev': bootStep('LMP', '{"ori": "lmp"}'),
'klp-emu-dev': bootStep('KLP', '{"ori": "klp"}'),
'gb-emu-dev': bootStep('GB', '{"ori": "gb"}'),
'ics-mr1-emu-dev': bootStep('ICS_MR1', '{"ori": "ics-mr1"}'),
'jb-emu-dev': bootStep('JB', '{"ori": "jb"}'),
'jb-mr1.1-emu-dev': bootStep('JB_MR1.1', '{"ori": "jb-mr1.1"}'),
'jb-mr2-emu-dev': bootStep('JB_MR2', '{"ori": "jb-mr2"}'),
}
# figure out which emulator to use, and which test steps to run
# For case 1, system-image builds, use only public emulator, and run boot test for the changing branch
# For case 2, emulator builds, use the triggering emulator branch, run public boot test
# For case 3, cross builds, if triggering factor is emulator branch, then use that emulator branch, on all system image other than public
# case 4, if changes are in system-image branch, need to check against all of known good emulator branches, and on the triggering branch image
def getTestConfig(project, cross_build):
# case 1
if project not in emulator_branches and not cross_build:
emulator_branch_to_use = [android_sdk_home]
steps_to_run = [project]
# case 2
elif project in emulator_branches and not cross_build:
emulator_branch_to_use = [project]
steps_to_run = [project]
# case 3
elif project in emulator_branches and cross_build:
emulator_branch_to_use = [project]
steps_to_run = [x for x in bootSteps if x not in emulator_branches]
# case 4
else:
emulator_branch_to_use = [x for x in emulator_branches]
steps_to_run = [project]
return emulator_branch_to_use, steps_to_run
# Functions to save and retrieve properties
# We save the last known good revision in a local csv file, then read it
# for cross build
# Since green build only triggers cross build on itself, local file works fine
# csv file format: branch,revison,file_list
build_cache = api.path.join(script_root, 'config', 'build_cache.csv')
def getProps():
props = {'blamelist': api.properties.get('blamelist'),
'file_list': '',
'logs_dir': api.properties.get('logs_dir'),
'buildername': '%s_cross-builds' % buildername.rsplit('_',1)[0],
'triggered': 'True',
'got_revision': rev,
'revision': rev}
last_build = {}
with open(build_cache,'r') as csvfile:
filereader = csv.reader(csvfile)
for row in filereader:
if row[0] in bootSteps:
last_build[row[0]] = [row[1], row[2]]
emulators,steps = getTestConfig(project, True)
for k in last_build:
if k in emulators:
props['file_list'] += last_build[k][1] + ','
props[k] = last_build[k][0]
elif k in steps:
props[k + '_file'] = last_build[k][1]
props[k] = last_build[k][0]
return props
def setProps():
props = {}
if api.path.exists(build_cache):
with open(build_cache,'r') as csvfile:
filereader = csv.reader(csvfile)
for row in filereader:
props[row[0]] = [row[1], row[2]]
props[project] = [rev, file_list]
with open(build_cache,'w') as csvfile:
filewriter = csv.writer(csvfile)
for line in props:
filewriter.writerow([line, props[line][0], props[line][1]])
# For cts test, download both of emulator and system image files
# triggerring branch could be either emulator or system image
if is_cts:
setProps()
with open(build_cache,'r') as csvfile:
filereader = csv.reader(csvfile)
file_list = ','.join([row[2] for row in filereader])
try:
api.python('Initialize Bot', init_bot_util_path,
['--build-dir', api.path['slave_build'],
'--props', api.json.dumps(api.properties.thaw()),
'--log-dir', log_dir],
env=env)
except api.step.StepFailure as f: # pragma: no cover
# Not able to delete some files, it won't be the fault of emulator
# not a stopper to run actual tests
# so set status to "warning" and continue test
f.result.presentation.status = api.step.WARNING
try:
api.python('Create CL List', create_cl_list_path,
['--poller', str(api.properties.get('blamelist')),
'--prevRevision', api.properties.get('prev_build'),
'--curRevision', api.properties.get('revision')],
env=env)
except api.step.StepFailure as f:
f.result.presentation.status = api.step.WARNING
except TypeError as f:
#This occurs when we fail to find 'prev_build' within the properties file.
# We will continue execution ignoring this error for now.
pass
if is_cts:
file_list = "cts"
api.python("Download and Unzip Images", image_util_path,
['--file', file_list,
'--build-dir', build_dir],
env=env)
if is_cts:
rev_file_path = api.path.join(script_root, 'config', 'rev.txt')
with open(rev_file_path) as revfile:
rev_str = revfile.read()
api.step('Rev emu-img %s' % rev_str, ['echo', rev_str])
emulator_branch_to_use, steps_to_run = getTestConfig(project, is_cross_build)
# filter out unavailable branches
steps_to_run = [x for x in steps_to_run if api.properties.get(x)]
emulator_branch_to_use = [x for x in emulator_branch_to_use if (api.properties.get(x) or x not in emulator_branches)]
with api.step.defer_results():
for step in steps_to_run:
if is_cross_build:
api.python("Download Image - %s" % step, image_util_path,
['--file', api.properties.get(step+'_file'),
'--build-dir', build_dir],
env=env)
for emu_branch in emulator_branch_to_use:
if 'emu-master-dev' in emu_branch or 'emu-2.4-release' in emu_branch:
emulator_path = api.path.join(emu_branch, 'emulator', 'emulator')
else:
emulator_path = api.path.join(emu_branch, 'tools', 'emulator')
emu_desc = "sdk emulator" if emu_branch not in emulator_branches else emu_branch
if not is_cts and not is_ui and not is_console and not is_avd:
step_data = bootSteps[step]
api.adt.PythonTestStep('Boot Test - %s System Image - %s' % (step_data.description, emu_desc),
api.path.join(log_dir, 'boot_test_%s_sysimage-%s' % (step_data.description, emu_desc)),
'test_boot.*',
'boot_cfg.csv',
step_data.filter,
emulator_path,
env)
elif is_ui:
step_data = bootSteps[step]
res = api.adt.PythonTestStep('Run Emulator UI Test',
api.path.join(log_dir, 'UI_test'),
'test_ui.*',
'ui_cfg.csv',
step_data.filter,
emulator_path,
env,
True)
# Here we upload the data on whether the build passed or failed to GCS
upload_data_path = api.path.join(script_root, 'utils', 'upload_test_stats_to_gcs.py')
upload_data_args = ['--test_type', 'system_image_ui',
'--buildnum', buildnum,
'--buildername', api.properties['buildername'],
'--timestamp', api.properties['requestedAt'],
'--build-dir', build_dir,
]
if res and res.is_ok:
upload_data_args.append('--passed')
upload_data_args.append('--platform')
if api.platform.is_linux:
upload_data_args.append('lin')
elif api.platform.is_mac:
upload_data_args.append('mac')
elif api.platform.is_win:
upload_data_args.append('win')
api.python("Upload Test Results to GCS", upload_data_path, upload_data_args, env=env)
elif is_console:
res = api.adt.PythonTestStep('Run Emulator Console Test',
api.path.join(log_dir, 'Console_test'),
'test_console.*',
'console_cfg.csv',
'{"gpu": "yes"}',
emulator_path,
env,
True)
# Here we upload the data on whether the build passed or failed to GCS
upload_data_path = api.path.join(script_root, 'utils', 'upload_test_stats_to_gcs.py')
upload_data_args = ['--test_type', 'console',
'--buildnum', buildnum,
'--buildername', api.properties['buildername'],
'--timestamp', api.properties['requestedAt'],
'--build-dir', build_dir,
]
if res and res.is_ok:
upload_data_args.append('--passed')
upload_data_args.append('--platform')
if api.platform.is_linux:
upload_data_args.append('lin')
elif api.platform.is_mac:
upload_data_args.append('mac')
elif api.platform.is_win:
upload_data_args.append('win')
api.python("Upload Test Results to GCS", upload_data_path, upload_data_args, env=env)
elif is_avd:
api.adt.PythonTestStep('Run AVD Launch Test',
api.path.join(log_dir, 'AVD_test'),
'launch_avd.*',
'avd_cfg.csv',
'{"gpu": "yes"}',
emulator_path,
env,
True)
if is_cts:
emulator_path = api.path.join('emu-master-dev', 'emulator', 'emulator')
api.adt.PythonTestStep('Run Emulator CTS Test',
api.path.join(log_dir, 'CTS_test'),
'test_cts.*',
'cts_cfg.csv',
'{}',
emulator_path,
env,
True)
api.adt.PythonTestStep('Run Emulator GTS Test',
api.path.join(log_dir, 'GTS_test'),
'test_cts.*',
'cts_cfg.csv',
'{}',
emulator_path,
env,
True)
logs_dir = '/home/user/buildbot/external/adt-infra/build/masters/master.client.adt/slave_logs/'
upload_log_args = ['--dir', log_dir,
'--name', 'build_%s-rev_%s.zip' % (buildnum, rev),
'--ip', MASTER_IP,
'--user', MASTER_USER,
'--dst', '%s%s/'% (logs_dir, buildername),
'--build-dir', build_dir]
if is_ui or is_console:
upload_log_args.append('--skiplog')
if api.platform.is_win:
upload_log_args.append('--iswindows')
api.python("Zip and Upload Logs", log_util_path, upload_log_args, env=env)
# Trigger next CTS build, to make CTS builder run continously
if is_cts:
api.trigger({
'buildername': buildername,
'got_revision': 'LATEST'
})
# If this build is triggered by scheduler, and it passes above steps
# trigger build on cross builers
if not is_cts and not is_ui and not is_console and not is_cross_build:
setProps()
api.trigger(getProps())
def GenTests(api):
yield (
api.test('basic-win32') +
api.platform.name('win') +
api.platform.bits(32) +
api.properties(
mastername='client.adt',
project='emu-master-dev',
buildername='Win 7 32-bit HD 4400',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu_gspoller_windows/sdk-repo-windows-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
)
)
yield (
api.test('basic-win64') +
api.platform.name('win') +
api.platform.bits(64) +
api.properties(
mastername='client.adt',
project='emu-master-dev',
buildername='Win 7 64-bit HD 4400',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu/sdk-repo-windows-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
)
)
yield (
api.test('basic-mac') +
api.platform.name('mac') +
api.properties(
mastername='client.adt',
project='emu-master-dev',
buildername='Mac 10.10.5 Iris Pro',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu/sdk-repo-mac-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
)
)
yield (
api.test('basic-linux') +
api.platform.name('linux') +
api.properties(
mastername='client.adt',
project='emu-master-dev',
buildername='Ubuntu 15.04 Quadro K600',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu/sdk-repo-linux-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
)
)
yield (
api.test('boot-test-mnc-project') +
api.platform.name('linux') +
api.properties(
mastername='client.adt',
project='git_mnc-emu-dev',
buildername='Ubuntu 15.04 Quadro K600',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu/sdk-repo-linux-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
)
)
yield (
api.test('boot-test-lmp-project') +
api.platform.name('linux') +
api.properties(
mastername='client.adt',
project='git_lmp-mr1-emu-dev',
buildername='Ubuntu 15.04 Quadro K600',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu/sdk-repo-linux-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
)
)
yield (
api.test('boot-test-timeout-fail') +
api.platform.name('linux') +
api.properties(
mastername='client.adt',
project='emu-master-dev',
buildername='Ubuntu 15.04 Quadro K600',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu_gspoller_linux/sdk-repo-windows-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
) +
api.override_step_data('Boot Test - Public System Image',
api.raw_io.stream_output('TIMEOUT: foobar', 'stderr')
) +
api.step_data('Boot Test - Public System Image', retcode=1)
)
yield (
api.test('cts-test-timeout-fail') +
api.platform.name('linux') +
api.properties(
mastername='client.adt',
project='emu-master-dev',
buildername='Ubuntu 15.04 Quadro K600',
lmp_revision='2460722',
mnc_revision='2458059',
emulator_image='/images/emu_gspoller_linux/sdk-repo-windows-tools-2344972.zip',
lmp_system_image='/images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2460722.zip,images/git_lmp-mr1-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2460722.zip',
mnc_system_image='/images/git_mnc-emu-dev-linux-sdk_google_phone_x86_64-sdk_addon/sdk-repo-linux-system-images-2458059.zip,/images/git_mnc-emu-dev-linux-sdk_google_phone_x86-sdk_addon/sdk-repo-linux-system-images-2458059.zip',
logs_dir='/home/slave_logs/',
buildnumber='3077',
) +
api.override_step_data('Run Emulator CTS Test',
api.raw_io.stream_output('TIMEOUT: foobar', 'stderr')
) +
api.step_data('Run Emulator CTS Test', retcode=1)
)