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 |