10fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz#!/usr/bin/env python3.4 20fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# 30fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# Copyright (C) 2016 The Android Open Source Project 40fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# 50fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# Licensed under the Apache License, Version 2.0 (the "License"); 60fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# you may not use this file except in compliance with the License. 70fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# You may obtain a copy of the License at 80fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# 90fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# http://www.apache.org/licenses/LICENSE-2.0 100fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# 110fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# Unless required by applicable law or agreed to in writing, software 120fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# distributed under the License is distributed on an "AS IS" BASIS, 130fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 140fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# See the License for the specific language governing permissions and 150fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# limitations under the License. 160fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 170fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz"""Module containing common logic from python testing tools.""" 180fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 190fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczimport abc 200fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczimport os 210d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewiczimport signal 220fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczimport shlex 230d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewiczimport shutil 24698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewiczimport time 250fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 26e03474846d69e82677abe2c9b66607d9556f455bAart Bikfrom enum import Enum 27e03474846d69e82677abe2c9b66607d9556f455bAart Bikfrom enum import unique 28e03474846d69e82677abe2c9b66607d9556f455bAart Bik 29e03474846d69e82677abe2c9b66607d9556f455bAart Bikfrom subprocess import DEVNULL 300fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczfrom subprocess import check_call 310fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczfrom subprocess import PIPE 320fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczfrom subprocess import Popen 3386379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewiczfrom subprocess import STDOUT 340fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczfrom subprocess import TimeoutExpired 350fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 360fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczfrom tempfile import mkdtemp 370fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczfrom tempfile import NamedTemporaryFile 380fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 390fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# Temporary directory path on device. 400fa3cbd4286db31c872c7009ff3cca359073c01fWojciech StaszkiewiczDEVICE_TMP_PATH = '/data/local/tmp' 410fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 420fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz# Architectures supported in dalvik cache. 430fa3cbd4286db31c872c7009ff3cca359073c01fWojciech StaszkiewiczDALVIK_CACHE_ARCHS = ['arm', 'arm64', 'x86', 'x86_64'] 440fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 450fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 460d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz@unique 470d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewiczclass RetCode(Enum): 480d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz """Enum representing normalized return codes.""" 490d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz SUCCESS = 0 500d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz TIMEOUT = 1 510d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz ERROR = 2 520d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz NOTCOMPILED = 3 530d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz NOTRUN = 4 540d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 550d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 56698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz@unique 57698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewiczclass LogSeverity(Enum): 58698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz VERBOSE = 0 59698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz DEBUG = 1 60698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz INFO = 2 61698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz WARNING = 3 62698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz ERROR = 4 63698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz FATAL = 5 64698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz SILENT = 6 65698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 66698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz @property 67698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def symbol(self): 68698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return self.name[0] 69698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 70698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz @classmethod 71698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def FromSymbol(cls, s): 72698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz for log_severity in LogSeverity: 73698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if log_severity.symbol == s: 74698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return log_severity 75698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz raise ValueError("{0} is not a valid log severity symbol".format(s)) 76698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 77698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def __ge__(self, other): 78698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if self.__class__ is other.__class__: 79698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return self.value >= other.value 80698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return NotImplemented 81698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 82698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def __gt__(self, other): 83698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if self.__class__ is other.__class__: 84698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return self.value > other.value 85698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return NotImplemented 86698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 87698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def __le__(self, other): 88698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if self.__class__ is other.__class__: 89698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return self.value <= other.value 90698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return NotImplemented 91698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 92698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def __lt__(self, other): 93698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if self.__class__ is other.__class__: 94698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return self.value < other.value 95e03474846d69e82677abe2c9b66607d9556f455bAart Bik return NotImplemented 96698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 97698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 980fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczdef GetEnvVariableOrError(variable_name): 990fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Gets value of an environmental variable. 1000fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1010fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz If the variable is not set raises FatalError. 1020fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1030fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 1040fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz variable_name: string, name of variable to get. 1050fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1060fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Returns: 1070fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz string, value of requested variable. 1080fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1090fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Raises: 1100fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz FatalError: Requested variable is not set. 1110fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 1120fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz top = os.environ.get(variable_name) 1130fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz if top is None: 1140fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz raise FatalError('{0} environmental variable not set.'.format( 1150fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz variable_name)) 1160fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return top 1170fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1180fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 119e03474846d69e82677abe2c9b66607d9556f455bAart Bikdef GetJackClassPath(): 120e03474846d69e82677abe2c9b66607d9556f455bAart Bik """Returns Jack's classpath.""" 121e03474846d69e82677abe2c9b66607d9556f455bAart Bik top = GetEnvVariableOrError('ANDROID_BUILD_TOP') 122e03474846d69e82677abe2c9b66607d9556f455bAart Bik libdir = top + '/out/host/common/obj/JAVA_LIBRARIES' 123e03474846d69e82677abe2c9b66607d9556f455bAart Bik return libdir + '/core-libart-hostdex_intermediates/classes.jack:' \ 124e03474846d69e82677abe2c9b66607d9556f455bAart Bik + libdir + '/core-oj-hostdex_intermediates/classes.jack' 125e03474846d69e82677abe2c9b66607d9556f455bAart Bik 126e03474846d69e82677abe2c9b66607d9556f455bAart Bik 1270fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczdef _DexArchCachePaths(android_data_path): 1280fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Returns paths to architecture specific caches. 1290fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1300fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 1310fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz android_data_path: string, path dalvik-cache resides in. 1320fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1330fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Returns: 1340fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Iterable paths to architecture specific caches. 1350fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 1360fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return ('{0}/dalvik-cache/{1}'.format(android_data_path, arch) 1370fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz for arch in DALVIK_CACHE_ARCHS) 1380fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1390fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1400d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewiczdef RunCommandForOutput(cmd, env, stdout, stderr, timeout=60): 1410d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz """Runs command piping output to files, stderr or stdout. 1420d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 1430d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz Args: 1440d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz cmd: list of strings, command to run. 1450d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz env: shell environment to run the command with. 1460d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz stdout: file handle or one of Subprocess.PIPE, Subprocess.STDOUT, 1470d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz Subprocess.DEVNULL, see Popen. 1480d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz stderr: file handle or one of Subprocess.PIPE, Subprocess.STDOUT, 1490d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz Subprocess.DEVNULL, see Popen. 1500d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz timeout: int, timeout in seconds. 1510d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 1520d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz Returns: 1530d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz tuple (string, string, RetCode) stdout output, stderr output, normalized 1540d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz return code. 1550d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz """ 1560d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz proc = Popen(cmd, stdout=stdout, stderr=stderr, env=env, 1570d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz universal_newlines=True, start_new_session=True) 1580d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz try: 1590d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz (output, stderr_output) = proc.communicate(timeout=timeout) 1600d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz if proc.returncode == 0: 1610d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz retcode = RetCode.SUCCESS 1620d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz else: 1630d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz retcode = RetCode.ERROR 1640d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz except TimeoutExpired: 1650d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz os.killpg(os.getpgid(proc.pid), signal.SIGTERM) 1660d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz (output, stderr_output) = proc.communicate() 1670d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz retcode = RetCode.TIMEOUT 1680d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz return (output, stderr_output, retcode) 1690d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 1700d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 171698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewiczdef _LogCmdOutput(logfile, cmd, output, retcode): 172698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz """Logs output of a command. 1730fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1740fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 1750fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz logfile: file handle to logfile. 176698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz cmd: list of strings, command. 177698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz output: command output. 178698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz retcode: RetCode, normalized retcode. 1790fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 18086379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz logfile.write('Command:\n{0}\n{1}\nReturn code: {2}\n'.format( 1810d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz CommandListToCommandString(cmd), output, retcode)) 1820fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 1830fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 184e03474846d69e82677abe2c9b66607d9556f455bAart Bikdef RunCommand(cmd, out, err, timeout=5): 185e03474846d69e82677abe2c9b66607d9556f455bAart Bik """Executes a command, and returns its return code. 186e03474846d69e82677abe2c9b66607d9556f455bAart Bik 187e03474846d69e82677abe2c9b66607d9556f455bAart Bik Args: 188e03474846d69e82677abe2c9b66607d9556f455bAart Bik cmd: list of strings, a command to execute 189e03474846d69e82677abe2c9b66607d9556f455bAart Bik out: string, file name to open for stdout (or None) 190e03474846d69e82677abe2c9b66607d9556f455bAart Bik err: string, file name to open for stderr (or None) 191e03474846d69e82677abe2c9b66607d9556f455bAart Bik timeout: int, time out in seconds 192e03474846d69e82677abe2c9b66607d9556f455bAart Bik Returns: 193e03474846d69e82677abe2c9b66607d9556f455bAart Bik RetCode, return code of running command (forced RetCode.TIMEOUT 194e03474846d69e82677abe2c9b66607d9556f455bAart Bik on timeout) 195e03474846d69e82677abe2c9b66607d9556f455bAart Bik """ 196e03474846d69e82677abe2c9b66607d9556f455bAart Bik devnull = DEVNULL 197e03474846d69e82677abe2c9b66607d9556f455bAart Bik outf = devnull 198e03474846d69e82677abe2c9b66607d9556f455bAart Bik if out is not None: 199e03474846d69e82677abe2c9b66607d9556f455bAart Bik outf = open(out, mode='w') 200e03474846d69e82677abe2c9b66607d9556f455bAart Bik errf = devnull 201e03474846d69e82677abe2c9b66607d9556f455bAart Bik if err is not None: 202e03474846d69e82677abe2c9b66607d9556f455bAart Bik errf = open(err, mode='w') 203e03474846d69e82677abe2c9b66607d9556f455bAart Bik (_, _, retcode) = RunCommandForOutput(cmd, None, outf, errf, timeout) 204e03474846d69e82677abe2c9b66607d9556f455bAart Bik if outf != devnull: 205e03474846d69e82677abe2c9b66607d9556f455bAart Bik outf.close() 206e03474846d69e82677abe2c9b66607d9556f455bAart Bik if errf != devnull: 207e03474846d69e82677abe2c9b66607d9556f455bAart Bik errf.close() 208e03474846d69e82677abe2c9b66607d9556f455bAart Bik return retcode 209e03474846d69e82677abe2c9b66607d9556f455bAart Bik 210e03474846d69e82677abe2c9b66607d9556f455bAart Bik 2110d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewiczdef CommandListToCommandString(cmd): 2120fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Converts shell command represented as list of strings to a single string. 2130fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2140fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Each element of the list is wrapped in double quotes. 2150fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2160fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 2170fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz cmd: list of strings, shell command. 2180fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2190fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Returns: 2200fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz string, shell command. 2210fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2220d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz return ' '.join([shlex.quote(segment) for segment in cmd]) 2230fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2240fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2250fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczclass FatalError(Exception): 2260fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Fatal error in script.""" 2270fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2280fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2290fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczclass ITestEnv(object): 2300fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Test environment abstraction. 2310fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2320fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Provides unified interface for interacting with host and device test 2330fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz environments. Creates a test directory and expose methods to modify test files 2340fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz and run commands. 2350fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2360fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz __meta_class__ = abc.ABCMeta 2370fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2380fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz @abc.abstractmethod 2390fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def CreateFile(self, name=None): 2400fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Creates a file in test directory. 2410fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2420fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Returned path to file can be used in commands run in the environment. 2430fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2440fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 2450fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz name: string, file name. If None file is named arbitrarily. 2460fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2470fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Returns: 2480fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz string, environment specific path to file. 2490fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2500fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2510fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz @abc.abstractmethod 2520fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def WriteLines(self, file_path, lines): 2530fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Writes lines to a file in test directory. 2540fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2550fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz If file exists it gets overwritten. If file doest not exist it is created. 2560fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2570fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 2580fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz file_path: string, environment specific path to file. 2590fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz lines: list of strings to write. 2600fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2610fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2620fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz @abc.abstractmethod 263698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def RunCommand(self, cmd, log_severity=LogSeverity.ERROR): 264698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz """Runs command in environment. 2650fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2660fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 26786379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz cmd: list of strings, command to run. 268698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz log_severity: LogSeverity, minimum severity of logs included in output. 2690fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Returns: 270698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz tuple (string, int) output, return code. 2710fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2720fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2730fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz @abc.abstractproperty 2740fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def logfile(self): 2750fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Gets file handle to logfile residing on host.""" 2760fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2770fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2780fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczclass HostTestEnv(ITestEnv): 2790fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Host test environment. Concrete implementation of ITestEnv. 2800fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2810fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Maintains a test directory in /tmp/. Runs commands on the host in modified 2820fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz shell environment. Mimics art script behavior. 2830fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2840fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz For methods documentation see base class. 2850fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2860fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2870d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz def __init__(self, directory_prefix, cleanup=True, logfile_path=None, 2880d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz timeout=60, x64=False): 2890fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Constructor. 2900fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 2910fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Args: 2920d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz directory_prefix: string, prefix for environment directory name. 2930d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz cleanup: boolean, if True remove test directory in destructor. 2940d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz logfile_path: string, can be used to specify custom logfile location. 2950d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz timeout: int, seconds, time to wait for single test run to finish. 2960fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz x64: boolean, whether to setup in x64 mode. 2970fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 2980d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._cleanup = cleanup 2990d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._timeout = timeout 3000d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._env_path = mkdtemp(dir='/tmp/', prefix=directory_prefix) 3010d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz if logfile_path is None: 3020d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._logfile = open('{0}/log'.format(self._env_path), 'w+') 3030d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz else: 3040d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._logfile = open(logfile_path, 'w+') 3050fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz os.mkdir('{0}/dalvik-cache'.format(self._env_path)) 3060fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz for arch_cache_path in _DexArchCachePaths(self._env_path): 3070fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz os.mkdir(arch_cache_path) 3080fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz lib = 'lib64' if x64 else 'lib' 3090fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz android_root = GetEnvVariableOrError('ANDROID_HOST_OUT') 3100fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz library_path = android_root + '/' + lib 3110fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz path = android_root + '/bin' 3120fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._shell_env = os.environ.copy() 3130fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._shell_env['ANDROID_DATA'] = self._env_path 3140fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._shell_env['ANDROID_ROOT'] = android_root 3150fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._shell_env['LD_LIBRARY_PATH'] = library_path 31686379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz self._shell_env['DYLD_LIBRARY_PATH'] = library_path 3170fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._shell_env['PATH'] = (path + ':' + self._shell_env['PATH']) 3180fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz # Using dlopen requires load bias on the host. 3190fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._shell_env['LD_USE_LOAD_BIAS'] = '1' 3200fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3210d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz def __del__(self): 3220d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz if self._cleanup: 3230d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz shutil.rmtree(self._env_path) 3240d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 3250fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def CreateFile(self, name=None): 3260fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz if name is None: 3270fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz f = NamedTemporaryFile(dir=self._env_path, delete=False) 3280fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz else: 3290fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz f = open('{0}/{1}'.format(self._env_path, name), 'w+') 3300fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return f.name 3310fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3320fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def WriteLines(self, file_path, lines): 3330fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz with open(file_path, 'w') as f: 3340fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz f.writelines('{0}\n'.format(line) for line in lines) 3350fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return 3360fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 337698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def RunCommand(self, cmd, log_severity=LogSeverity.ERROR): 3380fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._EmptyDexCache() 33986379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz env = self._shell_env.copy() 340698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz env.update({'ANDROID_LOG_TAGS':'*:' + log_severity.symbol.lower()}) 341698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz (output, err_output, retcode) = RunCommandForOutput( 342698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz cmd, env, PIPE, PIPE, self._timeout) 343698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # We append err_output to output to stay consistent with DeviceTestEnv 344698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # implementation. 345698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz output += err_output 346698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz _LogCmdOutput(self._logfile, cmd, output, retcode) 347698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return (output, retcode) 3480fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3490fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz @property 3500fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def logfile(self): 3510fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return self._logfile 3520fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3530fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def _EmptyDexCache(self): 3540fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Empties dex cache. 3550fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3560fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz Iterate over files in architecture specific cache directories and remove 3570fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz them. 3580fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 3590fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz for arch_cache_path in _DexArchCachePaths(self._env_path): 3600fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz for file_path in os.listdir(arch_cache_path): 3610fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz file_path = '{0}/{1}'.format(arch_cache_path, file_path) 3620fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz if os.path.isfile(file_path): 3630fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz os.unlink(file_path) 3640fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3650fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3660fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewiczclass DeviceTestEnv(ITestEnv): 3670fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Device test environment. Concrete implementation of ITestEnv. 3680fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3690fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz For methods documentation see base class. 3700fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """ 3710fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3720d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz def __init__(self, directory_prefix, cleanup=True, logfile_path=None, 3730d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz timeout=60, specific_device=None): 3740d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz """Constructor. 3750d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 3760d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz Args: 3770d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz directory_prefix: string, prefix for environment directory name. 3780d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz cleanup: boolean, if True remove test directory in destructor. 3790d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz logfile_path: string, can be used to specify custom logfile location. 3800d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz timeout: int, seconds, time to wait for single test run to finish. 3810d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz specific_device: string, serial number of device to use. 3820d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz """ 3830d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._cleanup = cleanup 3840d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._timeout = timeout 3850d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._specific_device = specific_device 3860d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._host_env_path = mkdtemp(dir='/tmp/', prefix=directory_prefix) 3870d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz if logfile_path is None: 3880d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._logfile = open('{0}/log'.format(self._host_env_path), 'w+') 3890d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz else: 3900d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz self._logfile = open(logfile_path, 'w+') 3910fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._device_env_path = '{0}/{1}'.format( 3920fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz DEVICE_TMP_PATH, os.path.basename(self._host_env_path)) 39386379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz self._shell_env = os.environ.copy() 3940fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3950fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._AdbMkdir('{0}/dalvik-cache'.format(self._device_env_path)) 3960fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz for arch_cache_path in _DexArchCachePaths(self._device_env_path): 3970fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._AdbMkdir(arch_cache_path) 3980fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 3990d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz def __del__(self): 4000d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz if self._cleanup: 4010d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz shutil.rmtree(self._host_env_path) 4020d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz check_call(shlex.split( 4030d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 'adb shell if [ -d "{0}" ]; then rm -rf "{0}"; fi' 4040d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz .format(self._device_env_path))) 4050d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz 4060fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def CreateFile(self, name=None): 4070fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz with NamedTemporaryFile(mode='w') as temp_file: 4080fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._AdbPush(temp_file.name, self._device_env_path) 4090fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz if name is None: 4100fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz name = os.path.basename(temp_file.name) 4110fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return '{0}/{1}'.format(self._device_env_path, name) 4120fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 4130fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def WriteLines(self, file_path, lines): 4140fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz with NamedTemporaryFile(mode='w') as temp_file: 4150fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz temp_file.writelines('{0}\n'.format(line) for line in lines) 41686379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz temp_file.flush() 4170fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._AdbPush(temp_file.name, file_path) 4180fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return 4190fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 420698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def _ExtractPid(self, brief_log_line): 421698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz """Extracts PID from a single logcat line in brief format.""" 422698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz pid_start_idx = brief_log_line.find('(') + 2 423698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if pid_start_idx == -1: 424698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return None 425698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz pid_end_idx = brief_log_line.find(')', pid_start_idx) 426698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if pid_end_idx == -1: 427698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return None 428698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return brief_log_line[pid_start_idx:pid_end_idx] 429698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 430698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def _ExtractSeverity(self, brief_log_line): 431698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz """Extracts LogSeverity from a single logcat line in brief format.""" 432698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if not brief_log_line: 433698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return None 434698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return LogSeverity.FromSymbol(brief_log_line[0]) 435698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz 436698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz def RunCommand(self, cmd, log_severity=LogSeverity.ERROR): 4370fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz self._EmptyDexCache() 438698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz env_vars_cmd = 'ANDROID_DATA={0} ANDROID_LOG_TAGS=*:i'.format( 439698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz self._device_env_path) 440698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz adb_cmd = ['adb'] 4410d0fd4a6bcf3b1223f1f5ed31d61aadfcfe79bc9Wojciech Staszkiewicz if self._specific_device: 442698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz adb_cmd += ['-s', self._specific_device] 443698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz logcat_cmd = adb_cmd + ['logcat', '-v', 'brief', '-s', '-b', 'main', 444698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz '-T', '1', 'dex2oat:*', 'dex2oatd:*'] 445698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz logcat_proc = Popen(logcat_cmd, stdout=PIPE, stderr=STDOUT, 446698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz universal_newlines=True) 447698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz cmd_str = CommandListToCommandString(cmd) 448698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # Print PID of the shell and exec command. We later retrieve this PID and 449698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # use it to filter dex2oat logs, keeping those with matching parent PID. 450698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz device_cmd = ('echo $$ && ' + env_vars_cmd + ' exec ' + cmd_str) 451698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz cmd = adb_cmd + ['shell', device_cmd] 452698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz (output, _, retcode) = RunCommandForOutput(cmd, self._shell_env, PIPE, 453698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz STDOUT, self._timeout) 454698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # We need to make sure to only kill logcat once all relevant logs arrive. 455698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # Sleep is used for simplicity. 456698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz time.sleep(0.5) 457698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz logcat_proc.kill() 458698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz end_of_first_line = output.find('\n') 459698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if end_of_first_line != -1: 460698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz parent_pid = output[:end_of_first_line] 461698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz output = output[end_of_first_line + 1:] 462698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz logcat_output, _ = logcat_proc.communicate() 463698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz logcat_lines = logcat_output.splitlines(keepends=True) 464698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz dex2oat_pids = [] 465698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz for line in logcat_lines: 466698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz # Dex2oat was started by our runtime instance. 467698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if 'Running dex2oat (parent PID = ' + parent_pid in line: 468698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz dex2oat_pids.append(self._ExtractPid(line)) 469698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz break 470698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if dex2oat_pids: 471698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz for line in logcat_lines: 472698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz if (self._ExtractPid(line) in dex2oat_pids and 473698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz self._ExtractSeverity(line) >= log_severity): 474698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz output += line 475698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz _LogCmdOutput(self._logfile, cmd, output, retcode) 476698e4b30e6d0e937e34e73a3c5349f67a076e1b5Wojciech Staszkiewicz return (output, retcode) 4770fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 4780fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz @property 4790fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def logfile(self): 4800fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz return self._logfile 4810fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 48286379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz def PushClasspath(self, classpath): 48386379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz """Push classpath to on-device test directory. 48486379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz 48586379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz Classpath can contain multiple colon separated file paths, each file is 48686379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz pushed. Returns analogous classpath with paths valid on device. 48786379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz 48886379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz Args: 48986379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz classpath: string, classpath in format 'a/b/c:d/e/f'. 49086379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz Returns: 49186379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz string, classpath valid on device. 49286379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz """ 49386379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz paths = classpath.split(':') 49486379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz device_paths = [] 49586379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz for path in paths: 49686379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz device_paths.append('{0}/{1}'.format( 49786379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz self._device_env_path, os.path.basename(path))) 49886379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz self._AdbPush(path, self._device_env_path) 49986379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz return ':'.join(device_paths) 50086379941f33ce651fc4cbc62ce7d95a15bbce8f8Wojciech Staszkiewicz 5010fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def _AdbPush(self, what, where): 5020fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz check_call(shlex.split('adb push "{0}" "{1}"'.format(what, where)), 5030fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz stdout=self._logfile, stderr=self._logfile) 5040fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 5050fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def _AdbMkdir(self, path): 5060fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz check_call(shlex.split('adb shell mkdir "{0}" -p'.format(path)), 5070fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz stdout=self._logfile, stderr=self._logfile) 5080fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz 5090fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz def _EmptyDexCache(self): 5100fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz """Empties dex cache.""" 5110fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz for arch_cache_path in _DexArchCachePaths(self._device_env_path): 5120fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz cmd = 'adb shell if [ -d "{0}" ]; then rm -f "{0}"/*; fi'.format( 5130fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz arch_cache_path) 5140fa3cbd4286db31c872c7009ff3cca359073c01fWojciech Staszkiewicz check_call(shlex.split(cmd), stdout=self._logfile, stderr=self._logfile) 515