Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 | 2 |
| 3 """ | 3 """ |
| 4 Copyright 2013 Google Inc. | 4 Copyright 2013 Google Inc. |
| 5 | 5 |
| 6 Use of this source code is governed by a BSD-style license that can be | 6 Use of this source code is governed by a BSD-style license that can be |
| 7 found in the LICENSE file. | 7 found in the LICENSE file. |
| 8 | 8 |
| 9 HTTP server for our HTML rebaseline viewer. | 9 HTTP server for our HTML rebaseline viewer. |
| 10 """ | 10 """ |
| 11 | 11 |
| 12 # System-level imports | 12 # System-level imports |
| 13 import argparse | 13 import argparse |
| 14 import BaseHTTPServer | 14 import BaseHTTPServer |
| 15 import json | 15 import json |
| 16 import logging | 16 import logging |
| 17 import os | 17 import os |
| 18 import posixpath | 18 import posixpath |
| 19 import re | 19 import re |
| 20 import shutil | 20 import shutil |
| 21 import socket | 21 import socket |
| 22 import subprocess | 22 import subprocess |
| 23 import thread | 23 import thread |
| 24 import threading | 24 import threading |
| 25 import time | 25 import time |
| 26 import urllib | |
| 26 import urlparse | 27 import urlparse |
| 27 | 28 |
| 28 # Must fix up PYTHONPATH before importing from within Skia | 29 # Must fix up PYTHONPATH before importing from within Skia |
| 29 import fix_pythonpath # pylint: disable=W0611 | 30 import fix_pythonpath # pylint: disable=W0611 |
| 30 | 31 |
| 31 # Imports from within Skia | 32 # Imports from within Skia |
| 32 from py.utils import gs_utils | 33 from py.utils import gs_utils |
| 34 import buildbot_globals | |
| 33 import gm_json | 35 import gm_json |
| 34 | 36 |
| 35 # Imports from local dir | 37 # Imports from local dir |
| 36 # | 38 # |
| 37 # pylint: disable=C0301 | 39 # pylint: disable=C0301 |
| 38 # Note: we import results under a different name, to avoid confusion with the | 40 # Note: we import results under a different name, to avoid confusion with the |
| 39 # Server.results() property. See discussion at | 41 # Server.results() property. See discussion at |
| 40 # https://codereview.chromium.org/195943004/diff/1/gm/rebaseline_server/server.p y#newcode44 | 42 # https://codereview.chromium.org/195943004/diff/1/gm/rebaseline_server/server.p y#newcode44 |
| 41 # pylint: enable=C0301 | 43 # pylint: enable=C0301 |
| 42 import compare_configs | 44 import compare_configs |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 92 LIVE_PARAM__DOWNLOAD_ONLY_DIFFERING = 'downloadOnlyDifferingImages' | 94 LIVE_PARAM__DOWNLOAD_ONLY_DIFFERING = 'downloadOnlyDifferingImages' |
| 93 LIVE_PARAM__SET_A_DIR = 'setADir' | 95 LIVE_PARAM__SET_A_DIR = 'setADir' |
| 94 LIVE_PARAM__SET_A_SECTION = 'setASection' | 96 LIVE_PARAM__SET_A_SECTION = 'setASection' |
| 95 LIVE_PARAM__SET_B_DIR = 'setBDir' | 97 LIVE_PARAM__SET_B_DIR = 'setBDir' |
| 96 LIVE_PARAM__SET_B_SECTION = 'setBSection' | 98 LIVE_PARAM__SET_B_SECTION = 'setBSection' |
| 97 | 99 |
| 98 # How often (in seconds) clients should reload while waiting for initial | 100 # How often (in seconds) clients should reload while waiting for initial |
| 99 # results to load. | 101 # results to load. |
| 100 RELOAD_INTERVAL_UNTIL_READY = 10 | 102 RELOAD_INTERVAL_UNTIL_READY = 10 |
| 101 | 103 |
| 102 SUMMARY_TYPES = [ | 104 _GM_SUMMARY_TYPES = [ |
| 103 results_mod.KEY__HEADER__RESULTS_FAILURES, | 105 results_mod.KEY__HEADER__RESULTS_FAILURES, |
| 104 results_mod.KEY__HEADER__RESULTS_ALL, | 106 results_mod.KEY__HEADER__RESULTS_ALL, |
| 105 ] | 107 ] |
| 106 # If --compare-configs is specified, compare these configs. | 108 # If --compare-configs is specified, compare these configs. |
| 107 CONFIG_PAIRS_TO_COMPARE = [('8888', 'gpu')] | 109 CONFIG_PAIRS_TO_COMPARE = [('8888', 'gpu')] |
| 108 | 110 |
| 111 # SKP results that are available to compare. | |
| 112 _SKP_BASE_GS_URL = 'gs://' + buildbot_globals.Get('skp_summaries_bucket') | |
| 113 _SKP_PLATFORMS = [ | |
| 114 'Test-Mac10.8-MacMini4.1-GeForce320M-x86_64-Debug', | |
| 115 'Test-Ubuntu12-ShuttleA-GTX660-x86-Release', | |
| 116 ] | |
| 117 | |
|
stephana
2014/08/13 13:39:26
Can you make a note what the next version of this
epoger
2014/08/13 14:25:04
Done.
| |
| 109 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' | 118 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' |
| 110 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' | 119 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' |
| 111 | 120 |
| 112 _SERVER = None # This gets filled in by main() | 121 _SERVER = None # This gets filled in by main() |
| 113 | 122 |
| 114 | 123 |
| 115 def _run_command(args, directory): | 124 def _run_command(args, directory): |
| 116 """Runs a command and returns stdout as a single string. | 125 """Runs a command and returns stdout as a single string. |
| 117 | 126 |
| 118 Args: | 127 Args: |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 config_pairs: what pairs of configs (if any) we compare actual results of | 172 config_pairs: what pairs of configs (if any) we compare actual results of |
| 164 """ | 173 """ |
| 165 dir_path = os.path.dirname(file_path) | 174 dir_path = os.path.dirname(file_path) |
| 166 if not os.path.isdir(dir_path): | 175 if not os.path.isdir(dir_path): |
| 167 os.makedirs(dir_path) | 176 os.makedirs(dir_path) |
| 168 with open(file_path, 'w') as file_handle: | 177 with open(file_path, 'w') as file_handle: |
| 169 file_handle.write( | 178 file_handle.write( |
| 170 '<!DOCTYPE html><html>' | 179 '<!DOCTYPE html><html>' |
| 171 '<head><title>rebaseline_server</title></head>' | 180 '<head><title>rebaseline_server</title></head>' |
| 172 '<body><ul>') | 181 '<body><ul>') |
| 173 if SUMMARY_TYPES: | 182 |
| 174 file_handle.write('<li>Expectations vs Actuals</li><ul>') | 183 if _GM_SUMMARY_TYPES: |
| 175 for summary_type in SUMMARY_TYPES: | 184 file_handle.write('<li>GM Expectations vs Actuals</li><ul>') |
| 185 for summary_type in _GM_SUMMARY_TYPES: | |
| 176 file_handle.write( | 186 file_handle.write( |
| 177 '<li><a href="/{static_directive}/view.html#/view.html?' | 187 '\n<li><a href="/{static_directive}/view.html#/view.html?' |
| 178 'resultsToLoad=/{results_directive}/{summary_type}">' | 188 'resultsToLoad=/{results_directive}/{summary_type}">' |
| 179 '{summary_type}</a></li>'.format( | 189 '{summary_type}</a></li>'.format( |
| 180 results_directive=GET__PRECOMPUTED_RESULTS, | 190 results_directive=GET__PRECOMPUTED_RESULTS, |
| 181 static_directive=GET__STATIC_CONTENTS, | 191 static_directive=GET__STATIC_CONTENTS, |
| 182 summary_type=summary_type)) | 192 summary_type=summary_type)) |
| 183 file_handle.write('</ul>') | 193 file_handle.write('</ul>') |
| 194 | |
| 184 if config_pairs: | 195 if config_pairs: |
| 185 file_handle.write('<li>Comparing configs within actual results</li><ul>') | 196 file_handle.write( |
| 197 '\n<li>Comparing configs within actual GM results</li><ul>') | |
| 186 for config_pair in config_pairs: | 198 for config_pair in config_pairs: |
| 187 file_handle.write('<li>%s vs %s:' % config_pair) | 199 file_handle.write('<li>%s vs %s:' % config_pair) |
| 188 for summary_type in SUMMARY_TYPES: | 200 for summary_type in _GM_SUMMARY_TYPES: |
| 189 file_handle.write( | 201 file_handle.write( |
| 190 ' <a href="/%s/view.html#/view.html?' | 202 ' <a href="/%s/view.html#/view.html?' |
| 191 'resultsToLoad=/%s/%s/%s-vs-%s_%s.json">%s</a>' % ( | 203 'resultsToLoad=/%s/%s/%s-vs-%s_%s.json">%s</a>' % ( |
| 192 GET__STATIC_CONTENTS, GET__STATIC_CONTENTS, | 204 GET__STATIC_CONTENTS, GET__STATIC_CONTENTS, |
| 193 GENERATED_JSON_SUBDIR, config_pair[0], config_pair[1], | 205 GENERATED_JSON_SUBDIR, config_pair[0], config_pair[1], |
| 194 summary_type, summary_type)) | 206 summary_type, summary_type)) |
| 195 file_handle.write('</li>') | 207 file_handle.write('</li>') |
| 196 file_handle.write('</ul>') | 208 file_handle.write('</ul>') |
| 197 file_handle.write('</ul></body></html>') | 209 |
| 210 if _SKP_PLATFORMS: | |
| 211 file_handle.write('\n<li>Rendered SKPs:<ul>') | |
| 212 for builder in _SKP_PLATFORMS: | |
| 213 file_handle.write( | |
| 214 '\n<li><a href="../live-view.html#live-view.html?%s">' % | |
| 215 urllib.urlencode({ | |
| 216 LIVE_PARAM__SET_A_SECTION: | |
| 217 gm_json.JSONKEY_EXPECTEDRESULTS, | |
| 218 LIVE_PARAM__SET_A_DIR: | |
| 219 posixpath.join(_SKP_BASE_GS_URL, builder), | |
| 220 LIVE_PARAM__SET_B_SECTION: | |
| 221 gm_json.JSONKEY_ACTUALRESULTS, | |
| 222 LIVE_PARAM__SET_B_DIR: | |
| 223 posixpath.join(_SKP_BASE_GS_URL, builder), | |
| 224 })) | |
| 225 file_handle.write('expected vs actuals on %s</a></li>' % builder) | |
| 226 file_handle.write( | |
| 227 '\n<li><a href="../live-view.html#live-view.html?%s">' % | |
| 228 urllib.urlencode({ | |
| 229 LIVE_PARAM__SET_A_SECTION: | |
| 230 gm_json.JSONKEY_ACTUALRESULTS, | |
| 231 LIVE_PARAM__SET_A_DIR: | |
| 232 posixpath.join(_SKP_BASE_GS_URL, _SKP_PLATFORMS[0]), | |
| 233 LIVE_PARAM__SET_B_SECTION: | |
| 234 gm_json.JSONKEY_ACTUALRESULTS, | |
| 235 LIVE_PARAM__SET_B_DIR: | |
| 236 posixpath.join(_SKP_BASE_GS_URL, _SKP_PLATFORMS[1]), | |
| 237 })) | |
| 238 file_handle.write('actuals on %s vs %s</a></li>' % ( | |
| 239 _SKP_PLATFORMS[0], _SKP_PLATFORMS[1])) | |
| 240 file_handle.write('</li>') | |
| 241 | |
| 242 file_handle.write('\n</ul></body></html>') | |
| 198 | 243 |
| 199 | 244 |
| 200 class Server(object): | 245 class Server(object): |
| 201 """ HTTP server for our HTML rebaseline viewer. """ | 246 """ HTTP server for our HTML rebaseline viewer. """ |
| 202 | 247 |
| 203 def __init__(self, | 248 def __init__(self, |
| 204 actuals_dir=DEFAULT_ACTUALS_DIR, | 249 actuals_dir=DEFAULT_ACTUALS_DIR, |
| 205 json_filename=DEFAULT_JSON_FILENAME, | 250 json_filename=DEFAULT_JSON_FILENAME, |
| 206 gm_summaries_bucket=DEFAULT_GM_SUMMARIES_BUCKET, | 251 gm_summaries_bucket=DEFAULT_GM_SUMMARIES_BUCKET, |
| 207 port=DEFAULT_PORT, export=False, editable=True, | 252 port=DEFAULT_PORT, export=False, editable=True, |
| (...skipping 191 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 399 for config_pair in self._config_pairs: | 444 for config_pair in self._config_pairs: |
| 400 config_comparisons = compare_configs.ConfigComparisons( | 445 config_comparisons = compare_configs.ConfigComparisons( |
| 401 configs=config_pair, | 446 configs=config_pair, |
| 402 actuals_root=self._actuals_dir, | 447 actuals_root=self._actuals_dir, |
| 403 generated_images_root=os.path.join( | 448 generated_images_root=os.path.join( |
| 404 PARENT_DIRECTORY, STATIC_CONTENTS_SUBDIR, | 449 PARENT_DIRECTORY, STATIC_CONTENTS_SUBDIR, |
| 405 GENERATED_IMAGES_SUBDIR), | 450 GENERATED_IMAGES_SUBDIR), |
| 406 diff_base_url=posixpath.join( | 451 diff_base_url=posixpath.join( |
| 407 os.pardir, GENERATED_IMAGES_SUBDIR), | 452 os.pardir, GENERATED_IMAGES_SUBDIR), |
| 408 builder_regex_list=self._builder_regex_list) | 453 builder_regex_list=self._builder_regex_list) |
| 409 for summary_type in SUMMARY_TYPES: | 454 for summary_type in _GM_SUMMARY_TYPES: |
| 410 gm_json.WriteToFile( | 455 gm_json.WriteToFile( |
| 411 config_comparisons.get_packaged_results_of_type( | 456 config_comparisons.get_packaged_results_of_type( |
| 412 results_type=summary_type), | 457 results_type=summary_type), |
| 413 os.path.join( | 458 os.path.join( |
| 414 json_dir, '%s-vs-%s_%s.json' % ( | 459 json_dir, '%s-vs-%s_%s.json' % ( |
| 415 config_pair[0], config_pair[1], summary_type))) | 460 config_pair[0], config_pair[1], summary_type))) |
| 416 | 461 |
| 417 def _result_loader(self, reload_seconds=0): | 462 def _result_loader(self, reload_seconds=0): |
| 418 """ Call self.update_results(), either once or periodically. | 463 """ Call self.update_results(), either once or periodically. |
| 419 | 464 |
| (...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 819 reload_seconds=args.reload, config_pairs=config_pairs, | 864 reload_seconds=args.reload, config_pairs=config_pairs, |
| 820 builder_regex_list=args.builders, boto_file_path=args.boto, | 865 builder_regex_list=args.builders, boto_file_path=args.boto, |
| 821 imagediffdb_threads=args.threads) | 866 imagediffdb_threads=args.threads) |
| 822 if args.truncate: | 867 if args.truncate: |
| 823 _SERVER.truncate_results = True | 868 _SERVER.truncate_results = True |
| 824 _SERVER.run() | 869 _SERVER.run() |
| 825 | 870 |
| 826 | 871 |
| 827 if __name__ == '__main__': | 872 if __name__ == '__main__': |
| 828 main() | 873 main() |
| OLD | NEW |