blob: e991ed78d980c57fffc7c10257b1f386166f826f [file] [log] [blame]
#!/usr/bin/env python
# Copyright (C) 2017 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import argparse
import os
import re
import subprocess
import sys
import time
""" Runs a test executable on Android.
Takes care of pushing the extra shared libraries that might be required by
some sanitizers. Propagates the test return code to the host, exiting with
0 only if the test execution succeeds on the device.
"""
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
ADB_PATH = os.path.join(ROOT_DIR, 'buildtools/android_sdk/platform-tools/adb')
def AdbCall(*args):
cmd = [ADB_PATH] + list(args)
print '> adb ' + ' '.join(args)
return subprocess.check_call(cmd)
def GetProp(prop):
cmd = [ADB_PATH, 'shell', 'getprop', prop]
print '> adb ' + ' '.join(cmd)
output = subprocess.check_output(cmd)
lines = output.splitlines()
assert len(lines) == 1
print lines[0]
return lines[0]
def BootCompleted():
return GetProp('sys.boot_completed') == '1'
def ExponentialBackOff(f):
delay_seconds = 1
while True:
if f():
return
time.sleep(delay_seconds)
delay_seconds *= 2
def Main():
parser = argparse.ArgumentParser()
parser.add_argument('--no-cleanup', '-n', action='store_true')
parser.add_argument('out_dir', help='out/android/')
parser.add_argument('test_name', help='libtracing_unittests')
args = parser.parse_args()
test_bin = os.path.join(args.out_dir, args.test_name)
assert os.path.exists(test_bin)
print 'Waiting for device ...'
AdbCall('wait-for-device')
ExponentialBackOff(BootCompleted)
target_dir = '/data/local/tmp/' + args.test_name
AdbCall('shell', 'rm -rf "%s"; mkdir -p "%s"' % (2 * (target_dir,)))
AdbCall('push', test_bin, target_dir)
# LLVM sanitizers require to sideload a libclangrtXX.so on the device.
sanitizer_libs = os.path.join(args.out_dir, 'sanitizer_libs')
env = ''
if os.path.exists(sanitizer_libs):
AdbCall('push', sanitizer_libs, target_dir)
env = 'LD_LIBRARY_PATH="%s/sanitizer_libs" ' % (target_dir)
cmd = env + target_dir + '/' + args.test_name
cmd += '; echo -e "\\nTEST_RET_CODE=$?"'
print cmd
test_output = subprocess.check_output([ADB_PATH, 'shell', cmd])
print test_output
retcode = re.search(r'^TEST_RET_CODE=(\d)', test_output, re.MULTILINE)
assert retcode, 'Could not find TEST_RET_CODE=N marker'
retcode = int(retcode.group(1))
if not args.no_cleanup:
AdbCall('shell', 'rm -rf "%s"' % target_dir)
return retcode
if __name__ == '__main__':
sys.exit(Main())