11cb0ef41Sopenharmony_ci# Copyright 2012 the V8 project authors. All rights reserved. 21cb0ef41Sopenharmony_ci# Redistribution and use in source and binary forms, with or without 31cb0ef41Sopenharmony_ci# modification, are permitted provided that the following conditions are 41cb0ef41Sopenharmony_ci# met: 51cb0ef41Sopenharmony_ci# 61cb0ef41Sopenharmony_ci# * Redistributions of source code must retain the above copyright 71cb0ef41Sopenharmony_ci# notice, this list of conditions and the following disclaimer. 81cb0ef41Sopenharmony_ci# * Redistributions in binary form must reproduce the above 91cb0ef41Sopenharmony_ci# copyright notice, this list of conditions and the following 101cb0ef41Sopenharmony_ci# disclaimer in the documentation and/or other materials provided 111cb0ef41Sopenharmony_ci# with the distribution. 121cb0ef41Sopenharmony_ci# * Neither the name of Google Inc. nor the names of its 131cb0ef41Sopenharmony_ci# contributors may be used to endorse or promote products derived 141cb0ef41Sopenharmony_ci# from this software without specific prior written permission. 151cb0ef41Sopenharmony_ci# 161cb0ef41Sopenharmony_ci# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 171cb0ef41Sopenharmony_ci# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 181cb0ef41Sopenharmony_ci# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 191cb0ef41Sopenharmony_ci# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 201cb0ef41Sopenharmony_ci# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 211cb0ef41Sopenharmony_ci# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 221cb0ef41Sopenharmony_ci# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 231cb0ef41Sopenharmony_ci# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 241cb0ef41Sopenharmony_ci# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 251cb0ef41Sopenharmony_ci# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 261cb0ef41Sopenharmony_ci# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 271cb0ef41Sopenharmony_ci 281cb0ef41Sopenharmony_ciimport copy 291cb0ef41Sopenharmony_ciimport os 301cb0ef41Sopenharmony_ciimport re 311cb0ef41Sopenharmony_ciimport shlex 321cb0ef41Sopenharmony_ci 331cb0ef41Sopenharmony_cifrom testrunner.outproc import base as outproc 341cb0ef41Sopenharmony_cifrom testrunner.local import command 351cb0ef41Sopenharmony_cifrom testrunner.local import statusfile 361cb0ef41Sopenharmony_cifrom testrunner.local import utils 371cb0ef41Sopenharmony_cifrom testrunner.local.variants import ALL_VARIANT_FLAGS 381cb0ef41Sopenharmony_cifrom testrunner.local.variants import INCOMPATIBLE_FLAGS_PER_VARIANT 391cb0ef41Sopenharmony_cifrom testrunner.local.variants import INCOMPATIBLE_FLAGS_PER_BUILD_VARIABLE 401cb0ef41Sopenharmony_cifrom testrunner.local.variants import INCOMPATIBLE_FLAGS_PER_EXTRA_FLAG 411cb0ef41Sopenharmony_ci 421cb0ef41Sopenharmony_ci 431cb0ef41Sopenharmony_ciFLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") 441cb0ef41Sopenharmony_ci 451cb0ef41Sopenharmony_ci# Patterns for additional resource files on Android. Files that are not covered 461cb0ef41Sopenharmony_ci# by one of the other patterns below will be specified in the resources section. 471cb0ef41Sopenharmony_ciRESOURCES_PATTERN = re.compile(r"//\s+Resources:(.*)") 481cb0ef41Sopenharmony_ci# Pattern to auto-detect files to push on Android for statements like: 491cb0ef41Sopenharmony_ci# load("path/to/file.js") 501cb0ef41Sopenharmony_ci# d8.file.execute("path/to/file.js") 511cb0ef41Sopenharmony_ciLOAD_PATTERN = re.compile( 521cb0ef41Sopenharmony_ci r"(?:execute|load|readbuffer|read)\((?:'|\")([^'\"]+)(?:'|\")\)") 531cb0ef41Sopenharmony_ci# Pattern to auto-detect files to push on Android for statements like: 541cb0ef41Sopenharmony_ci# import foobar from "path/to/file.js" 551cb0ef41Sopenharmony_ci# import {foo, bar} from "path/to/file.js" 561cb0ef41Sopenharmony_ci# export {"foo" as "bar"} from "path/to/file.js" 571cb0ef41Sopenharmony_ciMODULE_FROM_RESOURCES_PATTERN = re.compile( 581cb0ef41Sopenharmony_ci r"(?:import|export).*?from\s*\(?['\"]([^'\"]+)['\"]", 591cb0ef41Sopenharmony_ci re.MULTILINE | re.DOTALL) 601cb0ef41Sopenharmony_ci# Pattern to detect files to push on Android for statements like: 611cb0ef41Sopenharmony_ci# import "path/to/file.js" 621cb0ef41Sopenharmony_ci# import("module.mjs").catch()... 631cb0ef41Sopenharmony_ciMODULE_IMPORT_RESOURCES_PATTERN = re.compile( 641cb0ef41Sopenharmony_ci r"import\s*\(?['\"]([^'\"]+)['\"]", 651cb0ef41Sopenharmony_ci re.MULTILINE | re.DOTALL) 661cb0ef41Sopenharmony_ci# Pattern to detect and strip test262 frontmatter from tests to prevent false 671cb0ef41Sopenharmony_ci# positives for MODULE_RESOURCES_PATTERN above. 681cb0ef41Sopenharmony_ciTEST262_FRONTMATTER_PATTERN = re.compile(r"/\*---.*?---\*/", re.DOTALL) 691cb0ef41Sopenharmony_ci 701cb0ef41Sopenharmony_ciTIMEOUT_LONG = "long" 711cb0ef41Sopenharmony_ci 721cb0ef41Sopenharmony_cidef read_file(file): 731cb0ef41Sopenharmony_ci with open(file, encoding='ISO-8859-1') as f: 741cb0ef41Sopenharmony_ci return f.read() 751cb0ef41Sopenharmony_ci 761cb0ef41Sopenharmony_ciclass TestCase(object): 771cb0ef41Sopenharmony_ci def __init__(self, suite, path, name, test_config): 781cb0ef41Sopenharmony_ci self.suite = suite # TestSuite object 791cb0ef41Sopenharmony_ci 801cb0ef41Sopenharmony_ci self.path = path # string, e.g. 'div-mod', 'test-api/foo' 811cb0ef41Sopenharmony_ci self.name = name # string that identifies test in the status file 821cb0ef41Sopenharmony_ci 831cb0ef41Sopenharmony_ci self.variant = None # name of the used testing variant 841cb0ef41Sopenharmony_ci self.variant_flags = [] # list of strings, flags specific to this test 851cb0ef41Sopenharmony_ci 861cb0ef41Sopenharmony_ci # Fields used by the test processors. 871cb0ef41Sopenharmony_ci self.origin = None # Test that this test is subtest of. 881cb0ef41Sopenharmony_ci self.processor = None # Processor that created this subtest. 891cb0ef41Sopenharmony_ci self.procid = '%s/%s' % (self.suite.name, self.name) # unique id 901cb0ef41Sopenharmony_ci self.keep_output = False # Can output of this test be dropped 911cb0ef41Sopenharmony_ci 921cb0ef41Sopenharmony_ci # Test config contains information needed to build the command. 931cb0ef41Sopenharmony_ci self._test_config = test_config 941cb0ef41Sopenharmony_ci self._random_seed = None # Overrides test config value if not None 951cb0ef41Sopenharmony_ci 961cb0ef41Sopenharmony_ci # Outcomes 971cb0ef41Sopenharmony_ci self._statusfile_outcomes = None 981cb0ef41Sopenharmony_ci self._expected_outcomes = None 991cb0ef41Sopenharmony_ci self._checked_flag_contradictions = False 1001cb0ef41Sopenharmony_ci self._statusfile_flags = None 1011cb0ef41Sopenharmony_ci self.expected_failure_reason = None 1021cb0ef41Sopenharmony_ci 1031cb0ef41Sopenharmony_ci self._prepare_outcomes() 1041cb0ef41Sopenharmony_ci 1051cb0ef41Sopenharmony_ci def create_subtest(self, processor, subtest_id, variant=None, flags=None, 1061cb0ef41Sopenharmony_ci keep_output=False, random_seed=None): 1071cb0ef41Sopenharmony_ci subtest = copy.copy(self) 1081cb0ef41Sopenharmony_ci subtest.origin = self 1091cb0ef41Sopenharmony_ci subtest.processor = processor 1101cb0ef41Sopenharmony_ci subtest.procid += '.%s' % subtest_id 1111cb0ef41Sopenharmony_ci subtest.keep_output |= keep_output 1121cb0ef41Sopenharmony_ci if random_seed: 1131cb0ef41Sopenharmony_ci subtest._random_seed = random_seed 1141cb0ef41Sopenharmony_ci if flags: 1151cb0ef41Sopenharmony_ci subtest.variant_flags = subtest.variant_flags + flags 1161cb0ef41Sopenharmony_ci if variant is not None: 1171cb0ef41Sopenharmony_ci assert self.variant is None 1181cb0ef41Sopenharmony_ci subtest.variant = variant 1191cb0ef41Sopenharmony_ci subtest._prepare_outcomes() 1201cb0ef41Sopenharmony_ci return subtest 1211cb0ef41Sopenharmony_ci 1221cb0ef41Sopenharmony_ci def _prepare_outcomes(self, force_update=True): 1231cb0ef41Sopenharmony_ci if force_update or self._statusfile_outcomes is None: 1241cb0ef41Sopenharmony_ci def is_flag(outcome): 1251cb0ef41Sopenharmony_ci return outcome.startswith('--') 1261cb0ef41Sopenharmony_ci def not_flag(outcome): 1271cb0ef41Sopenharmony_ci return not is_flag(outcome) 1281cb0ef41Sopenharmony_ci 1291cb0ef41Sopenharmony_ci outcomes = self.suite.statusfile.get_outcomes(self.name, self.variant) 1301cb0ef41Sopenharmony_ci self._statusfile_outcomes = list(filter(not_flag, outcomes)) 1311cb0ef41Sopenharmony_ci self._statusfile_flags = list(filter(is_flag, outcomes)) 1321cb0ef41Sopenharmony_ci self._expected_outcomes = ( 1331cb0ef41Sopenharmony_ci self._parse_status_file_outcomes(self._statusfile_outcomes)) 1341cb0ef41Sopenharmony_ci 1351cb0ef41Sopenharmony_ci def _parse_status_file_outcomes(self, outcomes): 1361cb0ef41Sopenharmony_ci if (statusfile.FAIL_SLOPPY in outcomes and 1371cb0ef41Sopenharmony_ci '--use-strict' not in self.variant_flags): 1381cb0ef41Sopenharmony_ci return outproc.OUTCOMES_FAIL 1391cb0ef41Sopenharmony_ci 1401cb0ef41Sopenharmony_ci expected_outcomes = [] 1411cb0ef41Sopenharmony_ci if (statusfile.FAIL in outcomes or 1421cb0ef41Sopenharmony_ci statusfile.FAIL_OK in outcomes): 1431cb0ef41Sopenharmony_ci expected_outcomes.append(statusfile.FAIL) 1441cb0ef41Sopenharmony_ci if statusfile.CRASH in outcomes: 1451cb0ef41Sopenharmony_ci expected_outcomes.append(statusfile.CRASH) 1461cb0ef41Sopenharmony_ci 1471cb0ef41Sopenharmony_ci # Do not add PASS if there is nothing else. Empty outcomes are converted to 1481cb0ef41Sopenharmony_ci # the global [PASS]. 1491cb0ef41Sopenharmony_ci if expected_outcomes and statusfile.PASS in outcomes: 1501cb0ef41Sopenharmony_ci expected_outcomes.append(statusfile.PASS) 1511cb0ef41Sopenharmony_ci 1521cb0ef41Sopenharmony_ci # Avoid creating multiple instances of a list with a single FAIL. 1531cb0ef41Sopenharmony_ci if expected_outcomes == outproc.OUTCOMES_FAIL: 1541cb0ef41Sopenharmony_ci return outproc.OUTCOMES_FAIL 1551cb0ef41Sopenharmony_ci return expected_outcomes or outproc.OUTCOMES_PASS 1561cb0ef41Sopenharmony_ci 1571cb0ef41Sopenharmony_ci def allow_timeouts(self): 1581cb0ef41Sopenharmony_ci if self.expected_outcomes == outproc.OUTCOMES_PASS: 1591cb0ef41Sopenharmony_ci self._expected_outcomes = outproc.OUTCOMES_PASS_OR_TIMEOUT 1601cb0ef41Sopenharmony_ci elif self.expected_outcomes == outproc.OUTCOMES_FAIL: 1611cb0ef41Sopenharmony_ci self._expected_outcomes = outproc.OUTCOMES_FAIL_OR_TIMEOUT 1621cb0ef41Sopenharmony_ci elif statusfile.TIMEOUT not in self.expected_outcomes: 1631cb0ef41Sopenharmony_ci self._expected_outcomes = ( 1641cb0ef41Sopenharmony_ci self.expected_outcomes + [statusfile.TIMEOUT]) 1651cb0ef41Sopenharmony_ci 1661cb0ef41Sopenharmony_ci def allow_pass(self): 1671cb0ef41Sopenharmony_ci if self.expected_outcomes == outproc.OUTCOMES_TIMEOUT: 1681cb0ef41Sopenharmony_ci self._expected_outcomes = outproc.OUTCOMES_PASS_OR_TIMEOUT 1691cb0ef41Sopenharmony_ci elif self.expected_outcomes == outproc.OUTCOMES_FAIL: 1701cb0ef41Sopenharmony_ci self._expected_outcomes = outproc.OUTCOMES_FAIL_OR_PASS 1711cb0ef41Sopenharmony_ci elif statusfile.PASS not in self.expected_outcomes: 1721cb0ef41Sopenharmony_ci self._expected_outcomes = ( 1731cb0ef41Sopenharmony_ci self.expected_outcomes + [statusfile.PASS]) 1741cb0ef41Sopenharmony_ci 1751cb0ef41Sopenharmony_ci @property 1761cb0ef41Sopenharmony_ci def expected_outcomes(self): 1771cb0ef41Sopenharmony_ci def is_flag(maybe_flag): 1781cb0ef41Sopenharmony_ci return maybe_flag.startswith("--") # Best-effort heuristic. 1791cb0ef41Sopenharmony_ci 1801cb0ef41Sopenharmony_ci # Filter to flags, e.g.: ["--foo", "3", "--bar"] -> ["--foo", "--bar"]. 1811cb0ef41Sopenharmony_ci def filter_flags(normalized_flags): 1821cb0ef41Sopenharmony_ci return [f for f in normalized_flags if is_flag(f)]; 1831cb0ef41Sopenharmony_ci 1841cb0ef41Sopenharmony_ci def normalize_flag(flag): 1851cb0ef41Sopenharmony_ci return flag.replace("_", "-").replace("--no-", "--no") 1861cb0ef41Sopenharmony_ci 1871cb0ef41Sopenharmony_ci def normalize_flags(flags): 1881cb0ef41Sopenharmony_ci return [normalize_flag(flag) for flag in filter_flags(flags)] 1891cb0ef41Sopenharmony_ci 1901cb0ef41Sopenharmony_ci # Note this can get it wrong if the flag name starts with the characters 1911cb0ef41Sopenharmony_ci # "--no" where "no" is part of the flag name, e.g. "--nobodys-perfect". 1921cb0ef41Sopenharmony_ci # In that case the negation "--bodys-perfect" would be returned. This is 1931cb0ef41Sopenharmony_ci # a weakness we accept and hope to never run into. 1941cb0ef41Sopenharmony_ci def negate_flag(normalized_flag): 1951cb0ef41Sopenharmony_ci return ("--" + normalized_flag[4:] if normalized_flag.startswith("--no") 1961cb0ef41Sopenharmony_ci else "--no" + normalized_flag[2:]) 1971cb0ef41Sopenharmony_ci 1981cb0ef41Sopenharmony_ci def negate_flags(normalized_flags): 1991cb0ef41Sopenharmony_ci return [negate_flag(flag) for flag in normalized_flags] 2001cb0ef41Sopenharmony_ci 2011cb0ef41Sopenharmony_ci def has_flag(conflicting_flag, flags): 2021cb0ef41Sopenharmony_ci conflicting_flag = normalize_flag(conflicting_flag) 2031cb0ef41Sopenharmony_ci if conflicting_flag in flags: 2041cb0ef41Sopenharmony_ci return True 2051cb0ef41Sopenharmony_ci if conflicting_flag.endswith("*"): 2061cb0ef41Sopenharmony_ci return any(flag.startswith(conflicting_flag[:-1]) for flag in flags) 2071cb0ef41Sopenharmony_ci return False 2081cb0ef41Sopenharmony_ci 2091cb0ef41Sopenharmony_ci def check_flags(incompatible_flags, actual_flags, rule): 2101cb0ef41Sopenharmony_ci for incompatible_flag in incompatible_flags: 2111cb0ef41Sopenharmony_ci if has_flag(incompatible_flag, actual_flags): 2121cb0ef41Sopenharmony_ci self._statusfile_outcomes = outproc.OUTCOMES_FAIL 2131cb0ef41Sopenharmony_ci self._expected_outcomes = outproc.OUTCOMES_FAIL 2141cb0ef41Sopenharmony_ci self.expected_failure_reason = ("Rule " + rule + " in " + 2151cb0ef41Sopenharmony_ci "tools/testrunner/local/variants.py expected a flag " + 2161cb0ef41Sopenharmony_ci "contradiction error with " + incompatible_flag + ".") 2171cb0ef41Sopenharmony_ci 2181cb0ef41Sopenharmony_ci if not self._checked_flag_contradictions: 2191cb0ef41Sopenharmony_ci self._checked_flag_contradictions = True 2201cb0ef41Sopenharmony_ci 2211cb0ef41Sopenharmony_ci file_specific_flags = (self._get_source_flags() + self._get_suite_flags() 2221cb0ef41Sopenharmony_ci + self._get_statusfile_flags()) 2231cb0ef41Sopenharmony_ci file_specific_flags = normalize_flags(file_specific_flags) 2241cb0ef41Sopenharmony_ci extra_flags = normalize_flags(self._get_extra_flags()) 2251cb0ef41Sopenharmony_ci 2261cb0ef41Sopenharmony_ci # Contradiction: flags contains both a flag --foo and its negation 2271cb0ef41Sopenharmony_ci # --no-foo. 2281cb0ef41Sopenharmony_ci if self.variant in ALL_VARIANT_FLAGS: 2291cb0ef41Sopenharmony_ci for flags in ALL_VARIANT_FLAGS[self.variant]: 2301cb0ef41Sopenharmony_ci all_flags = (file_specific_flags + extra_flags 2311cb0ef41Sopenharmony_ci + normalize_flags(flags)) 2321cb0ef41Sopenharmony_ci check_flags(negate_flags(all_flags), all_flags, "Flag negations") 2331cb0ef41Sopenharmony_ci 2341cb0ef41Sopenharmony_ci # Contradiction: flags specified through the "Flags:" annotation are 2351cb0ef41Sopenharmony_ci # incompatible with the variant. 2361cb0ef41Sopenharmony_ci if self.variant in INCOMPATIBLE_FLAGS_PER_VARIANT: 2371cb0ef41Sopenharmony_ci check_flags(INCOMPATIBLE_FLAGS_PER_VARIANT[self.variant], file_specific_flags, 2381cb0ef41Sopenharmony_ci "INCOMPATIBLE_FLAGS_PER_VARIANT[\""+self.variant+"\"]") 2391cb0ef41Sopenharmony_ci 2401cb0ef41Sopenharmony_ci # Contradiction: flags specified through the "Flags:" annotation are 2411cb0ef41Sopenharmony_ci # incompatible with the build. 2421cb0ef41Sopenharmony_ci for variable, incompatible_flags in INCOMPATIBLE_FLAGS_PER_BUILD_VARIABLE.items(): 2431cb0ef41Sopenharmony_ci if self.suite.statusfile.variables[variable]: 2441cb0ef41Sopenharmony_ci check_flags(incompatible_flags, file_specific_flags, 2451cb0ef41Sopenharmony_ci "INCOMPATIBLE_FLAGS_PER_BUILD_VARIABLE[\""+variable+"\"]") 2461cb0ef41Sopenharmony_ci 2471cb0ef41Sopenharmony_ci # Contradiction: flags passed through --extra-flags are incompatible. 2481cb0ef41Sopenharmony_ci for extra_flag, incompatible_flags in INCOMPATIBLE_FLAGS_PER_EXTRA_FLAG.items(): 2491cb0ef41Sopenharmony_ci if has_flag(extra_flag, extra_flags): 2501cb0ef41Sopenharmony_ci check_flags(incompatible_flags, file_specific_flags, 2511cb0ef41Sopenharmony_ci "INCOMPATIBLE_FLAGS_PER_EXTRA_FLAG[\""+extra_flag+"\"]") 2521cb0ef41Sopenharmony_ci return self._expected_outcomes 2531cb0ef41Sopenharmony_ci 2541cb0ef41Sopenharmony_ci @property 2551cb0ef41Sopenharmony_ci def do_skip(self): 2561cb0ef41Sopenharmony_ci return (statusfile.SKIP in self._statusfile_outcomes and 2571cb0ef41Sopenharmony_ci not self.suite.test_config.run_skipped) 2581cb0ef41Sopenharmony_ci 2591cb0ef41Sopenharmony_ci @property 2601cb0ef41Sopenharmony_ci def is_heavy(self): 2611cb0ef41Sopenharmony_ci return statusfile.HEAVY in self._statusfile_outcomes 2621cb0ef41Sopenharmony_ci 2631cb0ef41Sopenharmony_ci @property 2641cb0ef41Sopenharmony_ci def is_slow(self): 2651cb0ef41Sopenharmony_ci return self.is_heavy or statusfile.SLOW in self._statusfile_outcomes 2661cb0ef41Sopenharmony_ci 2671cb0ef41Sopenharmony_ci @property 2681cb0ef41Sopenharmony_ci def is_fail_ok(self): 2691cb0ef41Sopenharmony_ci return statusfile.FAIL_OK in self._statusfile_outcomes 2701cb0ef41Sopenharmony_ci 2711cb0ef41Sopenharmony_ci @property 2721cb0ef41Sopenharmony_ci def is_pass_or_fail(self): 2731cb0ef41Sopenharmony_ci return (statusfile.PASS in self._statusfile_outcomes and 2741cb0ef41Sopenharmony_ci statusfile.FAIL in self._statusfile_outcomes and 2751cb0ef41Sopenharmony_ci statusfile.CRASH not in self._statusfile_outcomes) 2761cb0ef41Sopenharmony_ci 2771cb0ef41Sopenharmony_ci @property 2781cb0ef41Sopenharmony_ci def is_fail(self): 2791cb0ef41Sopenharmony_ci return (statusfile.FAIL in self._statusfile_outcomes and 2801cb0ef41Sopenharmony_ci statusfile.PASS not in self._statusfile_outcomes) 2811cb0ef41Sopenharmony_ci 2821cb0ef41Sopenharmony_ci @property 2831cb0ef41Sopenharmony_ci def only_standard_variant(self): 2841cb0ef41Sopenharmony_ci return statusfile.NO_VARIANTS in self._statusfile_outcomes 2851cb0ef41Sopenharmony_ci 2861cb0ef41Sopenharmony_ci def get_command(self): 2871cb0ef41Sopenharmony_ci params = self._get_cmd_params() 2881cb0ef41Sopenharmony_ci env = self._get_cmd_env() 2891cb0ef41Sopenharmony_ci shell = self.get_shell() 2901cb0ef41Sopenharmony_ci if utils.IsWindows(): 2911cb0ef41Sopenharmony_ci shell += '.exe' 2921cb0ef41Sopenharmony_ci shell_flags = self._get_shell_flags() 2931cb0ef41Sopenharmony_ci timeout = self._get_timeout(params) 2941cb0ef41Sopenharmony_ci return self._create_cmd(shell, shell_flags + params, env, timeout) 2951cb0ef41Sopenharmony_ci 2961cb0ef41Sopenharmony_ci def _get_cmd_params(self): 2971cb0ef41Sopenharmony_ci """Gets command parameters and combines them in the following order: 2981cb0ef41Sopenharmony_ci - files [empty by default] 2991cb0ef41Sopenharmony_ci - random seed 3001cb0ef41Sopenharmony_ci - mode flags (based on chosen mode) 3011cb0ef41Sopenharmony_ci - extra flags (from command line) 3021cb0ef41Sopenharmony_ci - user flags (variant/fuzzer flags) 3031cb0ef41Sopenharmony_ci - source flags (from source code) [empty by default] 3041cb0ef41Sopenharmony_ci - test-suite flags 3051cb0ef41Sopenharmony_ci - statusfile flags 3061cb0ef41Sopenharmony_ci 3071cb0ef41Sopenharmony_ci The best way to modify how parameters are created is to only override 3081cb0ef41Sopenharmony_ci methods for getting partial parameters. 3091cb0ef41Sopenharmony_ci """ 3101cb0ef41Sopenharmony_ci return ( 3111cb0ef41Sopenharmony_ci self._get_files_params() + 3121cb0ef41Sopenharmony_ci self._get_random_seed_flags() + 3131cb0ef41Sopenharmony_ci self._get_mode_flags() + 3141cb0ef41Sopenharmony_ci self._get_extra_flags() + 3151cb0ef41Sopenharmony_ci self._get_variant_flags() + 3161cb0ef41Sopenharmony_ci self._get_source_flags() + 3171cb0ef41Sopenharmony_ci self._get_suite_flags() + 3181cb0ef41Sopenharmony_ci self._get_statusfile_flags() 3191cb0ef41Sopenharmony_ci ) 3201cb0ef41Sopenharmony_ci 3211cb0ef41Sopenharmony_ci def _get_cmd_env(self): 3221cb0ef41Sopenharmony_ci return {} 3231cb0ef41Sopenharmony_ci 3241cb0ef41Sopenharmony_ci def _get_files_params(self): 3251cb0ef41Sopenharmony_ci return [] 3261cb0ef41Sopenharmony_ci 3271cb0ef41Sopenharmony_ci def _get_timeout_param(self): 3281cb0ef41Sopenharmony_ci return None 3291cb0ef41Sopenharmony_ci 3301cb0ef41Sopenharmony_ci def _get_random_seed_flags(self): 3311cb0ef41Sopenharmony_ci return ['--random-seed=%d' % self.random_seed] 3321cb0ef41Sopenharmony_ci 3331cb0ef41Sopenharmony_ci @property 3341cb0ef41Sopenharmony_ci def random_seed(self): 3351cb0ef41Sopenharmony_ci return self._random_seed or self._test_config.random_seed 3361cb0ef41Sopenharmony_ci 3371cb0ef41Sopenharmony_ci def _get_extra_flags(self): 3381cb0ef41Sopenharmony_ci return self._test_config.extra_flags 3391cb0ef41Sopenharmony_ci 3401cb0ef41Sopenharmony_ci def _get_variant_flags(self): 3411cb0ef41Sopenharmony_ci return self.variant_flags 3421cb0ef41Sopenharmony_ci 3431cb0ef41Sopenharmony_ci def _get_statusfile_flags(self): 3441cb0ef41Sopenharmony_ci """Gets runtime flags from a status file. 3451cb0ef41Sopenharmony_ci 3461cb0ef41Sopenharmony_ci Every outcome that starts with "--" is a flag. 3471cb0ef41Sopenharmony_ci """ 3481cb0ef41Sopenharmony_ci return self._statusfile_flags 3491cb0ef41Sopenharmony_ci 3501cb0ef41Sopenharmony_ci def _get_mode_flags(self): 3511cb0ef41Sopenharmony_ci return self._test_config.mode_flags 3521cb0ef41Sopenharmony_ci 3531cb0ef41Sopenharmony_ci def _get_source_flags(self): 3541cb0ef41Sopenharmony_ci return [] 3551cb0ef41Sopenharmony_ci 3561cb0ef41Sopenharmony_ci def _get_suite_flags(self): 3571cb0ef41Sopenharmony_ci return [] 3581cb0ef41Sopenharmony_ci 3591cb0ef41Sopenharmony_ci def _get_shell_flags(self): 3601cb0ef41Sopenharmony_ci return [] 3611cb0ef41Sopenharmony_ci 3621cb0ef41Sopenharmony_ci def _get_timeout(self, params): 3631cb0ef41Sopenharmony_ci timeout = self._test_config.timeout 3641cb0ef41Sopenharmony_ci if "--stress-opt" in params: 3651cb0ef41Sopenharmony_ci timeout *= 4 3661cb0ef41Sopenharmony_ci if "--jitless" in params: 3671cb0ef41Sopenharmony_ci timeout *= 2 3681cb0ef41Sopenharmony_ci if "--no-opt" in params: 3691cb0ef41Sopenharmony_ci timeout *= 2 3701cb0ef41Sopenharmony_ci if "--noenable-vfp3" in params: 3711cb0ef41Sopenharmony_ci timeout *= 2 3721cb0ef41Sopenharmony_ci if self._get_timeout_param() == TIMEOUT_LONG: 3731cb0ef41Sopenharmony_ci timeout *= 10 3741cb0ef41Sopenharmony_ci if self.is_slow: 3751cb0ef41Sopenharmony_ci timeout *= 4 3761cb0ef41Sopenharmony_ci return timeout 3771cb0ef41Sopenharmony_ci 3781cb0ef41Sopenharmony_ci def get_shell(self): 3791cb0ef41Sopenharmony_ci raise NotImplementedError() 3801cb0ef41Sopenharmony_ci 3811cb0ef41Sopenharmony_ci def _get_suffix(self): 3821cb0ef41Sopenharmony_ci return '.js' 3831cb0ef41Sopenharmony_ci 3841cb0ef41Sopenharmony_ci def _create_cmd(self, shell, params, env, timeout): 3851cb0ef41Sopenharmony_ci return command.Command( 3861cb0ef41Sopenharmony_ci cmd_prefix=self._test_config.command_prefix, 3871cb0ef41Sopenharmony_ci shell=os.path.abspath(os.path.join(self._test_config.shell_dir, shell)), 3881cb0ef41Sopenharmony_ci args=params, 3891cb0ef41Sopenharmony_ci env=env, 3901cb0ef41Sopenharmony_ci timeout=timeout, 3911cb0ef41Sopenharmony_ci verbose=self._test_config.verbose, 3921cb0ef41Sopenharmony_ci resources_func=self._get_resources, 3931cb0ef41Sopenharmony_ci handle_sigterm=True, 3941cb0ef41Sopenharmony_ci ) 3951cb0ef41Sopenharmony_ci 3961cb0ef41Sopenharmony_ci def _parse_source_flags(self, source=None): 3971cb0ef41Sopenharmony_ci source = source or self.get_source() 3981cb0ef41Sopenharmony_ci flags = [] 3991cb0ef41Sopenharmony_ci for match in re.findall(FLAGS_PATTERN, source): 4001cb0ef41Sopenharmony_ci flags += shlex.split(match.strip()) 4011cb0ef41Sopenharmony_ci return flags 4021cb0ef41Sopenharmony_ci 4031cb0ef41Sopenharmony_ci def is_source_available(self): 4041cb0ef41Sopenharmony_ci return self._get_source_path() is not None 4051cb0ef41Sopenharmony_ci 4061cb0ef41Sopenharmony_ci def get_source(self): 4071cb0ef41Sopenharmony_ci return read_file(self._get_source_path()) 4081cb0ef41Sopenharmony_ci 4091cb0ef41Sopenharmony_ci def _get_source_path(self): 4101cb0ef41Sopenharmony_ci return None 4111cb0ef41Sopenharmony_ci 4121cb0ef41Sopenharmony_ci def _get_resources(self): 4131cb0ef41Sopenharmony_ci """Returns a list of absolute paths with additional files needed by the 4141cb0ef41Sopenharmony_ci test case. 4151cb0ef41Sopenharmony_ci 4161cb0ef41Sopenharmony_ci Used to push additional files to Android devices. 4171cb0ef41Sopenharmony_ci """ 4181cb0ef41Sopenharmony_ci return [] 4191cb0ef41Sopenharmony_ci 4201cb0ef41Sopenharmony_ci def skip_predictable(self): 4211cb0ef41Sopenharmony_ci """Returns True if the test case is not suitable for predictable testing.""" 4221cb0ef41Sopenharmony_ci return True 4231cb0ef41Sopenharmony_ci 4241cb0ef41Sopenharmony_ci @property 4251cb0ef41Sopenharmony_ci def output_proc(self): 4261cb0ef41Sopenharmony_ci if self.expected_outcomes is outproc.OUTCOMES_PASS: 4271cb0ef41Sopenharmony_ci return outproc.DEFAULT 4281cb0ef41Sopenharmony_ci return outproc.OutProc(self.expected_outcomes) 4291cb0ef41Sopenharmony_ci 4301cb0ef41Sopenharmony_ci def __cmp__(self, other): 4311cb0ef41Sopenharmony_ci # Make sure that test cases are sorted correctly if sorted without 4321cb0ef41Sopenharmony_ci # key function. But using a key function is preferred for speed. 4331cb0ef41Sopenharmony_ci def cmp(x, y): 4341cb0ef41Sopenharmony_ci return (x > y) - (x < y) 4351cb0ef41Sopenharmony_ci return cmp( 4361cb0ef41Sopenharmony_ci (self.suite.name, self.name, self.variant), 4371cb0ef41Sopenharmony_ci (other.suite.name, other.name, other.variant) 4381cb0ef41Sopenharmony_ci ) 4391cb0ef41Sopenharmony_ci 4401cb0ef41Sopenharmony_ci def __str__(self): 4411cb0ef41Sopenharmony_ci return self.suite.name + '/' + self.name 4421cb0ef41Sopenharmony_ci 4431cb0ef41Sopenharmony_ci 4441cb0ef41Sopenharmony_ciclass D8TestCase(TestCase): 4451cb0ef41Sopenharmony_ci def get_shell(self): 4461cb0ef41Sopenharmony_ci return "d8" 4471cb0ef41Sopenharmony_ci 4481cb0ef41Sopenharmony_ci def _get_shell_flags(self): 4491cb0ef41Sopenharmony_ci return ['--test'] 4501cb0ef41Sopenharmony_ci 4511cb0ef41Sopenharmony_ci def _get_resources_for_file(self, file): 4521cb0ef41Sopenharmony_ci """Returns for a given file a list of absolute paths of files needed by the 4531cb0ef41Sopenharmony_ci given file. 4541cb0ef41Sopenharmony_ci """ 4551cb0ef41Sopenharmony_ci source = read_file(file) 4561cb0ef41Sopenharmony_ci result = [] 4571cb0ef41Sopenharmony_ci def add_path(path): 4581cb0ef41Sopenharmony_ci result.append(os.path.abspath(path.replace('/', os.path.sep))) 4591cb0ef41Sopenharmony_ci def add_import_path(import_path): 4601cb0ef41Sopenharmony_ci add_path(os.path.normpath( 4611cb0ef41Sopenharmony_ci os.path.join(os.path.dirname(file), import_path))) 4621cb0ef41Sopenharmony_ci def strip_test262_frontmatter(input): 4631cb0ef41Sopenharmony_ci return TEST262_FRONTMATTER_PATTERN.sub('', input) 4641cb0ef41Sopenharmony_ci for match in RESOURCES_PATTERN.finditer(source): 4651cb0ef41Sopenharmony_ci # There are several resources per line. Relative to base dir. 4661cb0ef41Sopenharmony_ci for path in match.group(1).strip().split(): 4671cb0ef41Sopenharmony_ci add_path(path) 4681cb0ef41Sopenharmony_ci # Strip test262 frontmatter before looking for load() and import/export 4691cb0ef41Sopenharmony_ci # statements. 4701cb0ef41Sopenharmony_ci source = strip_test262_frontmatter(source) 4711cb0ef41Sopenharmony_ci for match in LOAD_PATTERN.finditer(source): 4721cb0ef41Sopenharmony_ci # Files in load statements are relative to base dir. 4731cb0ef41Sopenharmony_ci add_path(match.group(1)) 4741cb0ef41Sopenharmony_ci # Imported files are relative to the file importing them. 4751cb0ef41Sopenharmony_ci for match in MODULE_FROM_RESOURCES_PATTERN.finditer(source): 4761cb0ef41Sopenharmony_ci add_import_path(match.group(1)) 4771cb0ef41Sopenharmony_ci for match in MODULE_IMPORT_RESOURCES_PATTERN.finditer(source): 4781cb0ef41Sopenharmony_ci add_import_path(match.group(1)) 4791cb0ef41Sopenharmony_ci return result 4801cb0ef41Sopenharmony_ci 4811cb0ef41Sopenharmony_ci def _get_resources(self): 4821cb0ef41Sopenharmony_ci """Returns the list of files needed by a test case.""" 4831cb0ef41Sopenharmony_ci if not self._get_source_path(): 4841cb0ef41Sopenharmony_ci return [] 4851cb0ef41Sopenharmony_ci result = set() 4861cb0ef41Sopenharmony_ci to_check = [self._get_source_path()] 4871cb0ef41Sopenharmony_ci # Recurse over all files until reaching a fixpoint. 4881cb0ef41Sopenharmony_ci while to_check: 4891cb0ef41Sopenharmony_ci next_resource = to_check.pop() 4901cb0ef41Sopenharmony_ci result.add(next_resource) 4911cb0ef41Sopenharmony_ci for resource in self._get_resources_for_file(next_resource): 4921cb0ef41Sopenharmony_ci # Only add files that exist on disc. The pattens we check for give some 4931cb0ef41Sopenharmony_ci # false positives otherwise. 4941cb0ef41Sopenharmony_ci if resource not in result and os.path.exists(resource): 4951cb0ef41Sopenharmony_ci to_check.append(resource) 4961cb0ef41Sopenharmony_ci return sorted(list(result)) 4971cb0ef41Sopenharmony_ci 4981cb0ef41Sopenharmony_ci def skip_predictable(self): 4991cb0ef41Sopenharmony_ci """Returns True if the test case is not suitable for predictable testing.""" 5001cb0ef41Sopenharmony_ci return (statusfile.FAIL in self.expected_outcomes or 5011cb0ef41Sopenharmony_ci self.output_proc.negative) 502