Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Side by Side Diff: gm/rebaseline_server/server.py

Issue 193023002: rebaseline_server: add actual_repo and actual_revision command line options (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | tools/svn.py » ('j') | tools/svn.py » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 """
(...skipping 25 matching lines...) Expand all
36 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY)) 36 TRUNK_DIRECTORY = os.path.dirname(os.path.dirname(PARENT_DIRECTORY))
37 TOOLS_DIRECTORY = os.path.join(TRUNK_DIRECTORY, 'tools') 37 TOOLS_DIRECTORY = os.path.join(TRUNK_DIRECTORY, 'tools')
38 if TOOLS_DIRECTORY not in sys.path: 38 if TOOLS_DIRECTORY not in sys.path:
39 sys.path.append(TOOLS_DIRECTORY) 39 sys.path.append(TOOLS_DIRECTORY)
40 import svn 40 import svn
41 41
42 # Imports from local dir 42 # Imports from local dir
43 import imagepairset 43 import imagepairset
44 import results 44 import results
45 45
46 ACTUALS_SVN_REPO = 'http://skia-autogen.googlecode.com/svn/gm-actual'
47 PATHSPLIT_RE = re.compile('/([^/]+)/(.+)') 46 PATHSPLIT_RE = re.compile('/([^/]+)/(.+)')
48 EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm') 47 EXPECTATIONS_DIR = os.path.join(TRUNK_DIRECTORY, 'expectations', 'gm')
49 GENERATED_IMAGES_ROOT = os.path.join(PARENT_DIRECTORY, 'static', 48 GENERATED_IMAGES_ROOT = os.path.join(PARENT_DIRECTORY, 'static',
50 'generated-images') 49 'generated-images')
51 50
52 # A simple dictionary of file name extensions to MIME types. The empty string 51 # A simple dictionary of file name extensions to MIME types. The empty string
53 # entry is used as the default when no extension was given or if the extension 52 # entry is used as the default when no extension was given or if the extension
54 # has no entry in this dictionary. 53 # has no entry in this dictionary.
55 MIME_TYPE_MAP = {'': 'application/octet-stream', 54 MIME_TYPE_MAP = {'': 'application/octet-stream',
56 'html': 'text/html', 55 'html': 'text/html',
(...skipping 11 matching lines...) Expand all
68 KEY__HEADER = 'header' 67 KEY__HEADER = 'header'
69 KEY__HEADER__DATAHASH = 'dataHash' 68 KEY__HEADER__DATAHASH = 'dataHash'
70 KEY__HEADER__IS_EDITABLE = 'isEditable' 69 KEY__HEADER__IS_EDITABLE = 'isEditable'
71 KEY__HEADER__IS_EXPORTED = 'isExported' 70 KEY__HEADER__IS_EXPORTED = 'isExported'
72 KEY__HEADER__IS_STILL_LOADING = 'resultsStillLoading' 71 KEY__HEADER__IS_STILL_LOADING = 'resultsStillLoading'
73 KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE = 'timeNextUpdateAvailable' 72 KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE = 'timeNextUpdateAvailable'
74 KEY__HEADER__TIME_UPDATED = 'timeUpdated' 73 KEY__HEADER__TIME_UPDATED = 'timeUpdated'
75 KEY__HEADER__TYPE = 'type' 74 KEY__HEADER__TYPE = 'type'
76 75
77 DEFAULT_ACTUALS_DIR = '.gm-actuals' 76 DEFAULT_ACTUALS_DIR = '.gm-actuals'
77 DEFAULT_ACTUALS_REPO_REVISION = 'HEAD'
78 DEFAULT_ACTUALS_REPO_URL = 'http://skia-autogen.googlecode.com/svn/gm-actual'
78 DEFAULT_PORT = 8888 79 DEFAULT_PORT = 8888
79 80
80 # How often (in seconds) clients should reload while waiting for initial 81 # How often (in seconds) clients should reload while waiting for initial
81 # results to load. 82 # results to load.
82 RELOAD_INTERVAL_UNTIL_READY = 10 83 RELOAD_INTERVAL_UNTIL_READY = 10
83 84
84 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length' 85 _HTTP_HEADER_CONTENT_LENGTH = 'Content-Length'
85 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type' 86 _HTTP_HEADER_CONTENT_TYPE = 'Content-Type'
86 87
87 _SERVER = None # This gets filled in by main() 88 _SERVER = None # This gets filled in by main()
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 os.makedirs(dir_path) 137 os.makedirs(dir_path)
137 local_checkout.Checkout(repo_url, '.') 138 local_checkout.Checkout(repo_url, '.')
138 return local_checkout 139 return local_checkout
139 140
140 141
141 class Server(object): 142 class Server(object):
142 """ HTTP server for our HTML rebaseline viewer. """ 143 """ HTTP server for our HTML rebaseline viewer. """
143 144
144 def __init__(self, 145 def __init__(self,
145 actuals_dir=DEFAULT_ACTUALS_DIR, 146 actuals_dir=DEFAULT_ACTUALS_DIR,
147 actuals_repo_revision=DEFAULT_ACTUALS_REPO_REVISION,
148 actuals_repo_url=DEFAULT_ACTUALS_REPO_URL,
146 port=DEFAULT_PORT, export=False, editable=True, 149 port=DEFAULT_PORT, export=False, editable=True,
147 reload_seconds=0): 150 reload_seconds=0):
148 """ 151 """
149 Args: 152 Args:
150 actuals_dir: directory under which we will check out the latest actual 153 actuals_dir: directory under which we will check out the latest actual
151 GM results 154 GM results
155 actuals_repo_revision: revision of actual-results.json files to process
156 actuals_repo_url: SVN repo to download actual-results.json files from
152 port: which TCP port to listen on for HTTP requests 157 port: which TCP port to listen on for HTTP requests
153 export: whether to allow HTTP clients on other hosts to access this server 158 export: whether to allow HTTP clients on other hosts to access this server
154 editable: whether HTTP clients are allowed to submit new baselines 159 editable: whether HTTP clients are allowed to submit new baselines
155 reload_seconds: polling interval with which to check for new results; 160 reload_seconds: polling interval with which to check for new results;
156 if 0, don't check for new results at all 161 if 0, don't check for new results at all
157 """ 162 """
158 self._actuals_dir = actuals_dir 163 self._actuals_dir = actuals_dir
164 self._actuals_repo_revision = actuals_repo_revision
165 self._actuals_repo_url = actuals_repo_url
159 self._port = port 166 self._port = port
160 self._export = export 167 self._export = export
161 self._editable = editable 168 self._editable = editable
162 self._reload_seconds = reload_seconds 169 self._reload_seconds = reload_seconds
163 self._actuals_repo = _create_svn_checkout( 170 self._actuals_repo = _create_svn_checkout(
164 dir_path=actuals_dir, repo_url=ACTUALS_SVN_REPO) 171 dir_path=actuals_dir, repo_url=actuals_repo_url)
165 172
166 # Reentrant lock that must be held whenever updating EITHER of: 173 # Reentrant lock that must be held whenever updating EITHER of:
167 # 1. self._results 174 # 1. self._results
168 # 2. the expected or actual results on local disk 175 # 2. the expected or actual results on local disk
169 self.results_rlock = threading.RLock() 176 self.results_rlock = threading.RLock()
170 # self._results will be filled in by calls to update_results() 177 # self._results will be filled in by calls to update_results()
171 self._results = None 178 self._results = None
172 179
173 @property 180 @property
174 def results(self): 181 def results(self):
(...skipping 27 matching lines...) Expand all
202 the same time. 209 the same time.
203 210
204 Args: 211 Args:
205 invalidate: if True, invalidate self._results immediately upon entry; 212 invalidate: if True, invalidate self._results immediately upon entry;
206 otherwise, we will let readers see those results until we 213 otherwise, we will let readers see those results until we
207 replace them 214 replace them
208 """ 215 """
209 with self.results_rlock: 216 with self.results_rlock:
210 if invalidate: 217 if invalidate:
211 self._results = None 218 self._results = None
212 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( 219 logging.info(
213 self._actuals_dir, ACTUALS_SVN_REPO)) 220 'Updating actual GM results in %s to revision %s from repo %s ...' % (
214 self._actuals_repo.Update('.') 221 self._actuals_dir, self._actuals_repo_revision,
222 self._actuals_repo_url))
223 self._actuals_repo.Update(path='.', revision=self._actuals_repo_revision)
215 224
216 # We only update the expectations dir if the server was run with a 225 # We only update the expectations dir if the server was run with a
217 # nonzero --reload argument; otherwise, we expect the user to maintain 226 # nonzero --reload argument; otherwise, we expect the user to maintain
218 # her own expectations as she sees fit. 227 # her own expectations as she sees fit.
219 # 228 #
220 # Because the Skia repo is moving from SVN to git, and git does not 229 # Because the Skia repo is moving from SVN to git, and git does not
221 # support updating a single directory tree, we have to update the entire 230 # support updating a single directory tree, we have to update the entire
222 # repo checkout. 231 # repo checkout.
223 # 232 #
224 # Because Skia uses depot_tools, we have to update using "gclient sync" 233 # Because Skia uses depot_tools, we have to update using "gclient sync"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 # the handler's .server instance variable. 333 # the handler's .server instance variable.
325 results_obj = _SERVER.results 334 results_obj = _SERVER.results
326 if results_obj: 335 if results_obj:
327 response_dict = self.package_results(results_obj, type) 336 response_dict = self.package_results(results_obj, type)
328 else: 337 else:
329 now = int(time.time()) 338 now = int(time.time())
330 response_dict = { 339 response_dict = {
331 KEY__HEADER: { 340 KEY__HEADER: {
332 KEY__HEADER__IS_STILL_LOADING: True, 341 KEY__HEADER__IS_STILL_LOADING: True,
333 KEY__HEADER__TIME_UPDATED: now, 342 KEY__HEADER__TIME_UPDATED: now,
334 KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE: 343 KEY__HEADER__TIME_NEXT_UPDATE_AVAILABLE: (
335 now + RELOAD_INTERVAL_UNTIL_READY, 344 now + RELOAD_INTERVAL_UNTIL_READY),
336 }, 345 },
337 } 346 }
338 self.send_json_dict(response_dict) 347 self.send_json_dict(response_dict)
339 348
340 def package_results(self, results_obj, type): 349 def package_results(self, results_obj, type):
341 """ Given a nonempty "results" object, package it as a response_dict 350 """ Given a nonempty "results" object, package it as a response_dict
342 as needed within do_GET_results. 351 as needed within do_GET_results.
343 352
344 Args: 353 Args:
345 results_obj: nonempty "results" object 354 results_obj: nonempty "results" object
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
525 def main(): 534 def main():
526 logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', 535 logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s',
527 datefmt='%m/%d/%Y %H:%M:%S', 536 datefmt='%m/%d/%Y %H:%M:%S',
528 level=logging.INFO) 537 level=logging.INFO)
529 parser = argparse.ArgumentParser() 538 parser = argparse.ArgumentParser()
530 parser.add_argument('--actuals-dir', 539 parser.add_argument('--actuals-dir',
531 help=('Directory into which we will check out the latest ' 540 help=('Directory into which we will check out the latest '
532 'actual GM results. If this directory does not ' 541 'actual GM results. If this directory does not '
533 'exist, it will be created. Defaults to %(default)s'), 542 'exist, it will be created. Defaults to %(default)s'),
534 default=DEFAULT_ACTUALS_DIR) 543 default=DEFAULT_ACTUALS_DIR)
544 parser.add_argument('--actuals-repo',
545 help=('URL of SVN repo to download actual-results.json '
546 'files from. Defaults to %(default)s'),
547 default=DEFAULT_ACTUALS_REPO_URL)
548 parser.add_argument('--actuals-revision',
549 help=('revision of actual-results.json files to process. '
550 'Defaults to %(default)s . Beware of setting this '
epoger 2014/03/10 18:08:54 I *think* that will work, but as noted in the warn
551 'argument in conjunction with --editable; you '
552 'probably only want to edit results at HEAD.'),
553 default=DEFAULT_ACTUALS_REPO_REVISION)
535 parser.add_argument('--editable', action='store_true', 554 parser.add_argument('--editable', action='store_true',
536 help=('Allow HTTP clients to submit new baselines.')) 555 help=('Allow HTTP clients to submit new baselines.'))
537 parser.add_argument('--export', action='store_true', 556 parser.add_argument('--export', action='store_true',
538 help=('Instead of only allowing access from HTTP clients ' 557 help=('Instead of only allowing access from HTTP clients '
539 'on localhost, allow HTTP clients on other hosts ' 558 'on localhost, allow HTTP clients on other hosts '
540 'to access this server. WARNING: doing so will ' 559 'to access this server. WARNING: doing so will '
541 'allow users on other hosts to modify your ' 560 'allow users on other hosts to modify your '
542 'GM expectations, if combined with --editable.')) 561 'GM expectations, if combined with --editable.'))
543 parser.add_argument('--port', type=int, 562 parser.add_argument('--port', type=int,
544 help=('Which TCP port to listen on for HTTP requests; ' 563 help=('Which TCP port to listen on for HTTP requests; '
545 'defaults to %(default)s'), 564 'defaults to %(default)s'),
546 default=DEFAULT_PORT) 565 default=DEFAULT_PORT)
547 parser.add_argument('--reload', type=int, 566 parser.add_argument('--reload', type=int,
548 help=('How often (a period in seconds) to update the ' 567 help=('How often (a period in seconds) to update the '
549 'results. If specified, both expected and actual ' 568 'results. If specified, both expected and actual '
550 'results will be updated by running "gclient sync" ' 569 'results will be updated by running "gclient sync" '
551 'on your Skia checkout as a whole. ' 570 'on your Skia checkout as a whole. '
552 'By default, we do not reload at all, and you ' 571 'By default, we do not reload at all, and you '
553 'must restart the server to pick up new data.'), 572 'must restart the server to pick up new data.'),
554 default=0) 573 default=0)
555 args = parser.parse_args() 574 args = parser.parse_args()
556 global _SERVER 575 global _SERVER
557 _SERVER = Server(actuals_dir=args.actuals_dir, 576 _SERVER = Server(actuals_dir=args.actuals_dir,
577 actuals_repo_revision=args.actuals_revision,
578 actuals_repo_url=args.actuals_repo,
558 port=args.port, export=args.export, editable=args.editable, 579 port=args.port, export=args.export, editable=args.editable,
559 reload_seconds=args.reload) 580 reload_seconds=args.reload)
560 _SERVER.run() 581 _SERVER.run()
561 582
562 583
563 if __name__ == '__main__': 584 if __name__ == '__main__':
564 main() 585 main()
OLDNEW
« no previous file with comments | « no previous file | tools/svn.py » ('j') | tools/svn.py » ('J')

Powered by Google App Engine
This is Rietveld 408576698