11cb0ef41Sopenharmony_ci#!/usr/bin/env python3 21cb0ef41Sopenharmony_ci# 31cb0ef41Sopenharmony_ci# Copyright 2008 the V8 project authors. All rights reserved. 41cb0ef41Sopenharmony_ci# Redistribution and use in source and binary forms, with or without 51cb0ef41Sopenharmony_ci# modification, are permitted provided that the following conditions are 61cb0ef41Sopenharmony_ci# met: 71cb0ef41Sopenharmony_ci# 81cb0ef41Sopenharmony_ci# * Redistributions of source code must retain the above copyright 91cb0ef41Sopenharmony_ci# notice, this list of conditions and the following disclaimer. 101cb0ef41Sopenharmony_ci# * Redistributions in binary form must reproduce the above 111cb0ef41Sopenharmony_ci# copyright notice, this list of conditions and the following 121cb0ef41Sopenharmony_ci# disclaimer in the documentation and/or other materials provided 131cb0ef41Sopenharmony_ci# with the distribution. 141cb0ef41Sopenharmony_ci# * Neither the name of Google Inc. nor the names of its 151cb0ef41Sopenharmony_ci# contributors may be used to endorse or promote products derived 161cb0ef41Sopenharmony_ci# from this software without specific prior written permission. 171cb0ef41Sopenharmony_ci# 181cb0ef41Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 191cb0ef41Sopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 201cb0ef41Sopenharmony_ci# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 211cb0ef41Sopenharmony_ci# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 221cb0ef41Sopenharmony_ci# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 231cb0ef41Sopenharmony_ci# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 241cb0ef41Sopenharmony_ci# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 251cb0ef41Sopenharmony_ci# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 261cb0ef41Sopenharmony_ci# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 271cb0ef41Sopenharmony_ci# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 281cb0ef41Sopenharmony_ci# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 291cb0ef41Sopenharmony_ci 301cb0ef41Sopenharmony_ci 311cb0ef41Sopenharmony_cifrom __future__ import print_function 321cb0ef41Sopenharmony_cifrom typing import Dict 331cb0ef41Sopenharmony_ciimport logging 341cb0ef41Sopenharmony_ciimport optparse 351cb0ef41Sopenharmony_ciimport os 361cb0ef41Sopenharmony_ciimport re 371cb0ef41Sopenharmony_ciimport signal 381cb0ef41Sopenharmony_ciimport subprocess 391cb0ef41Sopenharmony_ciimport sys 401cb0ef41Sopenharmony_ciimport tempfile 411cb0ef41Sopenharmony_ciimport time 421cb0ef41Sopenharmony_ciimport threading 431cb0ef41Sopenharmony_ciimport utils 441cb0ef41Sopenharmony_ciimport multiprocessing 451cb0ef41Sopenharmony_ciimport errno 461cb0ef41Sopenharmony_ciimport copy 471cb0ef41Sopenharmony_ciimport io 481cb0ef41Sopenharmony_ci 491cb0ef41Sopenharmony_ci 501cb0ef41Sopenharmony_ciif sys.version_info >= (3, 5): 511cb0ef41Sopenharmony_ci from importlib import machinery, util 521cb0ef41Sopenharmony_ci def get_module(name, path): 531cb0ef41Sopenharmony_ci loader_details = (machinery.SourceFileLoader, machinery.SOURCE_SUFFIXES) 541cb0ef41Sopenharmony_ci spec = machinery.FileFinder(path, loader_details).find_spec(name) 551cb0ef41Sopenharmony_ci module = util.module_from_spec(spec) 561cb0ef41Sopenharmony_ci spec.loader.exec_module(module) 571cb0ef41Sopenharmony_ci return module 581cb0ef41Sopenharmony_cielse: 591cb0ef41Sopenharmony_ci import imp 601cb0ef41Sopenharmony_ci def get_module(name, path): 611cb0ef41Sopenharmony_ci file = None 621cb0ef41Sopenharmony_ci try: 631cb0ef41Sopenharmony_ci (file, pathname, description) = imp.find_module(name, [path]) 641cb0ef41Sopenharmony_ci return imp.load_module(name, file, pathname, description) 651cb0ef41Sopenharmony_ci finally: 661cb0ef41Sopenharmony_ci if file: 671cb0ef41Sopenharmony_ci file.close() 681cb0ef41Sopenharmony_ci 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_cifrom io import open 711cb0ef41Sopenharmony_cifrom os.path import join, dirname, abspath, basename, isdir, exists 721cb0ef41Sopenharmony_cifrom datetime import datetime, timedelta 731cb0ef41Sopenharmony_citry: 741cb0ef41Sopenharmony_ci from queue import Queue, Empty # Python 3 751cb0ef41Sopenharmony_ciexcept ImportError: 761cb0ef41Sopenharmony_ci from Queue import Queue, Empty # Python 2 771cb0ef41Sopenharmony_ci 781cb0ef41Sopenharmony_cifrom functools import reduce 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_citry: 811cb0ef41Sopenharmony_ci from urllib.parse import unquote # Python 3 821cb0ef41Sopenharmony_ciexcept ImportError: 831cb0ef41Sopenharmony_ci from urllib import unquote # Python 2 841cb0ef41Sopenharmony_ci 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_cilogger = logging.getLogger('testrunner') 871cb0ef41Sopenharmony_ciskip_regex = re.compile(r'# SKIP\S*\s+(.*)', re.IGNORECASE) 881cb0ef41Sopenharmony_ci 891cb0ef41Sopenharmony_ciVERBOSE = False 901cb0ef41Sopenharmony_ci 911cb0ef41Sopenharmony_cios.umask(0o022) 921cb0ef41Sopenharmony_cios.environ['NODE_OPTIONS'] = '' 931cb0ef41Sopenharmony_ci 941cb0ef41Sopenharmony_ci# --------------------------------------------- 951cb0ef41Sopenharmony_ci# --- P r o g r e s s I n d i c a t o r s --- 961cb0ef41Sopenharmony_ci# --------------------------------------------- 971cb0ef41Sopenharmony_ci 981cb0ef41Sopenharmony_ci 991cb0ef41Sopenharmony_ciclass ProgressIndicator(object): 1001cb0ef41Sopenharmony_ci 1011cb0ef41Sopenharmony_ci def __init__(self, cases, flaky_tests_mode, measure_flakiness): 1021cb0ef41Sopenharmony_ci self.cases = cases 1031cb0ef41Sopenharmony_ci self.serial_id = 0 1041cb0ef41Sopenharmony_ci self.flaky_tests_mode = flaky_tests_mode 1051cb0ef41Sopenharmony_ci self.measure_flakiness = measure_flakiness 1061cb0ef41Sopenharmony_ci self.parallel_queue = Queue(len(cases)) 1071cb0ef41Sopenharmony_ci self.sequential_queue = Queue(len(cases)) 1081cb0ef41Sopenharmony_ci for case in cases: 1091cb0ef41Sopenharmony_ci if case.parallel: 1101cb0ef41Sopenharmony_ci self.parallel_queue.put_nowait(case) 1111cb0ef41Sopenharmony_ci else: 1121cb0ef41Sopenharmony_ci self.sequential_queue.put_nowait(case) 1131cb0ef41Sopenharmony_ci self.succeeded = 0 1141cb0ef41Sopenharmony_ci self.remaining = len(cases) 1151cb0ef41Sopenharmony_ci self.total = len(cases) 1161cb0ef41Sopenharmony_ci self.failed = [ ] 1171cb0ef41Sopenharmony_ci self.flaky_failed = [ ] 1181cb0ef41Sopenharmony_ci self.crashed = 0 1191cb0ef41Sopenharmony_ci self.lock = threading.Lock() 1201cb0ef41Sopenharmony_ci self.shutdown_event = threading.Event() 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci def GetFailureOutput(self, failure): 1231cb0ef41Sopenharmony_ci output = [] 1241cb0ef41Sopenharmony_ci if failure.output.stderr: 1251cb0ef41Sopenharmony_ci output += ["--- stderr ---" ] 1261cb0ef41Sopenharmony_ci output += [failure.output.stderr.strip()] 1271cb0ef41Sopenharmony_ci if failure.output.stdout: 1281cb0ef41Sopenharmony_ci output += ["--- stdout ---"] 1291cb0ef41Sopenharmony_ci output += [failure.output.stdout.strip()] 1301cb0ef41Sopenharmony_ci output += ["Command: %s" % EscapeCommand(failure.command)] 1311cb0ef41Sopenharmony_ci if failure.HasCrashed(): 1321cb0ef41Sopenharmony_ci output += ["--- %s ---" % PrintCrashed(failure.output.exit_code)] 1331cb0ef41Sopenharmony_ci if failure.HasTimedOut(): 1341cb0ef41Sopenharmony_ci output += ["--- TIMEOUT ---"] 1351cb0ef41Sopenharmony_ci output = "\n".join(output) 1361cb0ef41Sopenharmony_ci return output 1371cb0ef41Sopenharmony_ci 1381cb0ef41Sopenharmony_ci def PrintFailureOutput(self, failure): 1391cb0ef41Sopenharmony_ci print(self.GetFailureOutput(failure)) 1401cb0ef41Sopenharmony_ci 1411cb0ef41Sopenharmony_ci def PrintFailureHeader(self, test): 1421cb0ef41Sopenharmony_ci if test.IsNegative(): 1431cb0ef41Sopenharmony_ci negative_marker = '[negative] ' 1441cb0ef41Sopenharmony_ci else: 1451cb0ef41Sopenharmony_ci negative_marker = '' 1461cb0ef41Sopenharmony_ci print("=== %(label)s %(negative)s===" % { 1471cb0ef41Sopenharmony_ci 'label': test.GetLabel(), 1481cb0ef41Sopenharmony_ci 'negative': negative_marker 1491cb0ef41Sopenharmony_ci }) 1501cb0ef41Sopenharmony_ci print("Path: %s" % "/".join(test.path)) 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci def Run(self, tasks) -> Dict: 1531cb0ef41Sopenharmony_ci self.Starting() 1541cb0ef41Sopenharmony_ci threads = [] 1551cb0ef41Sopenharmony_ci # Spawn N-1 threads and then use this thread as the last one. 1561cb0ef41Sopenharmony_ci # That way -j1 avoids threading altogether which is a nice fallback 1571cb0ef41Sopenharmony_ci # in case of threading problems. 1581cb0ef41Sopenharmony_ci for i in range(tasks - 1): 1591cb0ef41Sopenharmony_ci thread = threading.Thread(target=self.RunSingle, args=[True, i + 1]) 1601cb0ef41Sopenharmony_ci threads.append(thread) 1611cb0ef41Sopenharmony_ci thread.start() 1621cb0ef41Sopenharmony_ci try: 1631cb0ef41Sopenharmony_ci self.RunSingle(False, 0) 1641cb0ef41Sopenharmony_ci # Wait for the remaining threads 1651cb0ef41Sopenharmony_ci for thread in threads: 1661cb0ef41Sopenharmony_ci # Use a timeout so that signals (ctrl-c) will be processed. 1671cb0ef41Sopenharmony_ci thread.join(timeout=1000000) 1681cb0ef41Sopenharmony_ci except (KeyboardInterrupt, SystemExit): 1691cb0ef41Sopenharmony_ci self.shutdown_event.set() 1701cb0ef41Sopenharmony_ci except Exception: 1711cb0ef41Sopenharmony_ci # If there's an exception we schedule an interruption for any 1721cb0ef41Sopenharmony_ci # remaining threads. 1731cb0ef41Sopenharmony_ci self.shutdown_event.set() 1741cb0ef41Sopenharmony_ci # ...and then reraise the exception to bail out 1751cb0ef41Sopenharmony_ci raise 1761cb0ef41Sopenharmony_ci self.Done() 1771cb0ef41Sopenharmony_ci return { 1781cb0ef41Sopenharmony_ci 'allPassed': not self.failed, 1791cb0ef41Sopenharmony_ci 'failed': self.failed, 1801cb0ef41Sopenharmony_ci } 1811cb0ef41Sopenharmony_ci 1821cb0ef41Sopenharmony_ci def RunSingle(self, parallel, thread_id): 1831cb0ef41Sopenharmony_ci while not self.shutdown_event.is_set(): 1841cb0ef41Sopenharmony_ci try: 1851cb0ef41Sopenharmony_ci test = self.parallel_queue.get_nowait() 1861cb0ef41Sopenharmony_ci except Empty: 1871cb0ef41Sopenharmony_ci if parallel: 1881cb0ef41Sopenharmony_ci return 1891cb0ef41Sopenharmony_ci try: 1901cb0ef41Sopenharmony_ci test = self.sequential_queue.get_nowait() 1911cb0ef41Sopenharmony_ci except Empty: 1921cb0ef41Sopenharmony_ci return 1931cb0ef41Sopenharmony_ci case = test 1941cb0ef41Sopenharmony_ci case.thread_id = thread_id 1951cb0ef41Sopenharmony_ci self.lock.acquire() 1961cb0ef41Sopenharmony_ci case.serial_id = self.serial_id 1971cb0ef41Sopenharmony_ci self.serial_id += 1 1981cb0ef41Sopenharmony_ci self.AboutToRun(case) 1991cb0ef41Sopenharmony_ci self.lock.release() 2001cb0ef41Sopenharmony_ci try: 2011cb0ef41Sopenharmony_ci start = datetime.now() 2021cb0ef41Sopenharmony_ci output = case.Run() 2031cb0ef41Sopenharmony_ci # SmartOS has a bug that causes unexpected ECONNREFUSED errors. 2041cb0ef41Sopenharmony_ci # See https://smartos.org/bugview/OS-2767 2051cb0ef41Sopenharmony_ci # If ECONNREFUSED on SmartOS, retry the test one time. 2061cb0ef41Sopenharmony_ci if (output.UnexpectedOutput() and 2071cb0ef41Sopenharmony_ci sys.platform == 'sunos5' and 2081cb0ef41Sopenharmony_ci 'ECONNREFUSED' in output.output.stderr): 2091cb0ef41Sopenharmony_ci output = case.Run() 2101cb0ef41Sopenharmony_ci output.diagnostic.append('ECONNREFUSED received, test retried') 2111cb0ef41Sopenharmony_ci case.duration = (datetime.now() - start) 2121cb0ef41Sopenharmony_ci except IOError: 2131cb0ef41Sopenharmony_ci return 2141cb0ef41Sopenharmony_ci if self.shutdown_event.is_set(): 2151cb0ef41Sopenharmony_ci return 2161cb0ef41Sopenharmony_ci self.lock.acquire() 2171cb0ef41Sopenharmony_ci if output.UnexpectedOutput(): 2181cb0ef41Sopenharmony_ci if FLAKY in output.test.outcomes and self.flaky_tests_mode == DONTCARE: 2191cb0ef41Sopenharmony_ci self.flaky_failed.append(output) 2201cb0ef41Sopenharmony_ci elif FLAKY in output.test.outcomes and self.flaky_tests_mode == KEEP_RETRYING: 2211cb0ef41Sopenharmony_ci for _ in range(99): 2221cb0ef41Sopenharmony_ci if not case.Run().UnexpectedOutput(): 2231cb0ef41Sopenharmony_ci self.flaky_failed.append(output) 2241cb0ef41Sopenharmony_ci break 2251cb0ef41Sopenharmony_ci else: 2261cb0ef41Sopenharmony_ci # If after 100 tries, the test is not passing, it's not flaky. 2271cb0ef41Sopenharmony_ci self.failed.append(output) 2281cb0ef41Sopenharmony_ci else: 2291cb0ef41Sopenharmony_ci self.failed.append(output) 2301cb0ef41Sopenharmony_ci if output.HasCrashed(): 2311cb0ef41Sopenharmony_ci self.crashed += 1 2321cb0ef41Sopenharmony_ci if self.measure_flakiness: 2331cb0ef41Sopenharmony_ci outputs = [case.Run() for _ in range(self.measure_flakiness)] 2341cb0ef41Sopenharmony_ci # +1s are there because the test already failed once at this point. 2351cb0ef41Sopenharmony_ci print(" failed %d out of %d" % (len([i for i in outputs if i.UnexpectedOutput()]) + 1, self.measure_flakiness + 1)) 2361cb0ef41Sopenharmony_ci else: 2371cb0ef41Sopenharmony_ci self.succeeded += 1 2381cb0ef41Sopenharmony_ci self.remaining -= 1 2391cb0ef41Sopenharmony_ci self.HasRun(output) 2401cb0ef41Sopenharmony_ci self.lock.release() 2411cb0ef41Sopenharmony_ci 2421cb0ef41Sopenharmony_ci 2431cb0ef41Sopenharmony_cidef EscapeCommand(command): 2441cb0ef41Sopenharmony_ci parts = [] 2451cb0ef41Sopenharmony_ci for part in command: 2461cb0ef41Sopenharmony_ci if ' ' in part: 2471cb0ef41Sopenharmony_ci # Escape spaces. We may need to escape more characters for this 2481cb0ef41Sopenharmony_ci # to work properly. 2491cb0ef41Sopenharmony_ci parts.append('"%s"' % part) 2501cb0ef41Sopenharmony_ci else: 2511cb0ef41Sopenharmony_ci parts.append(part) 2521cb0ef41Sopenharmony_ci return " ".join(parts) 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci 2551cb0ef41Sopenharmony_ciclass SimpleProgressIndicator(ProgressIndicator): 2561cb0ef41Sopenharmony_ci 2571cb0ef41Sopenharmony_ci def Starting(self): 2581cb0ef41Sopenharmony_ci print('Running %i tests' % len(self.cases)) 2591cb0ef41Sopenharmony_ci 2601cb0ef41Sopenharmony_ci def Done(self): 2611cb0ef41Sopenharmony_ci print() 2621cb0ef41Sopenharmony_ci for failed in self.failed: 2631cb0ef41Sopenharmony_ci self.PrintFailureHeader(failed.test) 2641cb0ef41Sopenharmony_ci self.PrintFailureOutput(failed) 2651cb0ef41Sopenharmony_ci if len(self.failed) == 0: 2661cb0ef41Sopenharmony_ci print("===") 2671cb0ef41Sopenharmony_ci print("=== All tests succeeded") 2681cb0ef41Sopenharmony_ci print("===") 2691cb0ef41Sopenharmony_ci else: 2701cb0ef41Sopenharmony_ci print() 2711cb0ef41Sopenharmony_ci print("===") 2721cb0ef41Sopenharmony_ci print("=== %i tests failed" % len(self.failed)) 2731cb0ef41Sopenharmony_ci if self.crashed > 0: 2741cb0ef41Sopenharmony_ci print("=== %i tests CRASHED" % self.crashed) 2751cb0ef41Sopenharmony_ci print("===") 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci 2781cb0ef41Sopenharmony_ciclass VerboseProgressIndicator(SimpleProgressIndicator): 2791cb0ef41Sopenharmony_ci 2801cb0ef41Sopenharmony_ci def AboutToRun(self, case): 2811cb0ef41Sopenharmony_ci print('Starting %s...' % case.GetLabel()) 2821cb0ef41Sopenharmony_ci sys.stdout.flush() 2831cb0ef41Sopenharmony_ci 2841cb0ef41Sopenharmony_ci def HasRun(self, output): 2851cb0ef41Sopenharmony_ci if output.UnexpectedOutput(): 2861cb0ef41Sopenharmony_ci if output.HasCrashed(): 2871cb0ef41Sopenharmony_ci outcome = 'CRASH' 2881cb0ef41Sopenharmony_ci else: 2891cb0ef41Sopenharmony_ci outcome = 'FAIL' 2901cb0ef41Sopenharmony_ci else: 2911cb0ef41Sopenharmony_ci outcome = 'pass' 2921cb0ef41Sopenharmony_ci print('Done running %s: %s' % (output.test.GetLabel(), outcome)) 2931cb0ef41Sopenharmony_ci 2941cb0ef41Sopenharmony_ci 2951cb0ef41Sopenharmony_ciclass DotsProgressIndicator(SimpleProgressIndicator): 2961cb0ef41Sopenharmony_ci 2971cb0ef41Sopenharmony_ci def AboutToRun(self, case): 2981cb0ef41Sopenharmony_ci pass 2991cb0ef41Sopenharmony_ci 3001cb0ef41Sopenharmony_ci def HasRun(self, output): 3011cb0ef41Sopenharmony_ci total = self.succeeded + len(self.failed) 3021cb0ef41Sopenharmony_ci if (total > 1) and (total % 50 == 1): 3031cb0ef41Sopenharmony_ci sys.stdout.write('\n') 3041cb0ef41Sopenharmony_ci if output.UnexpectedOutput(): 3051cb0ef41Sopenharmony_ci if output.HasCrashed(): 3061cb0ef41Sopenharmony_ci sys.stdout.write('C') 3071cb0ef41Sopenharmony_ci sys.stdout.flush() 3081cb0ef41Sopenharmony_ci elif output.HasTimedOut(): 3091cb0ef41Sopenharmony_ci sys.stdout.write('T') 3101cb0ef41Sopenharmony_ci sys.stdout.flush() 3111cb0ef41Sopenharmony_ci else: 3121cb0ef41Sopenharmony_ci sys.stdout.write('F') 3131cb0ef41Sopenharmony_ci sys.stdout.flush() 3141cb0ef41Sopenharmony_ci else: 3151cb0ef41Sopenharmony_ci sys.stdout.write('.') 3161cb0ef41Sopenharmony_ci sys.stdout.flush() 3171cb0ef41Sopenharmony_ci 3181cb0ef41Sopenharmony_ciclass ActionsAnnotationProgressIndicator(DotsProgressIndicator): 3191cb0ef41Sopenharmony_ci def GetAnnotationInfo(self, test, output): 3201cb0ef41Sopenharmony_ci traceback = output.stdout + output.stderr 3211cb0ef41Sopenharmony_ci find_full_path = re.search(r' +at .*\(.*%s:([0-9]+):([0-9]+)' % test.file, traceback) 3221cb0ef41Sopenharmony_ci col = line = 0 3231cb0ef41Sopenharmony_ci if find_full_path: 3241cb0ef41Sopenharmony_ci line, col = map(int, find_full_path.groups()) 3251cb0ef41Sopenharmony_ci root_path = abspath(join(dirname(__file__), '../')) + os.sep 3261cb0ef41Sopenharmony_ci filename = test.file.replace(root_path, "") 3271cb0ef41Sopenharmony_ci return filename, line, col 3281cb0ef41Sopenharmony_ci 3291cb0ef41Sopenharmony_ci def PrintFailureOutput(self, failure): 3301cb0ef41Sopenharmony_ci output = self.GetFailureOutput(failure) 3311cb0ef41Sopenharmony_ci filename, line, column = self.GetAnnotationInfo(failure.test, failure.output) 3321cb0ef41Sopenharmony_ci print("::error file=%s,line=%d,col=%d::%s" % (filename, line, column, output.replace('\n', '%0A'))) 3331cb0ef41Sopenharmony_ci 3341cb0ef41Sopenharmony_ciclass TapProgressIndicator(SimpleProgressIndicator): 3351cb0ef41Sopenharmony_ci 3361cb0ef41Sopenharmony_ci def _printDiagnostic(self): 3371cb0ef41Sopenharmony_ci logger.info(' severity: %s', self.severity) 3381cb0ef41Sopenharmony_ci self.exitcode and logger.info(' exitcode: %s', self.exitcode) 3391cb0ef41Sopenharmony_ci logger.info(' stack: |-') 3401cb0ef41Sopenharmony_ci 3411cb0ef41Sopenharmony_ci for l in self.traceback.splitlines(): 3421cb0ef41Sopenharmony_ci logger.info(' ' + l) 3431cb0ef41Sopenharmony_ci 3441cb0ef41Sopenharmony_ci def Starting(self): 3451cb0ef41Sopenharmony_ci logger.info('TAP version 13') 3461cb0ef41Sopenharmony_ci logger.info('1..%i' % len(self.cases)) 3471cb0ef41Sopenharmony_ci self._done = 0 3481cb0ef41Sopenharmony_ci 3491cb0ef41Sopenharmony_ci def AboutToRun(self, case): 3501cb0ef41Sopenharmony_ci pass 3511cb0ef41Sopenharmony_ci 3521cb0ef41Sopenharmony_ci def HasRun(self, output): 3531cb0ef41Sopenharmony_ci self._done += 1 3541cb0ef41Sopenharmony_ci self.traceback = '' 3551cb0ef41Sopenharmony_ci self.severity = 'ok' 3561cb0ef41Sopenharmony_ci self.exitcode = '' 3571cb0ef41Sopenharmony_ci 3581cb0ef41Sopenharmony_ci # Print test name as (for example) "parallel/test-assert". Tests that are 3591cb0ef41Sopenharmony_ci # scraped from the addons documentation are all named test.js, making it 3601cb0ef41Sopenharmony_ci # hard to decipher what test is running when only the filename is printed. 3611cb0ef41Sopenharmony_ci prefix = abspath(join(dirname(__file__), '../test')) + os.sep 3621cb0ef41Sopenharmony_ci command = output.command[-1] 3631cb0ef41Sopenharmony_ci command = NormalizePath(command, prefix) 3641cb0ef41Sopenharmony_ci 3651cb0ef41Sopenharmony_ci if output.UnexpectedOutput(): 3661cb0ef41Sopenharmony_ci status_line = 'not ok %i %s' % (self._done, command) 3671cb0ef41Sopenharmony_ci self.severity = 'fail' 3681cb0ef41Sopenharmony_ci self.exitcode = output.output.exit_code 3691cb0ef41Sopenharmony_ci self.traceback = output.output.stdout + output.output.stderr 3701cb0ef41Sopenharmony_ci 3711cb0ef41Sopenharmony_ci if FLAKY in output.test.outcomes and self.flaky_tests_mode == DONTCARE: 3721cb0ef41Sopenharmony_ci status_line = status_line + ' # TODO : Fix flaky test' 3731cb0ef41Sopenharmony_ci self.severity = 'flaky' 3741cb0ef41Sopenharmony_ci 3751cb0ef41Sopenharmony_ci logger.info(status_line) 3761cb0ef41Sopenharmony_ci 3771cb0ef41Sopenharmony_ci if output.HasCrashed(): 3781cb0ef41Sopenharmony_ci self.severity = 'crashed' 3791cb0ef41Sopenharmony_ci 3801cb0ef41Sopenharmony_ci elif output.HasTimedOut(): 3811cb0ef41Sopenharmony_ci self.severity = 'fail' 3821cb0ef41Sopenharmony_ci 3831cb0ef41Sopenharmony_ci else: 3841cb0ef41Sopenharmony_ci skip = skip_regex.search(output.output.stdout) 3851cb0ef41Sopenharmony_ci if skip: 3861cb0ef41Sopenharmony_ci logger.info( 3871cb0ef41Sopenharmony_ci 'ok %i %s # skip %s' % (self._done, command, skip.group(1))) 3881cb0ef41Sopenharmony_ci else: 3891cb0ef41Sopenharmony_ci status_line = 'ok %i %s' % (self._done, command) 3901cb0ef41Sopenharmony_ci if FLAKY in output.test.outcomes: 3911cb0ef41Sopenharmony_ci status_line = status_line + ' # TODO : Fix flaky test' 3921cb0ef41Sopenharmony_ci logger.info(status_line) 3931cb0ef41Sopenharmony_ci 3941cb0ef41Sopenharmony_ci if output.diagnostic: 3951cb0ef41Sopenharmony_ci self.severity = 'ok' 3961cb0ef41Sopenharmony_ci if isinstance(output.diagnostic, list): 3971cb0ef41Sopenharmony_ci self.traceback = '\n'.join(output.diagnostic) 3981cb0ef41Sopenharmony_ci else: 3991cb0ef41Sopenharmony_ci self.traceback = output.diagnostic 4001cb0ef41Sopenharmony_ci 4011cb0ef41Sopenharmony_ci 4021cb0ef41Sopenharmony_ci duration = output.test.duration 4031cb0ef41Sopenharmony_ci logger.info(' ---') 4041cb0ef41Sopenharmony_ci logger.info(' duration_ms: %.5f' % (duration / timedelta(milliseconds=1))) 4051cb0ef41Sopenharmony_ci if self.severity != 'ok' or self.traceback != '': 4061cb0ef41Sopenharmony_ci if output.HasTimedOut(): 4071cb0ef41Sopenharmony_ci self.traceback = 'timeout\n' + output.output.stdout + output.output.stderr 4081cb0ef41Sopenharmony_ci self._printDiagnostic() 4091cb0ef41Sopenharmony_ci logger.info(' ...') 4101cb0ef41Sopenharmony_ci 4111cb0ef41Sopenharmony_ci def Done(self): 4121cb0ef41Sopenharmony_ci pass 4131cb0ef41Sopenharmony_ci 4141cb0ef41Sopenharmony_ciclass DeoptsCheckProgressIndicator(SimpleProgressIndicator): 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci def Starting(self): 4171cb0ef41Sopenharmony_ci pass 4181cb0ef41Sopenharmony_ci 4191cb0ef41Sopenharmony_ci def AboutToRun(self, case): 4201cb0ef41Sopenharmony_ci pass 4211cb0ef41Sopenharmony_ci 4221cb0ef41Sopenharmony_ci def HasRun(self, output): 4231cb0ef41Sopenharmony_ci # Print test name as (for example) "parallel/test-assert". Tests that are 4241cb0ef41Sopenharmony_ci # scraped from the addons documentation are all named test.js, making it 4251cb0ef41Sopenharmony_ci # hard to decipher what test is running when only the filename is printed. 4261cb0ef41Sopenharmony_ci prefix = abspath(join(dirname(__file__), '../test')) + os.sep 4271cb0ef41Sopenharmony_ci command = output.command[-1] 4281cb0ef41Sopenharmony_ci command = NormalizePath(command, prefix) 4291cb0ef41Sopenharmony_ci 4301cb0ef41Sopenharmony_ci stdout = output.output.stdout.strip() 4311cb0ef41Sopenharmony_ci printed_file = False 4321cb0ef41Sopenharmony_ci for line in stdout.splitlines(): 4331cb0ef41Sopenharmony_ci if ( 4341cb0ef41Sopenharmony_ci (line.startswith("[aborted optimiz") or line.startswith("[disabled optimiz")) and 4351cb0ef41Sopenharmony_ci ("because:" in line or "reason:" in line) 4361cb0ef41Sopenharmony_ci ): 4371cb0ef41Sopenharmony_ci if not printed_file: 4381cb0ef41Sopenharmony_ci printed_file = True 4391cb0ef41Sopenharmony_ci print('==== %s ====' % command) 4401cb0ef41Sopenharmony_ci self.failed.append(output) 4411cb0ef41Sopenharmony_ci print(' %s' % line) 4421cb0ef41Sopenharmony_ci 4431cb0ef41Sopenharmony_ci def Done(self): 4441cb0ef41Sopenharmony_ci pass 4451cb0ef41Sopenharmony_ci 4461cb0ef41Sopenharmony_ci 4471cb0ef41Sopenharmony_ciclass CompactProgressIndicator(ProgressIndicator): 4481cb0ef41Sopenharmony_ci 4491cb0ef41Sopenharmony_ci def __init__(self, cases, flaky_tests_mode, measure_flakiness, templates): 4501cb0ef41Sopenharmony_ci super(CompactProgressIndicator, self).__init__(cases, flaky_tests_mode, measure_flakiness) 4511cb0ef41Sopenharmony_ci self.templates = templates 4521cb0ef41Sopenharmony_ci self.last_status_length = 0 4531cb0ef41Sopenharmony_ci self.start_time = time.time() 4541cb0ef41Sopenharmony_ci 4551cb0ef41Sopenharmony_ci def Starting(self): 4561cb0ef41Sopenharmony_ci pass 4571cb0ef41Sopenharmony_ci 4581cb0ef41Sopenharmony_ci def Done(self): 4591cb0ef41Sopenharmony_ci self.PrintProgress('Done\n') 4601cb0ef41Sopenharmony_ci 4611cb0ef41Sopenharmony_ci def AboutToRun(self, case): 4621cb0ef41Sopenharmony_ci self.PrintProgress(case.GetLabel()) 4631cb0ef41Sopenharmony_ci 4641cb0ef41Sopenharmony_ci def HasRun(self, output): 4651cb0ef41Sopenharmony_ci if output.UnexpectedOutput(): 4661cb0ef41Sopenharmony_ci self.ClearLine(self.last_status_length) 4671cb0ef41Sopenharmony_ci self.PrintFailureHeader(output.test) 4681cb0ef41Sopenharmony_ci stdout = output.output.stdout.strip() 4691cb0ef41Sopenharmony_ci if len(stdout): 4701cb0ef41Sopenharmony_ci print(self.templates['stdout'] % stdout) 4711cb0ef41Sopenharmony_ci stderr = output.output.stderr.strip() 4721cb0ef41Sopenharmony_ci if len(stderr): 4731cb0ef41Sopenharmony_ci print(self.templates['stderr'] % stderr) 4741cb0ef41Sopenharmony_ci print("Command: %s" % EscapeCommand(output.command)) 4751cb0ef41Sopenharmony_ci if output.HasCrashed(): 4761cb0ef41Sopenharmony_ci print("--- %s ---" % PrintCrashed(output.output.exit_code)) 4771cb0ef41Sopenharmony_ci if output.HasTimedOut(): 4781cb0ef41Sopenharmony_ci print("--- TIMEOUT ---") 4791cb0ef41Sopenharmony_ci print("\n") # Two blank lines between failures, for visual separation 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_ci def Truncate(self, str, length): 4821cb0ef41Sopenharmony_ci if length and (len(str) > (length - 3)): 4831cb0ef41Sopenharmony_ci return str[:(length-3)] + "..." 4841cb0ef41Sopenharmony_ci else: 4851cb0ef41Sopenharmony_ci return str 4861cb0ef41Sopenharmony_ci 4871cb0ef41Sopenharmony_ci def PrintProgress(self, name): 4881cb0ef41Sopenharmony_ci self.ClearLine(self.last_status_length) 4891cb0ef41Sopenharmony_ci elapsed = time.time() - self.start_time 4901cb0ef41Sopenharmony_ci status = self.templates['status_line'] % { 4911cb0ef41Sopenharmony_ci 'passed': self.succeeded, 4921cb0ef41Sopenharmony_ci 'remaining': (((self.total - self.remaining) * 100) // self.total), 4931cb0ef41Sopenharmony_ci 'failed': len(self.failed), 4941cb0ef41Sopenharmony_ci 'test': name, 4951cb0ef41Sopenharmony_ci 'mins': int(elapsed) / 60, 4961cb0ef41Sopenharmony_ci 'secs': int(elapsed) % 60 4971cb0ef41Sopenharmony_ci } 4981cb0ef41Sopenharmony_ci status = self.Truncate(status, 78) 4991cb0ef41Sopenharmony_ci self.last_status_length = len(status) 5001cb0ef41Sopenharmony_ci print(status, end='') 5011cb0ef41Sopenharmony_ci sys.stdout.flush() 5021cb0ef41Sopenharmony_ci 5031cb0ef41Sopenharmony_ci 5041cb0ef41Sopenharmony_ciclass ColorProgressIndicator(CompactProgressIndicator): 5051cb0ef41Sopenharmony_ci 5061cb0ef41Sopenharmony_ci def __init__(self, cases, flaky_tests_mode, measure_flakiness): 5071cb0ef41Sopenharmony_ci templates = { 5081cb0ef41Sopenharmony_ci 'status_line': "[%(mins)02i:%(secs)02i|\033[34m%%%(remaining) 4d\033[0m|\033[32m+%(passed) 4d\033[0m|\033[31m-%(failed) 4d\033[0m]: %(test)s", 5091cb0ef41Sopenharmony_ci 'stdout': "\033[1m%s\033[0m", 5101cb0ef41Sopenharmony_ci 'stderr': "\033[31m%s\033[0m", 5111cb0ef41Sopenharmony_ci } 5121cb0ef41Sopenharmony_ci super(ColorProgressIndicator, self).__init__(cases, flaky_tests_mode, measure_flakiness, templates) 5131cb0ef41Sopenharmony_ci 5141cb0ef41Sopenharmony_ci def ClearLine(self, last_line_length): 5151cb0ef41Sopenharmony_ci print("\033[1K\r", end='') 5161cb0ef41Sopenharmony_ci 5171cb0ef41Sopenharmony_ci 5181cb0ef41Sopenharmony_ciclass MonochromeProgressIndicator(CompactProgressIndicator): 5191cb0ef41Sopenharmony_ci 5201cb0ef41Sopenharmony_ci def __init__(self, cases, flaky_tests_mode, measure_flakiness): 5211cb0ef41Sopenharmony_ci templates = { 5221cb0ef41Sopenharmony_ci 'status_line': "[%(mins)02i:%(secs)02i|%%%(remaining) 4d|+%(passed) 4d|-%(failed) 4d]: %(test)s", 5231cb0ef41Sopenharmony_ci 'stdout': '%s', 5241cb0ef41Sopenharmony_ci 'stderr': '%s', 5251cb0ef41Sopenharmony_ci 'clear': lambda last_line_length: ("\r" + (" " * last_line_length) + "\r"), 5261cb0ef41Sopenharmony_ci 'max_length': 78 5271cb0ef41Sopenharmony_ci } 5281cb0ef41Sopenharmony_ci super(MonochromeProgressIndicator, self).__init__(cases, flaky_tests_mode, measure_flakiness, templates) 5291cb0ef41Sopenharmony_ci 5301cb0ef41Sopenharmony_ci def ClearLine(self, last_line_length): 5311cb0ef41Sopenharmony_ci print(("\r" + (" " * last_line_length) + "\r"), end='') 5321cb0ef41Sopenharmony_ci 5331cb0ef41Sopenharmony_ci 5341cb0ef41Sopenharmony_ciPROGRESS_INDICATORS = { 5351cb0ef41Sopenharmony_ci 'verbose': VerboseProgressIndicator, 5361cb0ef41Sopenharmony_ci 'dots': DotsProgressIndicator, 5371cb0ef41Sopenharmony_ci 'actions': ActionsAnnotationProgressIndicator, 5381cb0ef41Sopenharmony_ci 'color': ColorProgressIndicator, 5391cb0ef41Sopenharmony_ci 'tap': TapProgressIndicator, 5401cb0ef41Sopenharmony_ci 'mono': MonochromeProgressIndicator, 5411cb0ef41Sopenharmony_ci 'deopts': DeoptsCheckProgressIndicator 5421cb0ef41Sopenharmony_ci} 5431cb0ef41Sopenharmony_ci 5441cb0ef41Sopenharmony_ci 5451cb0ef41Sopenharmony_ci# ------------------------- 5461cb0ef41Sopenharmony_ci# --- F r a m e w o r k --- 5471cb0ef41Sopenharmony_ci# ------------------------- 5481cb0ef41Sopenharmony_ci 5491cb0ef41Sopenharmony_ci 5501cb0ef41Sopenharmony_ciclass CommandOutput(object): 5511cb0ef41Sopenharmony_ci 5521cb0ef41Sopenharmony_ci def __init__(self, exit_code, timed_out, stdout, stderr): 5531cb0ef41Sopenharmony_ci self.exit_code = exit_code 5541cb0ef41Sopenharmony_ci self.timed_out = timed_out 5551cb0ef41Sopenharmony_ci self.stdout = stdout 5561cb0ef41Sopenharmony_ci self.stderr = stderr 5571cb0ef41Sopenharmony_ci self.failed = None 5581cb0ef41Sopenharmony_ci 5591cb0ef41Sopenharmony_ci 5601cb0ef41Sopenharmony_ciclass TestCase(object): 5611cb0ef41Sopenharmony_ci 5621cb0ef41Sopenharmony_ci def __init__(self, context, path, arch, mode): 5631cb0ef41Sopenharmony_ci self.path = path 5641cb0ef41Sopenharmony_ci self.context = context 5651cb0ef41Sopenharmony_ci self.duration = None 5661cb0ef41Sopenharmony_ci self.arch = arch 5671cb0ef41Sopenharmony_ci self.mode = mode 5681cb0ef41Sopenharmony_ci self.parallel = False 5691cb0ef41Sopenharmony_ci self.disable_core_files = False 5701cb0ef41Sopenharmony_ci self.serial_id = 0 5711cb0ef41Sopenharmony_ci self.thread_id = 0 5721cb0ef41Sopenharmony_ci 5731cb0ef41Sopenharmony_ci def IsNegative(self): 5741cb0ef41Sopenharmony_ci return self.context.expect_fail 5751cb0ef41Sopenharmony_ci 5761cb0ef41Sopenharmony_ci def DidFail(self, output): 5771cb0ef41Sopenharmony_ci if output.failed is None: 5781cb0ef41Sopenharmony_ci output.failed = self.IsFailureOutput(output) 5791cb0ef41Sopenharmony_ci return output.failed 5801cb0ef41Sopenharmony_ci 5811cb0ef41Sopenharmony_ci def IsFailureOutput(self, output): 5821cb0ef41Sopenharmony_ci return output.exit_code != 0 5831cb0ef41Sopenharmony_ci 5841cb0ef41Sopenharmony_ci def GetSource(self): 5851cb0ef41Sopenharmony_ci return "(no source available)" 5861cb0ef41Sopenharmony_ci 5871cb0ef41Sopenharmony_ci def RunCommand(self, command, env): 5881cb0ef41Sopenharmony_ci full_command = self.context.processor(command) 5891cb0ef41Sopenharmony_ci output = Execute(full_command, 5901cb0ef41Sopenharmony_ci self.context, 5911cb0ef41Sopenharmony_ci self.context.GetTimeout(self.mode, self.config.section), 5921cb0ef41Sopenharmony_ci env, 5931cb0ef41Sopenharmony_ci disable_core_files = self.disable_core_files) 5941cb0ef41Sopenharmony_ci return TestOutput(self, 5951cb0ef41Sopenharmony_ci full_command, 5961cb0ef41Sopenharmony_ci output, 5971cb0ef41Sopenharmony_ci self.context.store_unexpected_output) 5981cb0ef41Sopenharmony_ci 5991cb0ef41Sopenharmony_ci def Run(self): 6001cb0ef41Sopenharmony_ci try: 6011cb0ef41Sopenharmony_ci result = self.RunCommand(self.GetCommand(), { 6021cb0ef41Sopenharmony_ci "TEST_SERIAL_ID": "%d" % self.serial_id, 6031cb0ef41Sopenharmony_ci "TEST_THREAD_ID": "%d" % self.thread_id, 6041cb0ef41Sopenharmony_ci "TEST_PARALLEL" : "%d" % self.parallel 6051cb0ef41Sopenharmony_ci }) 6061cb0ef41Sopenharmony_ci finally: 6071cb0ef41Sopenharmony_ci # Tests can leave the tty in non-blocking mode. If the test runner 6081cb0ef41Sopenharmony_ci # tries to print to stdout/stderr after that and the tty buffer is 6091cb0ef41Sopenharmony_ci # full, it'll die with a EAGAIN OSError. Ergo, put the tty back in 6101cb0ef41Sopenharmony_ci # blocking mode before proceeding. 6111cb0ef41Sopenharmony_ci if sys.platform != 'win32': 6121cb0ef41Sopenharmony_ci from fcntl import fcntl, F_GETFL, F_SETFL 6131cb0ef41Sopenharmony_ci from os import O_NONBLOCK 6141cb0ef41Sopenharmony_ci for fd in 0,1,2: fcntl(fd, F_SETFL, ~O_NONBLOCK & fcntl(fd, F_GETFL)) 6151cb0ef41Sopenharmony_ci 6161cb0ef41Sopenharmony_ci return result 6171cb0ef41Sopenharmony_ci 6181cb0ef41Sopenharmony_ci 6191cb0ef41Sopenharmony_ciclass TestOutput(object): 6201cb0ef41Sopenharmony_ci 6211cb0ef41Sopenharmony_ci def __init__(self, test, command, output, store_unexpected_output): 6221cb0ef41Sopenharmony_ci self.test = test 6231cb0ef41Sopenharmony_ci self.command = command 6241cb0ef41Sopenharmony_ci self.output = output 6251cb0ef41Sopenharmony_ci self.store_unexpected_output = store_unexpected_output 6261cb0ef41Sopenharmony_ci self.diagnostic = [] 6271cb0ef41Sopenharmony_ci 6281cb0ef41Sopenharmony_ci def UnexpectedOutput(self): 6291cb0ef41Sopenharmony_ci if self.HasCrashed(): 6301cb0ef41Sopenharmony_ci outcome = CRASH 6311cb0ef41Sopenharmony_ci elif self.HasTimedOut(): 6321cb0ef41Sopenharmony_ci outcome = TIMEOUT 6331cb0ef41Sopenharmony_ci elif self.HasFailed(): 6341cb0ef41Sopenharmony_ci outcome = FAIL 6351cb0ef41Sopenharmony_ci else: 6361cb0ef41Sopenharmony_ci outcome = PASS 6371cb0ef41Sopenharmony_ci return not outcome in self.test.outcomes 6381cb0ef41Sopenharmony_ci 6391cb0ef41Sopenharmony_ci def HasCrashed(self): 6401cb0ef41Sopenharmony_ci if utils.IsWindows(): 6411cb0ef41Sopenharmony_ci return 0x80000000 & self.output.exit_code and not (0x3FFFFF00 & self.output.exit_code) 6421cb0ef41Sopenharmony_ci else: 6431cb0ef41Sopenharmony_ci # Timed out tests will have exit_code -signal.SIGTERM. 6441cb0ef41Sopenharmony_ci if self.output.timed_out: 6451cb0ef41Sopenharmony_ci return False 6461cb0ef41Sopenharmony_ci return self.output.exit_code < 0 6471cb0ef41Sopenharmony_ci 6481cb0ef41Sopenharmony_ci def HasTimedOut(self): 6491cb0ef41Sopenharmony_ci return self.output.timed_out 6501cb0ef41Sopenharmony_ci 6511cb0ef41Sopenharmony_ci def HasFailed(self): 6521cb0ef41Sopenharmony_ci execution_failed = self.test.DidFail(self.output) 6531cb0ef41Sopenharmony_ci if self.test.IsNegative(): 6541cb0ef41Sopenharmony_ci return not execution_failed 6551cb0ef41Sopenharmony_ci else: 6561cb0ef41Sopenharmony_ci return execution_failed 6571cb0ef41Sopenharmony_ci 6581cb0ef41Sopenharmony_ci 6591cb0ef41Sopenharmony_cidef KillProcessWithID(pid, signal_to_send=signal.SIGTERM): 6601cb0ef41Sopenharmony_ci if utils.IsWindows(): 6611cb0ef41Sopenharmony_ci os.popen('taskkill /T /F /PID %d' % pid) 6621cb0ef41Sopenharmony_ci else: 6631cb0ef41Sopenharmony_ci os.kill(pid, signal_to_send) 6641cb0ef41Sopenharmony_ci 6651cb0ef41Sopenharmony_ci 6661cb0ef41Sopenharmony_ciMAX_SLEEP_TIME = 0.1 6671cb0ef41Sopenharmony_ciINITIAL_SLEEP_TIME = 0.0001 6681cb0ef41Sopenharmony_ciSLEEP_TIME_FACTOR = 1.25 6691cb0ef41Sopenharmony_ci 6701cb0ef41Sopenharmony_ciSEM_INVALID_VALUE = -1 6711cb0ef41Sopenharmony_ciSEM_NOGPFAULTERRORBOX = 0x0002 # Microsoft Platform SDK WinBase.h 6721cb0ef41Sopenharmony_ci 6731cb0ef41Sopenharmony_cidef Win32SetErrorMode(mode): 6741cb0ef41Sopenharmony_ci prev_error_mode = SEM_INVALID_VALUE 6751cb0ef41Sopenharmony_ci try: 6761cb0ef41Sopenharmony_ci import ctypes 6771cb0ef41Sopenharmony_ci prev_error_mode = ctypes.windll.kernel32.SetErrorMode(mode) 6781cb0ef41Sopenharmony_ci except ImportError: 6791cb0ef41Sopenharmony_ci pass 6801cb0ef41Sopenharmony_ci return prev_error_mode 6811cb0ef41Sopenharmony_ci 6821cb0ef41Sopenharmony_ci 6831cb0ef41Sopenharmony_cidef KillTimedOutProcess(context, pid): 6841cb0ef41Sopenharmony_ci signal_to_send = signal.SIGTERM 6851cb0ef41Sopenharmony_ci if context.abort_on_timeout: 6861cb0ef41Sopenharmony_ci # Using SIGABRT here allows the OS to generate a core dump that can be 6871cb0ef41Sopenharmony_ci # looked at post-mortem, which helps for investigating failures that are 6881cb0ef41Sopenharmony_ci # difficult to reproduce. 6891cb0ef41Sopenharmony_ci signal_to_send = signal.SIGABRT 6901cb0ef41Sopenharmony_ci KillProcessWithID(pid, signal_to_send) 6911cb0ef41Sopenharmony_ci 6921cb0ef41Sopenharmony_ci 6931cb0ef41Sopenharmony_cidef RunProcess(context, timeout, args, **rest): 6941cb0ef41Sopenharmony_ci if context.verbose: print("#", " ".join(args)) 6951cb0ef41Sopenharmony_ci popen_args = args 6961cb0ef41Sopenharmony_ci prev_error_mode = SEM_INVALID_VALUE 6971cb0ef41Sopenharmony_ci if utils.IsWindows(): 6981cb0ef41Sopenharmony_ci if context.suppress_dialogs: 6991cb0ef41Sopenharmony_ci # Try to change the error mode to avoid dialogs on fatal errors. Don't 7001cb0ef41Sopenharmony_ci # touch any existing error mode flags by merging the existing error mode. 7011cb0ef41Sopenharmony_ci # See http://blogs.msdn.com/oldnewthing/archive/2004/07/27/198410.aspx. 7021cb0ef41Sopenharmony_ci error_mode = SEM_NOGPFAULTERRORBOX 7031cb0ef41Sopenharmony_ci prev_error_mode = Win32SetErrorMode(error_mode) 7041cb0ef41Sopenharmony_ci Win32SetErrorMode(error_mode | prev_error_mode) 7051cb0ef41Sopenharmony_ci 7061cb0ef41Sopenharmony_ci process = subprocess.Popen( 7071cb0ef41Sopenharmony_ci args = popen_args, 7081cb0ef41Sopenharmony_ci **rest 7091cb0ef41Sopenharmony_ci ) 7101cb0ef41Sopenharmony_ci if utils.IsWindows() and context.suppress_dialogs and prev_error_mode != SEM_INVALID_VALUE: 7111cb0ef41Sopenharmony_ci Win32SetErrorMode(prev_error_mode) 7121cb0ef41Sopenharmony_ci # Compute the end time - if the process crosses this limit we 7131cb0ef41Sopenharmony_ci # consider it timed out. 7141cb0ef41Sopenharmony_ci if timeout is None: end_time = None 7151cb0ef41Sopenharmony_ci else: end_time = time.time() + timeout 7161cb0ef41Sopenharmony_ci timed_out = False 7171cb0ef41Sopenharmony_ci # Repeatedly check the exit code from the process in a 7181cb0ef41Sopenharmony_ci # loop and keep track of whether or not it times out. 7191cb0ef41Sopenharmony_ci exit_code = None 7201cb0ef41Sopenharmony_ci sleep_time = INITIAL_SLEEP_TIME 7211cb0ef41Sopenharmony_ci 7221cb0ef41Sopenharmony_ci while exit_code is None: 7231cb0ef41Sopenharmony_ci if (not end_time is None) and (time.time() >= end_time): 7241cb0ef41Sopenharmony_ci # Kill the process and wait for it to exit. 7251cb0ef41Sopenharmony_ci KillTimedOutProcess(context, process.pid) 7261cb0ef41Sopenharmony_ci exit_code = process.wait() 7271cb0ef41Sopenharmony_ci timed_out = True 7281cb0ef41Sopenharmony_ci else: 7291cb0ef41Sopenharmony_ci exit_code = process.poll() 7301cb0ef41Sopenharmony_ci time.sleep(sleep_time) 7311cb0ef41Sopenharmony_ci sleep_time = sleep_time * SLEEP_TIME_FACTOR 7321cb0ef41Sopenharmony_ci if sleep_time > MAX_SLEEP_TIME: 7331cb0ef41Sopenharmony_ci sleep_time = MAX_SLEEP_TIME 7341cb0ef41Sopenharmony_ci return (process, exit_code, timed_out) 7351cb0ef41Sopenharmony_ci 7361cb0ef41Sopenharmony_ci 7371cb0ef41Sopenharmony_cidef PrintError(str): 7381cb0ef41Sopenharmony_ci sys.stderr.write(str) 7391cb0ef41Sopenharmony_ci sys.stderr.write('\n') 7401cb0ef41Sopenharmony_ci 7411cb0ef41Sopenharmony_ci 7421cb0ef41Sopenharmony_cidef CheckedUnlink(name): 7431cb0ef41Sopenharmony_ci while True: 7441cb0ef41Sopenharmony_ci try: 7451cb0ef41Sopenharmony_ci os.unlink(name) 7461cb0ef41Sopenharmony_ci except OSError as e: 7471cb0ef41Sopenharmony_ci # On Windows unlink() fails if another process (typically a virus scanner 7481cb0ef41Sopenharmony_ci # or the indexing service) has the file open. Those processes keep a 7491cb0ef41Sopenharmony_ci # file open for a short time only, so yield and try again; it'll succeed. 7501cb0ef41Sopenharmony_ci if sys.platform == 'win32' and e.errno == errno.EACCES: 7511cb0ef41Sopenharmony_ci time.sleep(0) 7521cb0ef41Sopenharmony_ci continue 7531cb0ef41Sopenharmony_ci PrintError("os.unlink() " + str(e)) 7541cb0ef41Sopenharmony_ci break 7551cb0ef41Sopenharmony_ci 7561cb0ef41Sopenharmony_cidef Execute(args, context, timeout=None, env=None, disable_core_files=False, stdin=None): 7571cb0ef41Sopenharmony_ci (fd_out, outname) = tempfile.mkstemp() 7581cb0ef41Sopenharmony_ci (fd_err, errname) = tempfile.mkstemp() 7591cb0ef41Sopenharmony_ci 7601cb0ef41Sopenharmony_ci if env is None: 7611cb0ef41Sopenharmony_ci env = {} 7621cb0ef41Sopenharmony_ci env_copy = os.environ.copy() 7631cb0ef41Sopenharmony_ci 7641cb0ef41Sopenharmony_ci # Remove NODE_PATH 7651cb0ef41Sopenharmony_ci if "NODE_PATH" in env_copy: 7661cb0ef41Sopenharmony_ci del env_copy["NODE_PATH"] 7671cb0ef41Sopenharmony_ci 7681cb0ef41Sopenharmony_ci # Remove NODE_REPL_EXTERNAL_MODULE 7691cb0ef41Sopenharmony_ci if "NODE_REPL_EXTERNAL_MODULE" in env_copy: 7701cb0ef41Sopenharmony_ci del env_copy["NODE_REPL_EXTERNAL_MODULE"] 7711cb0ef41Sopenharmony_ci 7721cb0ef41Sopenharmony_ci # Extend environment 7731cb0ef41Sopenharmony_ci for key, value in env.items(): 7741cb0ef41Sopenharmony_ci env_copy[key] = value 7751cb0ef41Sopenharmony_ci 7761cb0ef41Sopenharmony_ci preexec_fn = None 7771cb0ef41Sopenharmony_ci 7781cb0ef41Sopenharmony_ci if disable_core_files and not utils.IsWindows(): 7791cb0ef41Sopenharmony_ci def disableCoreFiles(): 7801cb0ef41Sopenharmony_ci import resource 7811cb0ef41Sopenharmony_ci resource.setrlimit(resource.RLIMIT_CORE, (0,0)) 7821cb0ef41Sopenharmony_ci preexec_fn = disableCoreFiles 7831cb0ef41Sopenharmony_ci 7841cb0ef41Sopenharmony_ci (process, exit_code, timed_out) = RunProcess( 7851cb0ef41Sopenharmony_ci context, 7861cb0ef41Sopenharmony_ci timeout, 7871cb0ef41Sopenharmony_ci args = args, 7881cb0ef41Sopenharmony_ci stdin = stdin, 7891cb0ef41Sopenharmony_ci stdout = fd_out, 7901cb0ef41Sopenharmony_ci stderr = fd_err, 7911cb0ef41Sopenharmony_ci env = env_copy, 7921cb0ef41Sopenharmony_ci preexec_fn = preexec_fn 7931cb0ef41Sopenharmony_ci ) 7941cb0ef41Sopenharmony_ci os.close(fd_out) 7951cb0ef41Sopenharmony_ci os.close(fd_err) 7961cb0ef41Sopenharmony_ci output = open(outname, encoding='utf8').read() 7971cb0ef41Sopenharmony_ci errors = open(errname, encoding='utf8').read() 7981cb0ef41Sopenharmony_ci CheckedUnlink(outname) 7991cb0ef41Sopenharmony_ci CheckedUnlink(errname) 8001cb0ef41Sopenharmony_ci 8011cb0ef41Sopenharmony_ci return CommandOutput(exit_code, timed_out, output, errors) 8021cb0ef41Sopenharmony_ci 8031cb0ef41Sopenharmony_ci 8041cb0ef41Sopenharmony_cidef CarCdr(path): 8051cb0ef41Sopenharmony_ci if len(path) == 0: 8061cb0ef41Sopenharmony_ci return (None, [ ]) 8071cb0ef41Sopenharmony_ci else: 8081cb0ef41Sopenharmony_ci return (path[0], path[1:]) 8091cb0ef41Sopenharmony_ci 8101cb0ef41Sopenharmony_ci 8111cb0ef41Sopenharmony_ciclass TestConfiguration(object): 8121cb0ef41Sopenharmony_ci def __init__(self, context, root, section): 8131cb0ef41Sopenharmony_ci self.context = context 8141cb0ef41Sopenharmony_ci self.root = root 8151cb0ef41Sopenharmony_ci self.section = section 8161cb0ef41Sopenharmony_ci 8171cb0ef41Sopenharmony_ci def Contains(self, path, file): 8181cb0ef41Sopenharmony_ci if len(path) > len(file): 8191cb0ef41Sopenharmony_ci return False 8201cb0ef41Sopenharmony_ci for i in range(len(path)): 8211cb0ef41Sopenharmony_ci if not path[i].match(NormalizePath(file[i])): 8221cb0ef41Sopenharmony_ci return False 8231cb0ef41Sopenharmony_ci return True 8241cb0ef41Sopenharmony_ci 8251cb0ef41Sopenharmony_ci def GetTestStatus(self, sections, defs): 8261cb0ef41Sopenharmony_ci status_file = join(self.root, '%s.status' % self.section) 8271cb0ef41Sopenharmony_ci if exists(status_file): 8281cb0ef41Sopenharmony_ci ReadConfigurationInto(status_file, sections, defs) 8291cb0ef41Sopenharmony_ci 8301cb0ef41Sopenharmony_ci 8311cb0ef41Sopenharmony_ciclass TestSuite(object): 8321cb0ef41Sopenharmony_ci 8331cb0ef41Sopenharmony_ci def __init__(self, name): 8341cb0ef41Sopenharmony_ci self.name = name 8351cb0ef41Sopenharmony_ci 8361cb0ef41Sopenharmony_ci def GetName(self): 8371cb0ef41Sopenharmony_ci return self.name 8381cb0ef41Sopenharmony_ci 8391cb0ef41Sopenharmony_ci 8401cb0ef41Sopenharmony_ciclass TestRepository(TestSuite): 8411cb0ef41Sopenharmony_ci 8421cb0ef41Sopenharmony_ci def __init__(self, path): 8431cb0ef41Sopenharmony_ci normalized_path = abspath(path) 8441cb0ef41Sopenharmony_ci super(TestRepository, self).__init__(basename(normalized_path)) 8451cb0ef41Sopenharmony_ci self.path = normalized_path 8461cb0ef41Sopenharmony_ci self.is_loaded = False 8471cb0ef41Sopenharmony_ci self.config = None 8481cb0ef41Sopenharmony_ci 8491cb0ef41Sopenharmony_ci def GetConfiguration(self, context): 8501cb0ef41Sopenharmony_ci if self.is_loaded: 8511cb0ef41Sopenharmony_ci return self.config 8521cb0ef41Sopenharmony_ci self.is_loaded = True 8531cb0ef41Sopenharmony_ci 8541cb0ef41Sopenharmony_ci module = get_module('testcfg', self.path) 8551cb0ef41Sopenharmony_ci self.config = module.GetConfiguration(context, self.path) 8561cb0ef41Sopenharmony_ci if hasattr(self.config, 'additional_flags'): 8571cb0ef41Sopenharmony_ci self.config.additional_flags += context.node_args 8581cb0ef41Sopenharmony_ci else: 8591cb0ef41Sopenharmony_ci self.config.additional_flags = context.node_args 8601cb0ef41Sopenharmony_ci return self.config 8611cb0ef41Sopenharmony_ci 8621cb0ef41Sopenharmony_ci def GetBuildRequirements(self, path, context): 8631cb0ef41Sopenharmony_ci return self.GetConfiguration(context).GetBuildRequirements() 8641cb0ef41Sopenharmony_ci 8651cb0ef41Sopenharmony_ci def AddTestsToList(self, result, current_path, path, context, arch, mode): 8661cb0ef41Sopenharmony_ci tests = self.GetConfiguration(context).ListTests(current_path, path, 8671cb0ef41Sopenharmony_ci arch, mode) 8681cb0ef41Sopenharmony_ci result += tests 8691cb0ef41Sopenharmony_ci for i in range(1, context.repeat): 8701cb0ef41Sopenharmony_ci result += copy.deepcopy(tests) 8711cb0ef41Sopenharmony_ci 8721cb0ef41Sopenharmony_ci def GetTestStatus(self, context, sections, defs): 8731cb0ef41Sopenharmony_ci self.GetConfiguration(context).GetTestStatus(sections, defs) 8741cb0ef41Sopenharmony_ci 8751cb0ef41Sopenharmony_ci 8761cb0ef41Sopenharmony_ciclass LiteralTestSuite(TestSuite): 8771cb0ef41Sopenharmony_ci def __init__(self, tests_repos, test_root): 8781cb0ef41Sopenharmony_ci super(LiteralTestSuite, self).__init__('root') 8791cb0ef41Sopenharmony_ci self.tests_repos = tests_repos 8801cb0ef41Sopenharmony_ci self.test_root = test_root 8811cb0ef41Sopenharmony_ci 8821cb0ef41Sopenharmony_ci def GetBuildRequirements(self, path, context): 8831cb0ef41Sopenharmony_ci (name, rest) = CarCdr(path) 8841cb0ef41Sopenharmony_ci result = [ ] 8851cb0ef41Sopenharmony_ci for test in self.tests_repos: 8861cb0ef41Sopenharmony_ci if not name or name.match(test.GetName()): 8871cb0ef41Sopenharmony_ci result += test.GetBuildRequirements(rest, context) 8881cb0ef41Sopenharmony_ci return result 8891cb0ef41Sopenharmony_ci 8901cb0ef41Sopenharmony_ci def ListTests(self, current_path, path, context, arch, mode): 8911cb0ef41Sopenharmony_ci (name, rest) = CarCdr(path) 8921cb0ef41Sopenharmony_ci result = [ ] 8931cb0ef41Sopenharmony_ci for test in self.tests_repos: 8941cb0ef41Sopenharmony_ci test_name = test.GetName() 8951cb0ef41Sopenharmony_ci if not name or name.match(test_name): 8961cb0ef41Sopenharmony_ci full_path = current_path + [test_name] 8971cb0ef41Sopenharmony_ci test.AddTestsToList(result, full_path, path, context, arch, mode) 8981cb0ef41Sopenharmony_ci result.sort(key=lambda x: x.GetName()) 8991cb0ef41Sopenharmony_ci return result 9001cb0ef41Sopenharmony_ci 9011cb0ef41Sopenharmony_ci def GetTestStatus(self, context, sections, defs): 9021cb0ef41Sopenharmony_ci # Just read the test configuration from root_path/root.status. 9031cb0ef41Sopenharmony_ci root = TestConfiguration(context, self.test_root, 'root') 9041cb0ef41Sopenharmony_ci root.GetTestStatus(sections, defs) 9051cb0ef41Sopenharmony_ci for tests_repos in self.tests_repos: 9061cb0ef41Sopenharmony_ci tests_repos.GetTestStatus(context, sections, defs) 9071cb0ef41Sopenharmony_ci 9081cb0ef41Sopenharmony_ci 9091cb0ef41Sopenharmony_ciTIMEOUT_SCALEFACTOR = { 9101cb0ef41Sopenharmony_ci 'arm' : { 'debug' : 8, 'release' : 3 }, # The ARM buildbots are slow. 9111cb0ef41Sopenharmony_ci 'riscv64' : { 'debug' : 8, 'release' : 3 }, # The riscv devices are slow. 9121cb0ef41Sopenharmony_ci 'ia32' : { 'debug' : 4, 'release' : 1 }, 9131cb0ef41Sopenharmony_ci 'ppc' : { 'debug' : 4, 'release' : 1 }, 9141cb0ef41Sopenharmony_ci 's390' : { 'debug' : 4, 'release' : 1 } } 9151cb0ef41Sopenharmony_ci 9161cb0ef41Sopenharmony_ci 9171cb0ef41Sopenharmony_ciclass Context(object): 9181cb0ef41Sopenharmony_ci 9191cb0ef41Sopenharmony_ci def __init__(self, workspace, verbose, vm, args, expect_fail, 9201cb0ef41Sopenharmony_ci timeout, processor, suppress_dialogs, 9211cb0ef41Sopenharmony_ci store_unexpected_output, repeat, abort_on_timeout): 9221cb0ef41Sopenharmony_ci self.workspace = workspace 9231cb0ef41Sopenharmony_ci self.verbose = verbose 9241cb0ef41Sopenharmony_ci self.vm = vm 9251cb0ef41Sopenharmony_ci self.node_args = args 9261cb0ef41Sopenharmony_ci self.expect_fail = expect_fail 9271cb0ef41Sopenharmony_ci self.timeout = timeout 9281cb0ef41Sopenharmony_ci self.processor = processor 9291cb0ef41Sopenharmony_ci self.suppress_dialogs = suppress_dialogs 9301cb0ef41Sopenharmony_ci self.store_unexpected_output = store_unexpected_output 9311cb0ef41Sopenharmony_ci self.repeat = repeat 9321cb0ef41Sopenharmony_ci self.abort_on_timeout = abort_on_timeout 9331cb0ef41Sopenharmony_ci self.v8_enable_inspector = True 9341cb0ef41Sopenharmony_ci self.node_has_crypto = True 9351cb0ef41Sopenharmony_ci 9361cb0ef41Sopenharmony_ci def GetVm(self, arch, mode): 9371cb0ef41Sopenharmony_ci if self.vm is not None: 9381cb0ef41Sopenharmony_ci return self.vm 9391cb0ef41Sopenharmony_ci if arch == 'none': 9401cb0ef41Sopenharmony_ci name = 'out/Debug/node' if mode == 'debug' else 'out/Release/node' 9411cb0ef41Sopenharmony_ci else: 9421cb0ef41Sopenharmony_ci name = 'out/%s.%s/node' % (arch, mode) 9431cb0ef41Sopenharmony_ci 9441cb0ef41Sopenharmony_ci # Currently GYP does not support output_dir for MSVS. 9451cb0ef41Sopenharmony_ci # http://code.google.com/p/gyp/issues/detail?id=40 9461cb0ef41Sopenharmony_ci # It will put the builds into Release/node.exe or Debug/node.exe 9471cb0ef41Sopenharmony_ci if utils.IsWindows(): 9481cb0ef41Sopenharmony_ci if not exists(name + '.exe'): 9491cb0ef41Sopenharmony_ci name = name.replace('out/', '') 9501cb0ef41Sopenharmony_ci name = os.path.abspath(name + '.exe') 9511cb0ef41Sopenharmony_ci 9521cb0ef41Sopenharmony_ci if not exists(name): 9531cb0ef41Sopenharmony_ci raise ValueError('Could not find executable. Should be ' + name) 9541cb0ef41Sopenharmony_ci 9551cb0ef41Sopenharmony_ci return name 9561cb0ef41Sopenharmony_ci 9571cb0ef41Sopenharmony_ci def GetTimeout(self, mode, section=''): 9581cb0ef41Sopenharmony_ci timeout = self.timeout * TIMEOUT_SCALEFACTOR[ARCH_GUESS or 'ia32'][mode] 9591cb0ef41Sopenharmony_ci if section == 'pummel' or section == 'benchmark': 9601cb0ef41Sopenharmony_ci timeout = timeout * 6 9611cb0ef41Sopenharmony_ci # We run all WPT from one subset in the same process using workers. 9621cb0ef41Sopenharmony_ci # As the number of the tests grow, it can take longer to run some of the 9631cb0ef41Sopenharmony_ci # subsets, but it's still overall faster than running them in different 9641cb0ef41Sopenharmony_ci # processes. 9651cb0ef41Sopenharmony_ci elif section == 'wpt': 9661cb0ef41Sopenharmony_ci timeout = timeout * 12 9671cb0ef41Sopenharmony_ci return timeout 9681cb0ef41Sopenharmony_ci 9691cb0ef41Sopenharmony_cidef RunTestCases(cases_to_run, progress, tasks, flaky_tests_mode, measure_flakiness): 9701cb0ef41Sopenharmony_ci progress = PROGRESS_INDICATORS[progress](cases_to_run, flaky_tests_mode, measure_flakiness) 9711cb0ef41Sopenharmony_ci return progress.Run(tasks) 9721cb0ef41Sopenharmony_ci 9731cb0ef41Sopenharmony_ci# ------------------------------------------- 9741cb0ef41Sopenharmony_ci# --- T e s t C o n f i g u r a t i o n --- 9751cb0ef41Sopenharmony_ci# ------------------------------------------- 9761cb0ef41Sopenharmony_ci 9771cb0ef41Sopenharmony_ci 9781cb0ef41Sopenharmony_ciRUN = 'run' 9791cb0ef41Sopenharmony_ciSKIP = 'skip' 9801cb0ef41Sopenharmony_ciFAIL = 'fail' 9811cb0ef41Sopenharmony_ciPASS = 'pass' 9821cb0ef41Sopenharmony_ciOKAY = 'okay' 9831cb0ef41Sopenharmony_ciTIMEOUT = 'timeout' 9841cb0ef41Sopenharmony_ciCRASH = 'crash' 9851cb0ef41Sopenharmony_ciSLOW = 'slow' 9861cb0ef41Sopenharmony_ciFLAKY = 'flaky' 9871cb0ef41Sopenharmony_ciDONTCARE = 'dontcare' 9881cb0ef41Sopenharmony_ciKEEP_RETRYING = 'keep_retrying' 9891cb0ef41Sopenharmony_ci 9901cb0ef41Sopenharmony_ciclass Expression(object): 9911cb0ef41Sopenharmony_ci pass 9921cb0ef41Sopenharmony_ci 9931cb0ef41Sopenharmony_ci 9941cb0ef41Sopenharmony_ciclass Constant(Expression): 9951cb0ef41Sopenharmony_ci 9961cb0ef41Sopenharmony_ci def __init__(self, value): 9971cb0ef41Sopenharmony_ci self.value = value 9981cb0ef41Sopenharmony_ci 9991cb0ef41Sopenharmony_ci def Evaluate(self, env, defs): 10001cb0ef41Sopenharmony_ci return self.value 10011cb0ef41Sopenharmony_ci 10021cb0ef41Sopenharmony_ci 10031cb0ef41Sopenharmony_ciclass Variable(Expression): 10041cb0ef41Sopenharmony_ci 10051cb0ef41Sopenharmony_ci def __init__(self, name): 10061cb0ef41Sopenharmony_ci self.name = name 10071cb0ef41Sopenharmony_ci 10081cb0ef41Sopenharmony_ci def GetOutcomes(self, env, defs): 10091cb0ef41Sopenharmony_ci if self.name in env: return set([env[self.name]]) 10101cb0ef41Sopenharmony_ci else: return set() 10111cb0ef41Sopenharmony_ci 10121cb0ef41Sopenharmony_ci 10131cb0ef41Sopenharmony_ciclass Outcome(Expression): 10141cb0ef41Sopenharmony_ci 10151cb0ef41Sopenharmony_ci def __init__(self, name): 10161cb0ef41Sopenharmony_ci self.name = name 10171cb0ef41Sopenharmony_ci 10181cb0ef41Sopenharmony_ci def GetOutcomes(self, env, defs): 10191cb0ef41Sopenharmony_ci if self.name in defs: 10201cb0ef41Sopenharmony_ci return defs[self.name].GetOutcomes(env, defs) 10211cb0ef41Sopenharmony_ci else: 10221cb0ef41Sopenharmony_ci return set([self.name]) 10231cb0ef41Sopenharmony_ci 10241cb0ef41Sopenharmony_ci 10251cb0ef41Sopenharmony_ciclass Operation(Expression): 10261cb0ef41Sopenharmony_ci 10271cb0ef41Sopenharmony_ci def __init__(self, left, op, right): 10281cb0ef41Sopenharmony_ci self.left = left 10291cb0ef41Sopenharmony_ci self.op = op 10301cb0ef41Sopenharmony_ci self.right = right 10311cb0ef41Sopenharmony_ci 10321cb0ef41Sopenharmony_ci def Evaluate(self, env, defs): 10331cb0ef41Sopenharmony_ci if self.op == '||' or self.op == ',': 10341cb0ef41Sopenharmony_ci return self.left.Evaluate(env, defs) or self.right.Evaluate(env, defs) 10351cb0ef41Sopenharmony_ci elif self.op == 'if': 10361cb0ef41Sopenharmony_ci return False 10371cb0ef41Sopenharmony_ci elif self.op == '==': 10381cb0ef41Sopenharmony_ci inter = self.left.GetOutcomes(env, defs) & self.right.GetOutcomes(env, defs) 10391cb0ef41Sopenharmony_ci return bool(inter) 10401cb0ef41Sopenharmony_ci else: 10411cb0ef41Sopenharmony_ci assert self.op == '&&' 10421cb0ef41Sopenharmony_ci return self.left.Evaluate(env, defs) and self.right.Evaluate(env, defs) 10431cb0ef41Sopenharmony_ci 10441cb0ef41Sopenharmony_ci def GetOutcomes(self, env, defs): 10451cb0ef41Sopenharmony_ci if self.op == '||' or self.op == ',': 10461cb0ef41Sopenharmony_ci return self.left.GetOutcomes(env, defs) | self.right.GetOutcomes(env, defs) 10471cb0ef41Sopenharmony_ci elif self.op == 'if': 10481cb0ef41Sopenharmony_ci if self.right.Evaluate(env, defs): 10491cb0ef41Sopenharmony_ci return self.left.GetOutcomes(env, defs) 10501cb0ef41Sopenharmony_ci else: 10511cb0ef41Sopenharmony_ci return set() 10521cb0ef41Sopenharmony_ci else: 10531cb0ef41Sopenharmony_ci assert self.op == '&&' 10541cb0ef41Sopenharmony_ci return self.left.GetOutcomes(env, defs) & self.right.GetOutcomes(env, defs) 10551cb0ef41Sopenharmony_ci 10561cb0ef41Sopenharmony_ci 10571cb0ef41Sopenharmony_cidef IsAlpha(str): 10581cb0ef41Sopenharmony_ci for char in str: 10591cb0ef41Sopenharmony_ci if not (char.isalpha() or char.isdigit() or char == '_'): 10601cb0ef41Sopenharmony_ci return False 10611cb0ef41Sopenharmony_ci return True 10621cb0ef41Sopenharmony_ci 10631cb0ef41Sopenharmony_ci 10641cb0ef41Sopenharmony_ciclass Tokenizer(object): 10651cb0ef41Sopenharmony_ci """A simple string tokenizer that chops expressions into variables, 10661cb0ef41Sopenharmony_ci parens and operators""" 10671cb0ef41Sopenharmony_ci 10681cb0ef41Sopenharmony_ci def __init__(self, expr): 10691cb0ef41Sopenharmony_ci self.index = 0 10701cb0ef41Sopenharmony_ci self.expr = expr 10711cb0ef41Sopenharmony_ci self.length = len(expr) 10721cb0ef41Sopenharmony_ci self.tokens = None 10731cb0ef41Sopenharmony_ci 10741cb0ef41Sopenharmony_ci def Current(self, length = 1): 10751cb0ef41Sopenharmony_ci if not self.HasMore(length): return "" 10761cb0ef41Sopenharmony_ci return self.expr[self.index:self.index+length] 10771cb0ef41Sopenharmony_ci 10781cb0ef41Sopenharmony_ci def HasMore(self, length = 1): 10791cb0ef41Sopenharmony_ci return self.index < self.length + (length - 1) 10801cb0ef41Sopenharmony_ci 10811cb0ef41Sopenharmony_ci def Advance(self, count = 1): 10821cb0ef41Sopenharmony_ci self.index = self.index + count 10831cb0ef41Sopenharmony_ci 10841cb0ef41Sopenharmony_ci def AddToken(self, token): 10851cb0ef41Sopenharmony_ci self.tokens.append(token) 10861cb0ef41Sopenharmony_ci 10871cb0ef41Sopenharmony_ci def SkipSpaces(self): 10881cb0ef41Sopenharmony_ci while self.HasMore() and self.Current().isspace(): 10891cb0ef41Sopenharmony_ci self.Advance() 10901cb0ef41Sopenharmony_ci 10911cb0ef41Sopenharmony_ci def Tokenize(self): 10921cb0ef41Sopenharmony_ci self.tokens = [ ] 10931cb0ef41Sopenharmony_ci while self.HasMore(): 10941cb0ef41Sopenharmony_ci self.SkipSpaces() 10951cb0ef41Sopenharmony_ci if not self.HasMore(): 10961cb0ef41Sopenharmony_ci return None 10971cb0ef41Sopenharmony_ci if self.Current() == '(': 10981cb0ef41Sopenharmony_ci self.AddToken('(') 10991cb0ef41Sopenharmony_ci self.Advance() 11001cb0ef41Sopenharmony_ci elif self.Current() == ')': 11011cb0ef41Sopenharmony_ci self.AddToken(')') 11021cb0ef41Sopenharmony_ci self.Advance() 11031cb0ef41Sopenharmony_ci elif self.Current() == '$': 11041cb0ef41Sopenharmony_ci self.AddToken('$') 11051cb0ef41Sopenharmony_ci self.Advance() 11061cb0ef41Sopenharmony_ci elif self.Current() == ',': 11071cb0ef41Sopenharmony_ci self.AddToken(',') 11081cb0ef41Sopenharmony_ci self.Advance() 11091cb0ef41Sopenharmony_ci elif IsAlpha(self.Current()): 11101cb0ef41Sopenharmony_ci buf = "" 11111cb0ef41Sopenharmony_ci while self.HasMore() and IsAlpha(self.Current()): 11121cb0ef41Sopenharmony_ci buf += self.Current() 11131cb0ef41Sopenharmony_ci self.Advance() 11141cb0ef41Sopenharmony_ci self.AddToken(buf) 11151cb0ef41Sopenharmony_ci elif self.Current(2) == '&&': 11161cb0ef41Sopenharmony_ci self.AddToken('&&') 11171cb0ef41Sopenharmony_ci self.Advance(2) 11181cb0ef41Sopenharmony_ci elif self.Current(2) == '||': 11191cb0ef41Sopenharmony_ci self.AddToken('||') 11201cb0ef41Sopenharmony_ci self.Advance(2) 11211cb0ef41Sopenharmony_ci elif self.Current(2) == '==': 11221cb0ef41Sopenharmony_ci self.AddToken('==') 11231cb0ef41Sopenharmony_ci self.Advance(2) 11241cb0ef41Sopenharmony_ci else: 11251cb0ef41Sopenharmony_ci return None 11261cb0ef41Sopenharmony_ci return self.tokens 11271cb0ef41Sopenharmony_ci 11281cb0ef41Sopenharmony_ci 11291cb0ef41Sopenharmony_ciclass Scanner(object): 11301cb0ef41Sopenharmony_ci """A simple scanner that can serve out tokens from a given list""" 11311cb0ef41Sopenharmony_ci 11321cb0ef41Sopenharmony_ci def __init__(self, tokens): 11331cb0ef41Sopenharmony_ci self.tokens = tokens 11341cb0ef41Sopenharmony_ci self.length = len(tokens) 11351cb0ef41Sopenharmony_ci self.index = 0 11361cb0ef41Sopenharmony_ci 11371cb0ef41Sopenharmony_ci def HasMore(self): 11381cb0ef41Sopenharmony_ci return self.index < self.length 11391cb0ef41Sopenharmony_ci 11401cb0ef41Sopenharmony_ci def Current(self): 11411cb0ef41Sopenharmony_ci return self.tokens[self.index] 11421cb0ef41Sopenharmony_ci 11431cb0ef41Sopenharmony_ci def Advance(self): 11441cb0ef41Sopenharmony_ci self.index = self.index + 1 11451cb0ef41Sopenharmony_ci 11461cb0ef41Sopenharmony_ci 11471cb0ef41Sopenharmony_cidef ParseAtomicExpression(scan): 11481cb0ef41Sopenharmony_ci if scan.Current() == "true": 11491cb0ef41Sopenharmony_ci scan.Advance() 11501cb0ef41Sopenharmony_ci return Constant(True) 11511cb0ef41Sopenharmony_ci elif scan.Current() == "false": 11521cb0ef41Sopenharmony_ci scan.Advance() 11531cb0ef41Sopenharmony_ci return Constant(False) 11541cb0ef41Sopenharmony_ci elif IsAlpha(scan.Current()): 11551cb0ef41Sopenharmony_ci name = scan.Current() 11561cb0ef41Sopenharmony_ci scan.Advance() 11571cb0ef41Sopenharmony_ci return Outcome(name.lower()) 11581cb0ef41Sopenharmony_ci elif scan.Current() == '$': 11591cb0ef41Sopenharmony_ci scan.Advance() 11601cb0ef41Sopenharmony_ci if not IsAlpha(scan.Current()): 11611cb0ef41Sopenharmony_ci return None 11621cb0ef41Sopenharmony_ci name = scan.Current() 11631cb0ef41Sopenharmony_ci scan.Advance() 11641cb0ef41Sopenharmony_ci return Variable(name.lower()) 11651cb0ef41Sopenharmony_ci elif scan.Current() == '(': 11661cb0ef41Sopenharmony_ci scan.Advance() 11671cb0ef41Sopenharmony_ci result = ParseLogicalExpression(scan) 11681cb0ef41Sopenharmony_ci if (not result) or (scan.Current() != ')'): 11691cb0ef41Sopenharmony_ci return None 11701cb0ef41Sopenharmony_ci scan.Advance() 11711cb0ef41Sopenharmony_ci return result 11721cb0ef41Sopenharmony_ci else: 11731cb0ef41Sopenharmony_ci return None 11741cb0ef41Sopenharmony_ci 11751cb0ef41Sopenharmony_ci 11761cb0ef41Sopenharmony_ciBINARIES = ['=='] 11771cb0ef41Sopenharmony_cidef ParseOperatorExpression(scan): 11781cb0ef41Sopenharmony_ci left = ParseAtomicExpression(scan) 11791cb0ef41Sopenharmony_ci if not left: return None 11801cb0ef41Sopenharmony_ci while scan.HasMore() and (scan.Current() in BINARIES): 11811cb0ef41Sopenharmony_ci op = scan.Current() 11821cb0ef41Sopenharmony_ci scan.Advance() 11831cb0ef41Sopenharmony_ci right = ParseOperatorExpression(scan) 11841cb0ef41Sopenharmony_ci if not right: 11851cb0ef41Sopenharmony_ci return None 11861cb0ef41Sopenharmony_ci left = Operation(left, op, right) 11871cb0ef41Sopenharmony_ci return left 11881cb0ef41Sopenharmony_ci 11891cb0ef41Sopenharmony_ci 11901cb0ef41Sopenharmony_cidef ParseConditionalExpression(scan): 11911cb0ef41Sopenharmony_ci left = ParseOperatorExpression(scan) 11921cb0ef41Sopenharmony_ci if not left: return None 11931cb0ef41Sopenharmony_ci while scan.HasMore() and (scan.Current() == 'if'): 11941cb0ef41Sopenharmony_ci scan.Advance() 11951cb0ef41Sopenharmony_ci right = ParseOperatorExpression(scan) 11961cb0ef41Sopenharmony_ci if not right: 11971cb0ef41Sopenharmony_ci return None 11981cb0ef41Sopenharmony_ci left= Operation(left, 'if', right) 11991cb0ef41Sopenharmony_ci return left 12001cb0ef41Sopenharmony_ci 12011cb0ef41Sopenharmony_ci 12021cb0ef41Sopenharmony_ciLOGICALS = ["&&", "||", ","] 12031cb0ef41Sopenharmony_cidef ParseLogicalExpression(scan): 12041cb0ef41Sopenharmony_ci left = ParseConditionalExpression(scan) 12051cb0ef41Sopenharmony_ci if not left: return None 12061cb0ef41Sopenharmony_ci while scan.HasMore() and (scan.Current() in LOGICALS): 12071cb0ef41Sopenharmony_ci op = scan.Current() 12081cb0ef41Sopenharmony_ci scan.Advance() 12091cb0ef41Sopenharmony_ci right = ParseConditionalExpression(scan) 12101cb0ef41Sopenharmony_ci if not right: 12111cb0ef41Sopenharmony_ci return None 12121cb0ef41Sopenharmony_ci left = Operation(left, op, right) 12131cb0ef41Sopenharmony_ci return left 12141cb0ef41Sopenharmony_ci 12151cb0ef41Sopenharmony_ci 12161cb0ef41Sopenharmony_cidef ParseCondition(expr): 12171cb0ef41Sopenharmony_ci """Parses a logical expression into an Expression object""" 12181cb0ef41Sopenharmony_ci tokens = Tokenizer(expr).Tokenize() 12191cb0ef41Sopenharmony_ci if not tokens: 12201cb0ef41Sopenharmony_ci print("Malformed expression: '%s'" % expr) 12211cb0ef41Sopenharmony_ci return None 12221cb0ef41Sopenharmony_ci scan = Scanner(tokens) 12231cb0ef41Sopenharmony_ci ast = ParseLogicalExpression(scan) 12241cb0ef41Sopenharmony_ci if not ast: 12251cb0ef41Sopenharmony_ci print("Malformed expression: '%s'" % expr) 12261cb0ef41Sopenharmony_ci return None 12271cb0ef41Sopenharmony_ci if scan.HasMore(): 12281cb0ef41Sopenharmony_ci print("Malformed expression: '%s'" % expr) 12291cb0ef41Sopenharmony_ci return None 12301cb0ef41Sopenharmony_ci return ast 12311cb0ef41Sopenharmony_ci 12321cb0ef41Sopenharmony_ci 12331cb0ef41Sopenharmony_ciclass Configuration(object): 12341cb0ef41Sopenharmony_ci """The parsed contents of a configuration file""" 12351cb0ef41Sopenharmony_ci 12361cb0ef41Sopenharmony_ci def __init__(self, sections, defs): 12371cb0ef41Sopenharmony_ci self.sections = sections 12381cb0ef41Sopenharmony_ci self.defs = defs 12391cb0ef41Sopenharmony_ci 12401cb0ef41Sopenharmony_ci def ClassifyTests(self, cases, env): 12411cb0ef41Sopenharmony_ci sections = [ s for s in self.sections if s.condition.Evaluate(env, self.defs) ] 12421cb0ef41Sopenharmony_ci all_rules = reduce(list.__add__, [s.rules for s in sections], []) 12431cb0ef41Sopenharmony_ci unused_rules = set(all_rules) 12441cb0ef41Sopenharmony_ci result = [] 12451cb0ef41Sopenharmony_ci for case in cases: 12461cb0ef41Sopenharmony_ci matches = [ r for r in all_rules if r.Contains(case.path) ] 12471cb0ef41Sopenharmony_ci outcomes_list = [ r.GetOutcomes(env, self.defs) for r in matches ] 12481cb0ef41Sopenharmony_ci outcomes = reduce(set.union, outcomes_list, set()) 12491cb0ef41Sopenharmony_ci unused_rules.difference_update(matches) 12501cb0ef41Sopenharmony_ci case.outcomes = set(outcomes) or set([PASS]) 12511cb0ef41Sopenharmony_ci # slow tests may also just pass. 12521cb0ef41Sopenharmony_ci if SLOW in case.outcomes: 12531cb0ef41Sopenharmony_ci case.outcomes.add(PASS) 12541cb0ef41Sopenharmony_ci result.append(case) 12551cb0ef41Sopenharmony_ci return result, unused_rules 12561cb0ef41Sopenharmony_ci 12571cb0ef41Sopenharmony_ci 12581cb0ef41Sopenharmony_ciclass Section(object): 12591cb0ef41Sopenharmony_ci """A section of the configuration file. Sections are enabled or 12601cb0ef41Sopenharmony_ci disabled prior to running the tests, based on their conditions""" 12611cb0ef41Sopenharmony_ci 12621cb0ef41Sopenharmony_ci def __init__(self, condition): 12631cb0ef41Sopenharmony_ci self.condition = condition 12641cb0ef41Sopenharmony_ci self.rules = [ ] 12651cb0ef41Sopenharmony_ci 12661cb0ef41Sopenharmony_ci def AddRule(self, rule): 12671cb0ef41Sopenharmony_ci self.rules.append(rule) 12681cb0ef41Sopenharmony_ci 12691cb0ef41Sopenharmony_ci 12701cb0ef41Sopenharmony_ciclass Rule(object): 12711cb0ef41Sopenharmony_ci """A single rule that specifies the expected outcome for a single 12721cb0ef41Sopenharmony_ci test.""" 12731cb0ef41Sopenharmony_ci 12741cb0ef41Sopenharmony_ci def __init__(self, raw_path, path, value): 12751cb0ef41Sopenharmony_ci self.raw_path = raw_path 12761cb0ef41Sopenharmony_ci self.path = path 12771cb0ef41Sopenharmony_ci self.value = value 12781cb0ef41Sopenharmony_ci 12791cb0ef41Sopenharmony_ci def GetOutcomes(self, env, defs): 12801cb0ef41Sopenharmony_ci return self.value.GetOutcomes(env, defs) 12811cb0ef41Sopenharmony_ci 12821cb0ef41Sopenharmony_ci def Contains(self, path): 12831cb0ef41Sopenharmony_ci if len(self.path) > len(path): 12841cb0ef41Sopenharmony_ci return False 12851cb0ef41Sopenharmony_ci for i in range(len(self.path)): 12861cb0ef41Sopenharmony_ci if not self.path[i].match(path[i]): 12871cb0ef41Sopenharmony_ci return False 12881cb0ef41Sopenharmony_ci return True 12891cb0ef41Sopenharmony_ci 12901cb0ef41Sopenharmony_ci 12911cb0ef41Sopenharmony_ciHEADER_PATTERN = re.compile(r'\[([^]]+)\]') 12921cb0ef41Sopenharmony_ciRULE_PATTERN = re.compile(r'\s*([^: ]*)\s*:(.*)') 12931cb0ef41Sopenharmony_ciDEF_PATTERN = re.compile(r'^def\s*(\w+)\s*=(.*)$') 12941cb0ef41Sopenharmony_ciPREFIX_PATTERN = re.compile(r'^\s*prefix\s+([\w_.\-/]+)$') 12951cb0ef41Sopenharmony_ci 12961cb0ef41Sopenharmony_ci 12971cb0ef41Sopenharmony_cidef ReadConfigurationInto(path, sections, defs): 12981cb0ef41Sopenharmony_ci current_section = Section(Constant(True)) 12991cb0ef41Sopenharmony_ci sections.append(current_section) 13001cb0ef41Sopenharmony_ci prefix = [] 13011cb0ef41Sopenharmony_ci for line in utils.ReadLinesFrom(path): 13021cb0ef41Sopenharmony_ci header_match = HEADER_PATTERN.match(line) 13031cb0ef41Sopenharmony_ci if header_match: 13041cb0ef41Sopenharmony_ci condition_str = header_match.group(1).strip() 13051cb0ef41Sopenharmony_ci condition = ParseCondition(condition_str) 13061cb0ef41Sopenharmony_ci new_section = Section(condition) 13071cb0ef41Sopenharmony_ci sections.append(new_section) 13081cb0ef41Sopenharmony_ci current_section = new_section 13091cb0ef41Sopenharmony_ci continue 13101cb0ef41Sopenharmony_ci rule_match = RULE_PATTERN.match(line) 13111cb0ef41Sopenharmony_ci if rule_match: 13121cb0ef41Sopenharmony_ci path = prefix + SplitPath(rule_match.group(1).strip()) 13131cb0ef41Sopenharmony_ci value_str = rule_match.group(2).strip() 13141cb0ef41Sopenharmony_ci value = ParseCondition(value_str) 13151cb0ef41Sopenharmony_ci if not value: 13161cb0ef41Sopenharmony_ci return False 13171cb0ef41Sopenharmony_ci current_section.AddRule(Rule(rule_match.group(1), path, value)) 13181cb0ef41Sopenharmony_ci continue 13191cb0ef41Sopenharmony_ci def_match = DEF_PATTERN.match(line) 13201cb0ef41Sopenharmony_ci if def_match: 13211cb0ef41Sopenharmony_ci name = def_match.group(1).lower() 13221cb0ef41Sopenharmony_ci value = ParseCondition(def_match.group(2).strip()) 13231cb0ef41Sopenharmony_ci if not value: 13241cb0ef41Sopenharmony_ci return False 13251cb0ef41Sopenharmony_ci defs[name] = value 13261cb0ef41Sopenharmony_ci continue 13271cb0ef41Sopenharmony_ci prefix_match = PREFIX_PATTERN.match(line) 13281cb0ef41Sopenharmony_ci if prefix_match: 13291cb0ef41Sopenharmony_ci prefix = SplitPath(prefix_match.group(1).strip()) 13301cb0ef41Sopenharmony_ci continue 13311cb0ef41Sopenharmony_ci raise Exception("Malformed line: '%s'." % line) 13321cb0ef41Sopenharmony_ci 13331cb0ef41Sopenharmony_ci 13341cb0ef41Sopenharmony_ci# --------------- 13351cb0ef41Sopenharmony_ci# --- M a i n --- 13361cb0ef41Sopenharmony_ci# --------------- 13371cb0ef41Sopenharmony_ci 13381cb0ef41Sopenharmony_ci 13391cb0ef41Sopenharmony_ciARCH_GUESS = utils.GuessArchitecture() 13401cb0ef41Sopenharmony_ci 13411cb0ef41Sopenharmony_ci 13421cb0ef41Sopenharmony_cidef BuildOptions(): 13431cb0ef41Sopenharmony_ci result = optparse.OptionParser() 13441cb0ef41Sopenharmony_ci result.add_option("-m", "--mode", help="The test modes in which to run (comma-separated)", 13451cb0ef41Sopenharmony_ci default='release') 13461cb0ef41Sopenharmony_ci result.add_option("-v", "--verbose", help="Verbose output", 13471cb0ef41Sopenharmony_ci default=False, action="store_true") 13481cb0ef41Sopenharmony_ci result.add_option('--logfile', dest='logfile', 13491cb0ef41Sopenharmony_ci help='write test output to file. NOTE: this only applies the tap progress indicator') 13501cb0ef41Sopenharmony_ci result.add_option("-p", "--progress", 13511cb0ef41Sopenharmony_ci help="The style of progress indicator (%s)" % ", ".join(PROGRESS_INDICATORS.keys()), 13521cb0ef41Sopenharmony_ci choices=list(PROGRESS_INDICATORS.keys()), default="mono") 13531cb0ef41Sopenharmony_ci result.add_option("--report", help="Print a summary of the tests to be run", 13541cb0ef41Sopenharmony_ci default=False, action="store_true") 13551cb0ef41Sopenharmony_ci result.add_option("-s", "--suite", help="A test suite", 13561cb0ef41Sopenharmony_ci default=[], action="append") 13571cb0ef41Sopenharmony_ci result.add_option("-t", "--timeout", help="Timeout in seconds", 13581cb0ef41Sopenharmony_ci default=120, type="int") 13591cb0ef41Sopenharmony_ci result.add_option("--arch", help='The architecture to run tests for', 13601cb0ef41Sopenharmony_ci default='none') 13611cb0ef41Sopenharmony_ci result.add_option("--snapshot", help="Run the tests with snapshot turned on", 13621cb0ef41Sopenharmony_ci default=False, action="store_true") 13631cb0ef41Sopenharmony_ci result.add_option("--special-command", default=None) 13641cb0ef41Sopenharmony_ci result.add_option("--node-args", dest="node_args", help="Args to pass through to Node", 13651cb0ef41Sopenharmony_ci default=[], action="append") 13661cb0ef41Sopenharmony_ci result.add_option("--expect-fail", dest="expect_fail", 13671cb0ef41Sopenharmony_ci help="Expect test cases to fail", default=False, action="store_true") 13681cb0ef41Sopenharmony_ci result.add_option("--valgrind", help="Run tests through valgrind", 13691cb0ef41Sopenharmony_ci default=False, action="store_true") 13701cb0ef41Sopenharmony_ci result.add_option("--worker", help="Run parallel tests inside a worker context", 13711cb0ef41Sopenharmony_ci default=False, action="store_true") 13721cb0ef41Sopenharmony_ci result.add_option("--check-deopts", help="Check tests for permanent deoptimizations", 13731cb0ef41Sopenharmony_ci default=False, action="store_true") 13741cb0ef41Sopenharmony_ci result.add_option("--cat", help="Print the source of the tests", 13751cb0ef41Sopenharmony_ci default=False, action="store_true") 13761cb0ef41Sopenharmony_ci result.add_option("--flaky-tests", 13771cb0ef41Sopenharmony_ci help="Regard tests marked as flaky (run|skip|dontcare|keep_retrying)", 13781cb0ef41Sopenharmony_ci default="run") 13791cb0ef41Sopenharmony_ci result.add_option("--measure-flakiness", 13801cb0ef41Sopenharmony_ci help="When a test fails, re-run it x number of times", 13811cb0ef41Sopenharmony_ci default=0, type="int") 13821cb0ef41Sopenharmony_ci result.add_option("--skip-tests", 13831cb0ef41Sopenharmony_ci help="Tests that should not be executed (comma-separated)", 13841cb0ef41Sopenharmony_ci default="") 13851cb0ef41Sopenharmony_ci result.add_option("--warn-unused", help="Report unused rules", 13861cb0ef41Sopenharmony_ci default=False, action="store_true") 13871cb0ef41Sopenharmony_ci result.add_option("-j", help="The number of parallel tasks to run, 0=use number of cores", 13881cb0ef41Sopenharmony_ci default=0, type="int") 13891cb0ef41Sopenharmony_ci result.add_option("-J", help="For legacy compatibility, has no effect", 13901cb0ef41Sopenharmony_ci default=False, action="store_true") 13911cb0ef41Sopenharmony_ci result.add_option("--time", help="Print timing information after running", 13921cb0ef41Sopenharmony_ci default=False, action="store_true") 13931cb0ef41Sopenharmony_ci result.add_option("--suppress-dialogs", help="Suppress Windows dialogs for crashing tests", 13941cb0ef41Sopenharmony_ci dest="suppress_dialogs", default=True, action="store_true") 13951cb0ef41Sopenharmony_ci result.add_option("--no-suppress-dialogs", help="Display Windows dialogs for crashing tests", 13961cb0ef41Sopenharmony_ci dest="suppress_dialogs", action="store_false") 13971cb0ef41Sopenharmony_ci result.add_option("--shell", help="Path to node executable", default=None) 13981cb0ef41Sopenharmony_ci result.add_option("--store-unexpected-output", 13991cb0ef41Sopenharmony_ci help="Store the temporary JS files from tests that fails", 14001cb0ef41Sopenharmony_ci dest="store_unexpected_output", default=True, action="store_true") 14011cb0ef41Sopenharmony_ci result.add_option("--no-store-unexpected-output", 14021cb0ef41Sopenharmony_ci help="Deletes the temporary JS files from tests that fails", 14031cb0ef41Sopenharmony_ci dest="store_unexpected_output", action="store_false") 14041cb0ef41Sopenharmony_ci result.add_option("-r", "--run", 14051cb0ef41Sopenharmony_ci help="Divide the tests in m groups (interleaved) and run tests from group n (--run=n,m with n < m)", 14061cb0ef41Sopenharmony_ci default="") 14071cb0ef41Sopenharmony_ci result.add_option('--temp-dir', 14081cb0ef41Sopenharmony_ci help='Optional path to change directory used for tests', default=False) 14091cb0ef41Sopenharmony_ci result.add_option('--test-root', 14101cb0ef41Sopenharmony_ci help='Optional path to change test directory', dest='test_root', default=None) 14111cb0ef41Sopenharmony_ci result.add_option('--repeat', 14121cb0ef41Sopenharmony_ci help='Number of times to repeat given tests', 14131cb0ef41Sopenharmony_ci default=1, type="int") 14141cb0ef41Sopenharmony_ci result.add_option('--abort-on-timeout', 14151cb0ef41Sopenharmony_ci help='Send SIGABRT instead of SIGTERM to kill processes that time out', 14161cb0ef41Sopenharmony_ci default=False, action="store_true", dest="abort_on_timeout") 14171cb0ef41Sopenharmony_ci result.add_option("--type", 14181cb0ef41Sopenharmony_ci help="Type of build (simple, fips, coverage)", 14191cb0ef41Sopenharmony_ci default=None) 14201cb0ef41Sopenharmony_ci return result 14211cb0ef41Sopenharmony_ci 14221cb0ef41Sopenharmony_ci 14231cb0ef41Sopenharmony_cidef ProcessOptions(options): 14241cb0ef41Sopenharmony_ci global VERBOSE 14251cb0ef41Sopenharmony_ci VERBOSE = options.verbose 14261cb0ef41Sopenharmony_ci options.arch = options.arch.split(',') 14271cb0ef41Sopenharmony_ci options.mode = options.mode.split(',') 14281cb0ef41Sopenharmony_ci options.run = options.run.split(',') 14291cb0ef41Sopenharmony_ci # Split at commas and filter out all the empty strings. 14301cb0ef41Sopenharmony_ci options.skip_tests = [test for test in options.skip_tests.split(',') if test] 14311cb0ef41Sopenharmony_ci if options.run == [""]: 14321cb0ef41Sopenharmony_ci options.run = None 14331cb0ef41Sopenharmony_ci elif len(options.run) != 2: 14341cb0ef41Sopenharmony_ci print("The run argument must be two comma-separated integers.") 14351cb0ef41Sopenharmony_ci return False 14361cb0ef41Sopenharmony_ci else: 14371cb0ef41Sopenharmony_ci try: 14381cb0ef41Sopenharmony_ci options.run = [int(level) for level in options.run] 14391cb0ef41Sopenharmony_ci except ValueError: 14401cb0ef41Sopenharmony_ci print("Could not parse the integers from the run argument.") 14411cb0ef41Sopenharmony_ci return False 14421cb0ef41Sopenharmony_ci if options.run[0] < 0 or options.run[1] < 0: 14431cb0ef41Sopenharmony_ci print("The run argument cannot have negative integers.") 14441cb0ef41Sopenharmony_ci return False 14451cb0ef41Sopenharmony_ci if options.run[0] >= options.run[1]: 14461cb0ef41Sopenharmony_ci print("The test group to run (n) must be smaller than number of groups (m).") 14471cb0ef41Sopenharmony_ci return False 14481cb0ef41Sopenharmony_ci if options.j == 0: 14491cb0ef41Sopenharmony_ci # inherit JOBS from environment if provided. some virtualised systems 14501cb0ef41Sopenharmony_ci # tends to exaggerate the number of available cpus/cores. 14511cb0ef41Sopenharmony_ci cores = os.environ.get('JOBS') 14521cb0ef41Sopenharmony_ci options.j = int(cores) if cores is not None else multiprocessing.cpu_count() 14531cb0ef41Sopenharmony_ci elif options.J: 14541cb0ef41Sopenharmony_ci # If someone uses -j and legacy -J, let them know that we will be respecting 14551cb0ef41Sopenharmony_ci # -j and ignoring -J, which is the opposite of what we used to do before -J 14561cb0ef41Sopenharmony_ci # became a legacy no-op. 14571cb0ef41Sopenharmony_ci print('Warning: Legacy -J option is ignored. Using the -j option.') 14581cb0ef41Sopenharmony_ci if options.flaky_tests not in [RUN, SKIP, DONTCARE, KEEP_RETRYING]: 14591cb0ef41Sopenharmony_ci print("Unknown flaky-tests mode %s" % options.flaky_tests) 14601cb0ef41Sopenharmony_ci return False 14611cb0ef41Sopenharmony_ci return True 14621cb0ef41Sopenharmony_ci 14631cb0ef41Sopenharmony_ci 14641cb0ef41Sopenharmony_ciREPORT_TEMPLATE = """\ 14651cb0ef41Sopenharmony_ciTotal: %(total)i tests 14661cb0ef41Sopenharmony_ci * %(skipped)4d tests will be skipped 14671cb0ef41Sopenharmony_ci * %(pass)4d tests are expected to pass 14681cb0ef41Sopenharmony_ci * %(fail_ok)4d tests are expected to fail that we won't fix 14691cb0ef41Sopenharmony_ci * %(fail)4d tests are expected to fail that we should fix\ 14701cb0ef41Sopenharmony_ci""" 14711cb0ef41Sopenharmony_ci 14721cb0ef41Sopenharmony_ci 14731cb0ef41Sopenharmony_ciclass Pattern(object): 14741cb0ef41Sopenharmony_ci 14751cb0ef41Sopenharmony_ci def __init__(self, pattern): 14761cb0ef41Sopenharmony_ci self.pattern = pattern 14771cb0ef41Sopenharmony_ci self.compiled = None 14781cb0ef41Sopenharmony_ci 14791cb0ef41Sopenharmony_ci def match(self, str): 14801cb0ef41Sopenharmony_ci if not self.compiled: 14811cb0ef41Sopenharmony_ci pattern = "^" + self.pattern.replace('*', '.*') + "$" 14821cb0ef41Sopenharmony_ci self.compiled = re.compile(pattern) 14831cb0ef41Sopenharmony_ci return self.compiled.match(str) 14841cb0ef41Sopenharmony_ci 14851cb0ef41Sopenharmony_ci def __str__(self): 14861cb0ef41Sopenharmony_ci return self.pattern 14871cb0ef41Sopenharmony_ci 14881cb0ef41Sopenharmony_ci 14891cb0ef41Sopenharmony_cidef SplitPath(path_arg): 14901cb0ef41Sopenharmony_ci stripped = [c.strip() for c in path_arg.split('/')] 14911cb0ef41Sopenharmony_ci return [Pattern(s) for s in stripped if len(s) > 0] 14921cb0ef41Sopenharmony_ci 14931cb0ef41Sopenharmony_cidef NormalizePath(path, prefix='test/'): 14941cb0ef41Sopenharmony_ci # strip the extra path information of the specified test 14951cb0ef41Sopenharmony_ci prefix = prefix.replace('\\', '/') 14961cb0ef41Sopenharmony_ci path = path.replace('\\', '/') 14971cb0ef41Sopenharmony_ci if path.startswith(prefix): 14981cb0ef41Sopenharmony_ci path = path[len(prefix):] 14991cb0ef41Sopenharmony_ci if path.endswith('.js'): 15001cb0ef41Sopenharmony_ci path = path[:-3] 15011cb0ef41Sopenharmony_ci elif path.endswith('.mjs'): 15021cb0ef41Sopenharmony_ci path = path[:-4] 15031cb0ef41Sopenharmony_ci return path 15041cb0ef41Sopenharmony_ci 15051cb0ef41Sopenharmony_cidef GetSpecialCommandProcessor(value): 15061cb0ef41Sopenharmony_ci if (not value) or (value.find('@') == -1): 15071cb0ef41Sopenharmony_ci def ExpandCommand(args): 15081cb0ef41Sopenharmony_ci return args 15091cb0ef41Sopenharmony_ci return ExpandCommand 15101cb0ef41Sopenharmony_ci else: 15111cb0ef41Sopenharmony_ci prefix, _, suffix = value.partition('@') 15121cb0ef41Sopenharmony_ci prefix = unquote(prefix).split() 15131cb0ef41Sopenharmony_ci suffix = unquote(suffix).split() 15141cb0ef41Sopenharmony_ci def ExpandCommand(args): 15151cb0ef41Sopenharmony_ci return prefix + args + suffix 15161cb0ef41Sopenharmony_ci return ExpandCommand 15171cb0ef41Sopenharmony_ci 15181cb0ef41Sopenharmony_cidef GetSuites(test_root): 15191cb0ef41Sopenharmony_ci def IsSuite(path): 15201cb0ef41Sopenharmony_ci return isdir(path) and exists(join(path, 'testcfg.py')) 15211cb0ef41Sopenharmony_ci return [ f for f in os.listdir(test_root) if IsSuite(join(test_root, f)) ] 15221cb0ef41Sopenharmony_ci 15231cb0ef41Sopenharmony_ci 15241cb0ef41Sopenharmony_cidef FormatTime(d): 15251cb0ef41Sopenharmony_ci millis = round(d * 1000) % 1000 15261cb0ef41Sopenharmony_ci return time.strftime("%M:%S.", time.gmtime(d)) + ("%03i" % millis) 15271cb0ef41Sopenharmony_ci 15281cb0ef41Sopenharmony_ci 15291cb0ef41Sopenharmony_cidef FormatTimedelta(td): 15301cb0ef41Sopenharmony_ci if hasattr(td, 'total_seconds'): 15311cb0ef41Sopenharmony_ci d = td.total_seconds() 15321cb0ef41Sopenharmony_ci else: # python2.6 compat 15331cb0ef41Sopenharmony_ci d = td.seconds + (td.microseconds / 10.0**6) 15341cb0ef41Sopenharmony_ci return FormatTime(d) 15351cb0ef41Sopenharmony_ci 15361cb0ef41Sopenharmony_ci 15371cb0ef41Sopenharmony_cidef PrintCrashed(code): 15381cb0ef41Sopenharmony_ci if utils.IsWindows(): 15391cb0ef41Sopenharmony_ci return "CRASHED" 15401cb0ef41Sopenharmony_ci else: 15411cb0ef41Sopenharmony_ci return "CRASHED (Signal: %d)" % -code 15421cb0ef41Sopenharmony_ci 15431cb0ef41Sopenharmony_ci 15441cb0ef41Sopenharmony_ci# these suites represent special cases that should not be run as part of the 15451cb0ef41Sopenharmony_ci# default JavaScript test-run, e.g., internet/ requires a network connection, 15461cb0ef41Sopenharmony_ci# addons/ requires compilation. 15471cb0ef41Sopenharmony_ciIGNORED_SUITES = [ 15481cb0ef41Sopenharmony_ci 'addons', 15491cb0ef41Sopenharmony_ci 'benchmark', 15501cb0ef41Sopenharmony_ci 'doctool', 15511cb0ef41Sopenharmony_ci 'embedding', 15521cb0ef41Sopenharmony_ci 'internet', 15531cb0ef41Sopenharmony_ci 'js-native-api', 15541cb0ef41Sopenharmony_ci 'node-api', 15551cb0ef41Sopenharmony_ci 'pummel', 15561cb0ef41Sopenharmony_ci 'tick-processor', 15571cb0ef41Sopenharmony_ci 'v8-updates' 15581cb0ef41Sopenharmony_ci] 15591cb0ef41Sopenharmony_ci 15601cb0ef41Sopenharmony_ci 15611cb0ef41Sopenharmony_cidef ArgsToTestPaths(test_root, args, suites): 15621cb0ef41Sopenharmony_ci if len(args) == 0 or 'default' in args: 15631cb0ef41Sopenharmony_ci def_suites = [s for s in suites if s not in IGNORED_SUITES] 15641cb0ef41Sopenharmony_ci args = [a for a in args if a != 'default'] + def_suites 15651cb0ef41Sopenharmony_ci subsystem_regex = re.compile(r'^[a-zA-Z-]*$') 15661cb0ef41Sopenharmony_ci check = lambda arg: subsystem_regex.match(arg) and (arg not in suites) 15671cb0ef41Sopenharmony_ci mapped_args = ["*/test*-%s-*" % arg if check(arg) else arg for arg in args] 15681cb0ef41Sopenharmony_ci paths = [SplitPath(NormalizePath(a)) for a in mapped_args] 15691cb0ef41Sopenharmony_ci return paths 15701cb0ef41Sopenharmony_ci 15711cb0ef41Sopenharmony_ci 15721cb0ef41Sopenharmony_cidef get_env_type(vm, options_type, context): 15731cb0ef41Sopenharmony_ci if options_type is not None: 15741cb0ef41Sopenharmony_ci env_type = options_type 15751cb0ef41Sopenharmony_ci else: 15761cb0ef41Sopenharmony_ci # 'simple' is the default value for 'env_type'. 15771cb0ef41Sopenharmony_ci env_type = 'simple' 15781cb0ef41Sopenharmony_ci ssl_ver = Execute([vm, '-p', 'process.versions.openssl'], context).stdout 15791cb0ef41Sopenharmony_ci if 'fips' in ssl_ver: 15801cb0ef41Sopenharmony_ci env_type = 'fips' 15811cb0ef41Sopenharmony_ci return env_type 15821cb0ef41Sopenharmony_ci 15831cb0ef41Sopenharmony_ci 15841cb0ef41Sopenharmony_cidef get_asan_state(): 15851cb0ef41Sopenharmony_ci return "on" if os.environ.get('ASAN') is not None else "off" 15861cb0ef41Sopenharmony_ci 15871cb0ef41Sopenharmony_ci 15881cb0ef41Sopenharmony_cidef Main(): 15891cb0ef41Sopenharmony_ci parser = BuildOptions() 15901cb0ef41Sopenharmony_ci (options, args) = parser.parse_args() 15911cb0ef41Sopenharmony_ci if not ProcessOptions(options): 15921cb0ef41Sopenharmony_ci parser.print_help() 15931cb0ef41Sopenharmony_ci return 1 15941cb0ef41Sopenharmony_ci 15951cb0ef41Sopenharmony_ci stream = sys.stdout 15961cb0ef41Sopenharmony_ci try: 15971cb0ef41Sopenharmony_ci sys.stdout.reconfigure(encoding='utf8') 15981cb0ef41Sopenharmony_ci except AttributeError: 15991cb0ef41Sopenharmony_ci # Python < 3.7 does not have reconfigure 16001cb0ef41Sopenharmony_ci stream = io.TextIOWrapper(sys.stdout.buffer,encoding='utf8') 16011cb0ef41Sopenharmony_ci ch = logging.StreamHandler(stream) 16021cb0ef41Sopenharmony_ci logger.addHandler(ch) 16031cb0ef41Sopenharmony_ci logger.setLevel(logging.INFO) 16041cb0ef41Sopenharmony_ci if options.logfile: 16051cb0ef41Sopenharmony_ci fh = logging.FileHandler(options.logfile, encoding='utf-8', mode='w') 16061cb0ef41Sopenharmony_ci logger.addHandler(fh) 16071cb0ef41Sopenharmony_ci 16081cb0ef41Sopenharmony_ci workspace = abspath(join(dirname(sys.argv[0]), '..')) 16091cb0ef41Sopenharmony_ci test_root = join(workspace, 'test') 16101cb0ef41Sopenharmony_ci if options.test_root is not None: 16111cb0ef41Sopenharmony_ci test_root = options.test_root 16121cb0ef41Sopenharmony_ci suites = GetSuites(test_root) 16131cb0ef41Sopenharmony_ci repositories = [TestRepository(join(test_root, name)) for name in suites] 16141cb0ef41Sopenharmony_ci repositories += [TestRepository(a) for a in options.suite] 16151cb0ef41Sopenharmony_ci 16161cb0ef41Sopenharmony_ci root = LiteralTestSuite(repositories, test_root) 16171cb0ef41Sopenharmony_ci paths = ArgsToTestPaths(test_root, args, suites) 16181cb0ef41Sopenharmony_ci 16191cb0ef41Sopenharmony_ci # Check for --valgrind option. If enabled, we overwrite the special 16201cb0ef41Sopenharmony_ci # command flag with a command that uses the run-valgrind.py script. 16211cb0ef41Sopenharmony_ci if options.valgrind: 16221cb0ef41Sopenharmony_ci run_valgrind = join(workspace, "tools", "run-valgrind.py") 16231cb0ef41Sopenharmony_ci options.special_command = "python -u " + run_valgrind + " @" 16241cb0ef41Sopenharmony_ci 16251cb0ef41Sopenharmony_ci if options.check_deopts: 16261cb0ef41Sopenharmony_ci options.node_args.append("--trace-opt") 16271cb0ef41Sopenharmony_ci options.node_args.append("--trace-file-names") 16281cb0ef41Sopenharmony_ci # --always-opt is needed because many tests do not run long enough for the 16291cb0ef41Sopenharmony_ci # optimizer to kick in, so this flag will force it to run. 16301cb0ef41Sopenharmony_ci options.node_args.append("--always-opt") 16311cb0ef41Sopenharmony_ci options.progress = "deopts" 16321cb0ef41Sopenharmony_ci 16331cb0ef41Sopenharmony_ci if options.worker: 16341cb0ef41Sopenharmony_ci run_worker = join(workspace, "tools", "run-worker.js") 16351cb0ef41Sopenharmony_ci options.node_args.append(run_worker) 16361cb0ef41Sopenharmony_ci 16371cb0ef41Sopenharmony_ci processor = GetSpecialCommandProcessor(options.special_command) 16381cb0ef41Sopenharmony_ci 16391cb0ef41Sopenharmony_ci context = Context(workspace, 16401cb0ef41Sopenharmony_ci VERBOSE, 16411cb0ef41Sopenharmony_ci options.shell, 16421cb0ef41Sopenharmony_ci options.node_args, 16431cb0ef41Sopenharmony_ci options.expect_fail, 16441cb0ef41Sopenharmony_ci options.timeout, 16451cb0ef41Sopenharmony_ci processor, 16461cb0ef41Sopenharmony_ci options.suppress_dialogs, 16471cb0ef41Sopenharmony_ci options.store_unexpected_output, 16481cb0ef41Sopenharmony_ci options.repeat, 16491cb0ef41Sopenharmony_ci options.abort_on_timeout) 16501cb0ef41Sopenharmony_ci 16511cb0ef41Sopenharmony_ci # Get status for tests 16521cb0ef41Sopenharmony_ci sections = [ ] 16531cb0ef41Sopenharmony_ci defs = { } 16541cb0ef41Sopenharmony_ci root.GetTestStatus(context, sections, defs) 16551cb0ef41Sopenharmony_ci config = Configuration(sections, defs) 16561cb0ef41Sopenharmony_ci 16571cb0ef41Sopenharmony_ci # List the tests 16581cb0ef41Sopenharmony_ci all_cases = [ ] 16591cb0ef41Sopenharmony_ci all_unused = [ ] 16601cb0ef41Sopenharmony_ci unclassified_tests = [ ] 16611cb0ef41Sopenharmony_ci globally_unused_rules = None 16621cb0ef41Sopenharmony_ci for path in paths: 16631cb0ef41Sopenharmony_ci for arch in options.arch: 16641cb0ef41Sopenharmony_ci for mode in options.mode: 16651cb0ef41Sopenharmony_ci vm = context.GetVm(arch, mode) 16661cb0ef41Sopenharmony_ci if not exists(vm): 16671cb0ef41Sopenharmony_ci print("Can't find shell executable: '%s'" % vm) 16681cb0ef41Sopenharmony_ci continue 16691cb0ef41Sopenharmony_ci archEngineContext = Execute([vm, "-p", "process.arch"], context) 16701cb0ef41Sopenharmony_ci vmArch = archEngineContext.stdout.rstrip() 16711cb0ef41Sopenharmony_ci if archEngineContext.exit_code != 0 or vmArch == "undefined": 16721cb0ef41Sopenharmony_ci print("Can't determine the arch of: '%s'" % vm) 16731cb0ef41Sopenharmony_ci print(archEngineContext.stderr.rstrip()) 16741cb0ef41Sopenharmony_ci continue 16751cb0ef41Sopenharmony_ci env = { 16761cb0ef41Sopenharmony_ci 'mode': mode, 16771cb0ef41Sopenharmony_ci 'system': utils.GuessOS(), 16781cb0ef41Sopenharmony_ci 'arch': vmArch, 16791cb0ef41Sopenharmony_ci 'type': get_env_type(vm, options.type, context), 16801cb0ef41Sopenharmony_ci 'asan': get_asan_state(), 16811cb0ef41Sopenharmony_ci } 16821cb0ef41Sopenharmony_ci test_list = root.ListTests([], path, context, arch, mode) 16831cb0ef41Sopenharmony_ci unclassified_tests += test_list 16841cb0ef41Sopenharmony_ci cases, unused_rules = config.ClassifyTests(test_list, env) 16851cb0ef41Sopenharmony_ci if globally_unused_rules is None: 16861cb0ef41Sopenharmony_ci globally_unused_rules = set(unused_rules) 16871cb0ef41Sopenharmony_ci else: 16881cb0ef41Sopenharmony_ci globally_unused_rules = ( 16891cb0ef41Sopenharmony_ci globally_unused_rules.intersection(unused_rules)) 16901cb0ef41Sopenharmony_ci all_cases += cases 16911cb0ef41Sopenharmony_ci all_unused.append(unused_rules) 16921cb0ef41Sopenharmony_ci 16931cb0ef41Sopenharmony_ci # We want to skip the inspector tests if node was built without the inspector. 16941cb0ef41Sopenharmony_ci has_inspector = Execute([vm, 16951cb0ef41Sopenharmony_ci '-p', 'process.features.inspector'], context) 16961cb0ef41Sopenharmony_ci if has_inspector.stdout.rstrip() == 'false': 16971cb0ef41Sopenharmony_ci context.v8_enable_inspector = False 16981cb0ef41Sopenharmony_ci 16991cb0ef41Sopenharmony_ci has_crypto = Execute([vm, 17001cb0ef41Sopenharmony_ci '-p', 'process.versions.openssl'], context) 17011cb0ef41Sopenharmony_ci if has_crypto.stdout.rstrip() == 'undefined': 17021cb0ef41Sopenharmony_ci context.node_has_crypto = False 17031cb0ef41Sopenharmony_ci 17041cb0ef41Sopenharmony_ci if options.cat: 17051cb0ef41Sopenharmony_ci visited = set() 17061cb0ef41Sopenharmony_ci for test in unclassified_tests: 17071cb0ef41Sopenharmony_ci key = tuple(test.path) 17081cb0ef41Sopenharmony_ci if key in visited: 17091cb0ef41Sopenharmony_ci continue 17101cb0ef41Sopenharmony_ci visited.add(key) 17111cb0ef41Sopenharmony_ci print("--- begin source: %s ---" % test.GetLabel()) 17121cb0ef41Sopenharmony_ci source = test.GetSource().strip() 17131cb0ef41Sopenharmony_ci print(source) 17141cb0ef41Sopenharmony_ci print("--- end source: %s ---" % test.GetLabel()) 17151cb0ef41Sopenharmony_ci return 0 17161cb0ef41Sopenharmony_ci 17171cb0ef41Sopenharmony_ci if options.warn_unused: 17181cb0ef41Sopenharmony_ci for rule in globally_unused_rules: 17191cb0ef41Sopenharmony_ci print("Rule for '%s' was not used." % '/'.join([str(s) for s in rule.path])) 17201cb0ef41Sopenharmony_ci 17211cb0ef41Sopenharmony_ci tempdir = os.environ.get('NODE_TEST_DIR') or options.temp_dir 17221cb0ef41Sopenharmony_ci if tempdir: 17231cb0ef41Sopenharmony_ci os.environ['NODE_TEST_DIR'] = tempdir 17241cb0ef41Sopenharmony_ci try: 17251cb0ef41Sopenharmony_ci os.makedirs(tempdir) 17261cb0ef41Sopenharmony_ci except OSError as exception: 17271cb0ef41Sopenharmony_ci if exception.errno != errno.EEXIST: 17281cb0ef41Sopenharmony_ci print("Could not create the temporary directory", options.temp_dir) 17291cb0ef41Sopenharmony_ci sys.exit(1) 17301cb0ef41Sopenharmony_ci 17311cb0ef41Sopenharmony_ci def should_keep(case): 17321cb0ef41Sopenharmony_ci if any((s in case.file) for s in options.skip_tests): 17331cb0ef41Sopenharmony_ci return False 17341cb0ef41Sopenharmony_ci elif SKIP in case.outcomes: 17351cb0ef41Sopenharmony_ci return False 17361cb0ef41Sopenharmony_ci elif (options.flaky_tests == SKIP) and (set([SLOW, FLAKY]) & case.outcomes): 17371cb0ef41Sopenharmony_ci return False 17381cb0ef41Sopenharmony_ci else: 17391cb0ef41Sopenharmony_ci return True 17401cb0ef41Sopenharmony_ci 17411cb0ef41Sopenharmony_ci cases_to_run = [ 17421cb0ef41Sopenharmony_ci test_case for test_case in all_cases if should_keep(test_case) 17431cb0ef41Sopenharmony_ci ] 17441cb0ef41Sopenharmony_ci 17451cb0ef41Sopenharmony_ci if options.report: 17461cb0ef41Sopenharmony_ci print(REPORT_TEMPLATE % { 17471cb0ef41Sopenharmony_ci 'total': len(all_cases), 17481cb0ef41Sopenharmony_ci 'skipped': len(all_cases) - len(cases_to_run), 17491cb0ef41Sopenharmony_ci 'pass': len([t for t in cases_to_run if PASS in t.outcomes]), 17501cb0ef41Sopenharmony_ci 'fail_ok': len([t for t in cases_to_run if t.outcomes == set([FAIL, OKAY])]), 17511cb0ef41Sopenharmony_ci 'fail': len([t for t in cases_to_run if t.outcomes == set([FAIL])]) 17521cb0ef41Sopenharmony_ci }) 17531cb0ef41Sopenharmony_ci 17541cb0ef41Sopenharmony_ci if options.run is not None: 17551cb0ef41Sopenharmony_ci # Must ensure the list of tests is sorted before selecting, to avoid 17561cb0ef41Sopenharmony_ci # silent errors if this file is changed to list the tests in a way that 17571cb0ef41Sopenharmony_ci # can be different in different machines 17581cb0ef41Sopenharmony_ci cases_to_run.sort(key=lambda c: (c.arch, c.mode, c.file)) 17591cb0ef41Sopenharmony_ci cases_to_run = [ cases_to_run[i] for i 17601cb0ef41Sopenharmony_ci in range(options.run[0], 17611cb0ef41Sopenharmony_ci len(cases_to_run), 17621cb0ef41Sopenharmony_ci options.run[1]) ] 17631cb0ef41Sopenharmony_ci if len(cases_to_run) == 0: 17641cb0ef41Sopenharmony_ci print("No tests to run.") 17651cb0ef41Sopenharmony_ci return 1 17661cb0ef41Sopenharmony_ci else: 17671cb0ef41Sopenharmony_ci try: 17681cb0ef41Sopenharmony_ci start = time.time() 17691cb0ef41Sopenharmony_ci result = RunTestCases(cases_to_run, options.progress, options.j, options.flaky_tests, options.measure_flakiness) 17701cb0ef41Sopenharmony_ci exitcode = 0 if result['allPassed'] else 1 17711cb0ef41Sopenharmony_ci duration = time.time() - start 17721cb0ef41Sopenharmony_ci except KeyboardInterrupt: 17731cb0ef41Sopenharmony_ci print("Interrupted") 17741cb0ef41Sopenharmony_ci return 1 17751cb0ef41Sopenharmony_ci 17761cb0ef41Sopenharmony_ci if options.time: 17771cb0ef41Sopenharmony_ci # Write the times to stderr to make it easy to separate from the 17781cb0ef41Sopenharmony_ci # test output. 17791cb0ef41Sopenharmony_ci print() 17801cb0ef41Sopenharmony_ci sys.stderr.write("--- Total time: %s ---\n" % FormatTime(duration)) 17811cb0ef41Sopenharmony_ci timed_tests = [ t for t in cases_to_run if not t.duration is None ] 17821cb0ef41Sopenharmony_ci timed_tests.sort(key=lambda x: x.duration) 17831cb0ef41Sopenharmony_ci for i, entry in enumerate(timed_tests[:20], start=1): 17841cb0ef41Sopenharmony_ci t = FormatTimedelta(entry.duration) 17851cb0ef41Sopenharmony_ci sys.stderr.write("%4i (%s) %s\n" % (i, t, entry.GetLabel())) 17861cb0ef41Sopenharmony_ci 17871cb0ef41Sopenharmony_ci if result['allPassed']: 17881cb0ef41Sopenharmony_ci print("\nAll tests passed.") 17891cb0ef41Sopenharmony_ci else: 17901cb0ef41Sopenharmony_ci print("\nFailed tests:") 17911cb0ef41Sopenharmony_ci for failure in result['failed']: 17921cb0ef41Sopenharmony_ci print(EscapeCommand(failure.command)) 17931cb0ef41Sopenharmony_ci 17941cb0ef41Sopenharmony_ci return exitcode 17951cb0ef41Sopenharmony_ci 17961cb0ef41Sopenharmony_ci 17971cb0ef41Sopenharmony_ciif __name__ == '__main__': 17981cb0ef41Sopenharmony_ci sys.exit(Main()) 1799