check-webkit-style of the chromium test_expectations.txt file doesn't test all chromi...
[WebKit-https.git] / Tools / Scripts / webkitpy / style / checkers / test_expectations.py
1 # Copyright (C) 2010 Google Inc. All rights reserved.
2 #
3 # Redistribution and use in source and binary forms, with or without
4 # modification, are permitted provided that the following conditions are
5 # met:
6 #
7 #     * Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 #     * Redistributions in binary form must reproduce the above
10 # copyright notice, this list of conditions and the following disclaimer
11 # in the documentation and/or other materials provided with the
12 # distribution.
13 #     * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission.
16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 """Checks WebKit style for test_expectations files."""
30
31 import logging
32 import os
33 import re
34 import sys
35
36 from common import TabChecker
37 from webkitpy.common.host import Host
38 from webkitpy.layout_tests.models import test_expectations
39 from webkitpy.layout_tests.port.base import DummyOptions
40
41
42 _log = logging.getLogger(__name__)
43
44
45 class TestExpectationsChecker(object):
46     """Processes test_expectations.txt lines for validating the syntax."""
47
48     categories = set(['test/expectations'])
49
50     def _determine_port_from_exepectations_path(self, host, expectations_path):
51         try:
52             # I believe what this is trying to do is "when the port name is chromium,
53             # get the chromium-port for this platform".  Unclear why that's needed??
54             port_name = expectations_path.split(host.filesystem.sep)[-2]
55             if not port_name:
56                 return None
57
58             # Pass a configuration to avoid calling default_configuration() when initializing the port (takes 0.5 seconds on a Mac Pro!).
59             if port_name == "chromium":
60                 return host.port_factory.get(options=DummyOptions(chromium=True, configuration="Release"))
61             return host.port_factory.get(port_name, options=DummyOptions(configuration="Release"))
62         except Exception, e:
63             _log.warn("Exception while getting port for path %s" % expectations_path)
64             return None
65
66     def __init__(self, file_path, handle_style_error, host=None):
67         self._file_path = file_path
68         self._handle_style_error = handle_style_error
69         self._handle_style_error.turn_off_line_filtering()
70         self._tab_checker = TabChecker(file_path, handle_style_error)
71         self._output_regex = re.compile('Line:(?P<line>\d+)\s*(?P<message>.+)')
72
73         # FIXME: host should be a required parameter, not an optional one.
74         host = host or Host()
75         host._initialize_scm()
76
77         # Determining the port of this expectations.
78         self._port_obj = self._determine_port_from_exepectations_path(host, file_path)
79         # Using 'test' port when we couldn't determine the port for this
80         # expectations.
81         if not self._port_obj:
82             _log.warn("Could not determine the port for %s. "
83                       "Using 'test' port, but platform-specific expectations "
84                       "will fail the check." % self._file_path)
85             self._port_obj = host.port_factory.get('test')
86         # Suppress error messages of test_expectations module since they will be reported later.
87         log = logging.getLogger("webkitpy.layout_tests.layout_package.test_expectations")
88         log.setLevel(logging.CRITICAL)
89
90     def _handle_error_message(self, lineno, message, confidence):
91         pass
92
93     def check_test_expectations(self, expectations_str, test_configuration, tests=None, overrides=None):
94         err = None
95         expectations = None
96         try:
97             expectations = test_expectations.TestExpectations(
98                 port=self._port_obj, expectations=expectations_str, tests=tests,
99                 test_config=test_configuration,
100                 is_lint_mode=True, overrides=overrides)
101         except test_expectations.ParseError, error:
102             err = error
103
104         if err:
105             level = 2
106             if err.fatal:
107                 level = 5
108             for error in err.errors:
109                 matched = self._output_regex.match(error)
110                 if matched:
111                     lineno, message = matched.group('line', 'message')
112                     self._handle_style_error(int(lineno), 'test/expectations', level, message)
113
114
115     def check_tabs(self, lines):
116         self._tab_checker.check(lines)
117
118     def check(self, lines):
119         overrides = self._port_obj.test_expectations_overrides()
120         expectations = '\n'.join(lines)
121         for test_configuration in self._port_obj.all_test_configurations():
122             self.check_test_expectations(expectations_str=expectations,
123                                          test_configuration=test_configuration,
124                                          tests=None,
125                                          overrides=overrides)
126         # Warn tabs in lines as well
127         self.check_tabs(lines)