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

Side by Side Diff: Tools/Scripts/webkitpy/layout_tests/port/base.py

Issue 546133003: Reformat webkitpy.layout_tests w/ format-webkitpy. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 3 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 | Annotate | Revision Log
OLDNEW
1 # Copyright (C) 2010 Google Inc. All rights reserved. 1 # Copyright (C) 2010 Google Inc. All rights reserved.
2 # 2 #
3 # Redistribution and use in source and binary forms, with or without 3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are 4 # modification, are permitted provided that the following conditions are
5 # met: 5 # met:
6 # 6 #
7 # * Redistributions of source code must retain the above copyright 7 # * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer. 8 # notice, this list of conditions and the following disclaimer.
9 # * Redistributions in binary form must reproduce the above 9 # * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer 10 # copyright notice, this list of conditions and the following disclaimer
(...skipping 21 matching lines...) Expand all
32 import cgi 32 import cgi
33 import difflib 33 import difflib
34 import errno 34 import errno
35 import itertools 35 import itertools
36 import logging 36 import logging
37 import os 37 import os
38 import operator 38 import operator
39 import optparse 39 import optparse
40 import re 40 import re
41 import sys 41 import sys
42 from functools import reduce
42 43
43 try: 44 try:
44 from collections import OrderedDict 45 from collections import OrderedDict
45 except ImportError: 46 except ImportError:
46 # Needed for Python < 2.7 47 # Needed for Python < 2.7
47 from webkitpy.thirdparty.ordered_dict import OrderedDict 48 from webkitpy.thirdparty.ordered_dict import OrderedDict
48 49
49 50
50 from webkitpy.common import find_files 51 from webkitpy.common import find_files
51 from webkitpy.common import read_checksum_from_png 52 from webkitpy.common import read_checksum_from_png
(...skipping 11 matching lines...) Expand all
63 from webkitpy.layout_tests.port import server_process 64 from webkitpy.layout_tests.port import server_process
64 from webkitpy.layout_tests.port.factory import PortFactory 65 from webkitpy.layout_tests.port.factory import PortFactory
65 from webkitpy.layout_tests.servers import apache_http 66 from webkitpy.layout_tests.servers import apache_http
66 from webkitpy.layout_tests.servers import pywebsocket 67 from webkitpy.layout_tests.servers import pywebsocket
67 68
68 _log = logging.getLogger(__name__) 69 _log = logging.getLogger(__name__)
69 70
70 71
71 # FIXME: This class should merge with WebKitPort now that Chromium behaves mostl y like other webkit ports. 72 # FIXME: This class should merge with WebKitPort now that Chromium behaves mostl y like other webkit ports.
72 class Port(object): 73 class Port(object):
74
73 """Abstract class for Port-specific hooks for the layout_test package.""" 75 """Abstract class for Port-specific hooks for the layout_test package."""
74 76
75 # Subclasses override this. This should indicate the basic implementation 77 # Subclasses override this. This should indicate the basic implementation
76 # part of the port name, e.g., 'mac', 'win', 'gtk'; there is probably (?) 78 # part of the port name, e.g., 'mac', 'win', 'gtk'; there is probably (?)
77 # one unique value per class. 79 # one unique value per class.
78 80
79 # FIXME: We should probably rename this to something like 'implementation_na me'. 81 # FIXME: We should probably rename this to something like 'implementation_na me'.
80 port_name = None 82 port_name = None
81 83
82 # Test names resemble unix relative paths, and use '/' as a directory separa tor. 84 # Test names resemble unix relative paths, and use '/' as a directory separa tor.
(...skipping 17 matching lines...) Expand all
100 102
101 ('mountainlion', 'x86'), 103 ('mountainlion', 'x86'),
102 ('mavericks', 'x86'), 104 ('mavericks', 'x86'),
103 ('xp', 'x86'), 105 ('xp', 'x86'),
104 ('win7', 'x86'), 106 ('win7', 'x86'),
105 ('lucid', 'x86'), 107 ('lucid', 'x86'),
106 ('lucid', 'x86_64'), 108 ('lucid', 'x86_64'),
107 # FIXME: Technically this should be 'arm', but adding a third architectu re type breaks TestConfigurationConverter. 109 # FIXME: Technically this should be 'arm', but adding a third architectu re type breaks TestConfigurationConverter.
108 # If we need this to be 'arm' in the future, then we first have to fix T estConfigurationConverter. 110 # If we need this to be 'arm' in the future, then we first have to fix T estConfigurationConverter.
109 ('icecreamsandwich', 'x86'), 111 ('icecreamsandwich', 'x86'),
110 ) 112 )
111 113
112 ALL_BASELINE_VARIANTS = [ 114 ALL_BASELINE_VARIANTS = [
113 'mac-mavericks', 'mac-mountainlion', 'mac-retina', 'mac-lion', 'mac-snow leopard', 115 'mac-mavericks', 'mac-mountainlion', 'mac-retina', 'mac-lion', 'mac-snow leopard',
114 'win-win7', 'win-xp', 116 'win-win7', 'win-xp',
115 'linux-x86_64', 'linux-x86', 117 'linux-x86_64', 'linux-x86',
116 ] 118 ]
117 119
118 CONFIGURATION_SPECIFIER_MACROS = { 120 CONFIGURATION_SPECIFIER_MACROS = {
119 'mac': ['snowleopard', 'lion', 'retina', 'mountainlion', 'mavericks'], 121 'mac': ['snowleopard', 'lion', 'retina', 'mountainlion', 'mavericks'],
120 'win': ['xp', 'win7'], 122 'win': ['xp', 'win7'],
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 # wdiff, assume it's not available. This will leak one 202 # wdiff, assume it's not available. This will leak one
201 # file descriptor but that's better than leaking each time 203 # file descriptor but that's better than leaking each time
202 # wdiff would be run. 204 # wdiff would be run.
203 # 205 #
204 # http://mail.python.org/pipermail/python-list/ 206 # http://mail.python.org/pipermail/python-list/
205 # 2008-August/505753.html 207 # 2008-August/505753.html
206 # http://bugs.python.org/issue3210 208 # http://bugs.python.org/issue3210
207 self._wdiff_available = None 209 self._wdiff_available = None
208 210
209 # FIXME: prettypatch.py knows this path, why is it copied here? 211 # FIXME: prettypatch.py knows this path, why is it copied here?
210 self._pretty_patch_path = self.path_from_webkit_base("Tools", "Scripts", "webkitruby", "PrettyPatch", "prettify.rb") 212 self._pretty_patch_path = self.path_from_webkit_base('Tools', 'Scripts', 'webkitruby', 'PrettyPatch', 'prettify.rb')
211 self._pretty_patch_available = None 213 self._pretty_patch_available = None
212 214
213 if not hasattr(options, 'configuration') or not options.configuration: 215 if not hasattr(options, 'configuration') or not options.configuration:
214 self.set_option_default('configuration', self.default_configuration( )) 216 self.set_option_default('configuration', self.default_configuration( ))
215 self._test_configuration = None 217 self._test_configuration = None
216 self._reftest_list = {} 218 self._reftest_list = {}
217 self._results_directory = None 219 self._results_directory = None
218 220
219 def buildbot_archives_baselines(self): 221 def buildbot_archives_baselines(self):
220 return True 222 return True
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
351 result = self._dump_reader.check_is_functional() and result 353 result = self._dump_reader.check_is_functional() and result
352 354
353 if needs_http: 355 if needs_http:
354 result = self.check_httpd() and result 356 result = self.check_httpd() and result
355 357
356 return test_run_results.OK_EXIT_STATUS if result else test_run_results.U NEXPECTED_ERROR_EXIT_STATUS 358 return test_run_results.OK_EXIT_STATUS if result else test_run_results.U NEXPECTED_ERROR_EXIT_STATUS
357 359
358 def _check_driver(self): 360 def _check_driver(self):
359 driver_path = self._path_to_driver() 361 driver_path = self._path_to_driver()
360 if not self._filesystem.exists(driver_path): 362 if not self._filesystem.exists(driver_path):
361 _log.error("%s was not found at %s" % (self.driver_name(), driver_pa th)) 363 _log.error('%s was not found at %s' % (self.driver_name(), driver_pa th))
362 return False 364 return False
363 return True 365 return True
364 366
365 def _check_port_build(self): 367 def _check_port_build(self):
366 # Ports can override this method to do additional checks. 368 # Ports can override this method to do additional checks.
367 return True 369 return True
368 370
369 def check_sys_deps(self, needs_http): 371 def check_sys_deps(self, needs_http):
370 """If the port needs to do some runtime checks to ensure that the 372 """If the port needs to do some runtime checks to ensure that the
371 tests can be run successfully, it should override this routine. 373 tests can be run successfully, it should override this routine.
(...skipping 17 matching lines...) Expand all
389 _log.error('') 391 _log.error('')
390 _log.error('For complete build requirements, please see:') 392 _log.error('For complete build requirements, please see:')
391 _log.error(self.BUILD_REQUIREMENTS_URL) 393 _log.error(self.BUILD_REQUIREMENTS_URL)
392 return test_run_results.SYS_DEPS_EXIT_STATUS 394 return test_run_results.SYS_DEPS_EXIT_STATUS
393 return test_run_results.OK_EXIT_STATUS 395 return test_run_results.OK_EXIT_STATUS
394 396
395 def check_image_diff(self, override_step=None, logging=True): 397 def check_image_diff(self, override_step=None, logging=True):
396 """This routine is used to check whether image_diff binary exists.""" 398 """This routine is used to check whether image_diff binary exists."""
397 image_diff_path = self._path_to_image_diff() 399 image_diff_path = self._path_to_image_diff()
398 if not self._filesystem.exists(image_diff_path): 400 if not self._filesystem.exists(image_diff_path):
399 _log.error("image_diff was not found at %s" % image_diff_path) 401 _log.error('image_diff was not found at %s' % image_diff_path)
400 return False 402 return False
401 return True 403 return True
402 404
403 def check_pretty_patch(self, logging=True): 405 def check_pretty_patch(self, logging=True):
404 """Checks whether we can use the PrettyPatch ruby script.""" 406 """Checks whether we can use the PrettyPatch ruby script."""
405 try: 407 try:
406 _ = self._executive.run_command(['ruby', '--version']) 408 _ = self._executive.run_command(['ruby', '--version'])
407 except OSError, e: 409 except OSError as e:
408 if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]: 410 if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]:
409 if logging: 411 if logging:
410 _log.warning("Ruby is not installed; can't generate pretty p atches.") 412 _log.warning("Ruby is not installed; can't generate pretty p atches.")
411 _log.warning('') 413 _log.warning('')
412 return False 414 return False
413 415
414 if not self._filesystem.exists(self._pretty_patch_path): 416 if not self._filesystem.exists(self._pretty_patch_path):
415 if logging: 417 if logging:
416 _log.warning("Unable to find %s; can't generate pretty patches." % self._pretty_patch_path) 418 _log.warning("Unable to find %s; can't generate pretty patches." % self._pretty_patch_path)
417 _log.warning('') 419 _log.warning('')
(...skipping 20 matching lines...) Expand all
438 return True 440 return True
439 441
440 def _wdiff_missing_message(self): 442 def _wdiff_missing_message(self):
441 return 'wdiff is not installed; please install it to generate word-by-wo rd diffs.' 443 return 'wdiff is not installed; please install it to generate word-by-wo rd diffs.'
442 444
443 def check_httpd(self): 445 def check_httpd(self):
444 httpd_path = self.path_to_apache() 446 httpd_path = self.path_to_apache()
445 try: 447 try:
446 server_name = self._filesystem.basename(httpd_path) 448 server_name = self._filesystem.basename(httpd_path)
447 env = self.setup_environ_for_server(server_name) 449 env = self.setup_environ_for_server(server_name)
448 if self._executive.run_command([httpd_path, "-v"], env=env, return_e xit_code=True) != 0: 450 if self._executive.run_command([httpd_path, '-v'], env=env, return_e xit_code=True) != 0:
449 _log.error("httpd seems broken. Cannot run http tests.") 451 _log.error('httpd seems broken. Cannot run http tests.')
450 return False 452 return False
451 return True 453 return True
452 except OSError: 454 except OSError:
453 _log.error("No httpd found. Cannot run http tests.") 455 _log.error('No httpd found. Cannot run http tests.')
454 return False 456 return False
455 457
456 def do_text_results_differ(self, expected_text, actual_text): 458 def do_text_results_differ(self, expected_text, actual_text):
457 return expected_text != actual_text 459 return expected_text != actual_text
458 460
459 def do_audio_results_differ(self, expected_audio, actual_audio): 461 def do_audio_results_differ(self, expected_audio, actual_audio):
460 return expected_audio != actual_audio 462 return expected_audio != actual_audio
461 463
462 def diff_image(self, expected_contents, actual_contents): 464 def diff_image(self, expected_contents, actual_contents):
463 """Compare two images and return a tuple of an image diff, and an error string. 465 """Compare two images and return a tuple of an image diff, and an error string.
464 466
465 If an error occurs (like image_diff isn't found, or crashes, we log an e rror and return True (for a diff). 467 If an error occurs (like image_diff isn't found, or crashes, we log an e rror and return True (for a diff).
466 """ 468 """
467 # If only one of them exists, return that one. 469 # If only one of them exists, return that one.
468 if not actual_contents and not expected_contents: 470 if not actual_contents and not expected_contents:
469 return (None, None) 471 return (None, None)
470 if not actual_contents: 472 if not actual_contents:
471 return (expected_contents, None) 473 return (expected_contents, None)
472 if not expected_contents: 474 if not expected_contents:
473 return (actual_contents, None) 475 return (actual_contents, None)
474 476
475 tempdir = self._filesystem.mkdtemp() 477 tempdir = self._filesystem.mkdtemp()
476 478
477 expected_filename = self._filesystem.join(str(tempdir), "expected.png") 479 expected_filename = self._filesystem.join(str(tempdir), 'expected.png')
478 self._filesystem.write_binary_file(expected_filename, expected_contents) 480 self._filesystem.write_binary_file(expected_filename, expected_contents)
479 481
480 actual_filename = self._filesystem.join(str(tempdir), "actual.png") 482 actual_filename = self._filesystem.join(str(tempdir), 'actual.png')
481 self._filesystem.write_binary_file(actual_filename, actual_contents) 483 self._filesystem.write_binary_file(actual_filename, actual_contents)
482 484
483 diff_filename = self._filesystem.join(str(tempdir), "diff.png") 485 diff_filename = self._filesystem.join(str(tempdir), 'diff.png')
484 486
485 # image_diff needs native win paths as arguments, so we need to convert them if running under cygwin. 487 # image_diff needs native win paths as arguments, so we need to convert them if running under cygwin.
486 native_expected_filename = self._convert_path(expected_filename) 488 native_expected_filename = self._convert_path(expected_filename)
487 native_actual_filename = self._convert_path(actual_filename) 489 native_actual_filename = self._convert_path(actual_filename)
488 native_diff_filename = self._convert_path(diff_filename) 490 native_diff_filename = self._convert_path(diff_filename)
489 491
490 executable = self._path_to_image_diff() 492 executable = self._path_to_image_diff()
491 # Note that although we are handed 'old', 'new', image_diff wants 'new', 'old'. 493 # Note that although we are handed 'old', 'new', image_diff wants 'new', 'old'.
492 comand = [executable, '--diff', native_actual_filename, native_expected_ filename, native_diff_filename] 494 comand = [executable, '--diff', native_actual_filename, native_expected_ filename, native_diff_filename]
493 495
494 result = None 496 result = None
495 err_str = None 497 err_str = None
496 try: 498 try:
497 exit_code = self._executive.run_command(comand, return_exit_code=Tru e) 499 exit_code = self._executive.run_command(comand, return_exit_code=Tru e)
498 if exit_code == 0: 500 if exit_code == 0:
499 # The images are the same. 501 # The images are the same.
500 result = None 502 result = None
501 elif exit_code == 1: 503 elif exit_code == 1:
502 result = self._filesystem.read_binary_file(native_diff_filename) 504 result = self._filesystem.read_binary_file(native_diff_filename)
503 else: 505 else:
504 err_str = "Image diff returned an exit code of %s. See http://cr bug.com/278596" % exit_code 506 err_str = 'Image diff returned an exit code of %s. See http://cr bug.com/278596' % exit_code
505 except OSError, e: 507 except OSError as e:
506 err_str = 'error running image diff: %s' % str(e) 508 err_str = 'error running image diff: %s' % str(e)
507 finally: 509 finally:
508 self._filesystem.rmtree(str(tempdir)) 510 self._filesystem.rmtree(str(tempdir))
509 511
510 return (result, err_str or None) 512 return (result, err_str or None)
511 513
512 def diff_text(self, expected_text, actual_text, expected_filename, actual_fi lename): 514 def diff_text(self, expected_text, actual_text, expected_filename, actual_fi lename):
513 """Returns a string containing the diff of the two text strings 515 """Returns a string containing the diff of the two text strings
514 in 'unified diff' format.""" 516 in 'unified diff' format."""
515 517
(...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after
674 """Returns the text output we expect the test to produce, or None 676 """Returns the text output we expect the test to produce, or None
675 if we don't expect there to be any text output. 677 if we don't expect there to be any text output.
676 End-of-line characters are normalized to '\n'.""" 678 End-of-line characters are normalized to '\n'."""
677 # FIXME: DRT output is actually utf-8, but since we don't decode the 679 # FIXME: DRT output is actually utf-8, but since we don't decode the
678 # output from DRT (instead treating it as a binary string), we read the 680 # output from DRT (instead treating it as a binary string), we read the
679 # baselines as a binary string, too. 681 # baselines as a binary string, too.
680 baseline_path = self.expected_filename(test_name, '.txt') 682 baseline_path = self.expected_filename(test_name, '.txt')
681 if not self._filesystem.exists(baseline_path): 683 if not self._filesystem.exists(baseline_path):
682 return None 684 return None
683 text = self._filesystem.read_binary_file(baseline_path) 685 text = self._filesystem.read_binary_file(baseline_path)
684 return text.replace("\r\n", "\n") 686 return text.replace('\r\n', '\n')
685 687
686 def _get_reftest_list(self, test_name): 688 def _get_reftest_list(self, test_name):
687 dirname = self._filesystem.join(self.layout_tests_dir(), self._filesyste m.dirname(test_name)) 689 dirname = self._filesystem.join(self.layout_tests_dir(), self._filesyste m.dirname(test_name))
688 if dirname not in self._reftest_list: 690 if dirname not in self._reftest_list:
689 self._reftest_list[dirname] = Port._parse_reftest_list(self._filesys tem, dirname) 691 self._reftest_list[dirname] = Port._parse_reftest_list(self._filesys tem, dirname)
690 return self._reftest_list[dirname] 692 return self._reftest_list[dirname]
691 693
692 @staticmethod 694 @staticmethod
693 def _parse_reftest_list(filesystem, test_dirpath): 695 def _parse_reftest_list(filesystem, test_dirpath):
694 reftest_list_path = filesystem.join(test_dirpath, 'reftest.list') 696 reftest_list_path = filesystem.join(test_dirpath, 'reftest.list')
695 if not filesystem.isfile(reftest_list_path): 697 if not filesystem.isfile(reftest_list_path):
696 return None 698 return None
697 reftest_list_file = filesystem.read_text_file(reftest_list_path) 699 reftest_list_file = filesystem.read_text_file(reftest_list_path)
698 700
699 parsed_list = {} 701 parsed_list = {}
700 for line in reftest_list_file.split('\n'): 702 for line in reftest_list_file.split('\n'):
701 line = re.sub('#.+$', '', line) 703 line = re.sub('#.+$', '', line)
702 split_line = line.split() 704 split_line = line.split()
703 if len(split_line) == 4: 705 if len(split_line) == 4:
704 # FIXME: Probably one of mozilla's extensions in the reftest.lis t format. Do we need to support this? 706 # FIXME: Probably one of mozilla's extensions in the reftest.lis t format. Do we need to support this?
705 _log.warning("unsupported reftest.list line '%s' in %s" % (line, reftest_list_path)) 707 _log.warning("unsupported reftest.list line '%s' in %s" % (line, reftest_list_path))
706 continue 708 continue
707 if len(split_line) < 3: 709 if len(split_line) < 3:
708 continue 710 continue
709 expectation_type, test_file, ref_file = split_line 711 expectation_type, test_file, ref_file = split_line
710 parsed_list.setdefault(filesystem.join(test_dirpath, test_file), []) .append((expectation_type, filesystem.join(test_dirpath, ref_file))) 712 parsed_list.setdefault(
713 filesystem.join(
714 test_dirpath,
715 test_file),
716 []).append(
717 (expectation_type,
718 filesystem.join(
719 test_dirpath,
720 ref_file)))
711 return parsed_list 721 return parsed_list
712 722
713 def reference_files(self, test_name): 723 def reference_files(self, test_name):
714 """Return a list of expectation (== or !=) and filename pairs""" 724 """Return a list of expectation (== or !=) and filename pairs"""
715 725
716 reftest_list = self._get_reftest_list(test_name) 726 reftest_list = self._get_reftest_list(test_name)
717 if not reftest_list: 727 if not reftest_list:
718 reftest_list = [] 728 reftest_list = []
719 for expectation, prefix in (('==', ''), ('!=', '-mismatch')): 729 for expectation, prefix in (('==', ''), ('!=', '-mismatch')):
720 for extention in Port._supported_file_extensions: 730 for extention in Port._supported_file_extensions:
721 path = self.expected_filename(test_name, prefix + extention) 731 path = self.expected_filename(test_name, prefix + extention)
722 if self._filesystem.exists(path): 732 if self._filesystem.exists(path):
723 reftest_list.append((expectation, path)) 733 reftest_list.append((expectation, path))
724 return reftest_list 734 return reftest_list
725 735
726 return reftest_list.get(self._filesystem.join(self.layout_tests_dir(), t est_name), []) # pylint: disable=E1103 736 return reftest_list.get(self._filesystem.join(self.layout_tests_dir(), t est_name), []) # pylint: disable=E1103
727 737
728 def tests(self, paths): 738 def tests(self, paths):
729 """Return the list of tests found matching paths.""" 739 """Return the list of tests found matching paths."""
730 tests = self._real_tests(paths) 740 tests = self._real_tests(paths)
731 tests.extend(self._virtual_tests(paths, self.populated_virtual_test_suit es())) 741 tests.extend(self._virtual_tests(paths, self.populated_virtual_test_suit es()))
732 return tests 742 return tests
733 743
734 def _real_tests(self, paths): 744 def _real_tests(self, paths):
735 # When collecting test cases, skip these directories 745 # When collecting test cases, skip these directories
736 skipped_directories = set(['.svn', '_svn', 'platform', 'resources', 'sup port', 'script-tests', 'reference', 'reftest']) 746 skipped_directories = set(['.svn', '_svn', 'platform', 'resources', 'sup port', 'script-tests', 'reference', 'reftest'])
737 files = find_files.find(self._filesystem, self.layout_tests_dir(), paths , skipped_directories, Port.is_test_file, self.test_key) 747 files = find_files.find(
748 self._filesystem,
749 self.layout_tests_dir(),
750 paths,
751 skipped_directories,
752 Port.is_test_file,
753 self.test_key)
738 return [self.relative_test_filename(f) for f in files] 754 return [self.relative_test_filename(f) for f in files]
739 755
740 # When collecting test cases, we include any file with these extensions. 756 # When collecting test cases, we include any file with these extensions.
741 _supported_file_extensions = set(['.html', '.xml', '.xhtml', '.xht', '.pl', 757 _supported_file_extensions = set(['.html', '.xml', '.xhtml', '.xht', '.pl',
742 '.htm', '.php', '.svg', '.mht', '.pdf']) 758 '.htm', '.php', '.svg', '.mht', '.pdf'])
743 759
744 @staticmethod 760 @staticmethod
745 # If any changes are made here be sure to update the isUsedInReftest method in old-run-webkit-tests as well. 761 # If any changes are made here be sure to update the isUsedInReftest method in old-run-webkit-tests as well.
746 def is_reference_html_file(filesystem, dirname, filename): 762 def is_reference_html_file(filesystem, dirname, filename):
747 if filename.startswith('ref-') or filename.startswith('notref-'): 763 if filename.startswith('ref-') or filename.startswith('notref-'):
748 return True 764 return True
749 filename_wihout_ext, unused = filesystem.splitext(filename) 765 filename_wihout_ext, unused = filesystem.splitext(filename)
750 for suffix in ['-expected', '-expected-mismatch', '-ref', '-notref']: 766 for suffix in ['-expected', '-expected-mismatch', '-ref', '-notref']:
751 if filename_wihout_ext.endswith(suffix): 767 if filename_wihout_ext.endswith(suffix):
752 return True 768 return True
753 return False 769 return False
754 770
755 @staticmethod 771 @staticmethod
756 def _has_supported_extension(filesystem, filename): 772 def _has_supported_extension(filesystem, filename):
757 """Return true if filename is one of the file extensions we want to run a test on.""" 773 """Return true if filename is one of the file extensions we want to run a test on."""
758 extension = filesystem.splitext(filename)[1] 774 extension = filesystem.splitext(filename)[1]
759 return extension in Port._supported_file_extensions 775 return extension in Port._supported_file_extensions
760 776
761 @staticmethod 777 @staticmethod
762 def is_test_file(filesystem, dirname, filename): 778 def is_test_file(filesystem, dirname, filename):
763 return Port._has_supported_extension(filesystem, filename) and not Port. is_reference_html_file(filesystem, dirname, filename) 779 return Port._has_supported_extension(
780 filesystem, filename) and not Port.is_reference_html_file(filesystem , dirname, filename)
764 781
765 ALL_TEST_TYPES = ['audio', 'harness', 'pixel', 'ref', 'text', 'unknown'] 782 ALL_TEST_TYPES = ['audio', 'harness', 'pixel', 'ref', 'text', 'unknown']
766 783
767 def test_type(self, test_name): 784 def test_type(self, test_name):
768 fs = self._filesystem 785 fs = self._filesystem
769 if fs.exists(self.expected_filename(test_name, '.png')): 786 if fs.exists(self.expected_filename(test_name, '.png')):
770 return 'pixel' 787 return 'pixel'
771 if fs.exists(self.expected_filename(test_name, '.wav')): 788 if fs.exists(self.expected_filename(test_name, '.wav')):
772 return 'audio' 789 return 'audio'
773 if self.reference_files(test_name): 790 if self.reference_files(test_name):
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
898 line = line.strip() 915 line = line.strip()
899 line = line.rstrip('/') # Best to normalize directory names to not include the trailing slash. 916 line = line.rstrip('/') # Best to normalize directory names to not include the trailing slash.
900 if line.startswith('#') or not len(line): 917 if line.startswith('#') or not len(line):
901 continue 918 continue
902 tests_to_skip.append(line) 919 tests_to_skip.append(line)
903 return tests_to_skip 920 return tests_to_skip
904 921
905 def _expectations_from_skipped_files(self, skipped_file_paths): 922 def _expectations_from_skipped_files(self, skipped_file_paths):
906 tests_to_skip = [] 923 tests_to_skip = []
907 for search_path in skipped_file_paths: 924 for search_path in skipped_file_paths:
908 filename = self._filesystem.join(self._webkit_baseline_path(search_p ath), "Skipped") 925 filename = self._filesystem.join(self._webkit_baseline_path(search_p ath), 'Skipped')
909 if not self._filesystem.exists(filename): 926 if not self._filesystem.exists(filename):
910 _log.debug("Skipped does not exist: %s" % filename) 927 _log.debug('Skipped does not exist: %s' % filename)
911 continue 928 continue
912 _log.debug("Using Skipped file: %s" % filename) 929 _log.debug('Using Skipped file: %s' % filename)
913 skipped_file_contents = self._filesystem.read_text_file(filename) 930 skipped_file_contents = self._filesystem.read_text_file(filename)
914 tests_to_skip.extend(self._tests_from_skipped_file_contents(skipped_ file_contents)) 931 tests_to_skip.extend(self._tests_from_skipped_file_contents(skipped_ file_contents))
915 return tests_to_skip 932 return tests_to_skip
916 933
917 @memoized 934 @memoized
918 def skipped_perf_tests(self): 935 def skipped_perf_tests(self):
919 return self._expectations_from_skipped_files([self.perf_tests_dir()]) 936 return self._expectations_from_skipped_files([self.perf_tests_dir()])
920 937
921 def skips_perf_test(self, test_name): 938 def skips_perf_test(self, test_name):
922 for test_or_category in self.skipped_perf_tests(): 939 for test_or_category in self.skipped_perf_tests():
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
992 try: 1009 try:
993 return self.path_from_chromium_base('webkit', self.get_option('confi guration'), 'layout-test-results') 1010 return self.path_from_chromium_base('webkit', self.get_option('confi guration'), 'layout-test-results')
994 except AssertionError: 1011 except AssertionError:
995 return self._build_path('layout-test-results') 1012 return self._build_path('layout-test-results')
996 1013
997 def setup_test_run(self): 1014 def setup_test_run(self):
998 """Perform port-specific work at the beginning of a test run.""" 1015 """Perform port-specific work at the beginning of a test run."""
999 # Delete the disk cache if any to ensure a clean test run. 1016 # Delete the disk cache if any to ensure a clean test run.
1000 dump_render_tree_binary_path = self._path_to_driver() 1017 dump_render_tree_binary_path = self._path_to_driver()
1001 cachedir = self._filesystem.dirname(dump_render_tree_binary_path) 1018 cachedir = self._filesystem.dirname(dump_render_tree_binary_path)
1002 cachedir = self._filesystem.join(cachedir, "cache") 1019 cachedir = self._filesystem.join(cachedir, 'cache')
1003 if self._filesystem.exists(cachedir): 1020 if self._filesystem.exists(cachedir):
1004 self._filesystem.rmtree(cachedir) 1021 self._filesystem.rmtree(cachedir)
1005 1022
1006 if self._dump_reader: 1023 if self._dump_reader:
1007 self._filesystem.maybe_make_directory(self._dump_reader.crash_dumps_ directory()) 1024 self._filesystem.maybe_make_directory(self._dump_reader.crash_dumps_ directory())
1008 1025
1009 def num_workers(self, requested_num_workers): 1026 def num_workers(self, requested_num_workers):
1010 """Returns the number of available workers (possibly less than the numbe r requested).""" 1027 """Returns the number of available workers (possibly less than the numbe r requested)."""
1011 return requested_num_workers 1028 return requested_num_workers
1012 1029
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 def create_driver(self, worker_number, no_timeout=False): 1103 def create_driver(self, worker_number, no_timeout=False):
1087 """Return a newly created Driver subclass for starting/stopping the test driver.""" 1104 """Return a newly created Driver subclass for starting/stopping the test driver."""
1088 return self._driver_class()(self, worker_number, pixel_tests=self.get_op tion('pixel_tests'), no_timeout=no_timeout) 1105 return self._driver_class()(self, worker_number, pixel_tests=self.get_op tion('pixel_tests'), no_timeout=no_timeout)
1089 1106
1090 def start_helper(self): 1107 def start_helper(self):
1091 """If a port needs to reconfigure graphics settings or do other 1108 """If a port needs to reconfigure graphics settings or do other
1092 things to ensure a known test configuration, it should override this 1109 things to ensure a known test configuration, it should override this
1093 method.""" 1110 method."""
1094 helper_path = self._path_to_helper() 1111 helper_path = self._path_to_helper()
1095 if helper_path: 1112 if helper_path:
1096 _log.debug("Starting layout helper %s" % helper_path) 1113 _log.debug('Starting layout helper %s' % helper_path)
1097 # Note: Not thread safe: http://bugs.python.org/issue2320 1114 # Note: Not thread safe: http://bugs.python.org/issue2320
1098 self._helper = self._executive.popen([helper_path], 1115 self._helper = self._executive.popen([helper_path],
1099 stdin=self._executive.PIPE, stdout=self._executive.PIPE, stderr= None) 1116 stdin=self._executive.PIPE, std out=self._executive.PIPE, stderr=None)
1100 is_ready = self._helper.stdout.readline() 1117 is_ready = self._helper.stdout.readline()
1101 if not is_ready.startswith('ready'): 1118 if not is_ready.startswith('ready'):
1102 _log.error("layout_test_helper failed to be ready") 1119 _log.error('layout_test_helper failed to be ready')
1103 1120
1104 def requires_http_server(self): 1121 def requires_http_server(self):
1105 """Does the port require an HTTP server for running tests? This could 1122 """Does the port require an HTTP server for running tests? This could
1106 be the case when the tests aren't run on the host platform.""" 1123 be the case when the tests aren't run on the host platform."""
1107 return False 1124 return False
1108 1125
1109 def start_http_server(self, additional_dirs, number_of_drivers): 1126 def start_http_server(self, additional_dirs, number_of_drivers):
1110 """Start a web server. Raise an error if it can't start or is already ru nning. 1127 """Start a web server. Raise an error if it can't start or is already ru nning.
1111 1128
1112 Ports can stub this out if they don't need a web server to be running."" " 1129 Ports can stub this out if they don't need a web server to be running."" "
(...skipping 19 matching lines...) Expand all
1132 # Apache < 2.4 on win32 does not support IPv6, nor does cygwin apache. 1149 # Apache < 2.4 on win32 does not support IPv6, nor does cygwin apache.
1133 if self.host.platform.is_cygwin() or self.host.platform.is_win(): 1150 if self.host.platform.is_cygwin() or self.host.platform.is_win():
1134 return False 1151 return False
1135 return True 1152 return True
1136 1153
1137 def stop_helper(self): 1154 def stop_helper(self):
1138 """Shut down the test helper if it is running. Do nothing if 1155 """Shut down the test helper if it is running. Do nothing if
1139 it isn't, or it isn't available. If a port overrides start_helper() 1156 it isn't, or it isn't available. If a port overrides start_helper()
1140 it must override this routine as well.""" 1157 it must override this routine as well."""
1141 if self._helper: 1158 if self._helper:
1142 _log.debug("Stopping layout test helper") 1159 _log.debug('Stopping layout test helper')
1143 try: 1160 try:
1144 self._helper.stdin.write("x\n") 1161 self._helper.stdin.write('x\n')
1145 self._helper.stdin.close() 1162 self._helper.stdin.close()
1146 self._helper.wait() 1163 self._helper.wait()
1147 except IOError, e: 1164 except IOError as e:
1148 pass 1165 pass
1149 finally: 1166 finally:
1150 self._helper = None 1167 self._helper = None
1151 1168
1152 def stop_http_server(self): 1169 def stop_http_server(self):
1153 """Shut down the http server if it is running. Do nothing if it isn't."" " 1170 """Shut down the http server if it is running. Do nothing if it isn't."" "
1154 if self._http_server: 1171 if self._http_server:
1155 self._http_server.stop() 1172 self._http_server.stop()
1156 self._http_server = None 1173 self._http_server = None
1157 1174
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1287 """Returns a list of (repository_name, repository_path) tuples of its de pending code base.""" 1304 """Returns a list of (repository_name, repository_path) tuples of its de pending code base."""
1288 return [('blink', self.layout_tests_dir()), 1305 return [('blink', self.layout_tests_dir()),
1289 ('chromium', self.path_from_chromium_base('build'))] 1306 ('chromium', self.path_from_chromium_base('build'))]
1290 1307
1291 _WDIFF_DEL = '##WDIFF_DEL##' 1308 _WDIFF_DEL = '##WDIFF_DEL##'
1292 _WDIFF_ADD = '##WDIFF_ADD##' 1309 _WDIFF_ADD = '##WDIFF_ADD##'
1293 _WDIFF_END = '##WDIFF_END##' 1310 _WDIFF_END = '##WDIFF_END##'
1294 1311
1295 def _format_wdiff_output_as_html(self, wdiff): 1312 def _format_wdiff_output_as_html(self, wdiff):
1296 wdiff = cgi.escape(wdiff) 1313 wdiff = cgi.escape(wdiff)
1297 wdiff = wdiff.replace(self._WDIFF_DEL, "<span class=del>") 1314 wdiff = wdiff.replace(self._WDIFF_DEL, '<span class=del>')
1298 wdiff = wdiff.replace(self._WDIFF_ADD, "<span class=add>") 1315 wdiff = wdiff.replace(self._WDIFF_ADD, '<span class=add>')
1299 wdiff = wdiff.replace(self._WDIFF_END, "</span>") 1316 wdiff = wdiff.replace(self._WDIFF_END, '</span>')
1300 html = "<head><style>.del { background: #faa; } " 1317 html = '<head><style>.del { background: #faa; } '
1301 html += ".add { background: #afa; }</style></head>" 1318 html += '.add { background: #afa; }</style></head>'
1302 html += "<pre>%s</pre>" % wdiff 1319 html += '<pre>%s</pre>' % wdiff
1303 return html 1320 return html
1304 1321
1305 def _wdiff_command(self, actual_filename, expected_filename): 1322 def _wdiff_command(self, actual_filename, expected_filename):
1306 executable = self._path_to_wdiff() 1323 executable = self._path_to_wdiff()
1307 return [executable, 1324 return [executable,
1308 "--start-delete=%s" % self._WDIFF_DEL, 1325 '--start-delete=%s' % self._WDIFF_DEL,
1309 "--end-delete=%s" % self._WDIFF_END, 1326 '--end-delete=%s' % self._WDIFF_END,
1310 "--start-insert=%s" % self._WDIFF_ADD, 1327 '--start-insert=%s' % self._WDIFF_ADD,
1311 "--end-insert=%s" % self._WDIFF_END, 1328 '--end-insert=%s' % self._WDIFF_END,
1312 actual_filename, 1329 actual_filename,
1313 expected_filename] 1330 expected_filename]
1314 1331
1315 @staticmethod 1332 @staticmethod
1316 def _handle_wdiff_error(script_error): 1333 def _handle_wdiff_error(script_error):
1317 # Exit 1 means the files differed, any other exit code is an error. 1334 # Exit 1 means the files differed, any other exit code is an error.
1318 if script_error.exit_code != 1: 1335 if script_error.exit_code != 1:
1319 raise script_error 1336 raise script_error
1320 1337
1321 def _run_wdiff(self, actual_filename, expected_filename): 1338 def _run_wdiff(self, actual_filename, expected_filename):
1322 """Runs wdiff and may throw exceptions. 1339 """Runs wdiff and may throw exceptions.
1323 This is mostly a hook for unit testing.""" 1340 This is mostly a hook for unit testing."""
1324 # Diffs are treated as binary as they may include multiple files 1341 # Diffs are treated as binary as they may include multiple files
1325 # with conflicting encodings. Thus we do not decode the output. 1342 # with conflicting encodings. Thus we do not decode the output.
1326 command = self._wdiff_command(actual_filename, expected_filename) 1343 command = self._wdiff_command(actual_filename, expected_filename)
1327 wdiff = self._executive.run_command(command, decode_output=False, 1344 wdiff = self._executive.run_command(command, decode_output=False,
1328 error_handler=self._handle_wdiff_error) 1345 error_handler=self._handle_wdiff_err or)
1329 return self._format_wdiff_output_as_html(wdiff) 1346 return self._format_wdiff_output_as_html(wdiff)
1330 1347
1331 _wdiff_error_html = "Failed to run wdiff, see error log." 1348 _wdiff_error_html = 'Failed to run wdiff, see error log.'
1332 1349
1333 def wdiff_text(self, actual_filename, expected_filename): 1350 def wdiff_text(self, actual_filename, expected_filename):
1334 """Returns a string of HTML indicating the word-level diff of the 1351 """Returns a string of HTML indicating the word-level diff of the
1335 contents of the two filenames. Returns an empty string if word-level 1352 contents of the two filenames. Returns an empty string if word-level
1336 diffing isn't available.""" 1353 diffing isn't available."""
1337 if not self.wdiff_available(): 1354 if not self.wdiff_available():
1338 return "" 1355 return ''
1339 try: 1356 try:
1340 # It's possible to raise a ScriptError we pass wdiff invalid paths. 1357 # It's possible to raise a ScriptError we pass wdiff invalid paths.
1341 return self._run_wdiff(actual_filename, expected_filename) 1358 return self._run_wdiff(actual_filename, expected_filename)
1342 except OSError as e: 1359 except OSError as e:
1343 if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]: 1360 if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]:
1344 # Silently ignore cases where wdiff is missing. 1361 # Silently ignore cases where wdiff is missing.
1345 self._wdiff_available = False 1362 self._wdiff_available = False
1346 return "" 1363 return ''
1347 raise 1364 raise
1348 except ScriptError as e: 1365 except ScriptError as e:
1349 _log.error("Failed to run wdiff: %s" % e) 1366 _log.error('Failed to run wdiff: %s' % e)
1350 self._wdiff_available = False 1367 self._wdiff_available = False
1351 return self._wdiff_error_html 1368 return self._wdiff_error_html
1352 1369
1353 # This is a class variable so we can test error output easily. 1370 # This is a class variable so we can test error output easily.
1354 _pretty_patch_error_html = "Failed to run PrettyPatch, see error log." 1371 _pretty_patch_error_html = 'Failed to run PrettyPatch, see error log.'
1355 1372
1356 def pretty_patch_text(self, diff_path): 1373 def pretty_patch_text(self, diff_path):
1357 if self._pretty_patch_available is None: 1374 if self._pretty_patch_available is None:
1358 self._pretty_patch_available = self.check_pretty_patch(logging=False ) 1375 self._pretty_patch_available = self.check_pretty_patch(logging=False )
1359 if not self._pretty_patch_available: 1376 if not self._pretty_patch_available:
1360 return self._pretty_patch_error_html 1377 return self._pretty_patch_error_html
1361 command = ("ruby", "-I", self._filesystem.dirname(self._pretty_patch_pat h), 1378 command = ('ruby', '-I', self._filesystem.dirname(self._pretty_patch_pat h),
1362 self._pretty_patch_path, diff_path) 1379 self._pretty_patch_path, diff_path)
1363 try: 1380 try:
1364 # Diffs are treated as binary (we pass decode_output=False) as they 1381 # Diffs are treated as binary (we pass decode_output=False) as they
1365 # may contain multiple files of conflicting encodings. 1382 # may contain multiple files of conflicting encodings.
1366 return self._executive.run_command(command, decode_output=False) 1383 return self._executive.run_command(command, decode_output=False)
1367 except OSError, e: 1384 except OSError as e:
1368 # If the system is missing ruby log the error and stop trying. 1385 # If the system is missing ruby log the error and stop trying.
1369 self._pretty_patch_available = False 1386 self._pretty_patch_available = False
1370 _log.error("Failed to run PrettyPatch (%s): %s" % (command, e)) 1387 _log.error('Failed to run PrettyPatch (%s): %s' % (command, e))
1371 return self._pretty_patch_error_html 1388 return self._pretty_patch_error_html
1372 except ScriptError, e: 1389 except ScriptError as e:
1373 # If ruby failed to run for some reason, log the command 1390 # If ruby failed to run for some reason, log the command
1374 # output and stop trying. 1391 # output and stop trying.
1375 self._pretty_patch_available = False 1392 self._pretty_patch_available = False
1376 _log.error("Failed to run PrettyPatch (%s):\n%s" % (command, e.messa ge_with_output())) 1393 _log.error('Failed to run PrettyPatch (%s):\n%s' % (command, e.messa ge_with_output()))
1377 return self._pretty_patch_error_html 1394 return self._pretty_patch_error_html
1378 1395
1379 def default_configuration(self): 1396 def default_configuration(self):
1380 return self._config.default_configuration() 1397 return self._config.default_configuration()
1381 1398
1382 def clobber_old_port_specific_results(self): 1399 def clobber_old_port_specific_results(self):
1383 pass 1400 pass
1384 1401
1385 # FIXME: This does not belong on the port object. 1402 # FIXME: This does not belong on the port object.
1386 @memoized 1403 @memoized
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1427 # We pass sys_platform into this method to make it easy to unit test. 1444 # We pass sys_platform into this method to make it easy to unit test.
1428 def _apache_config_file_name_for_platform(self, sys_platform): 1445 def _apache_config_file_name_for_platform(self, sys_platform):
1429 if sys_platform == 'cygwin': 1446 if sys_platform == 'cygwin':
1430 return 'cygwin-httpd.conf' # CYGWIN is the only platform to still u se Apache 1.3. 1447 return 'cygwin-httpd.conf' # CYGWIN is the only platform to still u se Apache 1.3.
1431 if sys_platform.startswith('linux'): 1448 if sys_platform.startswith('linux'):
1432 if self._is_redhat_based(): 1449 if self._is_redhat_based():
1433 return 'fedora-httpd-' + self._apache_version() + '.conf' 1450 return 'fedora-httpd-' + self._apache_version() + '.conf'
1434 if self._is_debian_based(): 1451 if self._is_debian_based():
1435 return 'debian-httpd-' + self._apache_version() + '.conf' 1452 return 'debian-httpd-' + self._apache_version() + '.conf'
1436 # All platforms use apache2 except for CYGWIN (and Mac OS X Tiger and pr ior, which we no longer support). 1453 # All platforms use apache2 except for CYGWIN (and Mac OS X Tiger and pr ior, which we no longer support).
1437 return "apache2-httpd.conf" 1454 return 'apache2-httpd.conf'
1438 1455
1439 def _path_to_driver(self, configuration=None): 1456 def _path_to_driver(self, configuration=None):
1440 """Returns the full path to the test driver.""" 1457 """Returns the full path to the test driver."""
1441 return self._build_path(self.driver_name()) 1458 return self._build_path(self.driver_name())
1442 1459
1443 def _path_to_webcore_library(self): 1460 def _path_to_webcore_library(self):
1444 """Returns the full path to a built copy of WebCore.""" 1461 """Returns the full path to a built copy of WebCore."""
1445 return None 1462 return None
1446 1463
1447 def _path_to_helper(self): 1464 def _path_to_helper(self):
1448 """Returns the full path to the layout_test_helper binary, which 1465 """Returns the full path to the layout_test_helper binary, which
1449 is used to help configure the system for the test run, or None 1466 is used to help configure the system for the test run, or None
1450 if no helper is needed. 1467 if no helper is needed.
1451 1468
1452 This is likely only used by start/stop_helper().""" 1469 This is likely only used by start/stop_helper()."""
1453 return None 1470 return None
1454 1471
1455 def _path_to_image_diff(self): 1472 def _path_to_image_diff(self):
1456 """Returns the full path to the image_diff binary, or None if it is not available. 1473 """Returns the full path to the image_diff binary, or None if it is not available.
1457 1474
1458 This is likely used only by diff_image()""" 1475 This is likely used only by diff_image()"""
1459 return self._build_path('image_diff') 1476 return self._build_path('image_diff')
1460 1477
1461 @memoized 1478 @memoized
1462 def _path_to_wdiff(self): 1479 def _path_to_wdiff(self):
1463 """Returns the full path to the wdiff binary, or None if it is not avail able. 1480 """Returns the full path to the wdiff binary, or None if it is not avail able.
1464 1481
1465 This is likely used only by wdiff_text()""" 1482 This is likely used only by wdiff_text()"""
1466 for path in ("/usr/bin/wdiff", "/usr/bin/dwdiff"): 1483 for path in ('/usr/bin/wdiff', '/usr/bin/dwdiff'):
1467 if self._filesystem.exists(path): 1484 if self._filesystem.exists(path):
1468 return path 1485 return path
1469 return None 1486 return None
1470 1487
1471 def _webkit_baseline_path(self, platform): 1488 def _webkit_baseline_path(self, platform):
1472 """Return the full path to the top of the baseline tree for a 1489 """Return the full path to the top of the baseline tree for a
1473 given platform.""" 1490 given platform."""
1474 return self._filesystem.join(self.layout_tests_dir(), 'platform', platfo rm) 1491 return self._filesystem.join(self.layout_tests_dir(), 'platform', platfo rm)
1475 1492
1476 def _driver_class(self): 1493 def _driver_class(self):
(...skipping 11 matching lines...) Expand all
1488 1505
1489 def _get_crash_log(self, name, pid, stdout, stderr, newer_than): 1506 def _get_crash_log(self, name, pid, stdout, stderr, newer_than):
1490 if self._output_contains_sanitizer_messages(stderr): 1507 if self._output_contains_sanitizer_messages(stderr):
1491 # Running the symbolizer script can take a lot of memory, so we need to 1508 # Running the symbolizer script can take a lot of memory, so we need to
1492 # serialize access to it across all the concurrently running drivers . 1509 # serialize access to it across all the concurrently running drivers .
1493 1510
1494 # FIXME: investigate using LLVM_SYMBOLIZER_PATH here to reduce the o verhead. 1511 # FIXME: investigate using LLVM_SYMBOLIZER_PATH here to reduce the o verhead.
1495 sanitizer_filter_path = self.path_from_chromium_base('tools', 'valgr ind', 'asan', 'asan_symbolize.py') 1512 sanitizer_filter_path = self.path_from_chromium_base('tools', 'valgr ind', 'asan', 'asan_symbolize.py')
1496 sanitizer_strip_path_prefix = 'Release/../../' 1513 sanitizer_strip_path_prefix = 'Release/../../'
1497 if self._filesystem.exists(sanitizer_filter_path): 1514 if self._filesystem.exists(sanitizer_filter_path):
1498 stderr = self._executive.run_command(['flock', sys.executable, s anitizer_filter_path, sanitizer_strip_path_prefix], input=stderr, decode_output= False) 1515 stderr = self._executive.run_command(['flock',
1516 sys.executable,
1517 sanitizer_filter_path,
1518 sanitizer_strip_path_prefi x],
1519 input=stderr,
1520 decode_output=False)
1499 1521
1500 name_str = name or '<unknown process name>' 1522 name_str = name or '<unknown process name>'
1501 pid_str = str(pid or '<unknown>') 1523 pid_str = str(pid or '<unknown>')
1502 stdout_lines = (stdout or '<empty>').decode('utf8', 'replace').splitline s() 1524 stdout_lines = (stdout or '<empty>').decode('utf8', 'replace').splitline s()
1503 stderr_lines = (stderr or '<empty>').decode('utf8', 'replace').splitline s() 1525 stderr_lines = (stderr or '<empty>').decode('utf8', 'replace').splitline s()
1504 return (stderr, 'crash log for %s (pid %s):\n%s\n%s\n' % (name_str, pid_ str, 1526 return (stderr, 'crash log for %s (pid %s):\n%s\n%s\n' % (name_str, pid_ str,
1505 '\n'.join(('STDOUT: ' + l) for l in stdout_lines), 1527 '\n'.join(('ST DOUT: ' + l) for l in stdout_lines),
1506 '\n'.join(('STDERR: ' + l) for l in stderr_lines))) 1528 '\n'.join(('ST DERR: ' + l) for l in stderr_lines)))
1507 1529
1508 def look_for_new_crash_logs(self, crashed_processes, start_time): 1530 def look_for_new_crash_logs(self, crashed_processes, start_time):
1509 pass 1531 pass
1510 1532
1511 def look_for_new_samples(self, unresponsive_processes, start_time): 1533 def look_for_new_samples(self, unresponsive_processes, start_time):
1512 pass 1534 pass
1513 1535
1514 def sample_process(self, name, pid): 1536 def sample_process(self, name, pid):
1515 pass 1537 pass
1516 1538
1517 def physical_test_suites(self): 1539 def physical_test_suites(self):
1518 return [ 1540 return [
1519 # For example, to turn on force-compositing-mode in the svg/ directo ry: 1541 # For example, to turn on force-compositing-mode in the svg/ directo ry:
1520 # PhysicalTestSuite('svg', 1542 # PhysicalTestSuite('svg',
1521 # ['--force-compositing-mode']), 1543 # ['--force-compositing-mode']),
1522 ] 1544 ]
1523 1545
1524 def virtual_test_suites(self): 1546 def virtual_test_suites(self):
1525 return [ 1547 return [
1526 VirtualTestSuite('gpu', 1548 VirtualTestSuite('gpu',
1527 'fast/canvas', 1549 'fast/canvas',
1528 ['--enable-accelerated-2d-canvas']), 1550 ['--enable-accelerated-2d-canvas']),
1529 VirtualTestSuite('gpu', 1551 VirtualTestSuite('gpu',
1530 'canvas/philip', 1552 'canvas/philip',
1531 ['--enable-accelerated-2d-canvas']), 1553 ['--enable-accelerated-2d-canvas']),
1532 VirtualTestSuite('threaded', 1554 VirtualTestSuite('threaded',
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
1673 path = self._path_to_webcore_library() 1695 path = self._path_to_webcore_library()
1674 if path: 1696 if path:
1675 return [path] 1697 return [path]
1676 return [] 1698 return []
1677 1699
1678 def _symbols_string(self): 1700 def _symbols_string(self):
1679 symbols = '' 1701 symbols = ''
1680 for path_to_module in self._modules_to_search_for_symbols(): 1702 for path_to_module in self._modules_to_search_for_symbols():
1681 try: 1703 try:
1682 symbols += self._executive.run_command(['nm', path_to_module], e rror_handler=self._executive.ignore_error) 1704 symbols += self._executive.run_command(['nm', path_to_module], e rror_handler=self._executive.ignore_error)
1683 except OSError, e: 1705 except OSError as e:
1684 _log.warn("Failed to run nm: %s. Can't determine supported feat ures correctly." % e) 1706 _log.warn("Failed to run nm: %s. Can't determine supported feat ures correctly." % e)
1685 return symbols 1707 return symbols
1686 1708
1687 # Ports which use compile-time feature detection should define this method a nd return 1709 # Ports which use compile-time feature detection should define this method a nd return
1688 # a dictionary mapping from symbol substrings to possibly disabled test dire ctories. 1710 # a dictionary mapping from symbol substrings to possibly disabled test dire ctories.
1689 # When the symbol substrings are not matched, the directories will be skippe d. 1711 # When the symbol substrings are not matched, the directories will be skippe d.
1690 # If ports don't ever enable certain features, then those directories can ju st be 1712 # If ports don't ever enable certain features, then those directories can ju st be
1691 # in the Skipped list instead of compile-time-checked here. 1713 # in the Skipped list instead of compile-time-checked here.
1692 def _missing_symbol_to_skipped_tests(self): 1714 def _missing_symbol_to_skipped_tests(self):
1693 if self.PORT_HAS_AUDIO_CODECS_BUILT_IN: 1715 if self.PORT_HAS_AUDIO_CODECS_BUILT_IN:
1694 return {} 1716 return {}
1695 else: 1717 else:
1696 return { 1718 return {
1697 "ff_mp3_decoder": ["webaudio/codec-tests/mp3"], 1719 'ff_mp3_decoder': ['webaudio/codec-tests/mp3'],
1698 "ff_aac_decoder": ["webaudio/codec-tests/aac"], 1720 'ff_aac_decoder': ['webaudio/codec-tests/aac'],
1699 } 1721 }
1700 1722
1701 def _has_test_in_directories(self, directory_lists, test_list): 1723 def _has_test_in_directories(self, directory_lists, test_list):
1702 if not test_list: 1724 if not test_list:
1703 return False 1725 return False
1704 1726
1705 directories = itertools.chain.from_iterable(directory_lists) 1727 directories = itertools.chain.from_iterable(directory_lists)
1706 for directory, test in itertools.product(directories, test_list): 1728 for directory, test in itertools.product(directories, test_list):
1707 if test.startswith(directory): 1729 if test.startswith(directory):
1708 return True 1730 return True
1709 return False 1731 return False
1710 1732
1711 def _skipped_tests_for_unsupported_features(self, test_list): 1733 def _skipped_tests_for_unsupported_features(self, test_list):
1712 # Only check the symbols of there are tests in the test_list that might get skipped. 1734 # Only check the symbols of there are tests in the test_list that might get skipped.
1713 # This is a performance optimization to avoid the calling nm. 1735 # This is a performance optimization to avoid the calling nm.
1714 # Runtime feature detection not supported, fallback to static detection: 1736 # Runtime feature detection not supported, fallback to static detection:
1715 # Disable any tests for symbols missing from the executable or libraries . 1737 # Disable any tests for symbols missing from the executable or libraries .
1716 if self._has_test_in_directories(self._missing_symbol_to_skipped_tests() .values(), test_list): 1738 if self._has_test_in_directories(self._missing_symbol_to_skipped_tests() .values(), test_list):
1717 symbols_string = self._symbols_string() 1739 symbols_string = self._symbols_string()
1718 if symbols_string is not None: 1740 if symbols_string is not None:
1719 return reduce(operator.add, [directories for symbol_substring, d irectories in self._missing_symbol_to_skipped_tests().items() if symbol_substrin g not in symbols_string], []) 1741 return reduce(operator.add, [directories for symbol_substring, d irectories in self._missing_symbol_to_skipped_tests(
1742 ).items() if symbol_substring not in symbols_string], [])
1720 return [] 1743 return []
1721 1744
1722 def _convert_path(self, path): 1745 def _convert_path(self, path):
1723 """Handles filename conversion for subprocess command line args.""" 1746 """Handles filename conversion for subprocess command line args."""
1724 # See note above in diff_image() for why we need this. 1747 # See note above in diff_image() for why we need this.
1725 if sys.platform == 'cygwin': 1748 if sys.platform == 'cygwin':
1726 return cygpath(path) 1749 return cygpath(path)
1727 return path 1750 return path
1728 1751
1729 def _build_path(self, *comps): 1752 def _build_path(self, *comps):
1730 return self._build_path_with_configuration(None, *comps) 1753 return self._build_path_with_configuration(None, *comps)
1731 1754
1732 def _build_path_with_configuration(self, configuration, *comps): 1755 def _build_path_with_configuration(self, configuration, *comps):
1733 # Note that we don't do the option caching that the 1756 # Note that we don't do the option caching that the
1734 # base class does, because finding the right directory is relatively 1757 # base class does, because finding the right directory is relatively
1735 # fast. 1758 # fast.
1736 configuration = configuration or self.get_option('configuration') 1759 configuration = configuration or self.get_option('configuration')
1737 return self._static_build_path(self._filesystem, self.get_option('build_ directory'), 1760 return self._static_build_path(self._filesystem, self.get_option('build_ directory'),
1738 self.path_from_chromium_base(), configuration, comps) 1761 self.path_from_chromium_base(), configura tion, comps)
1739 1762
1740 def _check_driver_build_up_to_date(self, configuration): 1763 def _check_driver_build_up_to_date(self, configuration):
1741 if configuration in ('Debug', 'Release'): 1764 if configuration in ('Debug', 'Release'):
1742 try: 1765 try:
1743 debug_path = self._path_to_driver('Debug') 1766 debug_path = self._path_to_driver('Debug')
1744 release_path = self._path_to_driver('Release') 1767 release_path = self._path_to_driver('Release')
1745 1768
1746 debug_mtime = self._filesystem.mtime(debug_path) 1769 debug_mtime = self._filesystem.mtime(debug_path)
1747 release_mtime = self._filesystem.mtime(release_path) 1770 release_mtime = self._filesystem.mtime(release_path)
1748 1771
1749 if (debug_mtime > release_mtime and configuration == 'Release' o r 1772 if (debug_mtime > release_mtime and configuration == 'Release' o r
1750 release_mtime > debug_mtime and configuration == 'Debug'): 1773 release_mtime > debug_mtime and configuration == 'Debug' ):
1751 most_recent_binary = 'Release' if configuration == 'Debug' e lse 'Debug' 1774 most_recent_binary = 'Release' if configuration == 'Debug' e lse 'Debug'
1752 _log.warning('You are running the %s binary. However the %s binary appears to be more recent. ' 1775 _log.warning('You are running the %s binary. However the %s binary appears to be more recent. '
1753 'Please pass --%s.', configuration, most_recent _binary, most_recent_binary.lower()) 1776 'Please pass --%s.', configuration, most_recent _binary, most_recent_binary.lower())
1754 _log.warning('') 1777 _log.warning('')
1755 # This will fail if we don't have both a debug and release binary. 1778 # This will fail if we don't have both a debug and release binary.
1756 # That's fine because, in this case, we must already be running the 1779 # That's fine because, in this case, we must already be running the
1757 # most up-to-date one. 1780 # most up-to-date one.
1758 except OSError: 1781 except OSError:
1759 pass 1782 pass
1760 return True 1783 return True
1761 1784
1762 def _chromium_baseline_path(self, platform): 1785 def _chromium_baseline_path(self, platform):
1763 if platform is None: 1786 if platform is None:
1764 platform = self.name() 1787 platform = self.name()
1765 return self.path_from_webkit_base('LayoutTests', 'platform', platform) 1788 return self.path_from_webkit_base('LayoutTests', 'platform', platform)
1766 1789
1790
1767 class VirtualTestSuite(object): 1791 class VirtualTestSuite(object):
1792
1768 def __init__(self, name, base, args, use_legacy_naming=False, tests=None): 1793 def __init__(self, name, base, args, use_legacy_naming=False, tests=None):
1769 if use_legacy_naming: 1794 if use_legacy_naming:
1770 self.name = 'virtual/' + name 1795 self.name = 'virtual/' + name
1771 else: 1796 else:
1772 if name.find('/') != -1: 1797 if name.find('/') != -1:
1773 _log.error("Virtual test suites names cannot contain /'s: %s" % name) 1798 _log.error("Virtual test suites names cannot contain /'s: %s" % name)
1774 return 1799 return
1775 self.name = 'virtual/' + name + '/' + base 1800 self.name = 'virtual/' + name + '/' + base
1776 self.base = base 1801 self.base = base
1777 self.args = args 1802 self.args = args
1778 self.tests = tests or set() 1803 self.tests = tests or set()
1779 1804
1780 def __repr__(self): 1805 def __repr__(self):
1781 return "VirtualTestSuite('%s', '%s', %s)" % (self.name, self.base, self. args) 1806 return "VirtualTestSuite('%s', '%s', %s)" % (self.name, self.base, self. args)
1782 1807
1783 1808
1784 class PhysicalTestSuite(object): 1809 class PhysicalTestSuite(object):
1810
1785 def __init__(self, base, args): 1811 def __init__(self, base, args):
1786 self.name = base 1812 self.name = base
1787 self.base = base 1813 self.base = base
1788 self.args = args 1814 self.args = args
1789 self.tests = set() 1815 self.tests = set()
1790 1816
1791 def __repr__(self): 1817 def __repr__(self):
1792 return "PhysicalTestSuite('%s', '%s', %s)" % (self.name, self.base, self .args) 1818 return "PhysicalTestSuite('%s', '%s', %s)" % (self.name, self.base, self .args)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698