Home | History | Annotate | Download | only in testrunner
      1 # Copyright 2017, The Android Open Source Project
      2 #
      3 # Licensed under the Apache License, Version 2.0 (the "License");
      4 # you may not use this file except in compliance with the License.
      5 # You may obtain a copy of the License at
      6 #
      7 #     http://www.apache.org/licenses/LICENSE-2.0
      8 #
      9 # Unless required by applicable law or agreed to in writing, software
     10 # distributed under the License is distributed on an "AS IS" BASIS,
     11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     12 # See the License for the specific language governing permissions and
     13 # limitations under the License.
     14 
     15 import os
     16 import re
     17 import tempfile
     18 import subprocess
     19 
     20 _env = dict(os.environ)
     21 
     22 def _getEnvBoolean(var, default):
     23   val = _env.get(var)
     24   if val:
     25     if val == "True" or val == "true":
     26       return True
     27     if val == "False" or val == "false":
     28       return False
     29   return default
     30 
     31 _DUMP_MANY_VARS_LIST = ['HOST_2ND_ARCH_PREFIX',
     32                         'TARGET_2ND_ARCH',
     33                         'TARGET_ARCH',
     34                         'HOST_PREFER_32_BIT',
     35                         'HOST_OUT_EXECUTABLES',
     36                         'ANDROID_JAVA_TOOLCHAIN',
     37                         'ANDROID_COMPILE_WITH_JACK',
     38                         'USE_D8_BY_DEFAULT']
     39 _DUMP_MANY_VARS = None  # To be set to a dictionary with above list being the keys,
     40                         # and the build variable being the value.
     41 def _dump_many_vars(var_name):
     42   """
     43   Reach into the Android build system to dump many build vars simultaneously.
     44   Since the make system is so slow, we want to avoid calling into build frequently.
     45   """
     46   global _DUMP_MANY_VARS
     47   global _DUMP_MANY_VARS_LIST
     48 
     49   # Look up var from cache.
     50   if _DUMP_MANY_VARS:
     51     return _DUMP_MANY_VARS[var_name]
     52 
     53   all_vars=" ".join(_DUMP_MANY_VARS_LIST)
     54 
     55   # The command is taken from build/envsetup.sh to fetch build variables.
     56   command = ("build/soong/soong_ui.bash --dumpvars-mode --vars=\"%s\"") % (all_vars)
     57 
     58   config = subprocess.Popen(command,
     59                             stdout=subprocess.PIPE,
     60                             universal_newlines=True,
     61                             shell=True,
     62                             cwd=ANDROID_BUILD_TOP).communicate()[0] # read until EOF, select stdin
     63   # Prints out something like:
     64   # TARGET_ARCH='arm64'
     65   # HOST_ARCH='x86_64'
     66   _DUMP_MANY_VARS = {}
     67   for line in config.split("\n"):
     68     # Split out "$key='$value'" via regex.
     69     match = re.search("([^=]+)='([^']*)", line)
     70     if not match:
     71       continue
     72     key = match.group(1)
     73     value = match.group(2)
     74     _DUMP_MANY_VARS[key] = value
     75 
     76   return _DUMP_MANY_VARS[var_name]
     77 
     78 def _get_build_var(var_name):
     79   return _dump_many_vars(var_name)
     80 
     81 def _get_build_var_boolean(var, default):
     82   val = _get_build_var(var)
     83   if val:
     84     if val == "True" or val == "true":
     85       return True
     86     if val == "False" or val == "false":
     87       return False
     88   return default
     89 
     90 def get_env(key):
     91   return _env.get(key)
     92 
     93 def _get_android_build_top():
     94   path_to_top = _env.get('ANDROID_BUILD_TOP')
     95   if not path_to_top:
     96     # nothing set. try to guess it based on the relative path of this env.py file.
     97     this_file_path = os.path.realpath(__file__)
     98     path_to_top = os.path.join(os.path.dirname(this_file_path), '../../../')
     99     path_to_top = os.path.realpath(path_to_top)
    100 
    101   if not os.path.exists(os.path.join(path_to_top, 'build/envsetup.sh')):
    102     raise AssertionError("env.py must be located inside an android source tree")
    103 
    104   return path_to_top
    105 
    106 ANDROID_BUILD_TOP = _get_android_build_top()
    107 
    108 # Compiling with jack? Possible values in (True, False, 'default')
    109 ANDROID_COMPILE_WITH_JACK = _get_build_var_boolean('ANDROID_COMPILE_WITH_JACK', 'default')
    110 
    111 # Follow the build system's D8 usage.
    112 USE_D8_BY_DEFAULT = _get_build_var_boolean('USE_D8_BY_DEFAULT', False)
    113 
    114 # Directory used for temporary test files on the host.
    115 ART_HOST_TEST_DIR = tempfile.mkdtemp(prefix = 'test-art-')
    116 
    117 # Keep going after encountering a test failure?
    118 ART_TEST_KEEP_GOING = _getEnvBoolean('ART_TEST_KEEP_GOING', True)
    119 
    120 # Do you want failed tests to have their artifacts cleaned up?
    121 ART_TEST_RUN_TEST_ALWAYS_CLEAN = _getEnvBoolean('ART_TEST_RUN_TEST_ALWAYS_CLEAN', True)
    122 
    123 ART_TEST_BISECTION = _getEnvBoolean('ART_TEST_BISECTION', False)
    124 
    125 DEX2OAT_HOST_INSTRUCTION_SET_FEATURES = _env.get('DEX2OAT_HOST_INSTRUCTION_SET_FEATURES')
    126 
    127 # Do you want run-tests with the host/target's second arch?
    128 ART_TEST_RUN_TEST_2ND_ARCH = _getEnvBoolean('ART_TEST_RUN_TEST_2ND_ARCH', True)
    129 
    130 HOST_2ND_ARCH_PREFIX = _get_build_var('HOST_2ND_ARCH_PREFIX')
    131 HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES = _env.get(
    132   HOST_2ND_ARCH_PREFIX + 'DEX2OAT_HOST_INSTRUCTION_SET_FEATURES')
    133 
    134 ART_TEST_ANDROID_ROOT = _env.get('ART_TEST_ANDROID_ROOT')
    135 
    136 ART_TEST_WITH_STRACE = _getEnvBoolean('ART_TEST_DEBUG_GC', False)
    137 
    138 EXTRA_DISABLED_TESTS = set(_env.get("ART_TEST_RUN_TEST_SKIP", "").split())
    139 
    140 ART_TEST_RUN_TEST_BUILD = _getEnvBoolean('ART_TEST_RUN_TEST_BUILD', False)
    141 
    142 TARGET_2ND_ARCH = _get_build_var('TARGET_2ND_ARCH')
    143 TARGET_ARCH = _get_build_var('TARGET_ARCH')
    144 
    145 # Note: ART_2ND_PHONY_TEST_TARGET_SUFFIX is 2ND_ART_PHONY_TEST_TARGET_SUFFIX in .mk files
    146 # Note: ART_2ND_PHONY_TEST_HOST_SUFFIX is 2ND_ART_PHONY_HOST_TARGET_SUFFIX in .mk files
    147 # Python does not let us have variable names starting with a digit, so it has differ.
    148 
    149 if TARGET_2ND_ARCH:
    150   if "64" in TARGET_ARCH:
    151     ART_PHONY_TEST_TARGET_SUFFIX = "64"
    152     ART_2ND_PHONY_TEST_TARGET_SUFFIX = "32"
    153   else:
    154     ART_PHONY_TEST_TARGET_SUFFIX = "32"
    155     ART_2ND_PHONY_TEST_TARGET_SUFFIX = ""
    156 else:
    157   if "64" in TARGET_ARCH:
    158     ART_PHONY_TEST_TARGET_SUFFIX = "64"
    159     ART_2ND_PHONY_TEST_TARGET_SUFFIX = ""
    160   else:
    161     ART_PHONY_TEST_TARGET_SUFFIX = "32"
    162     ART_2ND_PHONY_TEST_TARGET_SUFFIX = ""
    163 
    164 HOST_PREFER_32_BIT = _get_build_var('HOST_PREFER_32_BIT')
    165 if HOST_PREFER_32_BIT == "true":
    166   ART_PHONY_TEST_HOST_SUFFIX = "32"
    167   ART_2ND_PHONY_TEST_HOST_SUFFIX = ""
    168 else:
    169   ART_PHONY_TEST_HOST_SUFFIX = "64"
    170   ART_2ND_PHONY_TEST_HOST_SUFFIX = "32"
    171 
    172 HOST_OUT_EXECUTABLES = os.path.join(ANDROID_BUILD_TOP,
    173                                     _get_build_var("HOST_OUT_EXECUTABLES"))
    174 
    175 # Set up default values for $JACK, $DX, $SMALI, etc to the $HOST_OUT_EXECUTABLES/$name path.
    176 for tool in ['jack', 'dx', 'smali', 'jasmin', 'dxmerger']:
    177   binary = tool if tool != 'dxmerger' else 'dexmerger'
    178   os.environ.setdefault(tool.upper(), HOST_OUT_EXECUTABLES + '/' + binary)
    179 
    180 ANDROID_JAVA_TOOLCHAIN = os.path.join(ANDROID_BUILD_TOP,
    181                                      _get_build_var('ANDROID_JAVA_TOOLCHAIN'))
    182 
    183 # include platform prebuilt java, javac, etc in $PATH.
    184 os.environ['PATH'] = ANDROID_JAVA_TOOLCHAIN + ':' + os.environ['PATH']
    185