Add Build and Test jobs for SKQP using docker.

Uses Docker to compile an APK and then run it on an emulator.

We use a specialized image for build (includes Clang, etc)
And then the 3rd party base image for just the test (which
has the emulator and SDK on it).

Bug: skia:7578, skia:7692
Change-Id: I948e0b091868e7173b00e3affd7c3d59a5cd1ec2
Reviewed-on: https://skia-review.googlesource.com/c/159681
Reviewed-by: Stephan Altmueller <stephana@google.com>
Reviewed-by: Hal Canary <halcanary@google.com>
This commit is contained in:
Kevin Lubick 2018-10-08 15:07:42 -04:00
parent 00de965d0d
commit 35b87a5b44
16 changed files with 943 additions and 53 deletions

View File

@ -501,6 +501,18 @@ func defaultSwarmDimensions(parts map[string]string) []string {
d["cpu"] = "x86-64-Haswell_GCE"
d["os"] = DEFAULT_OS_LINUX_GCE
d["machine_type"] = MACHINE_TYPE_SMALL
} else if strings.Contains(parts["extra_config"], "SKQP") && parts["cpu_or_gpu_value"] == "Emulator" {
if parts["model"] != "NUC7i5BNK" || d["os"] != DEFAULT_OS_DEBIAN {
glog.Fatalf("Please update defaultSwarmDimensions for SKQP::Emulator %s %s.", parts["os"], parts["model"])
}
d["cpu"] = "x86-64-i5-7260U"
d["os"] = "Debian-9.4"
// KVM means Kernel-based Virtual Machine, that is, can this vm virtualize commands
// For us, this means, can we run an x86 android emulator on it.
// kjlubick tried running this on GCE, but it was a bit too slow on the large install.
// So, we run on bare metal machines in the Skolo (that should also have KVM).
d["kvm"] = "1"
d["docker_installed"] = "true"
} else if parts["cpu_or_gpu"] == "CPU" {
modelMapping, ok := map[string]map[string]string{
"AVX": {
@ -785,11 +797,8 @@ func compile(b *specs.TasksCfgBuilder, name string, parts map[string]string) str
pkg := b.MustGetCipdPackageFromAsset("android_ndk_windows")
pkg.Path = "n"
task.CipdPackages = append(task.CipdPackages, pkg)
} else {
} else if !strings.Contains(name, "SKQP") {
task.Dependencies = append(task.Dependencies, isolateCIPDAsset(b, ISOLATE_NDK_LINUX_NAME))
if strings.Contains(name, "SKQP") {
task.Dependencies = append(task.Dependencies, isolateCIPDAsset(b, ISOLATE_SDK_LINUX_NAME), isolateCIPDAsset(b, ISOLATE_GO_LINUX_NAME), isolateCIPDAsset(b, ISOLATE_GO_DEPS_NAME))
}
}
} else if strings.Contains(name, "Chromecast") {
task.CipdPackages = append(task.CipdPackages, b.MustGetCipdPackageFromAsset("cast_toolchain"))
@ -1059,6 +1068,9 @@ func test(b *specs.TasksCfgBuilder, name string, parts map[string]string, compil
recipe := "test"
if strings.Contains(name, "SKQP") {
recipe = "skqp_test"
if strings.Contains(name, "Emulator") {
recipe = "test_skqp_emulator"
}
} else if strings.Contains(name, "OpenCL") {
// TODO(dogben): Longer term we may not want this to be called a "Test" task, but until we start
// running hs_bench or kx, it will be easier to fit into the current job name schema.
@ -1076,7 +1088,7 @@ func test(b *specs.TasksCfgBuilder, name string, parts map[string]string, compil
extraProps["internal_hardware_label"] = strconv.Itoa(*iid)
}
isolate := "test_skia_bundled.isolate"
if strings.Contains(name, "PathKit") || strings.Contains(name, "LottieWeb") {
if strings.Contains(name, "PathKit") || strings.Contains(name, "LottieWeb") || strings.Contains(name, "Emulator") {
isolate = "swarm_recipe.isolate"
}
task := kitchenTask(name, recipe, isolate, "", swarmDimensions(parts), extraProps, OUTPUT_TEST)
@ -1093,7 +1105,9 @@ func test(b *specs.TasksCfgBuilder, name string, parts map[string]string, compil
task.Dependencies = append(task.Dependencies, isolateCIPDAsset(b, ISOLATE_NDK_LINUX_NAME))
}
if strings.Contains(name, "SKQP") {
task.Dependencies = append(task.Dependencies, isolateCIPDAsset(b, ISOLATE_GCLOUD_LINUX_NAME))
if !strings.Contains(name, "Emulator") {
task.Dependencies = append(task.Dependencies, isolateCIPDAsset(b, ISOLATE_GCLOUD_LINUX_NAME))
}
}
if deps := getIsolatedCIPDDeps(parts); len(deps) > 0 {
task.Dependencies = append(task.Dependencies, deps...)

View File

@ -24,6 +24,7 @@
"Build-Debian9-Clang-x86-Debug-Android_Vulkan",
"Build-Debian9-Clang-x86-Release-Android",
"Build-Debian9-Clang-x86-Release-Android_Vulkan",
"Build-Debian9-Clang-x86-devrel-Android_SKQP",
"Build-Debian9-Clang-x86_64-Debug",
"Build-Debian9-Clang-x86_64-Debug-ASAN",
"Build-Debian9-Clang-x86_64-Debug-ASAN_Vulkan",
@ -419,6 +420,7 @@
"Test-Debian9-Clang-NUC5PPYH-GPU-IntelHD405-x86_64-Debug-All-Vulkan",
"Test-Debian9-Clang-NUC5PPYH-GPU-IntelHD405-x86_64-Release-All",
"Test-Debian9-Clang-NUC5PPYH-GPU-IntelHD405-x86_64-Release-All-Vulkan",
"Test-Debian9-Clang-NUC7i5BNK-CPU-Emulator-x86-devrel-All-Android_SKQP",
"Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All",
"Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All-OpenCL",
"Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All-Vulkan",

View File

@ -14,13 +14,17 @@ from . import chromecast
from . import default
from . import flutter
from . import pathkit
from . import skqp
from . import util
class BuildApi(recipe_api.RecipeApi):
def __init__(self, buildername, *args, **kwargs):
b = buildername
if 'Android' in b and not 'Flutter' in b:
if 'SKQP' in b and not 'Test' in b:
self.compile_fn = skqp.compile_fn
self.copy_fn = skqp.copy_extra_build_products
elif 'Android' in b and not 'Flutter' in b:
self.compile_fn = android.compile_fn
self.copy_fn = android.copy_extra_build_products
elif 'Chromebook' in b:

View File

@ -0,0 +1,121 @@
[
{
"cmd": [
"python",
"-u",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"ensure-directory",
"--mode",
"0777",
"[START_DIR]/cache/docker/skqp"
],
"infra_step": true,
"name": "mkdirs out_dir"
},
{
"cmd": [
"docker",
"run",
"--rm",
"--workdir",
"/SRC/skia/infra/skqp",
"--volume",
"[START_DIR]/cache/work:/SRC",
"--volume",
"[START_DIR]/cache/docker/skqp:/OUT",
"gcr.io/skia-public/android-skqp:8.1_v1",
"./build_apk.sh"
],
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "Build SKQP apk with Docker"
},
{
"cmd": [
"python",
"-u",
"import errno\nimport glob\nimport os\nimport shutil\nimport sys\n\nsrc = sys.argv[1]\ndst = sys.argv[2]\nbuild_products_whitelist = ['bookmaker', 'dm', 'dm.exe', 'dm.app', 'nanobench.app', 'get_images_from_skps', 'get_images_from_skps.exe', 'hello-opencl', 'hello-opencl.exe', 'nanobench', 'nanobench.exe', 'skpbench', 'skpbench.exe', '*.so', '*.dll', '*.dylib', 'skia_launcher', 'skiaserve', 'lib/*.so', 'run_testlab', 'skqp-universal-debug.apk', 'whitelist_devices.json']\n\ntry:\n os.makedirs(dst)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\nfor pattern in build_products_whitelist:\n path = os.path.join(src, pattern)\n for f in glob.glob(path):\n dst_path = os.path.join(dst, os.path.relpath(f, src))\n if not os.path.isdir(os.path.dirname(dst_path)):\n os.makedirs(os.path.dirname(dst_path))\n print 'Copying build product %s to %s' % (f, dst_path)\n shutil.move(f, dst_path)\n",
"[START_DIR]/cache/work/skia/out/Build-Debian9-Clang-x86-devrel-Android_SKQP/devrel",
"[START_DIR]/[SWARM_OUT_DIR]/out/devrel"
],
"infra_step": true,
"name": "copy build products",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import errno@@@",
"@@@STEP_LOG_LINE@python.inline@import glob@@@",
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@import shutil@@@",
"@@@STEP_LOG_LINE@python.inline@import sys@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@src = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@dst = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@build_products_whitelist = ['bookmaker', 'dm', 'dm.exe', 'dm.app', 'nanobench.app', 'get_images_from_skps', 'get_images_from_skps.exe', 'hello-opencl', 'hello-opencl.exe', 'nanobench', 'nanobench.exe', 'skpbench', 'skpbench.exe', '*.so', '*.dll', '*.dylib', 'skia_launcher', 'skiaserve', 'lib/*.so', 'run_testlab', 'skqp-universal-debug.apk', 'whitelist_devices.json']@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(dst)@@@",
"@@@STEP_LOG_LINE@python.inline@except OSError as e:@@@",
"@@@STEP_LOG_LINE@python.inline@ if e.errno != errno.EEXIST:@@@",
"@@@STEP_LOG_LINE@python.inline@ raise@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@for pattern in build_products_whitelist:@@@",
"@@@STEP_LOG_LINE@python.inline@ path = os.path.join(src, pattern)@@@",
"@@@STEP_LOG_LINE@python.inline@ for f in glob.glob(path):@@@",
"@@@STEP_LOG_LINE@python.inline@ dst_path = os.path.join(dst, os.path.relpath(f, src))@@@",
"@@@STEP_LOG_LINE@python.inline@ if not os.path.isdir(os.path.dirname(dst_path)):@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(os.path.dirname(dst_path))@@@",
"@@@STEP_LOG_LINE@python.inline@ print 'Copying build product %s to %s' % (f, dst_path)@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.move(f, dst_path)@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import errno\nimport glob\nimport os\nimport shutil\nimport sys\n\nsrc = sys.argv[1]\ndst = sys.argv[2]\nbuild_products_whitelist = ['*.apk']\n\ntry:\n os.makedirs(dst)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\nfor pattern in build_products_whitelist:\n path = os.path.join(src, pattern)\n for f in glob.glob(path):\n dst_path = os.path.join(dst, os.path.relpath(f, src))\n if not os.path.isdir(os.path.dirname(dst_path)):\n os.makedirs(os.path.dirname(dst_path))\n print 'Copying build product %s to %s' % (f, dst_path)\n # Because Docker usually has some strange permissions (like root\n # ownership), we'd rather not keep those around. copyfile doesn't\n # keep the metadata around, so that helps us.\n shutil.copyfile(f, dst_path)\n",
"[START_DIR]/cache/docker/skqp",
"[START_DIR]/[SWARM_OUT_DIR]/out/devrel"
],
"infra_step": true,
"name": "copy apk output",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import errno@@@",
"@@@STEP_LOG_LINE@python.inline@import glob@@@",
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@import shutil@@@",
"@@@STEP_LOG_LINE@python.inline@import sys@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@src = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@dst = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@build_products_whitelist = ['*.apk']@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(dst)@@@",
"@@@STEP_LOG_LINE@python.inline@except OSError as e:@@@",
"@@@STEP_LOG_LINE@python.inline@ if e.errno != errno.EEXIST:@@@",
"@@@STEP_LOG_LINE@python.inline@ raise@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@for pattern in build_products_whitelist:@@@",
"@@@STEP_LOG_LINE@python.inline@ path = os.path.join(src, pattern)@@@",
"@@@STEP_LOG_LINE@python.inline@ for f in glob.glob(path):@@@",
"@@@STEP_LOG_LINE@python.inline@ dst_path = os.path.join(dst, os.path.relpath(f, src))@@@",
"@@@STEP_LOG_LINE@python.inline@ if not os.path.isdir(os.path.dirname(dst_path)):@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(os.path.dirname(dst_path))@@@",
"@@@STEP_LOG_LINE@python.inline@ print 'Copying build product %s to %s' % (f, dst_path)@@@",
"@@@STEP_LOG_LINE@python.inline@ # Because Docker usually has some strange permissions (like root@@@",
"@@@STEP_LOG_LINE@python.inline@ # ownership), we'd rather not keep those around. copyfile doesn't@@@",
"@@@STEP_LOG_LINE@python.inline@ # keep the metadata around, so that helps us.@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.copyfile(f, dst_path)@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"name": "$result",
"recipe_result": null,
"status_code": 0
}
]

View File

@ -32,7 +32,7 @@
"go",
"build",
"-o",
"[START_DIR]/cache/work/skia/out/Build-Debian9-Clang-universal-devrel-Android_SKQP/devrel/run_testlab",
"[START_DIR]/cache/work/skia/out/Test-Debian9-Clang-GCE-CPU-AVX2-universal-devrel-All-Android_SKQP/devrel/run_testlab",
"[START_DIR]/cache/work/skia/infra/cts/run_testlab.go"
],
"cwd": "[START_DIR]/cache/work/skia",
@ -52,7 +52,7 @@
"env": {
"ANDROID_HOME": "[START_DIR]/android_sdk_linux/android-sdk",
"ANDROID_NDK": "[START_DIR]/android_ndk_linux",
"APK_OUTPUT_DIR": "[START_DIR]/cache/work/skia/out/Build-Debian9-Clang-universal-devrel-Android_SKQP/devrel",
"APK_OUTPUT_DIR": "[START_DIR]/cache/work/skia/out/Test-Debian9-Clang-GCE-CPU-AVX2-universal-devrel-All-Android_SKQP/devrel",
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
@ -63,7 +63,7 @@
"python",
"-u",
"import errno\nimport glob\nimport os\nimport shutil\nimport sys\n\nsrc = sys.argv[1]\ndst = sys.argv[2]\nbuild_products_whitelist = ['bookmaker', 'dm', 'dm.exe', 'dm.app', 'nanobench.app', 'get_images_from_skps', 'get_images_from_skps.exe', 'hello-opencl', 'hello-opencl.exe', 'nanobench', 'nanobench.exe', 'skpbench', 'skpbench.exe', '*.so', '*.dll', '*.dylib', 'skia_launcher', 'skiaserve', 'lib/*.so', 'run_testlab', 'skqp-universal-debug.apk', 'whitelist_devices.json']\n\ntry:\n os.makedirs(dst)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\nfor pattern in build_products_whitelist:\n path = os.path.join(src, pattern)\n for f in glob.glob(path):\n dst_path = os.path.join(dst, os.path.relpath(f, src))\n if not os.path.isdir(os.path.dirname(dst_path)):\n os.makedirs(os.path.dirname(dst_path))\n print 'Copying build product %s to %s' % (f, dst_path)\n shutil.move(f, dst_path)\n",
"[START_DIR]/cache/work/skia/out/Build-Debian9-Clang-universal-devrel-Android_SKQP/devrel",
"[START_DIR]/cache/work/skia/out/Test-Debian9-Clang-GCE-CPU-AVX2-universal-devrel-All-Android_SKQP/devrel",
"[START_DIR]/[SWARM_OUT_DIR]/out/devrel"
],
"infra_step": true,

View File

@ -28,7 +28,7 @@ TEST_BUILDERS = [
'Build-Debian9-Clang-arm-Release-Android_API26',
'Build-Debian9-Clang-arm-Release-Android_ASAN',
'Build-Debian9-Clang-arm-Release-Chromebook_GLES',
'Build-Debian9-Clang-universal-devrel-Android_SKQP',
'Build-Debian9-Clang-x86-devrel-Android_SKQP',
'Build-Debian9-Clang-x86_64-Debug-Chromebook_GLES',
'Build-Debian9-Clang-x86_64-Debug-Coverage',
'Build-Debian9-Clang-x86_64-Debug-MSAN',
@ -62,6 +62,7 @@ TEST_BUILDERS = [
'Build-Win-Clang-x86-Debug-Exceptions',
'Build-Win-Clang-x86_64-Debug-OpenCL',
'Build-Win-Clang-x86_64-Release-Vulkan',
'Test-Debian9-Clang-GCE-CPU-AVX2-universal-devrel-All-Android_SKQP',
'Housekeeper-PerCommit-CheckGeneratedFiles',
]

View File

@ -0,0 +1,83 @@
# Copyright 2018 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.
DOCKER_IMAGE = 'gcr.io/skia-public/android-skqp:8.1_v1'
INNER_BUILD_DIR = '/SRC/skia/infra/skqp'
INNER_BUILD_SCRIPT = './build_apk.sh'
BUILD_PRODUCTS_ISOLATE_WHITELIST_SKQP = [
'*.apk'
]
def compile_fn(api, checkout_root, _ignore):
out_dir = api.vars.cache_dir.join('docker', 'skqp')
# We want to make sure the directories exist and were created by chrome-bot,
# because if that isn't the case, docker will make them and they will be
# owned by root, which causes mysterious failures. To mitigate this risk
# further, we don't use the same out_dir as everyone else (thus the _ignore)
# param. Instead, we use a "skqp" subdirectory in the "docker" named_cache.
api.file.ensure_directory('mkdirs out_dir', out_dir, mode=0777)
# This uses the emscriptem sdk docker image and says "run the
# build_apk.sh helper script in there". Additionally, it binds two
# folders: the skia checkout to /SRC and the output directory to /OUT
# The called helper script will make the compile happen and put the
# output in the right spot. The neat thing is that since the Skia checkout
# (and, by extension, the build script) is not a part of the image, but
# bound in at runtime, we don't have to re-build the image, except when the
# toolchain changes.
cmd = ['docker', 'run', '--rm',
'--workdir', INNER_BUILD_DIR,
'--volume', '%s:/SRC' % checkout_root,
'--volume', '%s:/OUT' % out_dir,
DOCKER_IMAGE, INNER_BUILD_SCRIPT]
api.run(
api.step,
'Build SKQP apk with Docker',
cmd=cmd)
def copy_extra_build_products(api, _ignore, dst):
out_dir = api.vars.cache_dir.join('docker', 'skqp')
# We don't use the normal copy_build_products because it uses
# shutil.move, which attempts to delete the previous file, which
# doesn't work because the docker created outputs are read-only and
# owned by root (aka only docker images). It's likely safe to change
# the shutil.move in the original script to a non-deleting thing
# (like copy or copyfile), but there's some subtle behavior differences
# especially with directories, that kjlubick felt it best not to risk it.
api.python.inline(
name='copy apk output',
program='''import errno
import glob
import os
import shutil
import sys
src = sys.argv[1]
dst = sys.argv[2]
build_products_whitelist = %s
try:
os.makedirs(dst)
except OSError as e:
if e.errno != errno.EEXIST:
raise
for pattern in build_products_whitelist:
path = os.path.join(src, pattern)
for f in glob.glob(path):
dst_path = os.path.join(dst, os.path.relpath(f, src))
if not os.path.isdir(os.path.dirname(dst_path)):
os.makedirs(os.path.dirname(dst_path))
print 'Copying build product %%s to %%s' %% (f, dst_path)
# Because Docker usually has some strange permissions (like root
# ownership), we'd rather not keep those around. copyfile doesn't
# keep the metadata around, so that helps us.
shutil.copyfile(f, dst_path)
''' % str(BUILD_PRODUCTS_ISOLATE_WHITELIST_SKQP),
args=[out_dir, dst],
infra_step=True)

View File

@ -115,57 +115,33 @@
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"copy",
"[START_DIR]/cache/work/skia/infra/bots/assets/android_ndk_linux/VERSION",
"/path/to/tmp/"
"ensure-directory",
"--mode",
"0777",
"[START_DIR]/cache/docker/skqp"
],
"infra_step": true,
"name": "Get android_ndk_linux VERSION"
"name": "mkdirs out_dir"
},
{
"cmd": [
"python",
"-u",
"[START_DIR]/cache/work/skia/bin/fetch-gn"
"docker",
"run",
"--rm",
"--workdir",
"/SRC/skia/infra/skqp",
"--volume",
"[START_DIR]/cache/work:/SRC",
"--volume",
"[START_DIR]/cache/docker/skqp:/OUT",
"gcr.io/skia-public/android-skqp:8.1_v1",
"./build_apk.sh"
],
"cwd": "[START_DIR]/cache/work/skia",
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"infra_step": true,
"name": "fetch-gn"
},
{
"cmd": [
"go",
"build",
"-o",
"[START_DIR]/cache/work/skia/out/Build-Debian9-Clang-universal-devrel-Android_SKQP/devrel/run_testlab",
"[START_DIR]/cache/work/skia/infra/cts/run_testlab.go"
],
"cwd": "[START_DIR]/cache/work/skia",
"env": {
"CHROME_HEADLESS": "1",
"GOPATH": "[START_DIR]/go_deps",
"GOROOT": "[START_DIR]/go/go",
"PATH": "[START_DIR]/go/go/bin:[START_DIR]/go_deps:<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "build firebase runner"
},
{
"cmd": [
"[START_DIR]/cache/work/skia/tools/skqp/make_universal_apk"
],
"cwd": "[START_DIR]/cache/work/skia",
"env": {
"ANDROID_HOME": "[START_DIR]/android_sdk_linux/android-sdk",
"ANDROID_NDK": "[START_DIR]/android_ndk_linux",
"APK_OUTPUT_DIR": "[START_DIR]/cache/work/skia/out/Build-Debian9-Clang-universal-devrel-Android_SKQP/devrel",
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "make_universal"
"name": "Build SKQP apk with Docker"
},
{
"cmd": [
@ -205,6 +181,47 @@
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import errno\nimport glob\nimport os\nimport shutil\nimport sys\n\nsrc = sys.argv[1]\ndst = sys.argv[2]\nbuild_products_whitelist = ['*.apk']\n\ntry:\n os.makedirs(dst)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\nfor pattern in build_products_whitelist:\n path = os.path.join(src, pattern)\n for f in glob.glob(path):\n dst_path = os.path.join(dst, os.path.relpath(f, src))\n if not os.path.isdir(os.path.dirname(dst_path)):\n os.makedirs(os.path.dirname(dst_path))\n print 'Copying build product %s to %s' % (f, dst_path)\n # Because Docker usually has some strange permissions (like root\n # ownership), we'd rather not keep those around. copyfile doesn't\n # keep the metadata around, so that helps us.\n shutil.copyfile(f, dst_path)\n",
"[START_DIR]/cache/docker/skqp",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "copy apk output",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import errno@@@",
"@@@STEP_LOG_LINE@python.inline@import glob@@@",
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@import shutil@@@",
"@@@STEP_LOG_LINE@python.inline@import sys@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@src = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@dst = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@build_products_whitelist = ['*.apk']@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(dst)@@@",
"@@@STEP_LOG_LINE@python.inline@except OSError as e:@@@",
"@@@STEP_LOG_LINE@python.inline@ if e.errno != errno.EEXIST:@@@",
"@@@STEP_LOG_LINE@python.inline@ raise@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@for pattern in build_products_whitelist:@@@",
"@@@STEP_LOG_LINE@python.inline@ path = os.path.join(src, pattern)@@@",
"@@@STEP_LOG_LINE@python.inline@ for f in glob.glob(path):@@@",
"@@@STEP_LOG_LINE@python.inline@ dst_path = os.path.join(dst, os.path.relpath(f, src))@@@",
"@@@STEP_LOG_LINE@python.inline@ if not os.path.isdir(os.path.dirname(dst_path)):@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(os.path.dirname(dst_path))@@@",
"@@@STEP_LOG_LINE@python.inline@ print 'Copying build product %s to %s' % (f, dst_path)@@@",
"@@@STEP_LOG_LINE@python.inline@ # Because Docker usually has some strange permissions (like root@@@",
"@@@STEP_LOG_LINE@python.inline@ # ownership), we'd rather not keep those around. copyfile doesn't@@@",
"@@@STEP_LOG_LINE@python.inline@ # keep the metadata around, so that helps us.@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.copyfile(f, dst_path)@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",

View File

@ -0,0 +1,181 @@
[
{
"cmd": [
"python",
"-u",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"ensure-directory",
"--mode",
"0777",
"[START_DIR]/cache/work"
],
"infra_step": true,
"name": "makedirs checkout_path"
},
{
"cmd": [
"python",
"-u",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"remove",
"[START_DIR]/cache/work/.gclient_entries"
],
"infra_step": true,
"name": "remove [START_DIR]/cache/work/.gclient_entries"
},
{
"cmd": [
"python",
"-u",
"RECIPE_MODULE[depot_tools::bot_update]/resources/bot_update.py",
"--spec-path",
"cache_dir = '[START_DIR]/cache/git'\nsolutions = [{'deps_file': '.DEPS.git', 'managed': False, 'name': 'skia', 'url': 'https://skia.googlesource.com/skia.git'}]",
"--patch_root",
"skia",
"--revision_mapping_file",
"{\"got_revision\": \"skia\"}",
"--git-cache-dir",
"[START_DIR]/cache/git",
"--cleanup-dir",
"[CLEANUP]/bot_update",
"--output_json",
"/path/to/tmp/json",
"--revision",
"skia@abc123"
],
"cwd": "[START_DIR]/cache/work",
"env_prefixes": {
"PATH": [
"RECIPE_PACKAGE_REPO[depot_tools]"
]
},
"infra_step": true,
"name": "bot_update",
"~followup_annotations": [
"@@@STEP_TEXT@Some step text@@@",
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"did_run\": true, @@@",
"@@@STEP_LOG_LINE@json.output@ \"fixed_revisions\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"skia\": \"abc123\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"manifest\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"skia\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"repository\": \"https://fake.org/skia.git\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"revision\": \"9046e2e693bb92a76e972b694580e5d17ad10748\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"patch_failure\": false, @@@",
"@@@STEP_LOG_LINE@json.output@ \"patch_root\": \"skia\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"properties\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"got_revision\": \"9046e2e693bb92a76e972b694580e5d17ad10748\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"got_revision_cp\": \"refs/heads/master@{#164710}\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"root\": \"skia\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"source_manifest\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"directories\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"skia\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"git_checkout\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"repo_url\": \"https://fake.org/skia.git\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"revision\": \"9046e2e693bb92a76e972b694580e5d17ad10748\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"version\": 0@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"step_text\": \"Some step text\"@@@",
"@@@STEP_LOG_LINE@json.output@}@@@",
"@@@STEP_LOG_END@json.output@@@",
"@@@SET_BUILD_PROPERTY@got_revision@\"9046e2e693bb92a76e972b694580e5d17ad10748\"@@@",
"@@@SET_BUILD_PROPERTY@got_revision_cp@\"refs/heads/master@{#164710}\"@@@"
]
},
{
"cmd": [
"python",
"-u",
"\nimport os\nimport subprocess\nimport sys\n\ncontainer_name = sys.argv[1]\ncheckout_root = sys.argv[2]\napk_location = sys.argv[3]\nDOCKER_IMAGE = sys.argv[4]\n\nMAX_TRIES = 5\n\nstart_cmd = ['docker', 'run', '--privileged', '--rm', '-d', # detached/daemon\n '--name', container_name,\n '--env', 'DEVICE=Samsung Galaxy S6',\n '--volume', '%s:/SRC' % checkout_root,\n '--volume', '%s:/OUT' % apk_location,\n DOCKER_IMAGE]\n\nwait_cmd = ['docker', 'exec', container_name,\n 'timeout', '45', 'adb', 'wait-for-device']\n\nfor t in range(MAX_TRIES):\n print 'Starting Emulator try %d' % t\n try:\n # Start emulator\n print subprocess.check_output(start_cmd)\n # Wait a short time using adb-wait-for-device\n print subprocess.check_output(wait_cmd)\n # if exit code 0, we are good so end loop\n print 'Emulator started'\n sys.exit(0)\n except subprocess.CalledProcessError:\n # else kill docker container\n print 'Killing and trying again'\n print subprocess.check_output(['docker', 'kill', container_name])\nprint 'Could not start emulator'\nsys.exit(1)\n",
"android_em",
"[START_DIR]/cache/work",
"[START_DIR]/build",
"butomo1989/docker-android-x86-8.1@sha256:ad75c888e373d9ea7a2821fd8f64b53c9a22b5827e6fa516b396739a20b9bb88"
],
"infra_step": true,
"name": "Start Emulator",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@import subprocess@@@",
"@@@STEP_LOG_LINE@python.inline@import sys@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@container_name = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@checkout_root = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@apk_location = sys.argv[3]@@@",
"@@@STEP_LOG_LINE@python.inline@DOCKER_IMAGE = sys.argv[4]@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@MAX_TRIES = 5@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@start_cmd = ['docker', 'run', '--privileged', '--rm', '-d', # detached/daemon@@@",
"@@@STEP_LOG_LINE@python.inline@ '--name', container_name,@@@",
"@@@STEP_LOG_LINE@python.inline@ '--env', 'DEVICE=Samsung Galaxy S6',@@@",
"@@@STEP_LOG_LINE@python.inline@ '--volume', '%s:/SRC' % checkout_root,@@@",
"@@@STEP_LOG_LINE@python.inline@ '--volume', '%s:/OUT' % apk_location,@@@",
"@@@STEP_LOG_LINE@python.inline@ DOCKER_IMAGE]@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@wait_cmd = ['docker', 'exec', container_name,@@@",
"@@@STEP_LOG_LINE@python.inline@ 'timeout', '45', 'adb', 'wait-for-device']@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@for t in range(MAX_TRIES):@@@",
"@@@STEP_LOG_LINE@python.inline@ print 'Starting Emulator try %d' % t@@@",
"@@@STEP_LOG_LINE@python.inline@ try:@@@",
"@@@STEP_LOG_LINE@python.inline@ # Start emulator@@@",
"@@@STEP_LOG_LINE@python.inline@ print subprocess.check_output(start_cmd)@@@",
"@@@STEP_LOG_LINE@python.inline@ # Wait a short time using adb-wait-for-device@@@",
"@@@STEP_LOG_LINE@python.inline@ print subprocess.check_output(wait_cmd)@@@",
"@@@STEP_LOG_LINE@python.inline@ # if exit code 0, we are good so end loop@@@",
"@@@STEP_LOG_LINE@python.inline@ print 'Emulator started'@@@",
"@@@STEP_LOG_LINE@python.inline@ sys.exit(0)@@@",
"@@@STEP_LOG_LINE@python.inline@ except subprocess.CalledProcessError:@@@",
"@@@STEP_LOG_LINE@python.inline@ # else kill docker container@@@",
"@@@STEP_LOG_LINE@python.inline@ print 'Killing and trying again'@@@",
"@@@STEP_LOG_LINE@python.inline@ print subprocess.check_output(['docker', 'kill', container_name])@@@",
"@@@STEP_LOG_LINE@python.inline@print 'Could not start emulator'@@@",
"@@@STEP_LOG_LINE@python.inline@sys.exit(1)@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"docker",
"exec",
"android_em",
"/SRC/skia/infra/skqp/run_skqp.sh"
],
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "Test SQKP with Android Emulator in Docker"
},
{
"cmd": [
"docker",
"kill",
"android_em"
],
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"infra_step": true,
"name": "Stop Emulator"
},
{
"name": "$result",
"recipe_result": null,
"status_code": 0
}
]

View File

@ -0,0 +1,104 @@
# Copyright 2018 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 which runs the SKQP apk using docker and an Android Emulator
DEPS = [
'checkout',
'infra',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/python',
'recipe_engine/step',
'run',
'vars',
]
# This image is public, and thus doesn't require log-in to read.
DOCKER_IMAGE = ('butomo1989/docker-android-x86-8.1@sha256:'
'ad75c888e373d9ea7a2821fd8f64b53c9a22b5827e6fa516b396739a20b9bb88')
INNER_TEST_SCRIPT = '/SRC/skia/infra/skqp/run_skqp.sh'
def RunSteps(api):
api.vars.setup()
checkout_root = api.checkout.default_checkout_root
api.checkout.bot_update(checkout_root=checkout_root)
# This is where the APK should be, that is, where Swarming puts the inputs.
apk_location = api.vars.build_dir
container_name = 'android_em'
# Make sure the emulator starts up, with some resilence against
# occasional flakes.
api.python.inline(
name='Start Emulator',
program='''
import os
import subprocess
import sys
container_name = sys.argv[1]
checkout_root = sys.argv[2]
apk_location = sys.argv[3]
DOCKER_IMAGE = sys.argv[4]
MAX_TRIES = 5
start_cmd = ['docker', 'run', '--privileged', '--rm', '-d', # detached/daemon
'--name', container_name,
'--env', 'DEVICE=Samsung Galaxy S6',
'--volume', '%s:/SRC' % checkout_root,
'--volume', '%s:/OUT' % apk_location,
DOCKER_IMAGE]
wait_cmd = ['docker', 'exec', container_name,
'timeout', '45', 'adb', 'wait-for-device']
for t in range(MAX_TRIES):
print 'Starting Emulator try %d' % t
try:
# Start emulator
print subprocess.check_output(start_cmd)
# Wait a short time using adb-wait-for-device
print subprocess.check_output(wait_cmd)
# if exit code 0, we are good so end loop
print 'Emulator started'
sys.exit(0)
except subprocess.CalledProcessError:
# else kill docker container
print 'Killing and trying again'
print subprocess.check_output(['docker', 'kill', container_name])
print 'Could not start emulator'
sys.exit(1)
''',
args=[container_name, checkout_root, apk_location, DOCKER_IMAGE],
infra_step=True)
api.run(
api.step,
'Test SQKP with Android Emulator in Docker',
cmd=['docker', 'exec', container_name,
INNER_TEST_SCRIPT])
api.run(
api.step,
'Stop Emulator',
cmd=['docker', 'kill', container_name],
infra_step=True)
def GenTests(api):
yield (
api.test('Test-Debian9-Clang-GCE-CPU-Emulator-x86-devrel'
'-All-Android_SKQP') +
api.properties(buildername=('Test-Debian9-Clang-GCE-CPU-Emulator'
'-x86-devrel-All-Android_SKQP'),
repository='https://skia.googlesource.com/skia.git',
revision='abc123',
path_config='kitchen',
swarm_out_dir='[SWARM_OUT_DIR]')
)

View File

@ -126,6 +126,11 @@
"Build-Debian9-Clang-x86-Release-Android_Vulkan"
]
},
"Build-Debian9-Clang-x86-devrel-Android_SKQP": {
"tasks": [
"Build-Debian9-Clang-x86-devrel-Android_SKQP"
]
},
"Build-Debian9-Clang-x86_64-Debug": {
"tasks": [
"Build-Debian9-Clang-x86_64-Debug"
@ -2114,6 +2119,11 @@
"Upload-Test-Debian9-Clang-NUC5PPYH-GPU-IntelHD405-x86_64-Release-All-Vulkan"
]
},
"Test-Debian9-Clang-NUC7i5BNK-CPU-Emulator-x86-devrel-All-Android_SKQP": {
"tasks": [
"Test-Debian9-Clang-NUC7i5BNK-CPU-Emulator-x86-devrel-All-Android_SKQP"
]
},
"Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All": {
"tasks": [
"Upload-Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All"
@ -6050,6 +6060,130 @@
],
"service_account": "skia-external-compile-tasks@skia-swarming-bots.iam.gserviceaccount.com"
},
"Build-Debian9-Clang-x86-devrel-Android_SKQP": {
"caches": [
{
"name": "vpython",
"path": "cache/vpython"
},
{
"name": "git",
"path": "cache/git"
},
{
"name": "git_cache",
"path": "cache/git_cache"
},
{
"name": "work",
"path": "cache/work"
}
],
"cipd_packages": [
{
"name": "infra/tools/luci/kitchen/${platform}",
"path": ".",
"version": "git_revision:546aae39f1fb9dce9add528e2011afa574535ecd"
},
{
"name": "infra/tools/luci-auth/${platform}",
"path": "cipd_bin_packages",
"version": "git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c"
},
{
"name": "infra/tools/luci/vpython/${platform}",
"path": "cipd_bin_packages",
"version": "git_revision:b6cdec8586c9f8d3d728b1bc0bd4331330ba66fc"
},
{
"name": "infra/git/${platform}",
"path": "cipd_bin_packages",
"version": "version:2.17.1.chromium15"
},
{
"name": "infra/tools/git/${platform}",
"path": "cipd_bin_packages",
"version": "git_revision:0ae21738597e5601ba90372315145fec18582fc4"
},
{
"name": "infra/tools/luci/git-credential-luci/${platform}",
"path": "cipd_bin_packages",
"version": "git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c"
}
],
"command": [
"./kitchen${EXECUTABLE_SUFFIX}",
"cook",
"-checkout-dir",
"recipe_bundle",
"-mode",
"swarming",
"-luci-system-account",
"system",
"-cache-dir",
"cache",
"-temp-dir",
"tmp",
"-known-gerrit-host",
"android.googlesource.com",
"-known-gerrit-host",
"boringssl.googlesource.com",
"-known-gerrit-host",
"chromium.googlesource.com",
"-known-gerrit-host",
"dart.googlesource.com",
"-known-gerrit-host",
"fuchsia.googlesource.com",
"-known-gerrit-host",
"go.googlesource.com",
"-known-gerrit-host",
"llvm.googlesource.com",
"-known-gerrit-host",
"skia.googlesource.com",
"-known-gerrit-host",
"webrtc.googlesource.com",
"-output-result-json",
"${ISOLATED_OUTDIR}/build_result_filename",
"-workdir",
".",
"-recipe",
"compile",
"-properties",
"{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Build-Debian9-Clang-x86-devrel-Android_SKQP\",\"patch_issue\":\"<(ISSUE)\",\"patch_ref\":\"<(PATCH_REF)\",\"patch_repo\":\"<(PATCH_REPO)\",\"patch_set\":\"<(PATCHSET)\",\"patch_storage\":\"<(PATCH_STORAGE)\",\"repository\":\"<(REPO)\",\"revision\":\"<(REVISION)\",\"swarm_out_dir\":\"build\"}",
"-logdog-annotation-url",
"logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
],
"dependencies": [
"Housekeeper-PerCommit-BundleRecipes"
],
"dimensions": [
"cpu:x86-64-Haswell_GCE",
"gpu:none",
"machine_type:n1-highcpu-64",
"os:Debian-9.4",
"pool:Skia"
],
"env_prefixes": {
"PATH": [
"cipd_bin_packages",
"cipd_bin_packages/bin"
],
"VPYTHON_VIRTUALENV_ROOT": [
"cache/vpython"
]
},
"execution_timeout_ns": 3600000000000,
"extra_tags": {
"log_location": "logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
},
"io_timeout_ns": 3600000000000,
"isolate": "swarm_recipe.isolate",
"max_attempts": 1,
"outputs": [
"build"
],
"service_account": "skia-external-compile-tasks@skia-swarming-bots.iam.gserviceaccount.com"
},
"Build-Debian9-Clang-x86_64-Debug": {
"caches": [
{
@ -50102,6 +50236,119 @@
"test"
]
},
"Test-Debian9-Clang-NUC7i5BNK-CPU-Emulator-x86-devrel-All-Android_SKQP": {
"caches": [
{
"name": "vpython",
"path": "cache/vpython"
}
],
"cipd_packages": [
{
"name": "infra/tools/luci/kitchen/${platform}",
"path": ".",
"version": "git_revision:546aae39f1fb9dce9add528e2011afa574535ecd"
},
{
"name": "infra/tools/luci-auth/${platform}",
"path": "cipd_bin_packages",
"version": "git_revision:e1abc57be62d198b5c2f487bfb2fa2d2eb0e867c"
},
{
"name": "infra/tools/luci/vpython/${platform}",
"path": "cipd_bin_packages",
"version": "git_revision:b6cdec8586c9f8d3d728b1bc0bd4331330ba66fc"
},
{
"name": "skia/bots/skimage",
"path": "skimage",
"version": "version:34"
},
{
"name": "skia/bots/skp",
"path": "skp",
"version": "version:146"
},
{
"name": "skia/bots/svg",
"path": "svg",
"version": "version:9"
}
],
"command": [
"./kitchen${EXECUTABLE_SUFFIX}",
"cook",
"-checkout-dir",
"recipe_bundle",
"-mode",
"swarming",
"-luci-system-account",
"system",
"-cache-dir",
"cache",
"-temp-dir",
"tmp",
"-known-gerrit-host",
"android.googlesource.com",
"-known-gerrit-host",
"boringssl.googlesource.com",
"-known-gerrit-host",
"chromium.googlesource.com",
"-known-gerrit-host",
"dart.googlesource.com",
"-known-gerrit-host",
"fuchsia.googlesource.com",
"-known-gerrit-host",
"go.googlesource.com",
"-known-gerrit-host",
"llvm.googlesource.com",
"-known-gerrit-host",
"skia.googlesource.com",
"-known-gerrit-host",
"webrtc.googlesource.com",
"-output-result-json",
"${ISOLATED_OUTDIR}/build_result_filename",
"-workdir",
".",
"-recipe",
"test_skqp_emulator",
"-properties",
"{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Test-Debian9-Clang-NUC7i5BNK-CPU-Emulator-x86-devrel-All-Android_SKQP\",\"gold_hashes_url\":\"https://storage.googleapis.com/skia-infra-gm/hash_files/gold-prod-hashes.txt\",\"patch_issue\":\"<(ISSUE)\",\"patch_ref\":\"<(PATCH_REF)\",\"patch_repo\":\"<(PATCH_REPO)\",\"patch_set\":\"<(PATCHSET)\",\"patch_storage\":\"<(PATCH_STORAGE)\",\"repository\":\"<(REPO)\",\"revision\":\"<(REVISION)\",\"swarm_out_dir\":\"test\"}",
"-logdog-annotation-url",
"logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
],
"dependencies": [
"Housekeeper-PerCommit-BundleRecipes",
"Build-Debian9-Clang-x86-devrel-Android_SKQP"
],
"dimensions": [
"cpu:x86-64-i5-7260U",
"docker_installed:true",
"kvm:1",
"os:Debian-9.4",
"pool:Skia"
],
"env_prefixes": {
"PATH": [
"cipd_bin_packages",
"cipd_bin_packages/bin"
],
"VPYTHON_VIRTUALENV_ROOT": [
"cache/vpython"
]
},
"execution_timeout_ns": 14400000000000,
"expiration_ns": 72000000000000,
"extra_tags": {
"log_location": "logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
},
"io_timeout_ns": 14400000000000,
"isolate": "swarm_recipe.isolate",
"max_attempts": 1,
"outputs": [
"test"
]
},
"Test-Debian9-Clang-NUC7i5BNK-GPU-IntelIris640-x86_64-Debug-All": {
"caches": [
{

17
infra/skqp/build_apk.sh Executable file
View File

@ -0,0 +1,17 @@
#!/bin/bash
# Copyright 2018 Google LLC
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Assumes this is in a docker container with a skia repo mounted at /SRC
pushd ../../
./tools/skqp/make_universal_apk x86
# Clean out previous builds
rm /OUT/*
cp out/skqp/skqp-universal-debug.apk /OUT/skqp-universal-x86-debug.apk
popd

View File

@ -0,0 +1,34 @@
Docker
======
Docker files to ease working with the Android SDK/NDK and SKQP.
android-skqp
-------------
This image has an Android emulator, the Android SDK and NDK installed on it.
Additionally, it has the dependencies needed to build SKQP - Clang, python, ninja.
It gets manually pushed anytime there's an update to the Dockerfile or relevant
installed libraries.
docker build -t android-skqp ./android-skqp/
ANDROID_SDK_VERSION="8.1_v1" # use v2, v3 for respins
docker tag android-skqp gcr.io/skia-public/android-skqp:$ANDROID_SDK_VERSION
docker push gcr.io/skia-public/android-skqp:$ANDROID_SDK_VERSION
For testing the image locally, the following flow can be helpful:
docker build -t android-skqp ./android-skqp/
# start an emulator
docker run --privileged -d --name android_em -e DEVICE="Samsung Galaxy S6" -v $SKIA_ROOT:/SRC -v $SKIA_ROOT/out/skqp:/OUT android-skqp
# attach to that emulator
docker exec -it android_em /bin/bash
# Compile SKQP
docker run -it --rm -w /SRC/infra/skqp -v $SKIA_ROOT:/SRC android-skqp ./build_apk.sh
# Run SKQP (can't mount anything with -v here, must do it on original docker run)
docker exec -it android_em /SRC/infra/skqp/run_skqp.sh
# Cleanup
docker kill android_em
docker rm android_em

View File

@ -0,0 +1,39 @@
# This image can be used to build an Android app using the NDK, since $ANDROID_HOME is set.
# The only "Skia-specific" thing is the depot_tools, everything else is pretty generic.
#
# The base Docker image (butomo1989/docker-android-x86-8.1:1.4-p1) has an android emulator
# that can be run by doing the following
# docker run --privileged -d --name android_em -e DEVICE="Samsung Galaxy S6" butomo1989/docker-android-x86-8.1:1.4-p1
# Then, the running container can be attached to by:
# docker exec -it android_em /bin/bash
# Of course, this Docker image can also do that, it's just a bit heavier for "emulation only"
# tasks.
FROM butomo1989/docker-android-x86-8.1:1.4-p1
RUN apt-get update && apt-get upgrade -y && \
apt-get install -y \
clang-6.0 \
git \
python
RUN git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git /opt/depot_tools
WORKDIR /root
RUN wget -O /root/android-ndk-r18-linux-x86_64.zip https://storage.googleapis.com/skia-cdn/android-sdk/android-ndk-r18-linux-x86_64.zip && \
unzip /root/android-ndk-r18-linux-x86_64.zip && \
rm -f /root/android-ndk-r18-linux-x86_64.zip
RUN sdkmanager ndk-bundle "lldb;3.1" "cmake;3.6.4111459"
RUN update-alternatives --install /usr/bin/cc cc /usr/lib/llvm-6.0/bin/clang 20 && \
update-alternatives --install /usr/bin/c++ c++ /usr/lib/llvm-6.0/bin/clang++ 20
ENV CC="/usr/lib/llvm-6.0/bin/clang" \
CXX="/usr/lib/llvm-6.0/bin/clang++" \
PATH=/usr/lib/llvm-6.0/bin:$PATH
ENV PATH=$PATH:/opt/depot_tools
ENV ANDROID_NDK=/root/android-ndk-r18

27
infra/skqp/run_skqp.sh Executable file
View File

@ -0,0 +1,27 @@
#!/bin/bash
# Copyright 2018 Google LLC
#
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
#
# Assumes this is in a docker container with a skia repo mounted at /SRC and a folder containing the
# built APK to be in /OUT.
# Additionally, this assumes that the docker container was run to have an android emulator running
# that is accesible with adb.
# This script in particular doesn't care about arm vs x86, but the current incarnation has an x86
# emulator and so the apk should be built for that.
#
# Example usage:
#
set -ex
# Wait for boot
timeout 60 adb wait-for-device shell 'while [[ -z $(getprop sys.boot_completed) ]]; do sleep 1; done'
# Some extra sleep to make sure the emulator is awake and ready for installation
sleep 10
adb install -r /OUT/*.apk
adb logcat -c
adb shell am instrument -w org.skia.skqp
adb logcat -d TestRunner org.skia.skqp skia DEBUG "*:S"

View File

@ -13,7 +13,6 @@ dependencies {
android {
compileSdkVersion 26
buildToolsVersion "22.0.1"
defaultConfig {
applicationId "org.skia.skqp"
minSdkVersion 19