1d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com#!/usr/bin/env python 2d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# 369031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org# Copyright 2012 the V8 project authors. All rights reserved. 4192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# Redistribution and use in source and binary forms, with or without 5770963f23f4fc313db0fa3bac18b1b8aafb55f17robertphillips@google.com# modification, are permitted provided that the following conditions are 6192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# met: 7d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# 8d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# * Redistributions of source code must retain the above copyright 9192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# notice, this list of conditions and the following disclaimer. 10d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# * Redistributions in binary form must reproduce the above 11d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# copyright notice, this list of conditions and the following 12d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# disclaimer in the documentation and/or other materials provided 13d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# with the distribution. 14d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com# * Neither the name of Google Inc. nor the names of its 15e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# contributors may be used to endorse or promote products derived 16e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# from this software without specific prior written permission. 17e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# 18e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22e4d3e605f74a23d050abad29909af421d8b1cf1amtklein# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 235fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24d6bab0238655dbab24dfe92bd0b16b464310a8c7rmistry@google.com# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 255fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 265fb2ce38b3dcb8e60e9e112df23c9d42456d7069commit-bot@chromium.org# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org 3084b18c7e3e042bf206e1ace3d1b6ea5bb929fe51robertphillips@google.com# This script executes the passed command line on Android device 31192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# using 'adb shell' command. Unfortunately, 'adb shell' always 32192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# returns exit code 0, ignoring the exit code of executed command. 33266420722e18dcc8b6d4a7379a42b8591ccd2b6dcommit-bot@chromium.org# Since we need to return non-zero exit code if the command failed, 3438aeb0fd7a2bdab5e44531d96045dffe25c8e2b0commit-bot@chromium.org# we augment the passed command line with exit code checking statement 35192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# and output special error string in case of non-zero exit code. 36192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org# Then we parse the output of 'adb shell' and look for that error string. 37192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org 38266420722e18dcc8b6d4a7379a42b8591ccd2b6dcommit-bot@chromium.orgimport os 39266420722e18dcc8b6d4a7379a42b8591ccd2b6dcommit-bot@chromium.orgfrom os.path import join, dirname, abspath 4090b5a2a653b312ff9bcd7102412da2dbeb52368ccommit-bot@chromium.orgimport subprocess 4190b5a2a653b312ff9bcd7102412da2dbeb52368ccommit-bot@chromium.orgimport sys 42192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.orgimport tempfile 43192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org 44192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.orgdef Check(output, errors): 45192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org failed = any([s.startswith('/system/bin/sh:') or s.startswith('ANDROID') 469b14f26d0f3a974f3dd626c8354e1db1cfcd322frobertphillips for s in output.split('\n')]) 47192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org return 1 if failed else 0 48192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org 49192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.orgdef Execute(cmdline): 5069031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org (fd_out, outname) = tempfile.mkstemp() 5169031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org (fd_err, errname) = tempfile.mkstemp() 5269031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org process = subprocess.Popen( 5369031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org args=cmdline, 5469031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org shell=True, 5569031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org stdout=fd_out, 5669031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org stderr=fd_err, 5769031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org ) 5869031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org exit_code = process.wait() 5969031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org os.close(fd_out) 6069031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org os.close(fd_err) 6169031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org output = file(outname).read() 6269031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org errors = file(errname).read() 6369031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org os.unlink(outname) 6469031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org os.unlink(errname) 6569031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org sys.stdout.write(output) 6669031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org sys.stderr.write(errors) 6769031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org return exit_code or Check(output, errors) 68192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org 6969031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.orgdef Escape(arg): 7069031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org def ShouldEscape(): 7169031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org for x in arg: 7269031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org if not x.isalnum() and x != '-' and x != '_': 7369031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org return True 7469031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org return False 7569031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org 7669031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"')) 7769031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org 7869031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.orgdef WriteToTemporaryFile(data): 7969031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org (fd, fname) = tempfile.mkstemp() 8069031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org os.close(fd) 8169031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org tmp_file = open(fname, "w") 8269031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org tmp_file.write(data) 8369031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org tmp_file.close() 8469031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org return fname 8569031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org 8669031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.orgdef Main(): 8769031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org if (len(sys.argv) == 1): 8869031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org print("Usage: %s <command-to-run-on-device>" % sys.argv[0]) 8969031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org return 1 9069031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org workspace = abspath(join(dirname(sys.argv[0]), '..')) 9169031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org android_workspace = os.getenv("ANDROID_V8", "/data/local/tmp/v8") 9269031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org args = [Escape(arg) for arg in sys.argv[1:]] 9369031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org script = (" ".join(args) + "\n" 9469031a44273ccb7656df88c6bcb7b62f4d2731bbcommit-bot@chromium.org "case $? in\n" 959c4ff80d9b76e1bda532fb9182f66f67cfc95324mtklein " 0) ;;\n" 969c4ff80d9b76e1bda532fb9182f66f67cfc95324mtklein " *) echo \"ANDROID: Error returned by test\";;\n" 979c4ff80d9b76e1bda532fb9182f66f67cfc95324mtklein "esac\n") 989c4ff80d9b76e1bda532fb9182f66f67cfc95324mtklein script = script.replace(workspace, android_workspace) 999c4ff80d9b76e1bda532fb9182f66f67cfc95324mtklein script_file = WriteToTemporaryFile(script) 100192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org android_script_file = android_workspace + "/" + script_file 101192cbf67b281b20477320134962d554ed823c691commit-bot@chromium.org command = ("adb push '%s' %s;" % (script_file, android_script_file) + 102d36522d12d3e71958e50683a7eef43dc2a47d96dmtklein@google.com "adb shell 'sh %s';" % android_script_file + 103 "adb shell 'rm %s'" % android_script_file) 104 error_code = Execute(command) 105 os.unlink(script_file) 106 return error_code 107 108if __name__ == '__main__': 109 sys.exit(Main()) 110