Changeset 106293 in webkit


Ignore:
Timestamp:
Jan 30, 2012 3:16:08 PM (12 years ago)
Author:
ojan@chromium.org
Message:

Parsing test_expecations.txt + Skipped lists takes too long
https://bugs.webkit.org/show_bug.cgi?id=77059

Reviewed by Dirk Pranke.

This saves ~100ms on the Apple Mac port.
-memoize a bunch of path methods.
-Avoid doing multiple disk accesses per line.
-Parse the skipped list directly instead of turning it into a test_expecations.txt
formatting string and parsing that.

  • Scripts/webkitpy/layout_tests/models/test_expectations.py:

(TestExpectationParser):
(TestExpectationParser.expectation_for_skipped_test):
(TestExpectationParser._parse_line):
(TestExpectationParser._collect_matching_tests):
(TestExpectations.init):
(TestExpectations._add_skipped_tests):

  • Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py:

(test_add_skipped_tests):
(test_add_skipped_tests_duplicate):

  • Scripts/webkitpy/layout_tests/port/base.py:

(Port):
(Port.test_isfile):
(Port.normalize_test_name):
(Port.layout_tests_dir):
(Port.abspath_for_test):

  • Scripts/webkitpy/layout_tests/run_webkit_tests.py:
Location:
trunk/Tools
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/Tools/ChangeLog

    r106282 r106293  
     12012-01-30  Ojan Vafai  <ojan@chromium.org>
     2
     3        Parsing test_expecations.txt + Skipped lists takes too long
     4        https://bugs.webkit.org/show_bug.cgi?id=77059
     5
     6        Reviewed by Dirk Pranke.
     7
     8        This saves ~100ms on the Apple Mac port.
     9        -memoize a bunch of path methods.
     10        -Avoid doing multiple disk accesses per line.
     11        -Parse the skipped list directly instead of turning it into a test_expecations.txt
     12        formatting string and parsing that.
     13
     14        * Scripts/webkitpy/layout_tests/models/test_expectations.py:
     15        (TestExpectationParser):
     16        (TestExpectationParser.expectation_for_skipped_test):
     17        (TestExpectationParser._parse_line):
     18        (TestExpectationParser._collect_matching_tests):
     19        (TestExpectations.__init__):
     20        (TestExpectations._add_skipped_tests):
     21        * Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py:
     22        (test_add_skipped_tests):
     23        (test_add_skipped_tests_duplicate):
     24        * Scripts/webkitpy/layout_tests/port/base.py:
     25        (Port):
     26        (Port.test_isfile):
     27        (Port.normalize_test_name):
     28        (Port.layout_tests_dir):
     29        (Port.abspath_for_test):
     30        * Scripts/webkitpy/layout_tests/run_webkit_tests.py:
     31
    1322012-01-30  Alexis Menard  <alexis.menard@openbossa.org>
    233
  • trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py

    r106058 r106293  
    185185    """Provides parsing facilities for lines in the test_expectation.txt file."""
    186186
     187    DUMMY_BUG_MODIFIER = "bug_dummy"
    187188    BUG_MODIFIER_PREFIX = 'bug'
    188189    BUG_MODIFIER_REGEX = 'bug\d+'
    189190    REBASELINE_MODIFIER = 'rebaseline'
     191    FAIL_EXPECTATION = 'fail'
    190192    SKIP_MODIFIER = 'skip'
    191193    SLOW_MODIFIER = 'slow'
     
    206208        return expectations
    207209
     210    def expectation_for_skipped_test(self, test_name):
     211        expectation_line = TestExpectationLine()
     212        expectation_line.original_string = test_name
     213        expectation_line.modifiers = [TestExpectationParser.DUMMY_BUG_MODIFIER, TestExpectationParser.SKIP_MODIFIER]
     214        expectation_line.name = test_name
     215        expectation_line.expectations = [TestExpectationParser.FAIL_EXPECTATION]
     216        self._parse_line(expectation_line)
     217        return expectation_line
     218
    208219    def _parse_line(self, expectation_line):
    209220        if not expectation_line.name:
     
    211222
    212223        self._check_modifiers_against_expectations(expectation_line)
    213         if self._check_path_does_not_exist(expectation_line):
     224
     225        expectation_line.is_file = self._port.test_isfile(expectation_line.name)
     226        if not expectation_line.is_file and self._check_path_does_not_exist(expectation_line):
    214227            return
    215228
    216         expectation_line.path = self._port.normalize_test_name(expectation_line.name)
     229        if expectation_line.is_file:
     230            expectation_line.path = expectation_line.name
     231        else:
     232            expectation_line.path = self._port.normalize_test_name(expectation_line.name)
     233
    217234        self._collect_matching_tests(expectation_line)
    218235
     
    286303            return
    287304
    288         if self._port.test_isdir(expectation_line.path):
     305        if not expectation_line.is_file:
    289306            # this is a test category, return all the tests of the category.
    290307            expectation_line.matching_tests = [test for test in self._full_test_list if test.startswith(expectation_line.path)]
     
    703720        self._parser = TestExpectationParser(port, tests, is_lint_mode)
    704721        self._port = port
    705         self._test_configuration_converter = TestConfigurationConverter(port.all_test_configurations(), port.configuration_specifier_macros())
    706722        self._skipped_tests_warnings = []
    707723
     
    836852            if test.name and test.name in tests_to_skip:
    837853                self._skipped_tests_warnings.append(':%d %s is also in a Skipped file.' % (index, test.name))
    838         skipped_tests = '\n'.join(map(lambda test_path: 'BUG_SKIPPED SKIP : %s = FAIL' % test_path, tests_to_skip))
    839         for test in self._parser.parse(skipped_tests):
    840             self._model.add_expectation_line(test, overrides_allowed=True)
     854        for test_name in tests_to_skip:
     855            self._model.add_expectation_line(self._parser.expectation_for_skipped_test(test_name), overrides_allowed=True)
  • trunk/Tools/Scripts/webkitpy/layout_tests/models/test_expectations_unittest.py

    r105948 r106293  
    274274        port._filesystem.files[port._filesystem.join(port.layout_tests_dir(), 'platform/qt/Skipped')] = 'failures/expected/text.html'
    275275        port._filesystem.files[port._filesystem.join(port.layout_tests_dir(), 'failures/expected/text.html')] = 'foo'
    276         self.assertRaises(ParseError, TestExpectations, port, 'failures/expected/text.html\n', 'BUGX : failures/expected/text.html = text\n', None, True)
     276        expectations = TestExpectations(port, tests=['failures/expected/text.html'], expectations='', test_config=port.test_configuration())
     277        self.assertEquals(expectations.get_modifiers('failures/expected/text.html'), [TestExpectationParser.DUMMY_BUG_MODIFIER, TestExpectationParser.SKIP_MODIFIER])
     278        self.assertEquals(expectations.get_expectations('failures/expected/text.html'), set([FAIL]))
     279
     280    def test_add_skipped_tests_duplicate(self):
     281        port = MockHost().port_factory.get('qt')
     282        port._filesystem.files[port._filesystem.join(port.layout_tests_dir(), 'platform/qt/Skipped')] = 'failures/expected/text.html'
     283        port._filesystem.files[port._filesystem.join(port.layout_tests_dir(), 'failures/expected/text.html')] = 'foo'
     284        self.assertRaises(ParseError, TestExpectations, port, tests=['failures/expected/text.html'], expectations='BUGX : failures/expected/text.html = text\n', test_config=port.test_configuration(), is_lint_mode=True)
    277285
    278286
  • trunk/Tools/Scripts/webkitpy/layout_tests/port/base.py

    r106058 r106293  
    519519                      self._filesystem.listdir(layout_tests_dir))
    520520
     521    @memoized
     522    def test_isfile(self, test_name):
     523        """Return True if the test name refers to a directory of tests."""
     524        # Used by test_expectations.py to apply rules to whole directories.
     525        test_path = self.abspath_for_test(test_name)
     526        return self._filesystem.isfile(test_path)
     527
     528    @memoized
    521529    def test_isdir(self, test_name):
    522530        """Return True if the test name refers to a directory of tests."""
     
    541549    def normalize_test_name(self, test_name):
    542550        """Returns a normalized version of the test name or test directory."""
    543         if self.test_isdir(test_name) and not test_name.endswith('/'):
     551        if test_name.endswith('/'):
     552            return test_name
     553        if self.test_isdir(test_name):
    544554            return test_name + '/'
    545555        return test_name
     
    561571        self._filesystem.write_binary_file(baseline_path, data)
    562572
     573    @memoized
    563574    def layout_tests_dir(self):
    564575        """Return the absolute path to the top of the LayoutTests directory."""
    565         return self.path_from_webkit_base('LayoutTests')
     576        return self._filesystem.normpath(self.path_from_webkit_base('LayoutTests'))
    566577
    567578    def perf_tests_dir(self):
     
    698709        return filename[len(self.perf_tests_dir()) + 1:]
    699710
     711    @memoized
    700712    def abspath_for_test(self, test_name):
    701713        """Returns the full path to the file for a given test name. This is the
    702714        inverse of relative_test_filename()."""
    703         return self._filesystem.normpath(self._filesystem.join(self.layout_tests_dir(), test_name))
     715        return self._filesystem.join(self.layout_tests_dir(), test_name)
    704716
    705717    def results_directory(self):
Note: See TracChangeset for help on using the changeset viewer.