Add Perf jobs for PathKit

We have a similar ingestion strategy to Gold.

I tried to use something off the shelf like benchmark.js
but passing the PathKit context into the benchmarks was
non-trivial. Plus, making a basic benchmarking tool
ended up being not too hard.

We should be able to re-use the docker container/aggregator
for CanvasKit too.

Bug: skia:
Change-Id: I613dfc58ea57c31cf71566a8ac55f8df9272ad25
Reviewed-on: https://skia-review.googlesource.com/c/161620
Commit-Queue: Kevin Lubick <kjlubick@google.com>
Reviewed-by: Joe Gregorio <jcgregorio@google.com>
Reviewed-by: Stephan Altmueller <stephana@google.com>
This commit is contained in:
Kevin Lubick 2018-10-12 15:21:17 -04:00 committed by Skia Commit-Bot
parent 21bd60daa3
commit 556350de37
23 changed files with 2384 additions and 23 deletions

View File

@ -1135,6 +1135,8 @@ func perf(b *specs.TasksCfgBuilder, name string, parts map[string]string, compil
if strings.Contains(parts["extra_config"], "Skpbench") {
recipe = "skpbench"
isolate = relpath("skpbench_skia_bundled.isolate")
} else if strings.Contains(name, "PathKit") {
recipe = "perf_pathkit"
}
task := kitchenTask(name, recipe, isolate, "", swarmDimensions(parts), nil, OUTPUT_PERF)
task.CipdPackages = append(task.CipdPackages, pkgs...)

View File

@ -221,6 +221,8 @@
"Perf-Debian9-Clang-NUCDE3815TYKHE-GPU-IntelBayTrail-x86_64-Release-All",
"Perf-Debian9-Clang-ShuttleA-GPU-IntelHD2000-x86_64-Debug-All",
"Perf-Debian9-Clang-ShuttleA-GPU-IntelHD2000-x86_64-Release-All",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit",
"Perf-Debian9-GCC-GCE-CPU-AVX2-x86-Debug-All",
"Perf-Debian9-GCC-GCE-CPU-AVX2-x86_64-Debug-All",
"Perf-Mac-Clang-MacBook10.1-GPU-IntelHD615-x86_64-Debug-All",

View File

@ -0,0 +1,235 @@
[
{
"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",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"ensure-directory",
"--mode",
"0777",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "mkdirs out_dir"
},
{
"cmd": [
"python",
"-u",
"import errno\nimport os\nimport shutil\nimport sys\n\ncopy_dest = sys.argv[1]\nbase_dir = sys.argv[2]\nbundle_name = sys.argv[3]\nout_dir = sys.argv[4]\n\n# Clean out old binaries (if any)\ntry:\n shutil.rmtree(copy_dest)\nexcept OSError as e:\n if e.errno != errno.ENOENT:\n raise\n\n# Make folder\ntry:\n os.makedirs(copy_dest)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\n# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests\n# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)\ndest = os.path.join(copy_dest, 'pathkit.js')\nshutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)\nos.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.\n\nif bundle_name:\n dest = os.path.join(copy_dest, bundle_name)\n shutil.copyfile(os.path.join(base_dir, bundle_name), dest)\n os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.\n\n# Prepare output folder, api.file.ensure_directory doesn't touch\n# the permissions of the out directory if it already exists.\nos.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.\n",
"[START_DIR]/cache/work/skia/modules/pathkit/npm-asmjs/bin",
"[START_DIR]/build",
"pathkit.js.mem",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "Set up for docker",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import errno@@@",
"@@@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@copy_dest = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@base_dir = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@bundle_name = sys.argv[3]@@@",
"@@@STEP_LOG_LINE@python.inline@out_dir = sys.argv[4]@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Clean out old binaries (if any)@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.rmtree(copy_dest)@@@",
"@@@STEP_LOG_LINE@python.inline@except OSError as e:@@@",
"@@@STEP_LOG_LINE@python.inline@ if e.errno != errno.ENOENT:@@@",
"@@@STEP_LOG_LINE@python.inline@ raise@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Make folder@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(copy_dest)@@@",
"@@@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@# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests@@@",
"@@@STEP_LOG_LINE@python.inline@# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)@@@",
"@@@STEP_LOG_LINE@python.inline@dest = os.path.join(copy_dest, 'pathkit.js')@@@",
"@@@STEP_LOG_LINE@python.inline@shutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)@@@",
"@@@STEP_LOG_LINE@python.inline@os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@if bundle_name:@@@",
"@@@STEP_LOG_LINE@python.inline@ dest = os.path.join(copy_dest, bundle_name)@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.copyfile(os.path.join(base_dir, bundle_name), dest)@@@",
"@@@STEP_LOG_LINE@python.inline@ os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Prepare output folder, api.file.ensure_directory doesn't touch@@@",
"@@@STEP_LOG_LINE@python.inline@# the permissions of the out directory if it already exists.@@@",
"@@@STEP_LOG_LINE@python.inline@os.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
],
"name": "get swarming bot id",
"stdout": "/path/to/tmp/",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_BOT_ID', '')@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
],
"name": "get swarming task id",
"stdout": "/path/to/tmp/",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_TASK_ID', '')@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"docker",
"run",
"--shm-size=2gb",
"--rm",
"-v",
"[START_DIR]/cache/work:/SRC",
"-v",
"[START_DIR]/[SWARM_OUT_DIR]:/OUT",
"-e",
"ASM_JS=1",
"gcr.io/skia-public/perf-karma-chrome-tests:68.0.3440.106_v1",
"/SRC/skia/infra/pathkit/perf_pathkit.sh",
"--builder",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit",
"--git_hash",
"abc123",
"--buildbucket_build_id",
"",
"--bot_id",
"",
"--task_id",
"",
"--browser",
"Chrome",
"--config",
"Release",
"--compiled_language",
"asmjs"
],
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "Performance tests of PathKit with Docker"
},
{
"name": "$result",
"recipe_result": null,
"status_code": 0
}
]

View File

@ -0,0 +1,231 @@
[
{
"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",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"ensure-directory",
"--mode",
"0777",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "mkdirs out_dir"
},
{
"cmd": [
"python",
"-u",
"import errno\nimport os\nimport shutil\nimport sys\n\ncopy_dest = sys.argv[1]\nbase_dir = sys.argv[2]\nbundle_name = sys.argv[3]\nout_dir = sys.argv[4]\n\n# Clean out old binaries (if any)\ntry:\n shutil.rmtree(copy_dest)\nexcept OSError as e:\n if e.errno != errno.ENOENT:\n raise\n\n# Make folder\ntry:\n os.makedirs(copy_dest)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\n# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests\n# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)\ndest = os.path.join(copy_dest, 'pathkit.js')\nshutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)\nos.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.\n\nif bundle_name:\n dest = os.path.join(copy_dest, bundle_name)\n shutil.copyfile(os.path.join(base_dir, bundle_name), dest)\n os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.\n\n# Prepare output folder, api.file.ensure_directory doesn't touch\n# the permissions of the out directory if it already exists.\nos.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.\n",
"[START_DIR]/cache/work/skia/modules/pathkit/npm-wasm/bin",
"[START_DIR]/build",
"pathkit.wasm",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "Set up for docker",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import errno@@@",
"@@@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@copy_dest = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@base_dir = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@bundle_name = sys.argv[3]@@@",
"@@@STEP_LOG_LINE@python.inline@out_dir = sys.argv[4]@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Clean out old binaries (if any)@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.rmtree(copy_dest)@@@",
"@@@STEP_LOG_LINE@python.inline@except OSError as e:@@@",
"@@@STEP_LOG_LINE@python.inline@ if e.errno != errno.ENOENT:@@@",
"@@@STEP_LOG_LINE@python.inline@ raise@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Make folder@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(copy_dest)@@@",
"@@@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@# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests@@@",
"@@@STEP_LOG_LINE@python.inline@# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)@@@",
"@@@STEP_LOG_LINE@python.inline@dest = os.path.join(copy_dest, 'pathkit.js')@@@",
"@@@STEP_LOG_LINE@python.inline@shutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)@@@",
"@@@STEP_LOG_LINE@python.inline@os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@if bundle_name:@@@",
"@@@STEP_LOG_LINE@python.inline@ dest = os.path.join(copy_dest, bundle_name)@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.copyfile(os.path.join(base_dir, bundle_name), dest)@@@",
"@@@STEP_LOG_LINE@python.inline@ os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Prepare output folder, api.file.ensure_directory doesn't touch@@@",
"@@@STEP_LOG_LINE@python.inline@# the permissions of the out directory if it already exists.@@@",
"@@@STEP_LOG_LINE@python.inline@os.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
],
"name": "get swarming bot id",
"stdout": "/path/to/tmp/",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_BOT_ID', '')@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
],
"name": "get swarming task id",
"stdout": "/path/to/tmp/",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_TASK_ID', '')@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"docker",
"run",
"--shm-size=2gb",
"--rm",
"-v",
"[START_DIR]/cache/work:/SRC",
"-v",
"[START_DIR]/[SWARM_OUT_DIR]:/OUT",
"gcr.io/skia-public/perf-karma-chrome-tests:68.0.3440.106_v1",
"/SRC/skia/infra/pathkit/perf_pathkit.sh",
"--builder",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit",
"--git_hash",
"abc123",
"--buildbucket_build_id",
"",
"--bot_id",
"",
"--task_id",
"",
"--browser",
"Chrome",
"--config",
"Release"
],
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "Performance tests of PathKit with Docker"
},
{
"name": "$result",
"recipe_result": null,
"status_code": 0
}
]

View File

@ -0,0 +1,239 @@
[
{
"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",
"--patch_ref",
"https://skia.googlesource.com/skia.git@89/456789/12",
"--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",
"RECIPE_MODULE[recipe_engine::file]/resources/fileutil.py",
"--json-output",
"/path/to/tmp/json",
"ensure-directory",
"--mode",
"0777",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "mkdirs out_dir"
},
{
"cmd": [
"python",
"-u",
"import errno\nimport os\nimport shutil\nimport sys\n\ncopy_dest = sys.argv[1]\nbase_dir = sys.argv[2]\nbundle_name = sys.argv[3]\nout_dir = sys.argv[4]\n\n# Clean out old binaries (if any)\ntry:\n shutil.rmtree(copy_dest)\nexcept OSError as e:\n if e.errno != errno.ENOENT:\n raise\n\n# Make folder\ntry:\n os.makedirs(copy_dest)\nexcept OSError as e:\n if e.errno != errno.EEXIST:\n raise\n\n# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests\n# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)\ndest = os.path.join(copy_dest, 'pathkit.js')\nshutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)\nos.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.\n\nif bundle_name:\n dest = os.path.join(copy_dest, bundle_name)\n shutil.copyfile(os.path.join(base_dir, bundle_name), dest)\n os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.\n\n# Prepare output folder, api.file.ensure_directory doesn't touch\n# the permissions of the out directory if it already exists.\nos.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.\n",
"[START_DIR]/cache/work/skia/modules/pathkit/npm-wasm/bin",
"[START_DIR]/build",
"pathkit.wasm",
"[START_DIR]/[SWARM_OUT_DIR]"
],
"infra_step": true,
"name": "Set up for docker",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import errno@@@",
"@@@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@copy_dest = sys.argv[1]@@@",
"@@@STEP_LOG_LINE@python.inline@base_dir = sys.argv[2]@@@",
"@@@STEP_LOG_LINE@python.inline@bundle_name = sys.argv[3]@@@",
"@@@STEP_LOG_LINE@python.inline@out_dir = sys.argv[4]@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Clean out old binaries (if any)@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.rmtree(copy_dest)@@@",
"@@@STEP_LOG_LINE@python.inline@except OSError as e:@@@",
"@@@STEP_LOG_LINE@python.inline@ if e.errno != errno.ENOENT:@@@",
"@@@STEP_LOG_LINE@python.inline@ raise@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Make folder@@@",
"@@@STEP_LOG_LINE@python.inline@try:@@@",
"@@@STEP_LOG_LINE@python.inline@ os.makedirs(copy_dest)@@@",
"@@@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@# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests@@@",
"@@@STEP_LOG_LINE@python.inline@# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)@@@",
"@@@STEP_LOG_LINE@python.inline@dest = os.path.join(copy_dest, 'pathkit.js')@@@",
"@@@STEP_LOG_LINE@python.inline@shutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)@@@",
"@@@STEP_LOG_LINE@python.inline@os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@if bundle_name:@@@",
"@@@STEP_LOG_LINE@python.inline@ dest = os.path.join(copy_dest, bundle_name)@@@",
"@@@STEP_LOG_LINE@python.inline@ shutil.copyfile(os.path.join(base_dir, bundle_name), dest)@@@",
"@@@STEP_LOG_LINE@python.inline@ os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.@@@",
"@@@STEP_LOG_LINE@python.inline@@@@",
"@@@STEP_LOG_LINE@python.inline@# Prepare output folder, api.file.ensure_directory doesn't touch@@@",
"@@@STEP_LOG_LINE@python.inline@# the permissions of the out directory if it already exists.@@@",
"@@@STEP_LOG_LINE@python.inline@os.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import os\nprint os.environ.get('SWARMING_BOT_ID', '')\n"
],
"name": "get swarming bot id",
"stdout": "/path/to/tmp/",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_BOT_ID', '')@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"python",
"-u",
"import os\nprint os.environ.get('SWARMING_TASK_ID', '')\n"
],
"name": "get swarming task id",
"stdout": "/path/to/tmp/",
"~followup_annotations": [
"@@@STEP_LOG_LINE@python.inline@import os@@@",
"@@@STEP_LOG_LINE@python.inline@print os.environ.get('SWARMING_TASK_ID', '')@@@",
"@@@STEP_LOG_END@python.inline@@@"
]
},
{
"cmd": [
"docker",
"run",
"--shm-size=2gb",
"--rm",
"-v",
"[START_DIR]/cache/work:/SRC",
"-v",
"[START_DIR]/[SWARM_OUT_DIR]:/OUT",
"gcr.io/skia-public/perf-karma-chrome-tests:68.0.3440.106_v1",
"/SRC/skia/infra/pathkit/perf_pathkit.sh",
"--builder",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit",
"--git_hash",
"abc123",
"--buildbucket_build_id",
"",
"--bot_id",
"",
"--task_id",
"",
"--browser",
"Chrome",
"--config",
"Release",
"--issue",
"1234",
"--patchset",
"7",
"--patch_storage",
"gerrit"
],
"env": {
"CHROME_HEADLESS": "1",
"PATH": "<PATH>:RECIPE_PACKAGE_REPO[depot_tools]"
},
"name": "Performance tests of PathKit with Docker"
},
{
"name": "$result",
"recipe_result": null,
"status_code": 0
}
]

View File

@ -0,0 +1,162 @@
# 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 PathKit tests using docker
DEPS = [
'checkout',
'infra',
'recipe_engine/file',
'recipe_engine/path',
'recipe_engine/properties',
'recipe_engine/python',
'recipe_engine/step',
'run',
'vars',
]
DOCKER_IMAGE = 'gcr.io/skia-public/perf-karma-chrome-tests:68.0.3440.106_v1'
INNER_KARMA_SCRIPT = '/SRC/skia/infra/pathkit/perf_pathkit.sh'
def RunSteps(api):
api.vars.setup()
checkout_root = api.checkout.default_checkout_root
out_dir = api.vars.swarming_out_dir
api.checkout.bot_update(checkout_root=checkout_root)
# Make sure this exists, otherwise Docker will make it with root permissions.
api.file.ensure_directory('mkdirs out_dir', out_dir, mode=0777)
# The karma script is configured to look in ./npm-(asmjs|wasm)/bin/ for
# the test files to load, so we must copy them there (see Set up for docker).
copy_dest = checkout_root.join('skia', 'modules', 'pathkit',
'npm-wasm', 'bin')
if 'asmjs' in api.vars.builder_name:
copy_dest = checkout_root.join('skia', 'modules', 'pathkit',
'npm-asmjs', 'bin')
base_dir = api.vars.build_dir
bundle_name = 'pathkit.wasm'
if 'asmjs' in api.vars.builder_name:
bundle_name = 'pathkit.js.mem'
api.python.inline(
name='Set up for docker',
program='''import errno
import os
import shutil
import sys
copy_dest = sys.argv[1]
base_dir = sys.argv[2]
bundle_name = sys.argv[3]
out_dir = sys.argv[4]
# Clean out old binaries (if any)
try:
shutil.rmtree(copy_dest)
except OSError as e:
if e.errno != errno.ENOENT:
raise
# Make folder
try:
os.makedirs(copy_dest)
except OSError as e:
if e.errno != errno.EEXIST:
raise
# Copy binaries (pathkit.js and pathkit.wasm) to where the karma tests
# expect them ($SKIA_ROOT/modules/pathkit/npm-wasm/)
dest = os.path.join(copy_dest, 'pathkit.js')
shutil.copyfile(os.path.join(base_dir, 'pathkit.js'), dest)
os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.
if bundle_name:
dest = os.path.join(copy_dest, bundle_name)
shutil.copyfile(os.path.join(base_dir, bundle_name), dest)
os.chmod(dest, 0o644) # important, otherwise non-privileged docker can't read.
# Prepare output folder, api.file.ensure_directory doesn't touch
# the permissions of the out directory if it already exists.
os.chmod(out_dir, 0o777) # important, otherwise non-privileged docker can't write.
''',
args=[copy_dest, base_dir, bundle_name, out_dir],
infra_step=True)
cmd = ['docker', 'run', '--shm-size=2gb', '--rm',
'-v', '%s:/SRC' % checkout_root, '-v', '%s:/OUT' % out_dir]
if 'asmjs' in api.vars.builder_name:
cmd.extend(['-e', 'ASM_JS=1']) # -e sets environment variables
cmd.extend([
DOCKER_IMAGE, INNER_KARMA_SCRIPT,
'--builder', api.vars.builder_name,
'--git_hash', api.properties['revision'],
'--buildbucket_build_id', api.properties.get('buildbucket_build_id',
''),
'--bot_id', api.vars.swarming_bot_id,
'--task_id', api.vars.swarming_task_id,
'--browser', 'Chrome',
'--config', api.vars.configuration,
])
if 'asmjs' in api.vars.builder_name:
cmd.extend(['--compiled_language', 'asmjs']) # the default is wasm
if api.vars.is_trybot:
cmd.extend([
'--issue', api.vars.issue,
'--patchset', api.vars.patchset,
'--patch_storage', api.vars.patch_storage,
])
api.run(
api.step,
'Performance tests of PathKit with Docker',
cmd=cmd)
def GenTests(api):
yield (
api.test('Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit') +
api.properties(buildername=('Perf-Debian9-EMCC-GCE-CPU-AVX2'
'-wasm-Release-All-PathKit'),
repository='https://skia.googlesource.com/skia.git',
revision='abc123',
path_config='kitchen',
swarm_out_dir='[SWARM_OUT_DIR]')
)
yield (
api.test('Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit') +
api.properties(buildername=('Perf-Debian9-EMCC-GCE-CPU-AVX2'
'-asmjs-Release-All-PathKit'),
repository='https://skia.googlesource.com/skia.git',
revision='abc123',
path_config='kitchen',
swarm_out_dir='[SWARM_OUT_DIR]')
)
yield (
api.test('pathkit_trybot') +
api.properties(buildername=('Perf-Debian9-EMCC-GCE-CPU-AVX2'
'-wasm-Release-All-PathKit'),
repository='https://skia.googlesource.com/skia.git',
revision='abc123',
path_config='kitchen',
swarm_out_dir='[SWARM_OUT_DIR]',
patch_ref='89/456789/12',
patch_repo='https://skia.googlesource.com/skia.git',
patch_storage='gerrit',
patch_set=7,
patch_issue=1234,
gerrit_project='skia',
gerrit_url='https://skia-review.googlesource.com/')
)

View File

@ -1121,6 +1121,16 @@
"Upload-Perf-Debian9-Clang-ShuttleA-GPU-IntelHD2000-x86_64-Release-All"
]
},
"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit": {
"tasks": [
"Upload-Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit"
]
},
"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit": {
"tasks": [
"Upload-Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit"
]
},
"Perf-Debian9-GCC-GCE-CPU-AVX2-x86-Debug-All": {
"tasks": [
"Perf-Debian9-GCC-GCE-CPU-AVX2-x86-Debug-All"
@ -28642,6 +28652,200 @@
"perf"
]
},
"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit": {
"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"
}
],
"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",
"perf_pathkit",
"-properties",
"{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit\",\"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\":\"perf\"}",
"-logdog-annotation-url",
"logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
],
"dependencies": [
"Housekeeper-PerCommit-BundleRecipes",
"Build-Debian9-EMCC-asmjs-Release-PathKit"
],
"dimensions": [
"cpu:x86-64-Haswell_GCE",
"machine_type:n1-standard-16",
"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": "perf_skia_bundled.isolate",
"max_attempts": 1,
"outputs": [
"perf"
]
},
"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit": {
"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"
}
],
"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",
"perf_pathkit",
"-properties",
"{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit\",\"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\":\"perf\"}",
"-logdog-annotation-url",
"logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
],
"dependencies": [
"Housekeeper-PerCommit-BundleRecipes",
"Build-Debian9-EMCC-wasm-Release-PathKit"
],
"dimensions": [
"cpu:x86-64-Haswell_GCE",
"machine_type:n1-standard-16",
"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": "perf_skia_bundled.isolate",
"max_attempts": 1,
"outputs": [
"perf"
]
},
"Perf-Debian9-GCC-GCE-CPU-AVX2-x86-Debug-All": {
"caches": [
{
@ -74195,6 +74399,204 @@
"isolate": "swarm_recipe.isolate",
"service_account": "skia-external-nano-uploader@skia-swarming-bots.iam.gserviceaccount.com"
},
"Upload-Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit": {
"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": "infra/gsutil",
"path": "cipd_bin_packages",
"version": "version:4.28"
}
],
"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",
"upload_nano_results",
"-properties",
"{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit\",\"gs_bucket\":\"skia-perf\",\"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\":\"output_ignored\"}",
"-logdog-annotation-url",
"logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
],
"dependencies": [
"Housekeeper-PerCommit-BundleRecipes",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-asmjs-Release-All-PathKit"
],
"dimensions": [
"cpu:x86-64-Haswell_GCE",
"gpu:none",
"machine_type:n1-highmem-2",
"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",
"service_account": "skia-external-nano-uploader@skia-swarming-bots.iam.gserviceaccount.com"
},
"Upload-Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit": {
"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": "infra/gsutil",
"path": "cipd_bin_packages",
"version": "version:4.28"
}
],
"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",
"upload_nano_results",
"-properties",
"{\"$kitchen\":{\"devshell\":true,\"git_auth\":true},\"buildbucket_build_id\":\"<(BUILDBUCKET_BUILD_ID)\",\"buildername\":\"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit\",\"gs_bucket\":\"skia-perf\",\"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\":\"output_ignored\"}",
"-logdog-annotation-url",
"logdog://logs.chromium.org/skia/<(TASK_ID)/+/annotations"
],
"dependencies": [
"Housekeeper-PerCommit-BundleRecipes",
"Perf-Debian9-EMCC-GCE-CPU-AVX2-wasm-Release-All-PathKit"
],
"dimensions": [
"cpu:x86-64-Haswell_GCE",
"gpu:none",
"machine_type:n1-highmem-2",
"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",
"service_account": "skia-external-nano-uploader@skia-swarming-bots.iam.gserviceaccount.com"
},
"Upload-Perf-Mac-Clang-MacBook10.1-GPU-IntelHD615-x86_64-Release-All": {
"caches": [
{

View File

@ -1,8 +1,27 @@
gold-docker-image: aggregator
gold_docker_image: aggregator
# Set the build context to the current work dir, so we can copy
# the built binary to where we need it.
docker build -t gold-karma-chrome-tests -f ./docker/gold-karma-chrome-tests/Dockerfile .
perf_docker_image: aggregator
# Set the build context to the current work dir, so we can copy
# the built binary to where we need it.
docker build -t perf-karma-chrome-tests -f ./docker/perf-karma-chrome-tests/Dockerfile .
aggregator:
mkdir -p ./tmp
CGO_ENABLED=0 GOOS=linux go build -o ./tmp/gold-aggregator -a ./gold/
CGO_ENABLED=0 GOOS=linux go build -o ./tmp/gold-aggregator -a ./gold/
mkdir -p ./tmp
CGO_ENABLED=0 GOOS=linux go build -o ./tmp/perf-aggregator -a ./perf/
# Can check CHROME_VERSION with
# docker run karma-chrome-tests /usr/bin/google-chrome-stable --version
CHROME_VERSION=68.0.3440.106_v5
publish_gold_karma_chrome_tests: gold_docker_image
docker tag gold-karma-chrome-tests gcr.io/skia-public/gold-karma-chrome-tests:${CHROME_VERSION}
docker push gcr.io/skia-public/gold-karma-chrome-tests:${CHROME_VERSION}
publish_perf_karma_chrome_tests: perf_docker_image
docker tag perf-karma-chrome-tests gcr.io/skia-public/perf-karma-chrome-tests:${CHROME_VERSION}
docker push gcr.io/skia-public/perf-karma-chrome-tests:${CHROME_VERSION}

View File

@ -0,0 +1,16 @@
# TODO(kjlubick) add _v1 to this version to be like the others.
EMSDK_VERSION=1.38.6_jre
# Can check CHROME_VERSION with
# docker run karma-chrome-tests /usr/bin/google-chrome-stable --version
CHROME_VERSION=68.0.3440.106_v5
publish_emsdk_base:
docker build -t emsdk-base ./emsdk-base/
docker tag emsdk-base gcr.io/skia-public/emsdk-release:${EMSDK_VERSION}
docker push gcr.io/skia-public/emsdk-release:${EMSDK_VERSION}
publish_karma_chrome_tests:
docker build -t karma-chrome-tests ./karma-chrome-tests/
docker tag karma-chrome-tests gcr.io/skia-public/karma-chrome-tests:${CHROME_VERSION}
docker push gcr.io/skia-public/karma-chrome-tests:${CHROME_VERSION}

View File

@ -15,10 +15,7 @@ it Skia-exclusive.
It gets manually pushed anytime there's an update to the Dockerfile or relevant
installed libraries.
docker build -t emsdk-base ./emsdk-base/
EMSDK_VERSION="1.38.6_jre"
docker tag emsdk-base gcr.io/skia-public/emsdk-release:$EMSDK_VERSION
docker push gcr.io/skia-public/emsdk-release:$EMSDK_VERSION
make publish_emsdk_base
For testing the image locally, the following flow can be helpful:
@ -40,12 +37,7 @@ it Skia-exclusive.
It gets manually pushed anytime there's an update to the Dockerfile or relevant
installed libraries.
docker build -t karma-chrome-tests ./karma-chrome-tests/
# check the version of chrome with the following:
docker run karma-chrome-tests /usr/bin/google-chrome-stable --version
CHROME_VERSION="68.0.3440.106_v5" # use v1, v2, etc for any re-spins of the container.
docker tag karma-chrome-tests gcr.io/skia-public/karma-chrome-tests:$CHROME_VERSION
docker push gcr.io/skia-public/karma-chrome-tests:$CHROME_VERSION
make publish_karma_chrome_tests
Of note, some versions (generally before Chrome 60) run out of space on /dev/shm when
using the default Docker settings. To be safe, it is recommended to run the container
@ -72,12 +64,7 @@ It gets manually pushed anytime there's an update to the Dockerfile or the paren
image (karma-chrome-tests).
# Run the following from $SKIA_ROOT/infra/pathkit
make gold-docker-image
# check the version of chrome with the following:
docker run gold-karma-chrome-tests /usr/bin/google-chrome-stable --version
CHROME_VERSION="68.0.3440.106_v5" # use v1, v2, etc for any re-spins of the container.
docker tag gold-karma-chrome-tests gcr.io/skia-public/gold-karma-chrome-tests:$CHROME_VERSION
docker push gcr.io/skia-public/gold-karma-chrome-tests:$CHROME_VERSION
make publish_gold_karma_chrome_tests
Of note, some versions (generally before Chrome 60) run out of space on /dev/shm when
using the default Docker settings. To be safe, it is recommended to run the container
@ -92,3 +79,32 @@ For testing the image locally, the following can be helpful:
# Run the tests and collect Gold output with the local source repo
mkdir -p -m 0777 /tmp/dockergold
docker run --shm-size=2gb -v $SKIA_ROOT:/SRC -v /tmp/dockergold:/OUT gold-karma-chrome-tests /SRC/infra/pathkit/test_pathkit.sh
perf-karma-chrome-tests
------------------
This image has Google Chrome and karma/jasmine installed on it, which can
be used to run JS tests.
This image assumes the runner wants to collect the output images and JSON data
specific to Skia Infra's Perf tool.
It gets manually pushed anytime there's an update to the Dockerfile or the parent
image (karma-chrome-tests).
# Run the following from $SKIA_ROOT/infra/pathkit
make publish_perf_karma_chrome_tests
Of note, some versions (generally before Chrome 60) run out of space on /dev/shm when
using the default Docker settings. To be safe, it is recommended to run the container
with the flag --shm-size=2gb.
For testing the image locally, the following can be helpful:
# Run the following from $SKIA_ROOT/infra/pathkit
make perf-docker-image
# Run bash in it to poke around and make sure things are properly installed
docker run -it --shm-size=2gb perf-karma-chrome-tests /bin/bash
# Run the tests and collect Perf output with the local source repo
mkdir -p -m 0777 /tmp/dockerperf
docker run --shm-size=2gb -v $SKIA_ROOT:/SRC -v /tmp/dockerperf:/OUT perf-karma-chrome-tests /SRC/infra/pathkit/perf_pathkit.sh

View File

@ -0,0 +1,9 @@
# Docker container with Chrome, and karma/jasmine, to be used to run JS tests and
# collect output for Skia Infra's Perf tool.
#
# Tests will be run as non-root (user skia, in fact), so /OUT should have permissions
# 777 so as to be able to create output there.
FROM gcr.io/skia-public/karma-chrome-tests:68.0.3440.106_v5
COPY /tmp/perf-aggregator /opt/perf-aggregator

View File

@ -0,0 +1,200 @@
// 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.
package main
// This server runs along side the karma tests and listens for POST requests
// when any test case reports it has output for Perf. See perfReporter.js
// for the browser side part.
// Unlike the gold ingester, the perf ingester allows multiple reports
// of the same benchmark and will output the average of these results
// on a call to dump
import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"path"
"strconv"
"github.com/google/uuid"
"go.skia.org/infra/perf/go/ingestcommon"
)
// upload_nano_results looks for anything*.json
// We add the random UUID to avoid name clashes when uploading to
// the perf bucket (which uploads to folders based on Month/Day/Hour, which can
// easily have duplication if multiple perf tasks run in an hour.)
var JSON_FILENAME = fmt.Sprintf("%s_browser_bench.json", uuid.New().String())
var (
outDir = flag.String("out_dir", "/OUT/", "location to dump the Perf JSON")
port = flag.String("port", "8081", "Port to listen on.")
botId = flag.String("bot_id", "", "swarming bot id")
browser = flag.String("browser", "Chrome", "Browser Key")
buildBucketID = flag.Int64("buildbucket_build_id", 0, "Buildbucket build id key")
builder = flag.String("builder", "", "Builder, like 'Test-Debian9-EMCC-GCE-CPU-AVX2-wasm-Debug-All-PathKit'")
compiledLanguage = flag.String("compiled_language", "wasm", "wasm or asm.js")
config = flag.String("config", "Release", "Configuration (e.g. Debug/Release) key")
gitHash = flag.String("git_hash", "-", "The git commit hash of the version being tested")
hostOS = flag.String("host_os", "Debian9", "OS Key")
issue = flag.Int64("issue", 0, "issue (if tryjob)")
patch_storage = flag.String("patch_storage", "", "patch storage (if tryjob)")
patchset = flag.Int64("patchset", 0, "patchset (if tryjob)")
taskId = flag.String("task_id", "", "swarming task id")
)
// Received from the JS side.
type reportBody struct {
// a name describing the benchmark. Should be unique enough to allow use of grep.
BenchName string `json:"bench_name"`
// The number of microseconds of the task.
TimeMicroSeconds float64 `json:"time_us"`
}
// The keys to be used at the top level for all Results.
var defaultKeys map[string]string
// contains all the results reported in through report_perf_data
var results map[string][]reportBody
type BenchData struct {
Hash string `json:"gitHash"`
Issue string `json:"issue"`
PatchSet string `json:"patchset"`
Key map[string]string `json:"key"`
Options map[string]string `json:"options,omitempty"`
Results map[string]ingestcommon.BenchResults `json:"results"`
PatchStorage string `json:"patch_storage,omitempty"`
SwarmingTaskID string `json:"swarming_task_id,omitempty"`
SwarmingBotID string `json:"swarming_bot_id,omitempty"`
}
func main() {
flag.Parse()
defaultKeys = map[string]string{
"arch": "WASM",
"browser": *browser,
"compiled_language": *compiledLanguage,
"compiler": "emsdk",
"configuration": *config,
"cpu_or_gpu": "CPU",
"cpu_or_gpu_value": "Browser",
"os": *hostOS,
"source_type": "pathkit",
}
results = make(map[string][]reportBody)
http.HandleFunc("/report_perf_data", reporter)
http.HandleFunc("/dump_json", dumpJSON)
fmt.Printf("Waiting for perf ingestion on port %s\n", *port)
log.Fatal(http.ListenAndServe(":"+*port, nil))
}
// reporter handles when the client reports a test has a benchmark.
func reporter(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Only POST accepted", 400)
return
}
defer r.Body.Close()
body, err := ioutil.ReadAll(r.Body)
if err != nil {
http.Error(w, "Malformed body", 400)
return
}
benchOutput := reportBody{}
if err := json.Unmarshal(body, &benchOutput); err != nil {
fmt.Println(err)
http.Error(w, "Could not unmarshal JSON", 400)
return
}
if _, err := w.Write([]byte("Accepted")); err != nil {
fmt.Printf("Could not write response: %s\n", err)
return
}
results[benchOutput.BenchName] = append(results[benchOutput.BenchName], benchOutput)
}
// createOutputFile creates a file and set permissions correctly.
func createOutputFile(p string) (*os.File, error) {
outputFile, err := os.Create(p)
if err != nil {
return nil, fmt.Errorf("Could not open file %s on disk: %s", p, err)
}
// Make this accessible (and deletable) by all users
if err = outputFile.Chmod(0666); err != nil {
return nil, fmt.Errorf("Could not change permissions of file %s: %s", p, err)
}
return outputFile, nil
}
// dumpJSON writes out a JSON file with all the results, typically at the end of
// all the tests. If there is more than one result per benchmark, we report the average.
func dumpJSON(w http.ResponseWriter, r *http.Request) {
if r.Method != "POST" {
http.Error(w, "Only POST accepted", 400)
return
}
p := path.Join(*outDir, JSON_FILENAME)
outputFile, err := createOutputFile(p)
defer outputFile.Close()
if err != nil {
fmt.Println(err)
http.Error(w, "Could not open json file on disk", 500)
return
}
benchData := BenchData{
Hash: *gitHash,
Issue: strconv.FormatInt(*issue, 10),
PatchStorage: *patch_storage,
PatchSet: strconv.FormatInt(*patchset, 10),
Key: defaultKeys,
SwarmingBotID: *botId,
SwarmingTaskID: *taskId,
}
allResults := make(map[string]ingestcommon.BenchResults)
for name, benches := range results {
samples := []float64{}
total := float64(0)
for _, t := range benches {
samples = append(samples, t.TimeMicroSeconds)
total += t.TimeMicroSeconds
}
allResults[name] = map[string]ingestcommon.BenchResult{
"default": map[string]interface{}{
"average_us": total / float64(len(benches)),
"samples": samples,
},
}
}
benchData.Results = allResults
enc := json.NewEncoder(outputFile)
enc.SetIndent("", " ") // Make it human readable.
if err := enc.Encode(&benchData); err != nil {
fmt.Println(err)
http.Error(w, "Could not write json to disk", 500)
return
}
fmt.Println("JSON Written")
}

33
infra/pathkit/perf_pathkit.sh Executable file
View File

@ -0,0 +1,33 @@
#!/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.
# This assumes it is being run inside a docker container of perf-karma-chrome-tests
# and a Skia checkout has been mounted at /SRC and the output directory
# is mounted at /OUT
# For example:
# docker run -v $SKIA_ROOT:/SRC -v /tmp/dockerout:/OUT gcr.io/skia-public/perf-karma-chrome-tests:68.0.3440.106_v1 /SRC/infra/pathkit/perf_pathkit.sh
set -ex
#BASE_DIR is the dir this script is in ($SKIA_ROOT/infra/pathkit)
BASE_DIR=`cd $(dirname ${BASH_SOURCE[0]}) && pwd`
PATHKIT_DIR=$BASE_DIR/../../modules/pathkit
# Start the aggregator in the background
/opt/perf-aggregator $@ &
# Run the tests 10 times to get a wide set of data
for i in `seq 1 10`;
do
npx karma start $PATHKIT_DIR/karma.bench.conf.js --single-run
done
# Tell the aggregator to dump the json
# This curl command gets the HTTP code and stores it into $CODE
CODE=`curl -s -o /dev/null -I -w "%{http_code}" -X POST localhost:8081/dump_json`
if [ $CODE -ne 200 ]; then
# If we don't get 200 back, something is wrong with writing to disk, so exit with error
exit 1
fi

View File

@ -23,6 +23,7 @@
var PathKit = {
SkBits2FloatUnsigned: function(num) {},
_malloc: function(size) {},
_free: function(ptr) {},
onRuntimeInitialized: function() {},
_FromCmds: function(ptr, size) {},
loadCmdsTypedArray: function(arr) {},
@ -31,6 +32,9 @@ var PathKit = {
cubicYFromX: function(cpx1, cpy1, cpx2, cpy2, X) {},
cubicPtFromT: function(cpx1, cpy1, cpx2, cpy2, T) {},
/**
* @type {Float32Array}
*/
HEAPF32: {},
SkPath: {

View File

@ -63,7 +63,10 @@
// See above for example of cmds.
PathKit.FromCmds = function(cmds) {
var ptrLen = PathKit.loadCmdsTypedArray(cmds);
return PathKit._FromCmds(ptrLen[0], ptrLen[1]);
var path = PathKit._FromCmds(ptrLen[0], ptrLen[1]);
// TODO(kjlubick): cache this memory blob somehow.
PathKit._free(ptrLen[0]);
return path;
}
/**

View File

@ -0,0 +1,88 @@
const isDocker = require('is-docker')();
module.exports = function(config) {
// Set the default values to be what are needed when testing the
// WebAssembly build locally.
let cfg = {
// frameworks to use
// available frameworks: https://npmjs.org/browse/keyword/karma-adapter
frameworks: ['jasmine'],
// list of files / patterns to load in the browser
files: [
{ pattern: 'npm-wasm/bin/pathkit.wasm', included:false, served:true},
'perf/perfReporter.js',
'npm-wasm/bin/pathkit.js',
'perf/*.bench.js'
],
proxies: {
'/pathkit/': '/base/npm-wasm/bin/'
},
// test results reporter to use
// possible values: 'dots', 'progress'
// available reporters: https://npmjs.org/browse/keyword/karma-reporter
reporters: ['dots'],
// web server port
port: 4444,
// enable / disable colors in the output (reporters and logs)
colors: true,
// level of logging
// possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
logLevel: config.LOG_INFO,
// enable / disable watching file and executing tests whenever any file changes
autoWatch: true,
browserDisconnectTimeout: 10000,
browserNoActivityTimeout: 10000,
// start these browsers
browsers: ['Chrome'],
// Continuous Integration mode
// if true, Karma captures browsers, runs the tests and exits
singleRun: false,
// Concurrency level
// how many browser should be started simultaneous
concurrency: Infinity,
};
if (isDocker) {
// See https://hackernoon.com/running-karma-tests-with-headless-chrome-inside-docker-ae4aceb06ed3
cfg.browsers = ['ChromeHeadlessNoSandbox'],
cfg.customLaunchers = {
ChromeHeadlessNoSandbox: {
base: 'ChromeHeadless',
flags: [
// Without this flag, we see an error:
// Failed to move to new namespace: PID namespaces supported, Network namespace supported, but failed: errno = Operation not permitted
'--no-sandbox'
],
},
};
}
if (process.env.ASM_JS) {
console.log('asm.js is under test');
cfg.files = [
{ pattern: 'npm-asmjs/bin/pathkit.js.mem', included:false, served:true},
'perf/perfReporter.js',
'npm-asmjs/bin/pathkit.js',
'perf/*.bench.js'
];
cfg.proxies = {
'/pathkit/': '/base/npm-asmjs/bin/'
};
} else {
console.log('wasm is under test');
}
config.set(cfg);
}

View File

@ -18,7 +18,7 @@ module.exports = function(config) {
],
proxies: {
"/pathkit/": "/base/npm-wasm/bin/test/"
'/pathkit/': '/base/npm-wasm/bin/test/'
},
// test results reporter to use
@ -80,7 +80,7 @@ module.exports = function(config) {
];
cfg.proxies = {
"/pathkit/": "/base/npm-asmjs/bin/test/"
'/pathkit/': '/base/npm-asmjs/bin/test/'
};
} else {
console.log('wasm is under test');

View File

@ -1,6 +1,6 @@
{
"name": "pathkit-asmjs",
"version": "0.4.1",
"version": "0.4.2",
"description": "A asm.js version of Skia's PathOps toolkit",
"main": "bin/pathkit.js",
"homepage": "https://github.com/google/skia/tree/master/modules/pathkit",

View File

@ -1,6 +1,6 @@
{
"name": "pathkit-wasm",
"version": "0.4.1",
"version": "0.4.2",
"description": "A WASM version of Skia's PathOps toolkit",
"main": "bin/pathkit.js",
"homepage": "https://github.com/google/skia/tree/master/modules/pathkit",

View File

@ -0,0 +1,143 @@
describe('PathKit\'s Effects', function() {
// Note, don't try to print the PathKit object - it can cause Karma/Jasmine to lock up.
var PathKit = null;
const LoadPathKit = new Promise(function(resolve, reject) {
if (PathKit) {
resolve();
} else {
PathKitInit({
locateFile: (file) => '/pathkit/'+file,
}).then((_PathKit) => {
PathKit = _PathKit;
resolve();
});
}
});
// see https://fiddle.skia.org/c/@discrete_path
function drawStar(X=128, Y=128, R=116) {
let p = PathKit.NewPath();
p.moveTo(X + R, Y);
for (let i = 1; i < 8; i++) {
let a = 2.6927937 * i;
p.lineTo(X + R * Math.cos(a), Y + R * Math.sin(a));
}
p.closePath();
return p;
}
it('effects_dash', function(done) {
function setup(ctx) {
ctx.path = drawStar();
}
function test(ctx) {
let path = ctx.path.copy().dash(10, 3, 1);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('effects_dash', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('effects_trim', function(done) {
function setup(ctx) {
ctx.path = drawStar();
}
function test(ctx) {
let path = ctx.path.copy().trim(0.25, .8);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('effects_trim', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('effects_trim_complement', function(done) {
function setup(ctx) {
ctx.path = drawStar();
}
function test(ctx) {
let path = ctx.path.copy().trim(0.25, .8, true);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('effects_trim_complement', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('effects_transform', function(done) {
function setup(ctx) {
ctx.path = drawStar();
}
function test(ctx) {
let path = ctx.path.copy().transform(3, 0, 0,
0, 3, 0,
0, 0, 1);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('effects_transform', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('effects_stroke', function(done) {
function setup(ctx) {
ctx.path = drawStar();
}
function test(ctx) {
let path = ctx.path.copy().stroke({
width: 15,
join: PathKit.StrokeJoin.BEVEL,
cap: PathKit.StrokeCap.BUTT,
miter_limit: 2,
});
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('effects_stroke', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
});

View File

@ -0,0 +1,313 @@
describe('PathKit\'s Path Behavior', function() {
// Note, don't try to print the PathKit object - it can cause Karma/Jasmine to lock up.
var PathKit = null;
const LoadPathKit = new Promise(function(resolve, reject) {
if (PathKit) {
resolve();
} else {
PathKitInit({
locateFile: (file) => '/pathkit/'+file,
}).then((_PathKit) => {
PathKit = _PathKit;
resolve();
});
}
});
function drawPath() {
let path = PathKit.NewPath();
path.moveTo(20, 5);
path.lineTo(30, 20);
path.lineTo(40, 10);
path.lineTo(50, 20);
path.lineTo(60, 0);
path.lineTo(20, 5);
path.moveTo(20, 80);
path.bezierCurveTo(90, 10, 160, 150, 190, 10);
path.moveTo(36, 148);
path.quadraticCurveTo(66, 188, 120, 136);
path.lineTo(36, 148);
path.rect(5, 170, 20, 20);
path.moveTo(150, 180);
path.arcTo(150, 100, 50, 200, 20);
path.lineTo(160, 160);
path.moveTo(20, 120);
path.arc(20, 120, 18, 0, 1.75 * Math.PI);
path.lineTo(20, 120);
let secondPath = PathKit.NewPath();
secondPath.ellipse(130, 25, 30, 10, -1*Math.PI/8, Math.PI/6, 1.5*Math.PI, false);
path.addPath(secondPath);
let m = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();
m.a = 1; m.b = 0;
m.c = 0; m.d = 1;
m.e = 0; m.f = 20.5;
path.addPath(secondPath, m);
secondPath.delete();
return path;
}
it('path_path2dapi', function(done) {
function setup(ctx) { }
function test(ctx) {
path = drawPath();
path.delete();
}
function teardown(ctx) { }
LoadPathKit.then(() => {
benchmarkAndReport('path_path2dapi', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
describe('import options', function() {
it('path_copy', function(done) {
function setup(ctx) {
ctx.path = PathKit.FromSVGString('M 205,5 L 795,5 L 595,295 L 5,295 L 205,5 z');
}
function test(ctx) {
let p = ctx.path.copy();
p.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_copy', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_from_api_calls', function(done) {
function setup(ctx) { }
function test(ctx) {
let p = PathKit.NewPath()
.moveTo(205, 5)
.lineTo(795, 5)
.lineTo(595, 295)
.lineTo(5, 295)
.lineTo(205, 5)
.close();
p.delete();
}
function teardown(ctx) { }
LoadPathKit.then(() => {
benchmarkAndReport('path_from_api_calls', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_fromCmds', function(done) {
function setup(ctx) { }
function test(ctx) {
let p = PathKit.FromCmds(
[[PathKit.MOVE_VERB, 205, 5],
[PathKit.LINE_VERB, 795, 5],
[PathKit.LINE_VERB, 595, 295],
[PathKit.LINE_VERB, 5, 295],
[PathKit.LINE_VERB, 205, 5],
[PathKit.CLOSE_VERB]]);
p.delete();
}
function teardown(ctx) { }
LoadPathKit.then(() => {
benchmarkAndReport('path_fromCmds', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_fromSVGString', function(done) {
function setup(ctx) {}
function test(ctx) {
// https://upload.wikimedia.org/wikipedia/commons/e/e7/Simple_parallelogram.svg
let p = PathKit.FromSVGString('M 205,5 L 795,5 L 595,295 L 5,295 L 205,5 z');
p.delete();
}
function teardown(ctx) { }
LoadPathKit.then(() => {
benchmarkAndReport('path_fromSVGString', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
});
describe('export options', function() {
it('path_toCmds', function(done) {
function setup(ctx) {
ctx.path = drawPath();
}
function test(ctx) {
ctx.path.toCmds();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_toCmds', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_toPath2D', function(done) {
function setup(ctx) {
ctx.path = drawPath();
}
function test(ctx) {
ctx.path.toPath2D();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_toPath2D', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_toSVGString', function(done) {
function setup(ctx) {
ctx.path = drawPath();
}
function test(ctx) {
ctx.path.toSVGString();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_toSVGString', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
});
describe('matrix options', function() {
function drawTriangle() {
let path = PathKit.NewPath();
path.moveTo(0, 0);
path.lineTo(10, 0);
path.lineTo(10, 10);
path.close();
return path;
}
it('path_add_path_svgmatrix', function(done) {
function setup(ctx) {
ctx.path = drawTriangle();
}
function test(ctx) {
let path = PathKit.NewPath();
let m = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();
m.a = 1; m.b = 0;
m.c = 0; m.d = 1;
m.e = 0; m.f = 20.5;
path.addPath(ctx.path, m);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_add_path_svgmatrix', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_add_path_svgmatrix_reuse', function(done) {
function setup(ctx) {
ctx.path = drawTriangle();
let m = document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGMatrix();
ctx.matrix = m;
}
function test(ctx) {
let path = PathKit.NewPath();
let m = ctx.matrix
m.a = 1; m.b = 0;
m.c = 0; m.d = 1;
m.e = 0; m.f = 20.5;
path.addPath(ctx.path, m);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_add_path_svgmatrix_reuse', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('path_add_path_svgmatrix_bare', function(done) {
function setup(ctx) {
ctx.path = drawTriangle();
}
function test(ctx) {
let path = PathKit.NewPath();
path.addPath(ctx.path, 1, 0, 0, 1, 0, 20.5);
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('path_add_path_svgmatrix_bare', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
});
});

View File

@ -0,0 +1,172 @@
describe('PathKit\'s Pathops', function() {
// Note, don't try to print the PathKit object - it can cause Karma/Jasmine to lock up.
var PathKit = null;
const LoadPathKit = new Promise(function(resolve, reject) {
if (PathKit) {
resolve();
} else {
PathKitInit({
locateFile: (file) => '/pathkit/'+file,
}).then((_PathKit) => {
PathKit = _PathKit;
resolve();
});
}
});
// see https://fiddle.skia.org/c/@discrete_path
function drawStar(X=128, Y=128, R=116) {
let p = PathKit.NewPath();
p.moveTo(X + R, Y);
for (let i = 1; i < 8; i++) {
let a = 2.6927937 * i;
p.lineTo(X + R * Math.cos(a), Y + R * Math.sin(a));
}
p.closePath();
return p;
}
it('pathops_simplify', function(done) {
function setup(ctx) {
ctx.path = drawStar();
}
function test(ctx) {
let path = ctx.path.copy().simplify();
path.delete();
}
function teardown(ctx) {
ctx.path.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('pathops_simplify', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('pathops_diff', function(done) {
function setup(ctx) {
// Values chosen abitrarily to have some overlap and some not.
ctx.path1 = drawStar(X=120, Y=120);
ctx.path2 = drawStar(X=140, Y=145);
}
function test(ctx) {
let path = PathKit.MakeFromOp(ctx.path1, ctx.path2, PathKit.PathOp.DIFFERENCE);
path.delete();
}
function teardown(ctx) {
ctx.path1.delete();
ctx.path2.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('pathops_diff', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('pathops_intersect', function(done) {
function setup(ctx) {
// Values chosen abitrarily to have some overlap and some not.
ctx.path1 = drawStar(X=120, Y=120);
ctx.path2 = drawStar(X=140, Y=145);
}
function test(ctx) {
let path = PathKit.MakeFromOp(ctx.path1, ctx.path2, PathKit.PathOp.INTERSECT);
path.delete();
}
function teardown(ctx) {
ctx.path1.delete();
ctx.path2.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('pathops_intersect', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('pathops_union', function(done) {
function setup(ctx) {
// Values chosen abitrarily to have some overlap and some not.
ctx.path1 = drawStar(X=120, Y=120);
ctx.path2 = drawStar(X=140, Y=145);
}
function test(ctx) {
let path = PathKit.MakeFromOp(ctx.path1, ctx.path2, PathKit.PathOp.UNION);
path.delete();
}
function teardown(ctx) {
ctx.path1.delete();
ctx.path2.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('pathops_union', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('pathops_xor', function(done) {
function setup(ctx) {
// Values chosen abitrarily to have some overlap and some not.
ctx.path1 = drawStar(X=120, Y=120);
ctx.path2 = drawStar(X=140, Y=145);
}
function test(ctx) {
let path = PathKit.MakeFromOp(ctx.path1, ctx.path2, PathKit.PathOp.XOR);
path.delete();
}
function teardown(ctx) {
ctx.path1.delete();
ctx.path2.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('pathops_xor', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
it('pathops_reverse_diff', function(done) {
function setup(ctx) {
// Values chosen abitrarily to have some overlap and some not.
ctx.path1 = drawStar(X=120, Y=120);
ctx.path2 = drawStar(X=140, Y=145);
}
function test(ctx) {
let path = PathKit.MakeFromOp(ctx.path1, ctx.path2, PathKit.PathOp.REVERSE_DIFFERENCE);
path.delete();
}
function teardown(ctx) {
ctx.path1.delete();
ctx.path2.delete();
}
LoadPathKit.then(() => {
benchmarkAndReport('pathops_reverse_diff', setup, test, teardown).then(() => {
done();
}).catch(reportError(done));
});
});
});

View File

@ -0,0 +1,72 @@
const REPORT_URL = 'http://localhost:8081/report_perf_data'
// Set this to enforce that the perf server must be up.
// Typically used for debugging.
const fail_on_no_perf = false;
function benchmarkAndReport(benchName, setupFn, testFn, teardownFn) {
let ctx = {};
// warmup 3 times (arbitrary choice)
setupFn(ctx);
testFn(ctx);
testFn(ctx);
testFn(ctx);
teardownFn(ctx);
ctx = {};
setupFn(ctx);
let start = Date.now();
let now = start;
times = 0;
// See how many times we can do it in 100ms (arbitrary choice)
while (now - start < 100) {
testFn(ctx);
now = Date.now();
times++;
}
teardownFn(ctx);
// Try to make it go for 2 seconds (arbitrarily chosen)
// Since the pre-try took 100ms, multiply by 20 to get
// approximate tries in 2s
let goalTimes = times * 20;
setupFn(ctx);
start = Date.now();
times = 0;
while (times < goalTimes) {
testFn(ctx);
times++;
}
let end = Date.now();
teardownFn(ctx);
let us = (end - start) * 1000 / times;
console.log(benchName, `${us} microseconds`)
return _report(us, benchName);
}
function _report(microseconds, benchName) {
return fetch(REPORT_URL, {
method: 'POST',
mode: 'no-cors',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
'bench_name': benchName,
'time_us': microseconds,
})
}).then(() => console.log(`Successfully reported ${benchName} to perf aggregator`));
}
function reportError(done) {
return (e) => {
console.log("Error with fetching. Likely could not connect to aggegator server", e.message);
if (fail_on_no_perf) {
expect(e).toBeUndefined();
}
done();
};
}