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 """ |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 117 | 117 |
| 118 def reload_seconds(self): | 118 def reload_seconds(self): |
| 119 """ Returns the result reload period in seconds, or 0 if we don't reload | 119 """ Returns the result reload period in seconds, or 0 if we don't reload |
| 120 results. """ | 120 results. """ |
| 121 return self._reload_seconds | 121 return self._reload_seconds |
| 122 | 122 |
| 123 def update_results(self): | 123 def update_results(self): |
| 124 """ Create or update self.results, based on the expectations in | 124 """ Create or update self.results, based on the expectations in |
| 125 self._expectations_dir and the latest actuals from skia-autogen. | 125 self._expectations_dir and the latest actuals from skia-autogen. |
| 126 """ | 126 """ |
| 127 with self.results_lock: | 127 with self._svn_update_lock: |
| 128 # self.results_lock prevents us from updating the actual GM results | 128 # self._svn_update_lock prevents us from updating the actual GM results |
|
jcgregorio
2013/11/08 17:33:21
Comment seems wrong, doesn't this just prevent you
| |
| 129 # in multiple threads simultaneously | 129 # in multiple threads simultaneously |
| 130 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( | 130 logging.info('Updating actual GM results in %s from SVN repo %s ...' % ( |
| 131 self._actuals_dir, ACTUALS_SVN_REPO)) | 131 self._actuals_dir, ACTUALS_SVN_REPO)) |
| 132 actuals_repo = svn.Svn(self._actuals_dir) | 132 actuals_repo = svn.Svn(self._actuals_dir) |
| 133 if not os.path.isdir(self._actuals_dir): | 133 if not os.path.isdir(self._actuals_dir): |
| 134 os.makedirs(self._actuals_dir) | 134 os.makedirs(self._actuals_dir) |
| 135 actuals_repo.Checkout(ACTUALS_SVN_REPO, '.') | 135 actuals_repo.Checkout(ACTUALS_SVN_REPO, '.') |
| 136 else: | 136 else: |
| 137 actuals_repo.Update('.') | 137 actuals_repo.Update('.') |
| 138 | |
| 139 # We only update the expectations dir if the server was run with a | 138 # We only update the expectations dir if the server was run with a |
| 140 # nonzero --reload argument; otherwise, we expect the user to maintain | 139 # nonzero --reload argument; otherwise, we expect the user to maintain |
| 141 # her own expectations as she sees fit. | 140 # her own expectations as she sees fit. |
| 142 # | 141 # |
| 143 # self.results_lock prevents us from updating the expected GM results | 142 # self._svn_update_lock prevents us from updating the expected GM results |
| 144 # in multiple threads simultaneously | 143 # in multiple threads simultaneously |
| 145 # | 144 # |
| 146 # TODO(epoger): Use git instead of svn to check out expectations, since | 145 # TODO(epoger): Use git instead of svn to check out expectations, since |
| 147 # the Skia repo is moving to git. | 146 # the Skia repo is moving to git. |
| 148 if self._reload_seconds: | 147 if self._reload_seconds: |
| 149 logging.info( | 148 logging.info( |
| 150 'Updating expected GM results in %s from SVN repo %s ...' % ( | 149 'Updating expected GM results in %s from SVN repo %s ...' % ( |
| 151 self._expectations_dir, EXPECTATIONS_SVN_REPO)) | 150 self._expectations_dir, EXPECTATIONS_SVN_REPO)) |
| 152 expectations_repo = svn.Svn(self._expectations_dir) | 151 expectations_repo = svn.Svn(self._expectations_dir) |
| 153 if not os.path.isdir(self._expectations_dir): | 152 if not os.path.isdir(self._expectations_dir): |
| 154 os.makedirs(self._expectations_dir) | 153 os.makedirs(self._expectations_dir) |
| 155 expectations_repo.Checkout(EXPECTATIONS_SVN_REPO, '.') | 154 expectations_repo.Checkout(EXPECTATIONS_SVN_REPO, '.') |
| 156 else: | 155 else: |
| 157 expectations_repo.Update('.') | 156 expectations_repo.Update('.') |
| 157 # end of "with self._svn_update_lock:" | |
| 158 | 158 |
| 159 logging.info( | 159 logging.info( |
| 160 ('Parsing results from actuals in %s and expectations in %s, ' | 160 ('Parsing results from actuals in %s and expectations in %s, ' |
| 161 + 'and generating pixel diffs (may take a while) ...') % ( | 161 + 'and generating pixel diffs (may take a while) ...') % ( |
| 162 self._actuals_dir, self._expectations_dir)) | 162 self._actuals_dir, self._expectations_dir)) |
| 163 self.results = results.Results( | 163 new_results = results.Results( |
| 164 actuals_root=self._actuals_dir, | 164 actuals_root=self._actuals_dir, |
| 165 expected_root=self._expectations_dir, | 165 expected_root=self._expectations_dir, |
| 166 generated_images_root=GENERATED_IMAGES_ROOT) | 166 generated_images_root=GENERATED_IMAGES_ROOT) |
| 167 | 167 |
| 168 # Make sure we don't update self.results while a client is in the middle | |
| 169 # of reading from it. | |
| 170 with self.results_lock: | |
| 171 self.results = new_results | |
| 172 | |
| 168 def _result_reloader(self): | 173 def _result_reloader(self): |
| 169 """ If --reload argument was specified, reload results at the appropriate | 174 """ If --reload argument was specified, reload results at the appropriate |
| 170 interval. | 175 interval. |
| 171 """ | 176 """ |
| 172 while self._reload_seconds: | 177 while self._reload_seconds: |
| 173 time.sleep(self._reload_seconds) | 178 time.sleep(self._reload_seconds) |
| 174 self.update_results() | 179 self.update_results() |
| 175 | 180 |
| 176 def run(self): | 181 def run(self): |
| 177 self.results_lock = thread.allocate_lock() | 182 self.results_lock = thread.allocate_lock() |
|
jcgregorio
2013/11/08 17:33:21
Add docs here for what each lock is used for.
| |
| 183 self._svn_update_lock = thread.allocate_lock() | |
| 178 self.update_results() | 184 self.update_results() |
| 179 thread.start_new_thread(self._result_reloader, ()) | 185 thread.start_new_thread(self._result_reloader, ()) |
| 180 | 186 |
| 181 if self._export: | 187 if self._export: |
| 182 server_address = ('', self._port) | 188 server_address = ('', self._port) |
| 183 host = get_routable_ip_address() | 189 host = get_routable_ip_address() |
| 184 if self._editable: | 190 if self._editable: |
| 185 logging.warning('Running with combination of "export" and "editable" ' | 191 logging.warning('Running with combination of "export" and "editable" ' |
| 186 'flags. Users on other machines will ' | 192 'flags. Users on other machines will ' |
| 187 'be able to modify your GM expectations!') | 193 'be able to modify your GM expectations!') |
| 188 else: | 194 else: |
| 189 host = '127.0.0.1' | 195 host = '127.0.0.1' |
| 190 server_address = (host, self._port) | 196 server_address = (host, self._port) |
| 191 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) | 197 http_server = BaseHTTPServer.HTTPServer(server_address, HTTPRequestHandler) |
| 192 logging.info('Ready for requests on http://%s:%d' % (host, http_server.serve r_port)) | 198 logging.info('Ready for requests on http://%s:%d' % ( |
| 199 host, http_server.server_port)) | |
| 193 http_server.serve_forever() | 200 http_server.serve_forever() |
| 194 | 201 |
| 195 | 202 |
| 196 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): | 203 class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): |
| 197 """ HTTP request handlers for various types of queries this server knows | 204 """ HTTP request handlers for various types of queries this server knows |
| 198 how to handle (static HTML and Javascript, expected/actual results, etc.) | 205 how to handle (static HTML and Javascript, expected/actual results, etc.) |
| 199 """ | 206 """ |
| 200 def do_GET(self): | 207 def do_GET(self): |
| 201 """ Handles all GET requests, forwarding them to the appropriate | 208 """ Handles all GET requests, forwarding them to the appropriate |
| 202 do_GET_* dispatcher. """ | 209 do_GET_* dispatcher. """ |
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 442 args = parser.parse_args() | 449 args = parser.parse_args() |
| 443 global _SERVER | 450 global _SERVER |
| 444 _SERVER = Server(actuals_dir=args.actuals_dir, | 451 _SERVER = Server(actuals_dir=args.actuals_dir, |
| 445 expectations_dir=args.expectations_dir, | 452 expectations_dir=args.expectations_dir, |
| 446 port=args.port, export=args.export, editable=args.editable, | 453 port=args.port, export=args.export, editable=args.editable, |
| 447 reload_seconds=args.reload) | 454 reload_seconds=args.reload) |
| 448 _SERVER.run() | 455 _SERVER.run() |
| 449 | 456 |
| 450 if __name__ == '__main__': | 457 if __name__ == '__main__': |
| 451 main() | 458 main() |
| OLD | NEW |