Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 1 | # Copyright 2017 The Chromium Authors. All rights reserved. |
| 2 | # Use of this source code is governed by a BSD-style license that can be |
| 3 | # found in the LICENSE file. |
| 4 | |
| 5 | # Recipe which: |
| 6 | # 1) Extracts all fiddles out of markdown files. |
| 7 | # 2) Forces fiddle.skia.org to compile all those fiddles and get output in JSON. |
| 8 | # 3) Scans the output and reports any compiletime/runtime errors. |
| 9 | # 4) Updates markdown in site/user/api/ using the new hashes (if any) from |
| 10 | # fiddle.skia.org. |
| 11 | |
| 12 | import json |
| 13 | |
| 14 | |
| 15 | DEPS = [ |
| 16 | 'recipe_engine/context', |
| 17 | 'recipe_engine/file', |
| 18 | 'recipe_engine/path', |
| 19 | 'recipe_engine/properties', |
| 20 | 'recipe_engine/step', |
| 21 | 'core', |
| 22 | 'infra', |
| 23 | 'run', |
| 24 | 'vars', |
| 25 | ] |
| 26 | |
| 27 | UPDATE_DOCS_GITCOOKIES_FILE = 'update_docs.git_cookies' |
| 28 | UPDATE_DOCS_GITCOOKIES_GS_PATH = ( |
| 29 | 'gs://skia-buildbots/artifacts/server/.gitcookies_update-docs') |
| 30 | |
| 31 | |
| 32 | def go_get_fiddlecli(api): |
| 33 | env = api.context.env |
| 34 | env.update(api.infra.go_env) |
| 35 | with api.context(env=env): |
| 36 | api.run.with_retry( |
| 37 | api.step, |
| 38 | 'go get fiddlecli', |
| 39 | 5, # Update attempts. |
| 40 | cmd=[api.infra.go_exe, 'get', '-u', '-t', |
| 41 | 'go.skia.org/infra/fiddle/go/fiddlecli']) |
| 42 | |
| 43 | |
| 44 | def RunSteps(api): |
| 45 | api.vars.setup() |
Eric Boren | 86a1146 | 2018-02-22 10:03:56 -0500 | [diff] [blame^] | 46 | api.core.checkout_bot_update() |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 47 | api.infra.go_version() |
| 48 | go_get_fiddlecli(api) |
| 49 | |
| 50 | with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env): |
| 51 | bookmaker_binary = api.path.join(api.vars.skia_out, api.vars.configuration, |
| 52 | 'bookmaker') |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 53 | buildername = api.vars.builder_name |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 54 | |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 55 | if 'PerCommit' in buildername: |
| 56 | # Check to see if docs matches include/core. |
| 57 | cmd = [bookmaker_binary, |
| 58 | '-a', 'docs/status.json', # File containing status of docs. |
| 59 | '-x', # Check bmh against includes. |
| 60 | ] |
| 61 | try: |
| 62 | api.run(api.step, 'Validate docs match include/core/*.h', cmd=cmd) |
| 63 | except api.step.StepFailure as e: |
| 64 | # Display what needs to be fixed. |
| 65 | e.reason += ( |
| 66 | '\n\nView the output of the "Validate docs match include/core/*.h" ' |
| 67 | 'step to see how to get this bot green.' |
| 68 | '\n\nhttps://skia.org/user/api/usingBookmaker details how to build ' |
| 69 | 'and run the bookmaker utility locally if needed.') |
| 70 | raise e |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 71 | |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 72 | elif 'Nightly' in buildername: |
| 73 | fiddlecli_binary = api.path.join(api.infra.gopath, 'bin', 'fiddlecli') |
| 74 | fiddlecli_input = api.path.join(api.path['start_dir'], 'fiddle.json') |
| 75 | fiddlecli_output = api.path.join(api.path['start_dir'], 'fiddleout.json') |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 76 | |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 77 | # Step 1: Extract all fiddles out of markdown files. |
| 78 | cmd = [bookmaker_binary, |
| 79 | '-a', 'docs/status.json', # File containing status of docs. |
| 80 | '-e', fiddlecli_input, # Fiddle cli input. |
| 81 | ] |
| 82 | api.run(api.step, 'Extract all fiddles out of md files', cmd=cmd) |
Ravi Mistry | 5ca9413 | 2017-12-11 16:40:48 -0500 | [diff] [blame] | 83 | |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 84 | # Step 2: Forces fiddle.skia.org to compile all fiddles extracted out of |
| 85 | # markdown files and get output in JSON. |
| 86 | cmd = [fiddlecli_binary, |
| 87 | '--input', fiddlecli_input, |
| 88 | '--output', fiddlecli_output, |
| 89 | '--logtostderr', |
| 90 | '--force', |
| 91 | ] |
| 92 | api.run(api.step, 'Force fiddle to compile all examples', cmd=cmd) |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 93 | |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 94 | # Step 3: Scan the output of fiddlecli for any compiletime/runtime errors. |
| 95 | # Fail the recipe is there are any errors and summarize results at |
| 96 | # the end. |
| 97 | if api.path.exists(fiddlecli_output): |
| 98 | test_data = api.properties.get('fiddleout_test_data', '{}') |
| 99 | content = api.file.read_text('Read fiddleout.json', |
| 100 | fiddlecli_output, test_data=test_data) |
| 101 | out = json.loads(content) |
| 102 | # Do a dump of fiddlecli_output. Will be useful for debugging. |
| 103 | print 'Dump of %s:' % fiddlecli_output |
| 104 | print json.dumps(out, indent=4) |
| 105 | |
Ravi Mistry | 042b5e9 | 2018-02-08 14:54:52 -0500 | [diff] [blame] | 106 | failing_fiddles_to_errors = {} |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 107 | for fiddle_name in out: |
| 108 | props = out[fiddle_name] |
| 109 | if props['compile_errors'] or props['runtime_error']: |
Ravi Mistry | 042b5e9 | 2018-02-08 14:54:52 -0500 | [diff] [blame] | 110 | # Construct the error. |
| 111 | error = props['runtime_error'] |
| 112 | if props['compile_errors']: |
| 113 | for e in props['compile_errors']: |
| 114 | error += '%s\n' % e['text'] |
| 115 | failing_fiddles_to_errors[props['fiddleHash']] = error |
| 116 | |
| 117 | if failing_fiddles_to_errors: |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 118 | # create an eror message and fail the bot! |
Ravi Mistry | 042b5e9 | 2018-02-08 14:54:52 -0500 | [diff] [blame] | 119 | failure_msg = 'Failed fiddles with their errors:\n\n\n' |
| 120 | counter = 0 |
| 121 | for fiddle_hash, error in failing_fiddles_to_errors.iteritems(): |
| 122 | counter += 1 |
| 123 | failure_msg += '%d. https://fiddle.skia.org/c/%s\n\n' % ( |
| 124 | counter, fiddle_hash) |
| 125 | failure_msg += '%s\n\n' % error |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 126 | raise api.step.StepFailure(failure_msg) |
| 127 | |
| 128 | # Step 4: Update docs in site/user/api/ with the output of fiddlecli. |
| 129 | # If there are any new changes then upload and commit the changes. |
| 130 | update_docs_gitcookies = api.path['start_dir'].join( |
| 131 | UPDATE_DOCS_GITCOOKIES_FILE) |
| 132 | cmd = ['python', |
| 133 | api.vars.skia_dir.join('infra', 'bots', 'upload_md.py'), |
| 134 | '--bookmaker_binary', bookmaker_binary, |
| 135 | '--fiddlecli_output', fiddlecli_output, |
| 136 | '--gitcookies', str(update_docs_gitcookies)] |
| 137 | with api.infra.DownloadGitCookies( |
| 138 | UPDATE_DOCS_GITCOOKIES_GS_PATH, update_docs_gitcookies, api): |
| 139 | with api.context(cwd=api.vars.skia_dir, env=api.infra.go_env): |
| 140 | api.run(api.step, 'Generate and Upload Markdown files', cmd=cmd) |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 141 | |
| 142 | |
| 143 | def GenTests(api): |
| 144 | fiddleout_no_errors_test_data = """ |
| 145 | {"fiddle1": {"fiddleHash": "abc", |
| 146 | "compile_errors": [], |
| 147 | "runtime_error": ""}} |
| 148 | """ |
| 149 | fiddleout_with_errors_test_data = """ |
| 150 | {"fiddle1": {"fiddleHash": "abc", |
Ravi Mistry | 042b5e9 | 2018-02-08 14:54:52 -0500 | [diff] [blame] | 151 | "compile_errors": [ |
| 152 | { |
| 153 | "text": "ninja: Entering directory `out/Release'", |
| 154 | "line": 0, |
| 155 | "col": 0 |
| 156 | }, |
| 157 | { |
| 158 | "text": "[1/7] ACTION //:skia.h(//gn/toolchain:gcc_like)", |
| 159 | "line": 0, |
| 160 | "col": 0 |
| 161 | }, |
| 162 | { |
| 163 | "text": "[2/7] stamp obj/skia.h.stamp", |
| 164 | "line": 0, |
| 165 | "col": 0 |
| 166 | }, |
| 167 | { |
| 168 | "text": "[3/7] compile ../../tools/fiddle/draw.cpp", |
| 169 | "line": 0, |
| 170 | "col": 0 |
| 171 | }, |
| 172 | { |
| 173 | "text": "FAILED: obj/tools/fiddle/fiddle.draw.o ", |
| 174 | "line": 0, |
| 175 | "col": 0 |
| 176 | }, |
| 177 | { |
| 178 | "text": "c++ -MMD -MF obj/tools/fiddle/fiddle.draw.o.d -DNDEBUG -DSK_HAS_HEIF_LIBRARY -DSK_HAS_JPEG_LIBRARY -DSK_SUPPORT_PDF -DSK_PDF_USE_SFNTLY -DSK_HAS_PNG_LIBRARY -DSK_CODEC_DECODES_RAW -DSK_HAS_WEBP_LIBRARY -DSK_XML -DSK_GAMMA_APPLY_TO_A8 -DSK_ENABLE_DISCRETE_GPU -DGR_TEST_UTILS=1 -DSK_SAMPLES_FOR_X -DSK_SUPPORT_ATLAS_TEXT=1 -I../../tools/flags -I../../include/private -I../../src/c -I../../src/codec -I../../src/core -I../../src/effects -I../../src/fonts -I../../src/image -I../../src/images -I../../src/lazy -I../../src/opts -I../../src/pathops -I../../src/pdf -I../../src/ports -I../../src/sfnt -I../../src/shaders -I../../src/shaders/gradients -I../../src/sksl -I../../src/utils -I../../src/utils/win -I../../src/xml -I../../third_party/gif -I../../src/gpu -I../../tools/gpu -I../../include/android -I../../include/c -I../../include/codec -I../../include/config -I../../include/core -I../../include/effects -I../../include/encode -I../../include/gpu -I../../include/gpu/gl -I../../include/atlastext -I../../include/pathops -I../../include/ports -I../../include/svg -I../../include/utils -I../../include/utils/mac -I../../include/atlastext -Igen -fstrict-aliasing -fPIC -Werror -Wall -Wextra -Winit-self -Wpointer-arith -Wsign-compare -Wvla -Wno-deprecated-declarations -Wno-maybe-uninitialized -Wno-unused-parameter -O3 -fdata-sections -ffunction-sections -g -std=c++11 -fno-exceptions -fno-rtti -Wnon-virtual-dtor -Wno-error -c ../../tools/fiddle/draw.cpp -o obj/tools/fiddle/fiddle.draw.o", |
| 179 | "line": 0, |
| 180 | "col": 0 |
| 181 | }, |
| 182 | { |
| 183 | "text": "../../tools/fiddle/draw.cpp: In function 'void draw(SkCanvas*)':", |
| 184 | "line": 0, |
| 185 | "col": 0 |
| 186 | }, |
| 187 | { |
| 188 | "text": "draw.cpp:5:12: error: aggregate 'SkMask mask' has incomplete type and cannot be defined", |
| 189 | "line": 5, |
| 190 | "col": 12 |
| 191 | }, |
| 192 | { |
| 193 | "text": " }", |
| 194 | "line": 0, |
| 195 | "col": 0 |
| 196 | }, |
| 197 | { |
| 198 | "text": " ^ ", |
| 199 | "line": 0, |
| 200 | "col": 0 |
| 201 | }, |
| 202 | { |
| 203 | "text": "draw.cpp:6:28: error: incomplete type 'SkMask' used in nested name specifier", |
| 204 | "line": 6, |
| 205 | "col": 28 |
| 206 | }, |
| 207 | { |
| 208 | "text": " ", |
| 209 | "line": 0, |
| 210 | "col": 0 |
| 211 | }, |
| 212 | { |
| 213 | "text": " ^ ", |
| 214 | "line": 0, |
| 215 | "col": 0 |
| 216 | }, |
| 217 | { |
| 218 | "text": "draw.cpp:14:28: error: incomplete type 'SkMask' used in nested name specifier", |
| 219 | "line": 14, |
| 220 | "col": 28 |
| 221 | }, |
| 222 | { |
| 223 | "text": " uint8_t bytes[] = { 0, 1, 2, 3, 4, 5, 6, 7 };", |
| 224 | "line": 0, |
| 225 | "col": 0 |
| 226 | }, |
| 227 | { |
| 228 | "text": " ^~~~~~~~~~", |
| 229 | "line": 0, |
| 230 | "col": 0 |
| 231 | }, |
| 232 | { |
| 233 | "text": "[4/7] compile ../../tools/fiddle/egl_context.cpp", |
| 234 | "line": 0, |
| 235 | "col": 0 |
| 236 | }, |
| 237 | { |
| 238 | "text": "[5/7] compile ../../tools/fiddle/fiddle_main.cpp", |
| 239 | "line": 0, |
| 240 | "col": 0 |
| 241 | }, |
| 242 | { |
| 243 | "text": "[6/7] link libskia.a", |
| 244 | "line": 0, |
| 245 | "col": 0 |
| 246 | }, |
| 247 | { |
| 248 | "text": "ninja: build stopped: subcommand failed.", |
| 249 | "line": 0, |
| 250 | "col": 0 |
| 251 | }, |
| 252 | { |
| 253 | "text": "", |
| 254 | "line": 0, |
| 255 | "col": 0 |
| 256 | } |
| 257 | ], |
| 258 | "runtime_error": ""}} |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 259 | """ |
| 260 | yield ( |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 261 | api.test('percommit_bookmaker') + |
| 262 | api.properties(buildername='Housekeeper-PerCommit-Bookmaker', |
| 263 | repository='https://skia.googlesource.com/skia.git', |
| 264 | revision='abc123', |
| 265 | path_config='kitchen', |
| 266 | swarm_out_dir='[SWARM_OUT_DIR]') |
| 267 | ) |
| 268 | |
| 269 | yield ( |
| 270 | api.test('percommit_failed_validation') + |
| 271 | api.properties(buildername='Housekeeper-PerCommit-Bookmaker', |
| 272 | repository='https://skia.googlesource.com/skia.git', |
| 273 | revision='abc123', |
| 274 | path_config='kitchen', |
| 275 | swarm_out_dir='[SWARM_OUT_DIR]') + |
| 276 | api.step_data('Validate docs match include/core/*.h', retcode=1) |
| 277 | ) |
| 278 | |
| 279 | yield ( |
| 280 | api.test('nightly_bookmaker') + |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 281 | api.properties(buildername='Housekeeper-Nightly-Bookmaker', |
| 282 | repository='https://skia.googlesource.com/skia.git', |
| 283 | revision='abc123', |
| 284 | path_config='kitchen', |
| 285 | fiddleout_test_data=fiddleout_no_errors_test_data, |
| 286 | swarm_out_dir='[SWARM_OUT_DIR]') + |
| 287 | api.path.exists(api.path['start_dir'].join('fiddleout.json'), |
| 288 | api.path['start_dir'].join(UPDATE_DOCS_GITCOOKIES_FILE)) |
| 289 | ) |
| 290 | |
| 291 | yield ( |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 292 | api.test('nightly_failed_fiddles') + |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 293 | api.properties(buildername='Housekeeper-Nightly-Bookmaker', |
| 294 | repository='https://skia.googlesource.com/skia.git', |
| 295 | revision='abc123', |
| 296 | path_config='kitchen', |
| 297 | fiddleout_test_data=fiddleout_with_errors_test_data, |
| 298 | swarm_out_dir='[SWARM_OUT_DIR]') + |
| 299 | api.path.exists(api.path['start_dir'].join('fiddleout.json')) |
| 300 | ) |
| 301 | |
| 302 | yield ( |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 303 | api.test('nightly_failed_extract_fiddles') + |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 304 | api.properties(buildername='Housekeeper-Nightly-Bookmaker', |
| 305 | repository='https://skia.googlesource.com/skia.git', |
| 306 | revision='abc123', |
| 307 | path_config='kitchen', |
| 308 | swarm_out_dir='[SWARM_OUT_DIR]') + |
| 309 | api.step_data('Extract all fiddles out of md files', retcode=1) |
| 310 | ) |
| 311 | |
| 312 | yield ( |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 313 | api.test('nightly_failed_fiddlecli') + |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 314 | api.properties(buildername='Housekeeper-Nightly-Bookmaker', |
| 315 | repository='https://skia.googlesource.com/skia.git', |
| 316 | revision='abc123', |
| 317 | path_config='kitchen', |
| 318 | swarm_out_dir='[SWARM_OUT_DIR]') + |
| 319 | api.step_data('Force fiddle to compile all examples', retcode=1) |
| 320 | ) |
| 321 | |
| 322 | yield ( |
Ravi Mistry | d4731e9 | 2018-01-02 14:54:43 -0500 | [diff] [blame] | 323 | api.test('nightly_failed_upload') + |
Ravi Mistry | edc4f3e | 2017-12-08 12:58:20 -0500 | [diff] [blame] | 324 | api.properties(buildername='Housekeeper-Nightly-Bookmaker', |
| 325 | repository='https://skia.googlesource.com/skia.git', |
| 326 | revision='abc123', |
| 327 | path_config='kitchen', |
| 328 | swarm_out_dir='[SWARM_OUT_DIR]') + |
| 329 | api.step_data('Generate and Upload Markdown files', retcode=1) |
| 330 | ) |