1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#!/usr/bin/env python2.7
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
3ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# Copyright 2013, ARM Limited
4ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# All rights reserved.
5ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#
6ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# Redistribution and use in source and binary forms, with or without
7ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# modification, are permitted provided that the following conditions are met:
8ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#
9ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#   * Redistributions of source code must retain the above copyright notice,
10ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#     this list of conditions and the following disclaimer.
11ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#   * Redistributions in binary form must reproduce the above copyright notice,
12ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#     this list of conditions and the following disclaimer in the documentation
13ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#     and/or other materials provided with the distribution.
14ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#   * Neither the name of ARM Limited nor the names of its contributors may be
15ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#     used to endorse or promote products derived from this software without
16ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#     specific prior written permission.
17ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#
18ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND
19ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
22ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
29ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport os
30ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport sys
31ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport argparse
32ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport re
33ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlimport platform
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
35ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport util
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport git
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl# Google's cpplint.py from depot_tools is the linter used here.
39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlCPP_LINTER_RULES = '''
40ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/class
41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/deprecated
42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/endif_comment
43ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/forward_decl
44ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/include_order
45ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/printf_format
46ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlbuild/storage_class
47ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixllegal/copyright
48ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/boost
49ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/braces
50ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/casting
51ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/constructors
52ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/fn_size
53ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/function
54ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/multiline_comment
55ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/multiline_string
56ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/streams
57ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlreadability/utf8
58ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/arrays
59ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/casting
60ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/deprecated_fn
61ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/explicit
62ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/int
63ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/memset
64ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/mutex
65ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/nonconf
66ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/printf
67ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/printf_format
68ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/references
69ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/rtti
70ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/sizeof
71ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/string
72ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/virtual
73ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlruntime/vlog
74ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/blank_line
75ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/braces
76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/comma
77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/comments
78ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/end_of_line
79ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/ending_newline
80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/indent
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/labels
82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/line_length
83ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/newline
84ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/operators
85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/parens
86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/tab
87ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlwhitespace/todo
88ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl'''.split()
89ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
90ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
91ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixldef BuildOptions():
92ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  result = argparse.ArgumentParser(description='Run the linter and unit tests.')
93ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  result.add_argument('--verbose', '-v', action='store_true',
94ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      help='Print all tests output at the end.')
95ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  result.add_argument('--notest', action='store_true',
96ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      help='Do not run tests. Run the linter only.')
97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  result.add_argument('--nolint', action='store_true',
98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      help='Do not run the linter. Run the tests only.')
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  result.add_argument('--noclean', action='store_true',
100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      help='Do not clean before build.')
101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  result.add_argument('--jobs', '-j', metavar='N', type=int, default=1,
102ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl                      help='Allow N jobs at once.')
103ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  sim_default = 'off' if platform.machine() == 'aarch64' else 'on'
104ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  result.add_argument('--simulator', action='store', choices=['on', 'off'],
105ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                      default=sim_default,
106ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                      help='''Explicitly enable or disable the simulator. On
107ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                      this system, the default is "''' + sim_default + '".')
108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  return result.parse_args()
109ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
110ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixldef CleanBuildSystem():
112ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  def clean(mode):
113ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if args.verbose: print('Cleaning ' + mode + ' mode cctest...')
114ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    command = 'scons mode=%s simulator=%s target=cctest --clean' % \
115ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              (mode, args.simulator)
116ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    status, output = util.getstatusoutput(command)
117ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if status != 0:
118ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      print(output)
119ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      util.abort('Failed cleaning cctest: ' + command)
120ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  clean('debug')
121ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  clean('release')
122ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
123ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
124ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixldef BuildRequiredObjects():
125ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  def build(mode):
126ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if args.verbose: print('Building ' + mode + ' mode cctest...')
127ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    command = 'scons mode=%s simulator=%s target=cctest -j%u' % \
128ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl              (mode, args.simulator, args.jobs)
129ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    status, output = util.getstatusoutput(command)
130ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if status != 0:
131ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      print(output)
132ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      util.abort('Failed building cctest: ' + command)
133ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  build('debug')
134ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  build('release')
135ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
136ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
137ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlNOT_RUN = 'NOT RUN'
138ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlPASSED = 'PASSED'
139ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlFAILED = 'FAILED'
140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
141ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
142ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass Test:
143ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  def __init__(self, name, command, get_summary = util.last_line):
144ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.name = name
145ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.command = command
146ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.get_summary = get_summary
147ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    self.output = NOT_RUN
148ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    self.status = NOT_RUN
149ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    self.summary = NOT_RUN
150ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
151ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  def Run(self):
152ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if args.verbose: print('Running ' + self.name + '...')
153ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    retcode, self.output = util.getstatusoutput(self.command)
154ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    self.status = PASSED if retcode == 0 else FAILED
155ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.summary = self.get_summary(self.output)
156ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
157ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  def PrintOutcome(self):
158ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    print(('%-26s : %s') % (self.name, self.summary))
159ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
160ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  def PrintOutput(self):
161ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    print('\n\n=== OUTPUT of: ' + self.command + '\n')
162ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    print(self.output)
163ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
164ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
165ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlclass Tester:
166ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  def __init__(self):
167ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.tests = []
168ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
169ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  def AddTest(self, test):
170ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.tests.append(test)
171ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
172ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  def RunAll(self):
173ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    result = PASSED
174ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    for test in self.tests:
175ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      test.Run()
176ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      if test.status != PASSED: result = FAILED
177ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      test.PrintOutcome()
178ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    print('Presubmit tests ' + result + '.')
179ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
180ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  def PrintFailedTestOutput(self):
181ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    for test in self.tests:
182ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      if test.status == FAILED:
183ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        test.PrintOutput();
184ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
185ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
186ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlif __name__ == '__main__':
187ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  original_dir = os.path.abspath('.')
188ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # $ROOT/tools/presubmit.py
189ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  root_dir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
190ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  os.chdir(root_dir)
191ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  args = BuildOptions()
192ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
193ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if not args.nolint and not git.is_git_repository_root():
194ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    print 'WARNING: This is not a Git repository. The linter will not run.'
195ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    args.nolint = True
196ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
197ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  tester = Tester()
198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if not args.nolint:
199ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    CPP_EXT_REGEXP = re.compile('\.(cc|h)$')
200ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    SIM_TRACES_REGEXP = re.compile('test-simulator-traces-a64\.h$')
201ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    def is_linter_input(filename):
202ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # Don't lint the simulator traces file; it takes a very long time to check
203ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # and it's (mostly) generated automatically anyway.
204ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      if SIM_TRACES_REGEXP.search(filename): return False
205ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # Otherwise, lint all C++ files.
206ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      return CPP_EXT_REGEXP.search(filename) != None
207ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
208ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    lint_args = '--filter=-,+' + ',+'.join(CPP_LINTER_RULES) + ' '
209ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    tracked_files = git.get_tracked_files().split()
210ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    tracked_files = filter(is_linter_input, tracked_files)
211ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    tracked_files = ' '.join(tracked_files)
212ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    lint = Test('cpp lint', 'cpplint.py ' + lint_args + tracked_files)
213ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    tester.AddTest(lint)
214ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
215ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if not args.notest:
216ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if not args.noclean:
217ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      CleanBuildSystem()
218ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    BuildRequiredObjects()
219ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
220ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    def command(*test_args):
221ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      if args.verbose:
222ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        return 'tools/test.py --verbose ' + ' '.join(test_args)
223ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      else:
224ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl        return 'tools/test.py ' + ' '.join(test_args)
225ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
226ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if args.simulator == 'on':
227ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      tester.AddTest(Test('cctest release (debugger)',
228ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                          command('--cctest=cctest_sim', '--debugger')))
229ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      tester.AddTest(Test('cctest debug (debugger)',
230ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                          command('--cctest=cctest_sim_g', '--debugger')))
231ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      tester.AddTest(Test('cctest release (simulator)',
232ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                          command('--cctest=cctest_sim')))
233ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      tester.AddTest(Test('cctest debug (simulator)',
234ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                          command('--cctest=cctest_sim_g')))
235ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    else:
236ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      tester.AddTest(Test('cctest release', command('--cctest=cctest')))
237ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      tester.AddTest(Test('cctest debug', command('--cctest=cctest_g')))
238ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
239ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  tester.RunAll()
240ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
241ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  # If tests failed, print their output.
242ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  tester.PrintFailedTestOutput()
243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  if git.is_git_repository_root():
245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    untracked_files = git.get_untracked_files()
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    if untracked_files:
247ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      print '\nWARNING: The following files are untracked:'
248ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl      for f in untracked_files:
249ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl        print f.lstrip('?')
250