aboutsummaryrefslogtreecommitdiff
path: root/java-timeout
diff options
context:
space:
mode:
authorJames Lemieux <jplemieux@google.com>2018-01-28 02:56:27 -0800
committerJames Lemieux <jplemieux@google.com>2018-02-05 15:02:10 -0800
commit2a2559e5581c585721d342ffe6dceff6c5d7019e (patch)
treeb6f6360349e2d979893031712f909a22d07d42f1 /java-timeout
parentb0d9a6c2cb434aba94ba4be1c694e53588ddc399 (diff)
downloadrobolectric-shadows-2a2559e5581c585721d342ffe6dceff6c5d7019e.tar.gz
Create a run script for external/robolectric-shadows
This run script was copied from prebuilts/misc/common/robolectric/3.6.1 with small modifications. The 3.6.1 script only executes against public SDK versions which existed at the time of the robolectric 3.6.1 release. This script allows testing against the SDK currently under development. Bug: 72384841 Test: make Run_TeleService_robotests Change-Id: I038afbdfede230bc0050760f0419f5842139dde6
Diffstat (limited to 'java-timeout')
-rwxr-xr-xjava-timeout92
1 files changed, 92 insertions, 0 deletions
diff --git a/java-timeout b/java-timeout
new file mode 100755
index 000000000..69586d7b0
--- /dev/null
+++ b/java-timeout
@@ -0,0 +1,92 @@
+#!/bin/bash
+#
+# Script for running java with a timeout.
+#
+# The timeout in seconds must be the first argument. The rest of the arguments
+# are passed to the java binary itself.
+#
+# For example:
+# java-timeout 120 -cp classes.jar org.junit.runner.JUnitCore
+# runs:
+# java -cp classes.jar org.junit.runner.JUnitCore
+# with a timeout of 2 minutes.
+
+set -euo pipefail
+
+# Prints a message and terminates the process.
+function fatal() {
+ echo "FATAL: $*"
+ exit 113
+}
+
+# Function that is invoked if java is terminated due to timeout.
+# It take the process ID of the java command as an argument if it has already
+# been started, or the empty string if not. It should very rarely receive the
+# empty string as the pid, but it is possible.
+function on_timeout() {
+ echo 'FATAL: command timed out'
+
+ local pid="${1-}"
+ shift || fatal '[on_timeout] missing argument: pid'
+ test $# = 0 || fatal '[on_timeout] too many arguments'
+
+ if [ "$pid" != '' ]; then
+ # It is possible that the process already terminated, but there is not much
+ # we can do about that.
+ kill -TERM -- "-$pid" # Kill the entire process group.
+ fi
+}
+
+# Executes java with the given argument, waiting for a termination signal from
+# runalarm which this script is running under. The arguments are passed to the
+# java binary itself.
+function execute() {
+ # Trap SIGTERM, which is what we will receive if runalarm interrupts us.
+ local pid # Set below after we run the process.
+ trap 'on_timeout $pid' SIGTERM
+ # Starts java within a new process group and saves it process ID before
+ # blocking waiting for it to complete. 'setsid' starts the process within a
+ # new process group, which means that it will not be killed when this shell
+ # command is killed. This is needed so that the signal handler in the trap
+ # command above to be invoked before the java command is terminated (and will
+ # in fact have to terminate it itself).
+ setsid java "$@" & pid="$!"; wait "$pid"
+}
+
+# Runs java with a timeout. The first argument is either the timeout in seconds
+# or the string 'execute', which is used internally to execute the command under
+# runalarm.
+function main() {
+ local timeout_secs="${1-}"
+ shift || fatal '[main]: missing argument: timeout_secs'
+ # The reset of the arguments are meant for the java binary itself.
+
+ if [[ $timeout_secs = '0' ]]; then
+ # Run without any timeout.
+ java "$@"
+ elif [[ $timeout_secs = 'execute' ]]; then
+ # This means we actually have to execute the command.
+ execute "$@"
+ elif (( timeout_secs < 30 )); then
+ # We want to have a timeout of at least 30 seconds, so that we are
+ # guaranteed to be able to start the java command in the subshell. This also
+ # catches non-numeric arguments.
+ fatal 'Must specify a timeout of at least 30 seconds.'
+ else
+ # Wrap the command with runalarm if available. If runalarm is not
+ # installed try timeout which is available on Mac if GNU coreutils
+ # is installed.
+ if type runalarm > /dev/null 2>&1 ; then
+ runalarm -t "$timeout_secs" "$0" 'execute' "$@"
+ elif type gtimeout > /dev/null 2>&1 ; then
+ gtimeout "${timeout_secs}s" "$0" 'execute' "$@"
+ else
+ # No way to set a timeout available, just execute directly.
+ echo "Warning: unable to enforce timeout." 1>&2
+ java "$@"
+ fi
+ fi
+}
+
+
+main "$@"