Add Makefile targets for running tests on Android.
This allows to run tests on the attached Android device using > make android.check > make android.debug.check > make android.release.check > ANDROID_V8=/data/local/v8 TESTJOBS=-j4 make android.release.check -j10 Tests and binaries are copied to device location specified by the ANDROID_V8 variable and then tests are executed using the 'adb shell' program. R=jkummerow@chromium.org Review URL: https://chromiumcodereview.appspot.com/10696048 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11975 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
70d56acd1f
commit
c22c7054f2
25
Makefile
25
Makefile
@ -35,6 +35,7 @@ GYPFLAGS ?=
|
||||
TESTFLAGS ?=
|
||||
ANDROID_NDK_ROOT ?=
|
||||
ANDROID_TOOL_PREFIX = $(ANDROID_NDK_ROOT)/toolchain/bin/arm-linux-androideabi
|
||||
ANDROID_V8 ?= /data/local/v8
|
||||
|
||||
# Special build flags. Use them like this: "make library=shared"
|
||||
|
||||
@ -107,7 +108,7 @@ endif
|
||||
# - every combination <arch>.<mode>, e.g. "ia32.release"
|
||||
# - "native": current host's architecture, release mode
|
||||
# - any of the above with .check appended, e.g. "ia32.release.check"
|
||||
# - "android": cross-compile for Android/ARM (release mode)
|
||||
# - "android": cross-compile for Android/ARM
|
||||
# - default (no target specified): build all DEFAULT_ARCHES and MODES
|
||||
# - "check": build all targets and run all tests
|
||||
# - "<arch>.clean" for any <arch> in ARCHES
|
||||
@ -120,6 +121,7 @@ endif
|
||||
ARCHES = ia32 x64 arm mips
|
||||
DEFAULT_ARCHES = ia32 x64 arm
|
||||
MODES = release debug
|
||||
ANDROID_MODES = android.release android.debug
|
||||
|
||||
# List of files that trigger Makefile regeneration:
|
||||
GYPFILES = build/all.gyp build/common.gypi build/standalone.gypi \
|
||||
@ -166,8 +168,9 @@ native: $(OUTDIR)/Makefile.native
|
||||
CXX="$(CXX)" LINK="$(LINK)" BUILDTYPE=Release \
|
||||
builddir="$(shell pwd)/$(OUTDIR)/$@"
|
||||
|
||||
# TODO(jkummerow): add "android.debug" when we need it.
|
||||
android android.release: $(OUTDIR)/Makefile.android
|
||||
android: $(ANDROID_MODES)
|
||||
|
||||
$(ANDROID_MODES): $(OUTDIR)/Makefile.android
|
||||
@$(MAKE) -C "$(OUTDIR)" -f Makefile.android \
|
||||
CXX="$(ANDROID_TOOL_PREFIX)-g++" \
|
||||
AR="$(ANDROID_TOOL_PREFIX)-ar" \
|
||||
@ -175,8 +178,9 @@ android android.release: $(OUTDIR)/Makefile.android
|
||||
CC="$(ANDROID_TOOL_PREFIX)-gcc" \
|
||||
LD="$(ANDROID_TOOL_PREFIX)-ld" \
|
||||
LINK="$(ANDROID_TOOL_PREFIX)-g++" \
|
||||
BUILDTYPE=Release \
|
||||
builddir="$(shell pwd)/$(OUTDIR)/android.release"
|
||||
BUILDTYPE=$(shell echo $(subst .,,$(suffix $@)) | \
|
||||
python -c "print raw_input().capitalize()") \
|
||||
builddir="$(shell pwd)/$(OUTDIR)/$@"
|
||||
|
||||
# Test targets.
|
||||
check: all
|
||||
@ -196,6 +200,17 @@ $(CHECKS): $$(basename $$@)
|
||||
@tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
|
||||
--arch-and-mode=$(basename $@) $(TESTFLAGS)
|
||||
|
||||
$(addsuffix .sync, $(ANDROID_MODES)): $$(basename $$@)
|
||||
@tools/android-sync.sh $(basename $@) $(OUTDIR) \
|
||||
$(shell pwd) $(ANDROID_V8)
|
||||
|
||||
$(addsuffix .check, $(ANDROID_MODES)): $$(basename $$@).sync
|
||||
@tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR) \
|
||||
--arch-and-mode=$(basename $@) \
|
||||
--special-command="tools/android-run.py @"
|
||||
|
||||
android.check: android.release.check android.debug.check
|
||||
|
||||
native.check: native
|
||||
@tools/test-wrapper-gypbuild.py $(TESTJOBS) --outdir=$(OUTDIR)/native \
|
||||
--arch-and-mode=. $(TESTFLAGS)
|
||||
|
@ -54,7 +54,7 @@ test-profile-generator/RecordStackTraceAtStartProfiling: PASS || FAIL
|
||||
test-weakmaps/Shrinking: FAIL
|
||||
|
||||
##############################################################################
|
||||
[ $arch == arm ]
|
||||
[ $arch == arm || $arch == android ]
|
||||
|
||||
# We cannot assume that we can throw OutOfMemory exceptions in all situations.
|
||||
# Apparently our ARM box is in such a state. Skip the test as it also runs for
|
||||
|
@ -93,7 +93,8 @@ class CcTestConfiguration(test.TestConfiguration):
|
||||
if utils.IsWindows():
|
||||
executable += '.exe'
|
||||
executable = join(self.context.buildspace, executable)
|
||||
output = test.Execute([executable, '--list'], self.context)
|
||||
full_command = self.context.processor([executable, '--list'])
|
||||
output = test.Execute(full_command, self.context)
|
||||
if output.exit_code != 0:
|
||||
print output.stdout
|
||||
print output.stderr
|
||||
|
@ -49,28 +49,27 @@ regress/regress-create-exception: PASS, SKIP if $mode == debug
|
||||
##############################################################################
|
||||
# This one uses a built-in that's only present in debug mode. It takes
|
||||
# too long to run in debug mode on ARM and MIPS.
|
||||
fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm || $arch == mips)
|
||||
fuzz-natives: PASS, SKIP if ($mode == release || $arch == arm || $arch == android || $arch == mips)
|
||||
|
||||
big-object-literal: PASS, SKIP if ($arch == arm)
|
||||
big-object-literal: PASS, SKIP if ($arch == arm || $arch == android)
|
||||
|
||||
# Issue 488: this test sometimes times out.
|
||||
array-constructor: PASS || TIMEOUT
|
||||
|
||||
# Very slow on ARM and MIPS, contains no architecture dependent code.
|
||||
unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == mips)
|
||||
unicode-case-overoptimization: PASS, TIMEOUT if ($arch == arm || $arch == android || $arch == mips)
|
||||
|
||||
# Test Crankshaft compilation time. Expected to take too long in debug mode.
|
||||
regress/regress-1969: PASS, SKIP if $mode == debug
|
||||
|
||||
##############################################################################
|
||||
[ $isolates ]
|
||||
|
||||
# This test sets the umask on a per-process basis and hence cannot be
|
||||
# used in multi-threaded runs.
|
||||
d8-os: SKIP
|
||||
# On android there is no /tmp directory.
|
||||
d8-os: PASS, SKIP if ($isolates || $arch == android)
|
||||
|
||||
##############################################################################
|
||||
[ $arch == arm ]
|
||||
[ $arch == arm || $arch == android ]
|
||||
|
||||
# Slow tests which times out in debug mode.
|
||||
try: PASS, SKIP if $mode == debug
|
||||
|
108
tools/android-run.py
Executable file
108
tools/android-run.py
Executable file
@ -0,0 +1,108 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2012 the V8 project authors. All rights reserved.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# This script executes the passed command line on Android device
|
||||
# using 'adb shell' command. Unfortunately, 'adb shell' always
|
||||
# returns exit code 0, ignoring the exit code of executed command.
|
||||
# Since we need to return non-zero exit code if the command failed,
|
||||
# we augment the passed command line with exit code checking statement
|
||||
# and output special error string in case of non-zero exit code.
|
||||
# Then we parse the output of 'adb shell' and look for that error string.
|
||||
|
||||
import os
|
||||
from os.path import join, dirname, abspath
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
|
||||
def Check(output, errors):
|
||||
failed = any([s.startswith('/system/bin/sh:') or s.startswith('Error')
|
||||
for s in output.split('\n')])
|
||||
return 1 if failed else 0
|
||||
|
||||
def Execute(cmdline):
|
||||
(fd_out, outname) = tempfile.mkstemp()
|
||||
(fd_err, errname) = tempfile.mkstemp()
|
||||
process = subprocess.Popen(
|
||||
args=cmdline,
|
||||
shell=True,
|
||||
stdout=fd_out,
|
||||
stderr=fd_err,
|
||||
)
|
||||
exit_code = process.wait()
|
||||
os.close(fd_out)
|
||||
os.close(fd_err)
|
||||
output = file(outname).read()
|
||||
errors = file(errname).read()
|
||||
os.unlink(outname)
|
||||
os.unlink(errname)
|
||||
sys.stdout.write(output)
|
||||
sys.stderr.write(errors)
|
||||
return exit_code or Check(output, errors)
|
||||
|
||||
def Escape(arg):
|
||||
def ShouldEscape():
|
||||
for x in arg:
|
||||
if not x.isalnum() and x != '-' and x != '_':
|
||||
return True
|
||||
return False
|
||||
|
||||
return arg if not ShouldEscape() else '"%s"' % (arg.replace('"', '\\"'))
|
||||
|
||||
def WriteToTemporaryFile(data):
|
||||
(fd, fname) = tempfile.mkstemp()
|
||||
os.close(fd)
|
||||
tmp_file = open(fname, "w")
|
||||
tmp_file.write(data)
|
||||
tmp_file.close()
|
||||
return fname
|
||||
|
||||
def Main():
|
||||
if (len(sys.argv) == 1):
|
||||
print("Usage: %s <command-to-run-on-device>" % sys.argv[0])
|
||||
return 1
|
||||
workspace = abspath(join(dirname(sys.argv[0]), '..'))
|
||||
android_workspace = os.getenv("ANDROID_V8", "/data/local/v8")
|
||||
args = [Escape(arg) for arg in sys.argv[1:]]
|
||||
script = (" ".join(args) + "\n"
|
||||
"if [ $? -ne 0 ]\n"
|
||||
" then echo \"Error returned by test\";\n"
|
||||
"fi\n")
|
||||
script = script.replace(workspace, android_workspace)
|
||||
script_file = WriteToTemporaryFile(script)
|
||||
android_script_file = android_workspace + "/" + script_file
|
||||
command = ("adb push '%s' %s;" % (script_file, android_script_file) +
|
||||
"adb shell 'sh %s';" % android_script_file +
|
||||
"adb shell 'rm %s'" % android_script_file)
|
||||
error_code = Execute(command)
|
||||
os.unlink(script_file)
|
||||
return error_code
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(Main())
|
79
tools/android-sync.sh
Executable file
79
tools/android-sync.sh
Executable file
@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
# Copyright 2012 the V8 project authors. All rights reserved.
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met:
|
||||
#
|
||||
# * Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# * Redistributions in binary form must reproduce the above
|
||||
# copyright notice, this list of conditions and the following
|
||||
# disclaimer in the documentation and/or other materials provided
|
||||
# with the distribution.
|
||||
# * Neither the name of Google Inc. nor the names of its
|
||||
# contributors may be used to endorse or promote products derived
|
||||
# from this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
# This script pushes android binaries and test data to the device.
|
||||
# The first argument can be either "android.release" or "android.debug".
|
||||
# The second argument is a relative path to the output directory with binaries.
|
||||
# The third argument is the absolute path to the V8 directory on the host.
|
||||
# The fourth argument is the absolute path to the V8 directory on the device.
|
||||
|
||||
if [ ${#@} -lt 4 ] ; then
|
||||
echo "Error: need 4 arguments"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ARCH_MODE=$1
|
||||
OUTDIR=$2
|
||||
HOST_V8=$3
|
||||
ANDROID_V8=$4
|
||||
|
||||
function sync_file {
|
||||
local FILE=$1
|
||||
local ANDROID_HASH=$(adb shell "md5 \"$ANDROID_V8/$FILE\"")
|
||||
local HOST_HASH=$(md5sum "$HOST_V8/$FILE")
|
||||
if [ "${ANDROID_HASH%% *}" != "${HOST_HASH%% *}" ]; then
|
||||
adb push "$HOST_V8/$FILE" "$ANDROID_V8/$FILE" &> /dev/null
|
||||
fi
|
||||
echo -n "."
|
||||
}
|
||||
|
||||
function sync_dir {
|
||||
local DIR=$1
|
||||
echo -n "sync to $ANDROID_V8/$DIR"
|
||||
for FILE in $(find "$HOST_V8/$DIR" -type f); do
|
||||
local RELATIVE_FILE=${FILE:${#HOST_V8}}
|
||||
sync_file "$RELATIVE_FILE"
|
||||
done
|
||||
echo ""
|
||||
}
|
||||
|
||||
echo -n "sync to $ANDROID_V8/$OUTDIR/$ARCH_MODE"
|
||||
sync_file "$OUTDIR/$ARCH_MODE/cctest"
|
||||
sync_file "$OUTDIR/$ARCH_MODE/d8"
|
||||
sync_file "$OUTDIR/$ARCH_MODE/preparser"
|
||||
echo ""
|
||||
echo -n "sync to $ANDROID_V8/tools"
|
||||
sync_file tools/consarray.js
|
||||
sync_file tools/codemap.js
|
||||
sync_file tools/csvparser.js
|
||||
sync_file tools/profile.js
|
||||
sync_file tools/splaytree.js
|
||||
echo ""
|
||||
sync_dir test/message
|
||||
sync_dir test/mjsunit
|
||||
sync_dir test/preparser
|
@ -148,7 +148,7 @@ def ProcessOptions(options):
|
||||
print "Unknown mode %s" % mode
|
||||
return False
|
||||
for arch in options.arch:
|
||||
if not arch in ['ia32', 'x64', 'arm', 'mips']:
|
||||
if not arch in ['ia32', 'x64', 'arm', 'mips', 'android']:
|
||||
print "Unknown architecture %s" % arch
|
||||
return False
|
||||
if options.buildbot:
|
||||
|
@ -140,9 +140,9 @@ def EscapeCommand(command):
|
||||
parts = []
|
||||
for part in command:
|
||||
if ' ' in part:
|
||||
# Escape spaces. We may need to escape more characters for this
|
||||
# to work properly.
|
||||
parts.append('"%s"' % part)
|
||||
# Escape spaces and double quotes. We may need to escape more characters
|
||||
# for this to work properly.
|
||||
parts.append('"%s"' % part.replace('"', '\\"'))
|
||||
else:
|
||||
parts.append(part)
|
||||
return " ".join(parts)
|
||||
@ -1283,7 +1283,7 @@ def ProcessOptions(options):
|
||||
options.scons_flags.append("arch=" + options.arch)
|
||||
# Simulators are slow, therefore allow a longer default timeout.
|
||||
if options.timeout == -1:
|
||||
if options.arch == 'arm' or options.arch == 'mips':
|
||||
if options.arch in ['android', 'arm', 'mips']:
|
||||
options.timeout = 2 * TIMEOUT_DEFAULT;
|
||||
else:
|
||||
options.timeout = TIMEOUT_DEFAULT;
|
||||
|
Loading…
Reference in New Issue
Block a user