android-run.py 4.2 KB

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