test.py revision c68cb64496485710cdb5b8480f8fee287058c93f
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
33c68cb64496485710cdb5b8480f8fee287058c93farmvixlimport platform
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport subprocess
354a102baf640077d6794c0b33bb976f94b86c532barmvixlimport multiprocessing
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport time
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport util
38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
405799d6c5d10729eaade85ad608109c83ed1ae63barmvixlfrom printer import EnsureNewLine, Print, UpdateProgress
41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
435799d6c5d10729eaade85ad608109c83ed1ae63barmvixldef BuildOptions():
444a102baf640077d6794c0b33bb976f94b86c532barmvixl  result = argparse.ArgumentParser(
454a102baf640077d6794c0b33bb976f94b86c532barmvixl      description =
465799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      '''This tool runs each test reported by $CCTEST --list (and filtered as
475799d6c5d10729eaade85ad608109c83ed1ae63barmvixl         specified). A summary will be printed, and detailed test output will be
484a102baf640077d6794c0b33bb976f94b86c532barmvixl         stored in log/$CCTEST.''',
494a102baf640077d6794c0b33bb976f94b86c532barmvixl      # Print default values.
504a102baf640077d6794c0b33bb976f94b86c532barmvixl      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
515799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  result.add_argument('filters', metavar='filter', nargs='*',
525799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                      help='Run tests matching all of the (regexp) filters.')
535799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  result.add_argument('--cctest', action='store', required=True,
545799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                      help='The cctest executable to run.')
555799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  result.add_argument('--coloured_trace', action='store_true',
565799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                      help='''Pass --coloured_trace to cctest. This will put
575799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                              colour codes in the log files. The coloured output
585799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                              can be viewed by "less -R", for example.''')
595799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  result.add_argument('--debugger', action='store_true',
605799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                      help='''Pass --debugger to cctest, so that the debugger is
615799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                              used instead of the simulator. This has no effect
625799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                              when running natively.''')
635799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  result.add_argument('--verbose', action='store_true',
645799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                      help='Print verbose output.')
654a102baf640077d6794c0b33bb976f94b86c532barmvixl  result.add_argument('--jobs', '-j', metavar='N', type=int, nargs='?',
664a102baf640077d6794c0b33bb976f94b86c532barmvixl                      default=1, const=multiprocessing.cpu_count(),
674a102baf640077d6794c0b33bb976f94b86c532barmvixl                      help='''Runs the tests using N jobs. If the option is set
684a102baf640077d6794c0b33bb976f94b86c532barmvixl                      but no value is provided, the script will use as many jobs
694a102baf640077d6794c0b33bb976f94b86c532barmvixl                      as it thinks useful.''')
70c68cb64496485710cdb5b8480f8fee287058c93farmvixl  sim_default = 'off' if platform.machine() == 'aarch64' else 'on'
71c68cb64496485710cdb5b8480f8fee287058c93farmvixl  result.add_argument('--simulator', action='store', choices=['on', 'off'],
72c68cb64496485710cdb5b8480f8fee287058c93farmvixl                      default=sim_default,
73c68cb64496485710cdb5b8480f8fee287058c93farmvixl                      help='Explicitly enable or disable the simulator.')
745799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  return result.parse_args()
75ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
774a102baf640077d6794c0b33bb976f94b86c532barmvixldef VerbosePrint(verbose, string):
784a102baf640077d6794c0b33bb976f94b86c532barmvixl  if verbose:
795799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    Print(string)
80ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
825799d6c5d10729eaade85ad608109c83ed1ae63barmvixl# A class representing an individual test.
835799d6c5d10729eaade85ad608109c83ed1ae63barmvixlclass Test:
844a102baf640077d6794c0b33bb976f94b86c532barmvixl  def __init__(self, name, cctest, debugger, coloured_trace, verbose):
85ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.name = name
864a102baf640077d6794c0b33bb976f94b86c532barmvixl    self.cctest = cctest
874a102baf640077d6794c0b33bb976f94b86c532barmvixl    self.debugger = debugger
884a102baf640077d6794c0b33bb976f94b86c532barmvixl    self.coloured_trace = coloured_trace
894a102baf640077d6794c0b33bb976f94b86c532barmvixl    self.verbose = verbose
904a102baf640077d6794c0b33bb976f94b86c532barmvixl    self.logpath = os.path.join('log', os.path.basename(self.cctest))
914a102baf640077d6794c0b33bb976f94b86c532barmvixl    if self.debugger:
925799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      basename = name + '_debugger'
935799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    else:
945799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      basename = name
955799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    self.logout = os.path.join(self.logpath, basename + '.stdout')
965799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    self.logerr = os.path.join(self.logpath, basename + '.stderr')
97ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
98ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # Run the test.
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # Use a thread to be able to control the test.
1005799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  def Run(self):
1014a102baf640077d6794c0b33bb976f94b86c532barmvixl    command = [self.cctest, '--trace_sim', '--trace_reg', self.name]
1024a102baf640077d6794c0b33bb976f94b86c532barmvixl    if self.coloured_trace:
1035799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      command.append('--coloured_trace')
1044a102baf640077d6794c0b33bb976f94b86c532barmvixl    if self.debugger:
1054a102baf640077d6794c0b33bb976f94b86c532barmvixl      command.append('--debugger')
1065799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1074a102baf640077d6794c0b33bb976f94b86c532barmvixl    VerbosePrint(self.verbose, '==== Running ' + self.name + '... ====')
108ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sys.stdout.flush()
1095799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1105799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    process = subprocess.Popen(command,
1115799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                               stdout=subprocess.PIPE,
1125799d6c5d10729eaade85ad608109c83ed1ae63barmvixl                               stderr=subprocess.PIPE)
1135799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    # Get the output and return status of the test.
1145799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    stdout, stderr = process.communicate()
1155799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    retcode = process.poll()
1165799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1175799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    # Write stdout and stderr to the log.
1185799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    if not os.path.exists(self.logpath): os.makedirs(self.logpath)
1195799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    with open(self.logout, 'w') as f: f.write(stdout)
1205799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    with open(self.logerr, 'w') as f: f.write(stderr)
1215799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1225799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    if retcode == 0:
1235799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      # Success.
1245799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      # We normally only print the command on failure, but with --verbose we
1255799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      # should also print it on success.
1264a102baf640077d6794c0b33bb976f94b86c532barmvixl      VerbosePrint(self.verbose, 'COMMAND: ' + ' '.join(command))
1274a102baf640077d6794c0b33bb976f94b86c532barmvixl      VerbosePrint(self.verbose, 'LOG (stdout): ' + self.logout)
1284a102baf640077d6794c0b33bb976f94b86c532barmvixl      VerbosePrint(self.verbose, 'LOG (stderr): ' + self.logerr + '\n')
129ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    else:
1305799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      # Failure.
1315799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      Print('--- FAILED ' + self.name + ' ---')
1325799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      Print('COMMAND: ' + ' '.join(command))
1335799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      Print('LOG (stdout): ' + self.logout)
1345799d6c5d10729eaade85ad608109c83ed1ae63barmvixl      Print('LOG (stderr): ' + self.logerr + '\n')
135ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
136ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return retcode
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1395799d6c5d10729eaade85ad608109c83ed1ae63barmvixl# Scan matching tests and return a test manifest.
1404a102baf640077d6794c0b33bb976f94b86c532barmvixldef ReadManifest(cctest, filters = [],
1414a102baf640077d6794c0b33bb976f94b86c532barmvixl                 debugger = False, coloured_trace = False, verbose = False):
1424a102baf640077d6794c0b33bb976f94b86c532barmvixl  status, output = util.getstatusoutput(cctest +  ' --list')
1435799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  if status != 0: util.abort('Failed to list all tests')
1445799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1455799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  names = output.split()
1465799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  for f in filters:
1475799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    names = filter(re.compile(f).search, names)
1485799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1494a102baf640077d6794c0b33bb976f94b86c532barmvixl  return map(lambda x: Test(x, cctest, debugger, coloured_trace, verbose), names)
1504a102baf640077d6794c0b33bb976f94b86c532barmvixl
1514a102baf640077d6794c0b33bb976f94b86c532barmvixl
1524a102baf640077d6794c0b33bb976f94b86c532barmvixl# Shared state for multiprocessing. Ideally the context should be passed with
1534a102baf640077d6794c0b33bb976f94b86c532barmvixl# arguments, but constraints from the multiprocessing module prevent us from
1544a102baf640077d6794c0b33bb976f94b86c532barmvixl# doing so: the shared variables (multiprocessing.Value) must be global, or no
1554a102baf640077d6794c0b33bb976f94b86c532barmvixl# work is started. So we abstract some additional state into global variables to
1564a102baf640077d6794c0b33bb976f94b86c532barmvixl# simplify the implementation.
1574a102baf640077d6794c0b33bb976f94b86c532barmvixl# Read-write variables for the workers.
1584a102baf640077d6794c0b33bb976f94b86c532barmvixln_tests_passed = multiprocessing.Value('i', 0)
1594a102baf640077d6794c0b33bb976f94b86c532barmvixln_tests_failed = multiprocessing.Value('i', 0)
1604a102baf640077d6794c0b33bb976f94b86c532barmvixl# Read-only for workers.
1614a102baf640077d6794c0b33bb976f94b86c532barmvixln_tests = None
1624a102baf640077d6794c0b33bb976f94b86c532barmvixlstart_time = None
1634a102baf640077d6794c0b33bb976f94b86c532barmvixlverbose_test_run = None
1644a102baf640077d6794c0b33bb976f94b86c532barmvixltest_suite_name = ''
1654a102baf640077d6794c0b33bb976f94b86c532barmvixl
1664a102baf640077d6794c0b33bb976f94b86c532barmvixldef RunTest(test):
1674a102baf640077d6794c0b33bb976f94b86c532barmvixl  UpdateProgress(start_time, n_tests_passed.value, n_tests_failed.value,
1684a102baf640077d6794c0b33bb976f94b86c532barmvixl                 n_tests, verbose_test_run, test.name, test_suite_name)
1694a102baf640077d6794c0b33bb976f94b86c532barmvixl  # Run the test and update the statistics.
1704a102baf640077d6794c0b33bb976f94b86c532barmvixl  retcode = test.Run()
1714a102baf640077d6794c0b33bb976f94b86c532barmvixl  if retcode == 0:
1724a102baf640077d6794c0b33bb976f94b86c532barmvixl    with n_tests_passed.get_lock(): n_tests_passed.value += 1
1734a102baf640077d6794c0b33bb976f94b86c532barmvixl  else:
1744a102baf640077d6794c0b33bb976f94b86c532barmvixl    with n_tests_failed.get_lock(): n_tests_failed.value += 1
1755799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1765799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
1775799d6c5d10729eaade85ad608109c83ed1ae63barmvixl# Run all tests in the manifest.
1784a102baf640077d6794c0b33bb976f94b86c532barmvixl# This function won't run in parallel due to constraints from the
1794a102baf640077d6794c0b33bb976f94b86c532barmvixl# multiprocessing module.
1804a102baf640077d6794c0b33bb976f94b86c532barmvixl__run_tests_lock__ = multiprocessing.Lock()
1814a102baf640077d6794c0b33bb976f94b86c532barmvixldef RunTests(manifest, jobs = 1, verbose = False, debugger = False,
1824a102baf640077d6794c0b33bb976f94b86c532barmvixl             progress_prefix = ''):
1834a102baf640077d6794c0b33bb976f94b86c532barmvixl  global n_tests
1844a102baf640077d6794c0b33bb976f94b86c532barmvixl  global start_time
1854a102baf640077d6794c0b33bb976f94b86c532barmvixl  global verbose_test_run
1864a102baf640077d6794c0b33bb976f94b86c532barmvixl  global test_suite_name
1874a102baf640077d6794c0b33bb976f94b86c532barmvixl
1884a102baf640077d6794c0b33bb976f94b86c532barmvixl  with __run_tests_lock__:
1894a102baf640077d6794c0b33bb976f94b86c532barmvixl
1904a102baf640077d6794c0b33bb976f94b86c532barmvixl    # Reset the counters.
1914a102baf640077d6794c0b33bb976f94b86c532barmvixl    n_tests_passed.value = 0
1924a102baf640077d6794c0b33bb976f94b86c532barmvixl    n_tests_failed.value = 0
1934a102baf640077d6794c0b33bb976f94b86c532barmvixl
1944a102baf640077d6794c0b33bb976f94b86c532barmvixl    verbose_test_run = verbose
1954a102baf640077d6794c0b33bb976f94b86c532barmvixl    test_suite_name = progress_prefix
1964a102baf640077d6794c0b33bb976f94b86c532barmvixl
1974a102baf640077d6794c0b33bb976f94b86c532barmvixl    n_tests = len(manifest)
198ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
1994a102baf640077d6794c0b33bb976f94b86c532barmvixl    if n_tests == 0:
2004a102baf640077d6794c0b33bb976f94b86c532barmvixl      Print('No tests to run.')
2014a102baf640077d6794c0b33bb976f94b86c532barmvixl      return 0
2024a102baf640077d6794c0b33bb976f94b86c532barmvixl
2034a102baf640077d6794c0b33bb976f94b86c532barmvixl    VerbosePrint(verbose, 'Running %d tests...' % (n_tests))
2044a102baf640077d6794c0b33bb976f94b86c532barmvixl    start_time = time.time()
2054a102baf640077d6794c0b33bb976f94b86c532barmvixl
2064a102baf640077d6794c0b33bb976f94b86c532barmvixl    pool = multiprocessing.Pool(jobs)
2074a102baf640077d6794c0b33bb976f94b86c532barmvixl    # The '.get(9999999)' is workaround to allow killing the test script with
2084a102baf640077d6794c0b33bb976f94b86c532barmvixl    # ctrl+C from the shell. This bug is documented at
2094a102baf640077d6794c0b33bb976f94b86c532barmvixl    # http://bugs.python.org/issue8296.
2104a102baf640077d6794c0b33bb976f94b86c532barmvixl    work = pool.map_async(RunTest, manifest).get(9999999)
2114a102baf640077d6794c0b33bb976f94b86c532barmvixl
2124a102baf640077d6794c0b33bb976f94b86c532barmvixl    done_message = '== Done =='
2134a102baf640077d6794c0b33bb976f94b86c532barmvixl    UpdateProgress(start_time, n_tests_passed.value, n_tests_failed.value,
2144a102baf640077d6794c0b33bb976f94b86c532barmvixl                   n_tests, verbose, done_message, progress_prefix)
2154a102baf640077d6794c0b33bb976f94b86c532barmvixl
2164a102baf640077d6794c0b33bb976f94b86c532barmvixl    return n_tests_failed.value # 0 indicates success
217ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
218ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
219ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlif __name__ == '__main__':
220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # $ROOT/tools/test.py
221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  root_dir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2235799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  # Parse the arguments.
224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  args = BuildOptions()
225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2265799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  # Find a valid path to args.cctest (in case it doesn't begin with './').
2275799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  args.cctest = os.path.join('.', args.cctest)
2285799d6c5d10729eaade85ad608109c83ed1ae63barmvixl
2295799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  if not os.access(args.cctest, os.X_OK):
2305799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    print "'" + args.cctest + "' is not executable or does not exist."
2315799d6c5d10729eaade85ad608109c83ed1ae63barmvixl    sys.exit(1)
232ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2335799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  # List all matching tests.
2344a102baf640077d6794c0b33bb976f94b86c532barmvixl  manifest = ReadManifest(args.cctest, args.filters,
2354a102baf640077d6794c0b33bb976f94b86c532barmvixl                          args.debugger, args.coloured_trace, args.verbose)
236ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
237ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # Run the tests.
2384a102baf640077d6794c0b33bb976f94b86c532barmvixl  status = RunTests(manifest, jobs=args.jobs,
2394a102baf640077d6794c0b33bb976f94b86c532barmvixl                    verbose=args.verbose, debugger=args.debugger)
2405799d6c5d10729eaade85ad608109c83ed1ae63barmvixl  EnsureNewLine()
241ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
242ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  sys.exit(status)
243ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
244