1c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org#!/usr/bin/env python 2c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# 3c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# Copyright 2012 the V8 project authors. All rights reserved. 4c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# Redistribution and use in source and binary forms, with or without 5c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# modification, are permitted provided that the following conditions are 6c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# met: 7c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# 8c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# * Redistributions of source code must retain the above copyright 9c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# notice, this list of conditions and the following disclaimer. 10c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# * Redistributions in binary form must reproduce the above 11c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# copyright notice, this list of conditions and the following 12c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# disclaimer in the documentation and/or other materials provided 13c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# with the distribution. 14c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# * Neither the name of Google Inc. nor the names of its 15c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# contributors may be used to endorse or promote products derived 16c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# from this software without specific prior written permission. 17c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# 18c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 30c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# This script executes the passed command line on Android device 31c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# using 'adb shell' command. Unfortunately, 'adb shell' always 32c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# returns exit code 0, ignoring the exit code of executed command. 33c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# Since we need to return non-zero exit code if the command failed, 34c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# we augment the passed command line with exit code checking statement 35c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# and output special error string in case of non-zero exit code. 36c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org# Then we parse the output of 'adb shell' and look for that error string. 37c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 38c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgimport os 39c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgfrom os.path import join, dirname, abspath 40c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgimport subprocess 41c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgimport sys 42c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgimport tempfile 43c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 44c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgdef Check(output, errors): 45304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org failed = any([s.startswith('/system/bin/sh:') or s.startswith('ANDROID') 46c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org for s in output.split('\n')]) 47c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return 1 if failed else 0 48c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 49c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgdef Execute(cmdline): 50c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org (fd_out, outname) = tempfile.mkstemp() 51c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org (fd_err, errname) = tempfile.mkstemp() 52c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org process = subprocess.Popen( 53c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org args=cmdline, 54c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org shell=True, 55c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org stdout=fd_out, 56c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org stderr=fd_err, 57c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org ) 58c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org exit_code = process.wait() 59c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org os.close(fd_out) 60c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org os.close(fd_err) 61c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org output = file(outname).read() 62c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org errors = file(errname).read() 63c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org os.unlink(outname) 64c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org os.unlink(errname) 65c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org sys.stdout.write(output) 66c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org sys.stderr.write(errors) 67c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return exit_code or Check(output, errors) 68c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 69c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgdef Escape(arg): 70c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org def ShouldEscape(): 71c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org for x in arg: 72c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if not x.isalnum() and x != '-' and x != '_': 73c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return True 74c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return False 75c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 76c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"')) 77c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 78c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgdef WriteToTemporaryFile(data): 79c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org (fd, fname) = tempfile.mkstemp() 80c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org os.close(fd) 81c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org tmp_file = open(fname, "w") 82c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org tmp_file.write(data) 83c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org tmp_file.close() 84c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return fname 85c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 86c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgdef Main(): 87c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org if (len(sys.argv) == 1): 88c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org print("Usage: %s <command-to-run-on-device>" % sys.argv[0]) 89c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return 1 90c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org workspace = abspath(join(dirname(sys.argv[0]), '..')) 911510d58cbcf57c82a10e7d390bfe21a7ae68ba43mstarzinger@chromium.org android_workspace = os.getenv("ANDROID_V8", "/data/local/tmp/v8") 92c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org args = [Escape(arg) for arg in sys.argv[1:]] 93c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org script = (" ".join(args) + "\n" 94753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org "case $? in\n" 95304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org " 0) ;;\n" 96304cc33f8259ef467e8e3c79f448d0bae0e8cd85yangguo@chromium.org " *) echo \"ANDROID: Error returned by test\";;\n" 97753aee4dcf0868130789b5af7c1eeb6ab2ab24f9verwaest@chromium.org "esac\n") 98c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org script = script.replace(workspace, android_workspace) 99c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org script_file = WriteToTemporaryFile(script) 100c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org android_script_file = android_workspace + "/" + script_file 101c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org command = ("adb push '%s' %s;" % (script_file, android_script_file) + 102c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org "adb shell 'sh %s';" % android_script_file + 103c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org "adb shell 'rm %s'" % android_script_file) 104c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org error_code = Execute(command) 105c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org os.unlink(script_file) 106c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org return error_code 107c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org 108c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.orgif __name__ == '__main__': 109c6d9cee74ef337517b541fbd58e5438920699a77mstarzinger@chromium.org sys.exit(Main()) 110