OLD | NEW |
---|---|
1 # Copyright (C) 2010 Google Inc. All rights reserved. | 1 # Copyright (C) 2010 Google Inc. All rights reserved. |
2 # Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Sze ged | 2 # Copyright (C) 2010 Gabor Rapcsanyi (rgabor@inf.u-szeged.hu), University of Sze ged |
3 # | 3 # |
4 # Redistribution and use in source and binary forms, with or without | 4 # Redistribution and use in source and binary forms, with or without |
5 # modification, are permitted provided that the following conditions are | 5 # modification, are permitted provided that the following conditions are |
6 # met: | 6 # met: |
7 # | 7 # |
8 # * Redistributions of source code must retain the above copyright | 8 # * Redistributions of source code must retain the above copyright |
9 # notice, this list of conditions and the following disclaimer. | 9 # notice, this list of conditions and the following disclaimer. |
10 # * Redistributions in binary form must reproduce the above | 10 # * Redistributions in binary form must reproduce the above |
(...skipping 22 matching lines...) Expand all Loading... | |
33 objects to the Manager. The Manager then aggregates the TestFailures to | 33 objects to the Manager. The Manager then aggregates the TestFailures to |
34 create a final report. | 34 create a final report. |
35 """ | 35 """ |
36 | 36 |
37 import json | 37 import json |
38 import logging | 38 import logging |
39 import random | 39 import random |
40 import sys | 40 import sys |
41 import time | 41 import time |
42 | 42 |
43 from webkitpy.common.net.file_uploader import FileUploader | |
43 from webkitpy.layout_tests.controllers.layout_test_finder import LayoutTestFinde r | 44 from webkitpy.layout_tests.controllers.layout_test_finder import LayoutTestFinde r |
44 from webkitpy.layout_tests.controllers.layout_test_runner import LayoutTestRunne r | 45 from webkitpy.layout_tests.controllers.layout_test_runner import LayoutTestRunne r |
45 from webkitpy.layout_tests.controllers.test_result_writer import TestResultWrite r | 46 from webkitpy.layout_tests.controllers.test_result_writer import TestResultWrite r |
46 from webkitpy.layout_tests.layout_package import json_layout_results_generator | |
47 from webkitpy.layout_tests.layout_package import json_results_generator | 47 from webkitpy.layout_tests.layout_package import json_results_generator |
48 from webkitpy.layout_tests.models import test_expectations | 48 from webkitpy.layout_tests.models import test_expectations |
49 from webkitpy.layout_tests.models import test_failures | 49 from webkitpy.layout_tests.models import test_failures |
50 from webkitpy.layout_tests.models import test_run_results | 50 from webkitpy.layout_tests.models import test_run_results |
51 from webkitpy.layout_tests.models.test_input import TestInput | 51 from webkitpy.layout_tests.models.test_input import TestInput |
52 | 52 |
53 _log = logging.getLogger(__name__) | 53 _log = logging.getLogger(__name__) |
54 | 54 |
55 # Builder base URL where we have the archived test results. | 55 # Builder base URL where we have the archived test results. |
56 BUILDER_BASE_URL = "http://build.chromium.org/buildbot/layout_test_results/" | 56 BUILDER_BASE_URL = "http://build.chromium.org/buildbot/layout_test_results/" |
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
228 self._look_for_new_crash_logs(initial_results, start_time) | 228 self._look_for_new_crash_logs(initial_results, start_time) |
229 if retry_results: | 229 if retry_results: |
230 self._look_for_new_crash_logs(retry_results, start_time) | 230 self._look_for_new_crash_logs(retry_results, start_time) |
231 | 231 |
232 _log.debug("summarizing results") | 232 _log.debug("summarizing results") |
233 summarized_results = test_run_results.summarize_results(self._port, self ._expectations, initial_results, retry_results, enabled_pixel_tests_in_retry) | 233 summarized_results = test_run_results.summarize_results(self._port, self ._expectations, initial_results, retry_results, enabled_pixel_tests_in_retry) |
234 self._printer.print_results(end_time - start_time, initial_results, summ arized_results) | 234 self._printer.print_results(end_time - start_time, initial_results, summ arized_results) |
235 | 235 |
236 if not self._options.dry_run: | 236 if not self._options.dry_run: |
237 self._port.print_leaks_summary() | 237 self._port.print_leaks_summary() |
238 self._upload_json_files(summarized_results, initial_results) | 238 self._write_json_files(summarized_results, initial_results) |
239 self._upload_json_files() | |
239 | 240 |
240 results_path = self._filesystem.join(self._results_directory, "resul ts.html") | 241 results_path = self._filesystem.join(self._results_directory, "resul ts.html") |
241 self._copy_results_html_file(results_path) | 242 self._copy_results_html_file(results_path) |
242 if self._options.show_results and (initial_results.unexpected_result s_by_name or | 243 if self._options.show_results and (initial_results.unexpected_result s_by_name or |
243 (self._options.full_results_html and initial_results.total_failures)): | 244 (self._options.full_results_html and initial_results.total_failures)): |
244 self._port.show_results_html_file(results_path) | 245 self._port.show_results_html_file(results_path) |
245 | 246 |
246 return test_run_results.RunDetails(self._port.exit_code_from_summarized_ results(summarized_results), | 247 return test_run_results.RunDetails(self._port.exit_code_from_summarized_ results(summarized_results), |
247 summarized_results, initial_results, retry_results, enabled_pixel_tests_in_retry) | 248 summarized_results, initial_results, retry_results, enabled_pixel_tests_in_retry) |
248 | 249 |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
318 for dirname in possible_dirs: | 319 for dirname in possible_dirs: |
319 if self._filesystem.isdir(self._filesystem.join(layout_tests_dir, di rname)): | 320 if self._filesystem.isdir(self._filesystem.join(layout_tests_dir, di rname)): |
320 self._filesystem.rmtree(self._filesystem.join(self._results_dire ctory, dirname)) | 321 self._filesystem.rmtree(self._filesystem.join(self._results_dire ctory, dirname)) |
321 | 322 |
322 def _tests_to_retry(self, run_results, include_crashes): | 323 def _tests_to_retry(self, run_results, include_crashes): |
323 return [result.test_name for result in run_results.unexpected_results_by _name.values() if | 324 return [result.test_name for result in run_results.unexpected_results_by _name.values() if |
324 ((result.type != test_expectations.PASS) and | 325 ((result.type != test_expectations.PASS) and |
325 (result.type != test_expectations.MISSING) and | 326 (result.type != test_expectations.MISSING) and |
326 (result.type != test_expectations.CRASH or include_crashes)) ] | 327 (result.type != test_expectations.CRASH or include_crashes)) ] |
327 | 328 |
328 def _upload_json_files(self, summarized_results, initial_results): | 329 def _write_json_files(self, summarized_results, initial_results): |
329 """Writes the results of the test run as JSON files into the results | |
Julie Parent
2013/05/17 20:38:29
Why did you remove the parameter descriptions?
ojan
2013/05/17 20:41:37
They didn't seem terribly accurate or useful. You
| |
330 dir and upload the files to the appengine server. | |
331 | |
332 Args: | |
333 summarized_results: dict of results | |
334 initial_results: full summary object | |
335 """ | |
336 _log.debug("Writing JSON files in %s." % self._results_directory) | 330 _log.debug("Writing JSON files in %s." % self._results_directory) |
337 | 331 |
338 # FIXME: Upload stats.json to the server and delete times_ms. | 332 # FIXME: Upload stats.json to the server and delete times_ms. |
339 times_trie = json_results_generator.test_timings_trie(self._port, initia l_results.results_by_name.values()) | 333 times_trie = json_results_generator.test_timings_trie(self._port, initia l_results.results_by_name.values()) |
340 times_json_path = self._filesystem.join(self._results_directory, "times_ ms.json") | 334 times_json_path = self._filesystem.join(self._results_directory, "times_ ms.json") |
341 json_results_generator.write_json(self._filesystem, times_trie, times_js on_path) | 335 json_results_generator.write_json(self._filesystem, times_trie, times_js on_path) |
342 | 336 |
343 stats_trie = self._stats_trie(initial_results) | 337 stats_trie = self._stats_trie(initial_results) |
344 stats_path = self._filesystem.join(self._results_directory, "stats.json" ) | 338 stats_path = self._filesystem.join(self._results_directory, "stats.json" ) |
345 self._filesystem.write_text_file(stats_path, json.dumps(stats_trie)) | 339 self._filesystem.write_text_file(stats_path, json.dumps(stats_trie)) |
346 | 340 |
347 full_results_path = self._filesystem.join(self._results_directory, "full _results.json") | 341 full_results_path = self._filesystem.join(self._results_directory, "full _results.json") |
348 # We write full_results.json out as jsonp because we need to load it fro m a file url and Chromium doesn't allow that. | 342 # We write full_results.json out as jsonp because we need to load it fro m a file url and Chromium doesn't allow that. |
349 json_results_generator.write_json(self._filesystem, summarized_results, full_results_path, callback="ADD_RESULTS") | 343 json_results_generator.write_json(self._filesystem, summarized_results, full_results_path, callback="ADD_RESULTS") |
350 | 344 |
351 generator = json_layout_results_generator.JSONLayoutResultsGenerator( | |
352 self._port, self._options.builder_name, self._options.build_name, | |
353 self._options.build_number, self._results_directory, | |
354 BUILDER_BASE_URL, | |
355 self._expectations, initial_results, | |
356 self._options.test_results_server, | |
357 "layout-tests", | |
358 self._options.master_name) | |
359 | |
360 _log.debug("Finished writing JSON files.") | 345 _log.debug("Finished writing JSON files.") |
361 | 346 |
347 def _upload_json_files(self): | |
348 if not self._options.test_results_server: | |
349 return | |
362 | 350 |
363 json_files = ["incremental_results.json", "full_results.json", "times_ms .json"] | 351 if not self._options.master_name: |
352 _log.error("--test-results-server was set, but --master-name was not . Not uploading JSON files.") | |
353 return | |
364 | 354 |
365 generator.upload_json_files(json_files) | 355 _log.debug("Uploading JSON files for builder: %s", self._options.builder _name) |
356 attrs = [("builder", self._options.builder_name), | |
357 ("testtype", "layout-tests"), | |
358 ("master", self._options.master_name)] | |
366 | 359 |
367 incremental_results_path = self._filesystem.join(self._results_directory , "incremental_results.json") | 360 files = [(file, self._filesystem.join(self._results_directory, file)) fo r file in ["full_results.json", "times_ms.json"]] |
368 | 361 |
369 # Remove these files from the results directory so they don't take up to o much space on the buildbot. | 362 url = "http://%s/testfile/upload" % self._options.test_results_server |
370 # The tools use the version we uploaded to the results server anyway. | 363 # Set uploading timeout in case appengine server is having problems. |
371 self._filesystem.remove(times_json_path) | 364 # 120 seconds are more than enough to upload test results. |
372 self._filesystem.remove(incremental_results_path) | 365 uploader = FileUploader(url, 120) |
366 try: | |
367 response = uploader.upload_as_multipart_form_data(self._filesystem, files, attrs) | |
368 if response: | |
369 if response.code == 200: | |
370 _log.debug("JSON uploaded.") | |
371 else: | |
372 _log.debug("JSON upload failed, %d: '%s'" % (response.code, response.read())) | |
373 else: | |
374 _log.error("JSON upload failed; no response returned") | |
375 except Exception, err: | |
376 _log.error("Upload failed: %s" % err) | |
373 | 377 |
374 def _copy_results_html_file(self, destination_path): | 378 def _copy_results_html_file(self, destination_path): |
375 base_dir = self._port.path_from_webkit_base('LayoutTests', 'fast', 'harn ess') | 379 base_dir = self._port.path_from_webkit_base('LayoutTests', 'fast', 'harn ess') |
376 results_file = self._filesystem.join(base_dir, 'results.html') | 380 results_file = self._filesystem.join(base_dir, 'results.html') |
377 # Note that the results.html template file won't exist when we're using a MockFileSystem during unit tests, | 381 # Note that the results.html template file won't exist when we're using a MockFileSystem during unit tests, |
378 # so make sure it exists before we try to copy it. | 382 # so make sure it exists before we try to copy it. |
379 if self._filesystem.exists(results_file): | 383 if self._filesystem.exists(results_file): |
380 self._filesystem.copyfile(results_file, destination_path) | 384 self._filesystem.copyfile(results_file, destination_path) |
381 | 385 |
382 def _stats_trie(self, initial_results): | 386 def _stats_trie(self, initial_results): |
383 def _worker_number(worker_name): | 387 def _worker_number(worker_name): |
384 return int(worker_name.split('/')[1]) if worker_name else -1 | 388 return int(worker_name.split('/')[1]) if worker_name else -1 |
385 | 389 |
386 stats = {} | 390 stats = {} |
387 for result in initial_results.results_by_name.values(): | 391 for result in initial_results.results_by_name.values(): |
388 if result.type != test_expectations.SKIP: | 392 if result.type != test_expectations.SKIP: |
389 stats[result.test_name] = {'results': (_worker_number(result.wor ker_name), result.test_number, result.pid, int(result.test_run_time * 1000), int (result.total_run_time * 1000))} | 393 stats[result.test_name] = {'results': (_worker_number(result.wor ker_name), result.test_number, result.pid, int(result.test_run_time * 1000), int (result.total_run_time * 1000))} |
390 stats_trie = {} | 394 stats_trie = {} |
391 for name, value in stats.iteritems(): | 395 for name, value in stats.iteritems(): |
392 json_results_generator.add_path_to_trie(name, value, stats_trie) | 396 json_results_generator.add_path_to_trie(name, value, stats_trie) |
393 return stats_trie | 397 return stats_trie |
OLD | NEW |