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:
parent
00de965d0d
commit
35b87a5b44
@ -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...)
|
||||
|
@ -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",
|
||||
|
@ -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:
|
||||
|
@ -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
|
||||
}
|
||||
]
|
@ -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,
|
@ -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',
|
||||
]
|
||||
|
||||
|
83
infra/bots/recipe_modules/build/skqp.py
Normal file
83
infra/bots/recipe_modules/build/skqp.py
Normal 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)
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
]
|
104
infra/bots/recipes/test_skqp_emulator.py
Normal file
104
infra/bots/recipes/test_skqp_emulator.py
Normal 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]')
|
||||
)
|
@ -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
17
infra/skqp/build_apk.sh
Executable 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
|
34
infra/skqp/docker/README.md
Normal file
34
infra/skqp/docker/README.md
Normal 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
|
39
infra/skqp/docker/android-skqp/Dockerfile
Normal file
39
infra/skqp/docker/android-skqp/Dockerfile
Normal 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
27
infra/skqp/run_skqp.sh
Executable 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"
|
@ -13,7 +13,6 @@ dependencies {
|
||||
|
||||
android {
|
||||
compileSdkVersion 26
|
||||
buildToolsVersion "22.0.1"
|
||||
defaultConfig {
|
||||
applicationId "org.skia.skqp"
|
||||
minSdkVersion 19
|
||||
|
Loading…
Reference in New Issue
Block a user