blob: 98c6521fb41c5a5b05517d9a57821e41021e8df0 [file] [log] [blame]
# Copyright 2020 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.
import re
from PB.recipes.flutter.engine.engine import InputProperties
from PB.recipes.flutter.engine.engine import EnvProperties
PYTHON_VERSION_COMPATIBILITY = 'PY3'
DEPS = [
'depot_tools/depot_tools',
'flutter/bucket_util',
'flutter/os_utils',
'flutter/repo_util',
'fuchsia/goma',
'recipe_engine/buildbucket',
'recipe_engine/cipd',
'recipe_engine/context',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/python',
'recipe_engine/raw_io',
'recipe_engine/step',
]
PROPERTIES = InputProperties
ENV_PROPERTIES = EnvProperties
def GetCheckoutPath(api):
return api.path['cache'].join('builder', 'src')
def Build(api, config, *targets):
checkout = GetCheckoutPath(api)
build_dir = checkout.join('out', config)
goma_jobs = api.properties['goma_jobs']
ninja_args = [api.depot_tools.ninja_path, '-j', goma_jobs, '-C', build_dir]
ninja_args.extend(targets)
with api.goma.build_with_goma():
name = 'build %s' % ' '.join([config] + list(targets))
api.step(name, ninja_args)
def RunGN(api, *args):
checkout = GetCheckoutPath(api)
gn_cmd = ['python', checkout.join('flutter/tools/gn'), '--goma']
gn_cmd.extend(args)
api.step('gn %s' % ' '.join(args), gn_cmd)
def RunAndroidScenarioTests(api):
"""Runs the scenario test app on a x86 Android emulator.
See details at
https://chromium.googlesource.com/chromium/src/+/HEAD/docs/android_emulator.md#using-your-own-emulator-image
"""
engine_checkout = GetCheckoutPath(api)
android_tool_dir = engine_checkout.join('tools', 'android')
api.cipd.ensure(
android_tool_dir,
api.cipd.EnsureFile().add_package(
'chromium/tools/android/avd/linux-amd64',
'e5JfdaCjazDFh5uqhkPgVeZa9oCLVimm5_8TWAENz1gC'
)
)
avd_script_path = android_tool_dir.join(
'src', 'tools', 'android', 'avd', 'avd.py'
)
avd_config = android_tool_dir.join(
'src', 'tools', 'android', 'avd', 'proto', 'generic_android30.textpb'
)
emulator_pid = ''
with api.context(cwd=android_tool_dir):
api.python(
'Install Android emulator (API level 30)', avd_script_path,
['install', '--avd-config', avd_config]
)
output = api.python(
'Start Android emulator (API level 30)',
avd_script_path,
['start', '--no-read-only', '--avd-config', avd_config],
stdout=api.raw_io.output_text()
).stdout
m = re.match('.*pid: (\d+)\)', output)
emulator_pid = m.group(1)
test_dir = engine_checkout.join('flutter', 'testing')
scenario_app_tests = test_dir.join('scenario_app')
# Proxies `python` since vpython cannot resolve spec files outside of the jar
# file containing the python scripts.
gradle_home_bin_dir = scenario_app_tests.join('android', 'gradle-home', 'bin')
with api.context(cwd=scenario_app_tests,
env_prefixes={'PATH': [gradle_home_bin_dir]}):
result = api.step(
'Scenario App Integration Tests',
['./run_android_tests.sh', 'android_debug_x86'],
ok_ret='all'
)
api.step('Kill emulator', ['kill', '-9', emulator_pid])
build_failures_dir = scenario_app_tests.join('build', 'reports', 'diff_failures')
if api.path.exists(build_failures_dir):
# Upload any diff failures.
# If there are any, upload them to the cloud bucket.
api.bucket_util.upload_folder(
'Upload diff failures',
'src/flutter/testing/scenario_app',
'build/reports/diff_failures',
'diff_failures.zip',
bucket_name='flutter_logs',
)
def RunSteps(api, properties, env_properties):
# Collect memory/cpu/process after task execution.
api.os_utils.collect_os_info()
cache_root = api.path['cache'].join('builder')
checkout = GetCheckoutPath(api)
api.file.rmtree('Clobber build output', checkout.join('out'))
api.file.ensure_directory('Ensure checkout cache', cache_root)
api.goma.ensure()
dart_bin = checkout.join(
'third_party', 'dart', 'tools', 'sdks', 'dart-sdk', 'bin'
)
android_home = checkout.join('third_party', 'android_tools', 'sdk')
env = {
'GOMA_DIR': api.goma.goma_dir,
'ANDROID_HOME': str(android_home),
'FLUTTER_PREBUILT_DART_SDK': 'True',
}
env_prefixes = {'PATH': [dart_bin]}
api.repo_util.engine_checkout(
cache_root, env, env_prefixes, clobber=properties.clobber
)
with api.context(cwd=cache_root, env=env,
env_prefixes=env_prefixes), api.depot_tools.on_path():
RunGN(api, '--android', '--android-cpu=x86', '--no-lto')
Build(api, 'android_debug_x86')
RunAndroidScenarioTests(api)
with api.step.defer_results():
# This is to clean up leaked processes.
api.os_utils.kill_processes()
# Collect memory/cpu/process after task execution.
api.os_utils.collect_os_info()
def GenTests(api):
scenario_failures = GetCheckoutPath(api).join(
'flutter', 'testing', 'scenario_app', 'build', 'reports', 'diff_failures'
)
for upload_packages in (True, False):
yield api.test(
'without_failure_upload_%d' % upload_packages,
api.buildbucket.ci_build(
builder='Linux Engine',
git_repo='https://chromium.googlesource.com/external/github.com/flutter/engine',
project='flutter',
revision='abcd1234',
),
api.properties(
InputProperties(
goma_jobs='1024',
upload_packages=upload_packages,
),
),
api.step_data(
'Start Android emulator (API level 30)',
stdout=api.raw_io.output_text(
'android_30_google_apis_x86|emulator-5554 started (pid: 17687)'
)
)
)
test = api.test(
'with_failure_upload_%d' % upload_packages,
api.buildbucket.ci_build(
builder='Linux Engine',
git_repo='https://chromium.googlesource.com/external/github.com/flutter/engine',
project='flutter',
revision='abcd1234',
),
api.properties(
InputProperties(
goma_jobs='1024',
upload_packages=upload_packages,
clobber=False,
),
),
# Makes the test fail.
api.step_data('Scenario App Integration Tests', retcode=1),
api.path.exists(scenario_failures),
api.step_data(
'Start Android emulator (API level 30)',
stdout=api.raw_io.output_text(
'android_30_google_apis_x86|emulator-5554 started (pid: 17687)'
)
)
)
if upload_packages:
test += api.step_data(
'Ensure flutter/abcd1234/diff_failures.zip does not already exist on cloud storage',
retcode=1
)
yield test