1ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl#!/usr/bin/env python2.7
2ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
30cc8b6ece4b3e757e11a906a81ece292437713abarmvixl# Copyright 2014, 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
3339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixlimport platform
34ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport subprocess
3590b0414b6c794be58f34813f84c2c06e6a15be91armvixlimport multiprocessing
36ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport time
37ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlimport util
38ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
39ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
40ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlfrom printer import EnsureNewLine, Print, UpdateProgress
41ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
42ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
43ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixldef BuildOptions():
4490b0414b6c794be58f34813f84c2c06e6a15be91armvixl  result = argparse.ArgumentParser(
4590b0414b6c794be58f34813f84c2c06e6a15be91armvixl      description =
464a06316541258e3c058792321295ee36d409f419armvixl      '''This tool runs each test reported by $TEST --list (and filtered as
47ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl         specified). A summary will be printed, and detailed test output will be
484a06316541258e3c058792321295ee36d409f419armvixl         stored in log/$TEST.''',
4990b0414b6c794be58f34813f84c2c06e6a15be91armvixl      # Print default values.
5090b0414b6c794be58f34813f84c2c06e6a15be91armvixl      formatter_class=argparse.ArgumentDefaultsHelpFormatter)
51ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  result.add_argument('filters', metavar='filter', nargs='*',
52ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                      help='Run tests matching all of the (regexp) filters.')
534a06316541258e3c058792321295ee36d409f419armvixl  result.add_argument('--runner', action='store', required=True,
544a06316541258e3c058792321295ee36d409f419armvixl                      help='The test executable to run.')
55ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  result.add_argument('--coloured_trace', action='store_true',
564a06316541258e3c058792321295ee36d409f419armvixl                      help='''Pass --coloured_trace to the test runner. This
574a06316541258e3c058792321295ee36d409f419armvixl                              will put colour codes in the log files. The
584a06316541258e3c058792321295ee36d409f419armvixl                              coloured output can be viewed by "less -R", for
594a06316541258e3c058792321295ee36d409f419armvixl                              example.''')
60ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  result.add_argument('--debugger', action='store_true',
614a06316541258e3c058792321295ee36d409f419armvixl                      help='''Pass --debugger to test, so that the debugger is
62ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                              used instead of the simulator. This has no effect
63ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                              when running natively.''')
64ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  result.add_argument('--verbose', action='store_true',
65ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                      help='Print verbose output.')
6690b0414b6c794be58f34813f84c2c06e6a15be91armvixl  result.add_argument('--jobs', '-j', metavar='N', type=int, nargs='?',
6790b0414b6c794be58f34813f84c2c06e6a15be91armvixl                      default=1, const=multiprocessing.cpu_count(),
6890b0414b6c794be58f34813f84c2c06e6a15be91armvixl                      help='''Runs the tests using N jobs. If the option is set
6990b0414b6c794be58f34813f84c2c06e6a15be91armvixl                      but no value is provided, the script will use as many jobs
7090b0414b6c794be58f34813f84c2c06e6a15be91armvixl                      as it thinks useful.''')
7139ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  sim_default = 'off' if platform.machine() == 'aarch64' else 'on'
7239ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl  result.add_argument('--simulator', action='store', choices=['on', 'off'],
7339ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl                      default=sim_default,
7439ee1f4b336c7e6b25be0df6375c18dcbd577c09armvixl                      help='Explicitly enable or disable the simulator.')
75ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  return result.parse_args()
76ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
77ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
7890b0414b6c794be58f34813f84c2c06e6a15be91armvixldef VerbosePrint(verbose, string):
7990b0414b6c794be58f34813f84c2c06e6a15be91armvixl  if verbose:
80ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    Print(string)
81ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
82ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
83ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl# A class representing an individual test.
84ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixlclass Test:
854a06316541258e3c058792321295ee36d409f419armvixl  def __init__(self, name, runner, debugger, coloured_trace, verbose):
86ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    self.name = name
874a06316541258e3c058792321295ee36d409f419armvixl    self.runner = runner
8890b0414b6c794be58f34813f84c2c06e6a15be91armvixl    self.debugger = debugger
8990b0414b6c794be58f34813f84c2c06e6a15be91armvixl    self.coloured_trace = coloured_trace
9090b0414b6c794be58f34813f84c2c06e6a15be91armvixl    self.verbose = verbose
914a06316541258e3c058792321295ee36d409f419armvixl    self.logpath = os.path.join('log', os.path.basename(self.runner))
9290b0414b6c794be58f34813f84c2c06e6a15be91armvixl    if self.debugger:
93ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      basename = name + '_debugger'
94ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    else:
95ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      basename = name
96ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    self.logout = os.path.join(self.logpath, basename + '.stdout')
97ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    self.logerr = os.path.join(self.logpath, basename + '.stderr')
984a06316541258e3c058792321295ee36d409f419armvixl    if not os.path.exists(self.logpath): os.makedirs(self.logpath)
99ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
100ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # Run the test.
101ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # Use a thread to be able to control the test.
102ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  def Run(self):
1034a06316541258e3c058792321295ee36d409f419armvixl    command = \
1044a06316541258e3c058792321295ee36d409f419armvixl        [self.runner, '--trace_sim', '--trace_reg', '--trace_write', self.name]
10590b0414b6c794be58f34813f84c2c06e6a15be91armvixl    if self.coloured_trace:
106ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      command.append('--coloured_trace')
10790b0414b6c794be58f34813f84c2c06e6a15be91armvixl    if self.debugger:
10890b0414b6c794be58f34813f84c2c06e6a15be91armvixl      command.append('--debugger')
109ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
11090b0414b6c794be58f34813f84c2c06e6a15be91armvixl    VerbosePrint(self.verbose, '==== Running ' + self.name + '... ====')
111ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    sys.stdout.flush()
112ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
113ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    process = subprocess.Popen(command,
114ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                               stdout=subprocess.PIPE,
115ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl                               stderr=subprocess.PIPE)
116ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    # Get the output and return status of the test.
117ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    stdout, stderr = process.communicate()
118ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    retcode = process.poll()
119ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
120ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    # Write stdout and stderr to the log.
121ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    with open(self.logout, 'w') as f: f.write(stdout)
122ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    with open(self.logerr, 'w') as f: f.write(stderr)
123ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
124ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    if retcode == 0:
125ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # Success.
126ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # We normally only print the command on failure, but with --verbose we
127ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # should also print it on success.
12890b0414b6c794be58f34813f84c2c06e6a15be91armvixl      VerbosePrint(self.verbose, 'COMMAND: ' + ' '.join(command))
12990b0414b6c794be58f34813f84c2c06e6a15be91armvixl      VerbosePrint(self.verbose, 'LOG (stdout): ' + self.logout)
13090b0414b6c794be58f34813f84c2c06e6a15be91armvixl      VerbosePrint(self.verbose, 'LOG (stderr): ' + self.logerr + '\n')
131ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    else:
132ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      # Failure.
133ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      Print('--- FAILED ' + self.name + ' ---')
134ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      Print('COMMAND: ' + ' '.join(command))
135ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      Print('LOG (stdout): ' + self.logout)
136ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl      Print('LOG (stderr): ' + self.logerr + '\n')
137ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
138ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl    return retcode
139ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
140ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
141ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl# Scan matching tests and return a test manifest.
1424a06316541258e3c058792321295ee36d409f419armvixldef ReadManifest(runner, filters = [],
14390b0414b6c794be58f34813f84c2c06e6a15be91armvixl                 debugger = False, coloured_trace = False, verbose = False):
1444a06316541258e3c058792321295ee36d409f419armvixl  status, output = util.getstatusoutput(runner +  ' --list')
145ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  if status != 0: util.abort('Failed to list all tests')
146ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
147ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  names = output.split()
148ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  for f in filters:
149ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    names = filter(re.compile(f).search, names)
150ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
1514a06316541258e3c058792321295ee36d409f419armvixl  return map(lambda x:
1524a06316541258e3c058792321295ee36d409f419armvixl      Test(x, runner, debugger, coloured_trace, verbose), names)
15390b0414b6c794be58f34813f84c2c06e6a15be91armvixl
15490b0414b6c794be58f34813f84c2c06e6a15be91armvixl
15590b0414b6c794be58f34813f84c2c06e6a15be91armvixl# Shared state for multiprocessing. Ideally the context should be passed with
15690b0414b6c794be58f34813f84c2c06e6a15be91armvixl# arguments, but constraints from the multiprocessing module prevent us from
15790b0414b6c794be58f34813f84c2c06e6a15be91armvixl# doing so: the shared variables (multiprocessing.Value) must be global, or no
15890b0414b6c794be58f34813f84c2c06e6a15be91armvixl# work is started. So we abstract some additional state into global variables to
15990b0414b6c794be58f34813f84c2c06e6a15be91armvixl# simplify the implementation.
16090b0414b6c794be58f34813f84c2c06e6a15be91armvixl# Read-write variables for the workers.
16190b0414b6c794be58f34813f84c2c06e6a15be91armvixln_tests_passed = multiprocessing.Value('i', 0)
16290b0414b6c794be58f34813f84c2c06e6a15be91armvixln_tests_failed = multiprocessing.Value('i', 0)
16390b0414b6c794be58f34813f84c2c06e6a15be91armvixl# Read-only for workers.
16490b0414b6c794be58f34813f84c2c06e6a15be91armvixln_tests = None
16590b0414b6c794be58f34813f84c2c06e6a15be91armvixlstart_time = None
16690b0414b6c794be58f34813f84c2c06e6a15be91armvixlverbose_test_run = None
16790b0414b6c794be58f34813f84c2c06e6a15be91armvixltest_suite_name = ''
16890b0414b6c794be58f34813f84c2c06e6a15be91armvixl
16990b0414b6c794be58f34813f84c2c06e6a15be91armvixldef RunTest(test):
17090b0414b6c794be58f34813f84c2c06e6a15be91armvixl  UpdateProgress(start_time, n_tests_passed.value, n_tests_failed.value,
17190b0414b6c794be58f34813f84c2c06e6a15be91armvixl                 n_tests, verbose_test_run, test.name, test_suite_name)
17290b0414b6c794be58f34813f84c2c06e6a15be91armvixl  # Run the test and update the statistics.
17390b0414b6c794be58f34813f84c2c06e6a15be91armvixl  retcode = test.Run()
17490b0414b6c794be58f34813f84c2c06e6a15be91armvixl  if retcode == 0:
17590b0414b6c794be58f34813f84c2c06e6a15be91armvixl    with n_tests_passed.get_lock(): n_tests_passed.value += 1
17690b0414b6c794be58f34813f84c2c06e6a15be91armvixl  else:
17790b0414b6c794be58f34813f84c2c06e6a15be91armvixl    with n_tests_failed.get_lock(): n_tests_failed.value += 1
178ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
179ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
180ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl# Run all tests in the manifest.
18190b0414b6c794be58f34813f84c2c06e6a15be91armvixl# This function won't run in parallel due to constraints from the
18290b0414b6c794be58f34813f84c2c06e6a15be91armvixl# multiprocessing module.
18390b0414b6c794be58f34813f84c2c06e6a15be91armvixl__run_tests_lock__ = multiprocessing.Lock()
18490b0414b6c794be58f34813f84c2c06e6a15be91armvixldef RunTests(manifest, jobs = 1, verbose = False, debugger = False,
18590b0414b6c794be58f34813f84c2c06e6a15be91armvixl             progress_prefix = ''):
18690b0414b6c794be58f34813f84c2c06e6a15be91armvixl  global n_tests
18790b0414b6c794be58f34813f84c2c06e6a15be91armvixl  global start_time
18890b0414b6c794be58f34813f84c2c06e6a15be91armvixl  global verbose_test_run
18990b0414b6c794be58f34813f84c2c06e6a15be91armvixl  global test_suite_name
19090b0414b6c794be58f34813f84c2c06e6a15be91armvixl
19190b0414b6c794be58f34813f84c2c06e6a15be91armvixl  with __run_tests_lock__:
19290b0414b6c794be58f34813f84c2c06e6a15be91armvixl
19390b0414b6c794be58f34813f84c2c06e6a15be91armvixl    # Reset the counters.
19490b0414b6c794be58f34813f84c2c06e6a15be91armvixl    n_tests_passed.value = 0
19590b0414b6c794be58f34813f84c2c06e6a15be91armvixl    n_tests_failed.value = 0
19690b0414b6c794be58f34813f84c2c06e6a15be91armvixl
19790b0414b6c794be58f34813f84c2c06e6a15be91armvixl    verbose_test_run = verbose
19890b0414b6c794be58f34813f84c2c06e6a15be91armvixl    test_suite_name = progress_prefix
19990b0414b6c794be58f34813f84c2c06e6a15be91armvixl
20090b0414b6c794be58f34813f84c2c06e6a15be91armvixl    n_tests = len(manifest)
201ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
20290b0414b6c794be58f34813f84c2c06e6a15be91armvixl    if n_tests == 0:
20390b0414b6c794be58f34813f84c2c06e6a15be91armvixl      Print('No tests to run.')
20490b0414b6c794be58f34813f84c2c06e6a15be91armvixl      return 0
20590b0414b6c794be58f34813f84c2c06e6a15be91armvixl
20690b0414b6c794be58f34813f84c2c06e6a15be91armvixl    VerbosePrint(verbose, 'Running %d tests...' % (n_tests))
20790b0414b6c794be58f34813f84c2c06e6a15be91armvixl    start_time = time.time()
20890b0414b6c794be58f34813f84c2c06e6a15be91armvixl
20990b0414b6c794be58f34813f84c2c06e6a15be91armvixl    pool = multiprocessing.Pool(jobs)
21090b0414b6c794be58f34813f84c2c06e6a15be91armvixl    # The '.get(9999999)' is workaround to allow killing the test script with
21190b0414b6c794be58f34813f84c2c06e6a15be91armvixl    # ctrl+C from the shell. This bug is documented at
21290b0414b6c794be58f34813f84c2c06e6a15be91armvixl    # http://bugs.python.org/issue8296.
21390b0414b6c794be58f34813f84c2c06e6a15be91armvixl    work = pool.map_async(RunTest, manifest).get(9999999)
21490b0414b6c794be58f34813f84c2c06e6a15be91armvixl
21590b0414b6c794be58f34813f84c2c06e6a15be91armvixl    done_message = '== Done =='
21690b0414b6c794be58f34813f84c2c06e6a15be91armvixl    UpdateProgress(start_time, n_tests_passed.value, n_tests_failed.value,
21790b0414b6c794be58f34813f84c2c06e6a15be91armvixl                   n_tests, verbose, done_message, progress_prefix)
21890b0414b6c794be58f34813f84c2c06e6a15be91armvixl
21990b0414b6c794be58f34813f84c2c06e6a15be91armvixl    return n_tests_failed.value # 0 indicates success
220ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
221ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
222ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixlif __name__ == '__main__':
223ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # $ROOT/tools/test.py
224ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  root_dir = os.path.dirname(os.path.dirname(os.path.abspath(sys.argv[0])))
225ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
226ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  # Parse the arguments.
227ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  args = BuildOptions()
228ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
2294a06316541258e3c058792321295ee36d409f419armvixl  # Find a valid path to args.runner (in case it doesn't begin with './').
2304a06316541258e3c058792321295ee36d409f419armvixl  args.runner = os.path.join('.', args.runner)
231ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl
2324a06316541258e3c058792321295ee36d409f419armvixl  if not os.access(args.runner, os.X_OK):
2334a06316541258e3c058792321295ee36d409f419armvixl    print "'" + args.test + "' is not executable or does not exist."
234ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl    sys.exit(1)
235ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
236ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  # List all matching tests.
2374a06316541258e3c058792321295ee36d409f419armvixl  manifest = ReadManifest(args.runner, args.filters,
23890b0414b6c794be58f34813f84c2c06e6a15be91armvixl                          args.debugger, args.coloured_trace, args.verbose)
239ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
240ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  # Run the tests.
24190b0414b6c794be58f34813f84c2c06e6a15be91armvixl  status = RunTests(manifest, jobs=args.jobs,
24290b0414b6c794be58f34813f84c2c06e6a15be91armvixl                    verbose=args.verbose, debugger=args.debugger)
243ae093bfb93c7d6b6cc143546a4211995a9db4ebfarmvixl  EnsureNewLine()
244ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
245ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl  sys.exit(status)
246ad96eda8944ab1c1ba55715c50d9d6f0a3ed1dcarmvixl
247