1# Copyright 2019, VIXL authors 2# All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are met: 6# 7# * Redistributions of source code must retain the above copyright notice, 8# this list of conditions and the following disclaimer. 9# * Redistributions in binary form must reproduce the above copyright notice, 10# this list of conditions and the following disclaimer in the documentation 11# and/or other materials provided with the distribution. 12# * Neither the name of ARM Limited nor the names of its contributors may be 13# used to endorse or promote products derived from this software without 14# specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS CONTRIBUTORS "AS IS" AND 17# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 20# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 23# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 24# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 25# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27import re 28import subprocess 29 30from known_test_failures import FilterKnownTestFailures 31import printer 32import threaded_tests 33from threaded_tests import Test 34import util 35 36# Scan matching tests and return a test manifest. 37def GetTests(runner, filters = []): 38 rc, output = util.getstatusoutput(runner + ' --list') 39 if rc != 0: util.abort('Failed to list all tests') 40 41 tests = output.split() 42 for f in filters: 43 tests = filter(re.compile(f).search, tests) 44 45 return tests 46 47def RunTest(test): 48 command = test.args['command'] 49 p = subprocess.Popen(command, 50 stdout=subprocess.PIPE, 51 stderr=subprocess.STDOUT) 52 p_out, p_err = p.communicate() 53 rc = p.poll() 54 55 if rc == 0: 56 skipped = False 57 lines = p_out.split('\n') 58 skipped_id = "SKIPPED: " 59 for i in range(len(lines)): 60 if lines[i].startswith(skipped_id): 61 skipped = True 62 reason = lines[i][len(skipped_id):] 63 with Test.n_tests_skipped.get_lock(): 64 Test.n_tests_skipped.value += 1 65 test.shared.tests_skipped.setdefault(reason, 0) 66 test.shared.tests_skipped[reason] += 1 67 break 68 if not skipped: 69 with Test.n_tests_passed.get_lock(): Test.n_tests_passed.value += 1 70 else: 71 with Test.n_tests_failed.get_lock(): Test.n_tests_failed.value += 1 72 73 printer.__print_lock__.acquire() 74 75 printer.UpdateProgress(test.shared.start_time, 76 Test.n_tests_passed.value, 77 Test.n_tests_failed.value, 78 test.shared.n_tests, 79 Test.n_tests_skipped.value, 80 test.shared.n_known_failures, 81 test.name, 82 prevent_next_overwrite = (rc != 0), 83 has_lock = True, 84 prefix = test.shared.progress_prefix) 85 86 if rc != 0: 87 printer.Print('FAILED: ' + test.name, has_lock = True) 88 printer.Print(printer.COLOUR_RED + ' '.join(command) + printer.NO_COLOUR, 89 has_lock = True) 90 printer.Print(p_out, has_lock = True) 91 92 printer.__print_lock__.release() 93 94class TestQueue(threaded_tests.TestQueue): 95 def __init__(self): 96 super(TestQueue, self).__init__('test_runner: ') 97 98 def AddTests(self, test_runner_command, filters, runtime_options, under_valgrind): 99 tests = GetTests(test_runner_command, filters) 100 n_tests_total = len(tests) 101 tests, skipped = FilterKnownTestFailures(tests, under_valgrind = under_valgrind) 102 for n_tests, reason in skipped: 103 if n_tests > 0: 104 self.AddKnownFailures(reason, n_tests) 105 106 if len(tests) == 0: 107 printer.Print('No tests to run.') 108 return 109 110 base_command = [] 111 if under_valgrind: 112 base_command += ['valgrind'] 113 base_command += [test_runner_command] 114 for test in tests: 115 command = base_command + [test] + runtime_options 116 self.AddTest(test, command = command) 117 118 def Run(self, jobs, verbose): 119 return super(TestQueue, self).Run(jobs, verbose, RunTest) 120