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

Side by Side Diff: Tools/Scripts/webkitpy/layout_tests/lint_test_expectations.py

Issue 963723002: Add JSON support to lint-test-expectations (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Created 5 years, 9 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
« no previous file with comments | « no previous file | Tools/Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright (C) 2012 Google Inc. All rights reserved. 1 # Copyright (C) 2012 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
11 # in the documentation and/or other materials provided with the 11 # in the documentation and/or other materials provided with the
12 # distribution. 12 # distribution.
13 # * Neither the name of Google Inc. nor the names of its 13 # * Neither the name of Google Inc. nor the names of its
14 # contributors may be used to endorse or promote products derived from 14 # contributors may be used to endorse or promote products derived from
15 # this software without specific prior written permission. 15 # this software without specific prior written permission.
16 # 16 #
17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 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. 27 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 28
29 import json
29 import logging 30 import logging
30 import optparse 31 import optparse
31 import signal 32 import signal
32 import traceback 33 import traceback
33 34
34 from webkitpy.common.host import Host 35 from webkitpy.common.host import Host
35 from webkitpy.layout_tests.models import test_expectations 36 from webkitpy.layout_tests.models import test_expectations
36 from webkitpy.layout_tests.port import platform_options 37 from webkitpy.layout_tests.port import platform_options
37 38
38 39
39 # This mirrors what the shell normally does. 40 # This mirrors what the shell normally does.
40 INTERRUPTED_EXIT_STATUS = signal.SIGINT + 128 41 INTERRUPTED_EXIT_STATUS = signal.SIGINT + 128
41 42
42 # This is a randomly chosen exit code that can be tested against to 43 # This is a randomly chosen exit code that can be tested against to
43 # indicate that an unexpected exception occurred. 44 # indicate that an unexpected exception occurred.
44 EXCEPTIONAL_EXIT_STATUS = 254 45 EXCEPTIONAL_EXIT_STATUS = 254
45 46
46 _log = logging.getLogger(__name__) 47 _log = logging.getLogger(__name__)
47 48
48 49
49 def lint(host, options): 50 def lint(host, options):
50 ports_to_lint = [host.port_factory.get(name) for name in host.port_factory.a ll_port_names(options.platform)] 51 ports_to_lint = [host.port_factory.get(name) for name in host.port_factory.a ll_port_names(options.platform)]
51 files_linted = set() 52 files_linted = set()
52 lint_failed = False
53 53
54 failures = []
54 for port_to_lint in ports_to_lint: 55 for port_to_lint in ports_to_lint:
55 expectations_dict = port_to_lint.expectations_dict() 56 expectations_dict = port_to_lint.expectations_dict()
56 57
57 for expectations_file in expectations_dict.keys(): 58 for expectations_file in expectations_dict.keys():
58 if expectations_file in files_linted: 59 if expectations_file in files_linted:
59 continue 60 continue
60 61
61 try: 62 try:
62 test_expectations.TestExpectations(port_to_lint, 63 test_expectations.TestExpectations(port_to_lint,
63 expectations_dict={expectations_file: expectations_dict[expe ctations_file]}, 64 expectations_dict={expectations_file: expectations_dict[expe ctations_file]},
64 is_lint_mode=True) 65 is_lint_mode=True)
65 except test_expectations.ParseError as e: 66 except test_expectations.ParseError as e:
66 lint_failed = True
67 _log.error('') 67 _log.error('')
68 for warning in e.warnings: 68 for warning in e.warnings:
69 _log.error(warning) 69 _log.error(warning)
70 failures.append('%s: %s' % (expectations_file, warning))
70 _log.error('') 71 _log.error('')
71 files_linted.add(expectations_file) 72 files_linted.add(expectations_file)
72 return lint_failed 73 return failures
73 74
74 75
75 def check_virtual_test_suites(host, options): 76 def check_virtual_test_suites(host, options):
76 port = host.port_factory.get(options=options) 77 port = host.port_factory.get(options=options)
77 fs = host.filesystem 78 fs = host.filesystem
78 layout_tests_dir = port.layout_tests_dir() 79 layout_tests_dir = port.layout_tests_dir()
79 virtual_suites = port.virtual_test_suites() 80 virtual_suites = port.virtual_test_suites()
80 81
81 check_failed = False 82 failures = []
82 for suite in virtual_suites: 83 for suite in virtual_suites:
83 comps = [layout_tests_dir] + suite.name.split('/') + ['README.txt'] 84 comps = [layout_tests_dir] + suite.name.split('/') + ['README.txt']
84 path_to_readme = fs.join(*comps) 85 path_to_readme = fs.join(*comps)
85 if not fs.exists(path_to_readme): 86 if not fs.exists(path_to_readme):
86 _log.error('LayoutTests/%s/README.txt is missing (each virtual suite must have one).' % suite.name) 87 failure = 'LayoutTests/%s/README.txt is missing (each virtual suite must have one).' % suite.name
87 check_failed = True 88 _log.error(failure)
88 if check_failed: 89 failures.append(failure)
90 if failures:
89 _log.error('') 91 _log.error('')
90 return check_failed 92 return failures
91 93
92 94
93 def set_up_logging(logging_stream): 95 def set_up_logging(logging_stream):
94 logger = logging.getLogger() 96 logger = logging.getLogger()
95 logger.setLevel(logging.INFO) 97 logger.setLevel(logging.INFO)
96 handler = logging.StreamHandler(logging_stream) 98 handler = logging.StreamHandler(logging_stream)
97 logger.addHandler(handler) 99 logger.addHandler(handler)
98 return (logger, handler) 100 return (logger, handler)
99 101
100 102
101 def tear_down_logging(logger, handler): 103 def tear_down_logging(logger, handler):
102 logger.removeHandler(handler) 104 logger.removeHandler(handler)
103 105
104 106
105 def run_checks(host, options, logging_stream): 107 def run_checks(host, options, logging_stream):
106 logger, handler = set_up_logging(logging_stream) 108 logger, handler = set_up_logging(logging_stream)
107 try: 109 try:
108 lint_failed = lint(host, options) 110 failures = []
109 check_failed = check_virtual_test_suites(host, options) 111 failures.extend(lint(host, options))
110 if lint_failed or check_failed: 112 failures.extend(check_virtual_test_suites(host, options))
113
114 if options.json:
115 with open(options.json, 'w') as f:
116 json.dump(failures, f)
117
118 if failures:
111 _log.error('Lint failed.') 119 _log.error('Lint failed.')
112 return 1 120 return 1
113 else: 121 else:
114 _log.info('Lint succeeded.') 122 _log.info('Lint succeeded.')
115 return 0 123 return 0
116 finally: 124 finally:
117 logger.removeHandler(handler) 125 logger.removeHandler(handler)
118 126
119 127
120 def main(argv, _, stderr): 128 def main(argv, _, stderr):
121 parser = optparse.OptionParser(option_list=platform_options(use_globs=True)) 129 parser = optparse.OptionParser(option_list=platform_options(use_globs=True))
130 parser.add_option('--json', help='Path to JSON output file')
122 options, _ = parser.parse_args(argv) 131 options, _ = parser.parse_args(argv)
123 132
124 if options.platform and 'test' in options.platform: 133 if options.platform and 'test' in options.platform:
125 # It's a bit lame to import mocks into real code, but this allows the us er 134 # It's a bit lame to import mocks into real code, but this allows the us er
126 # to run tests against the test platform interactively, which is useful for 135 # to run tests against the test platform interactively, which is useful for
127 # debugging test failures. 136 # debugging test failures.
128 from webkitpy.common.host_mock import MockHost 137 from webkitpy.common.host_mock import MockHost
129 host = MockHost() 138 host = MockHost()
130 else: 139 else:
131 host = Host() 140 host = Host()
132 141
133 try: 142 try:
134 exit_status = run_checks(host, options, stderr) 143 exit_status = run_checks(host, options, stderr)
135 except KeyboardInterrupt: 144 except KeyboardInterrupt:
136 exit_status = INTERRUPTED_EXIT_STATUS 145 exit_status = INTERRUPTED_EXIT_STATUS
137 except Exception as e: 146 except Exception as e:
138 print >> stderr, '\n%s raised: %s' % (e.__class__.__name__, str(e)) 147 print >> stderr, '\n%s raised: %s' % (e.__class__.__name__, str(e))
139 traceback.print_exc(file=stderr) 148 traceback.print_exc(file=stderr)
140 exit_status = EXCEPTIONAL_EXIT_STATUS 149 exit_status = EXCEPTIONAL_EXIT_STATUS
141 150
142 return exit_status 151 return exit_status
OLDNEW
« no previous file with comments | « no previous file | Tools/Scripts/webkitpy/layout_tests/lint_test_expectations_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698