• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash
2#
3# Runs robolectric tests.
4
5set -euo pipefail
6
7# Terminate with a fatal error.
8function fatal() {
9  echo "Fatal: $*"
10  exit 113
11}
12
13# Ensures that the given variable is set.
14function validate_var() {
15  local name="$1"; shift || fatal "Missing argument: name"
16  test $# = 0 || fatal "Too many arguments"
17
18  eval [[ -n \${${name}+dummy} ]] || {
19    echo "Variable not set: $name";
20    return 1;
21  }
22}
23
24# Ensures that all the required variables are set.
25function validate_vars() {
26  test $# = 0 || fatal "Too many arguments"
27
28  validate_var 'PRIVATE_INTERMEDIATES'
29  validate_var 'PRIVATE_JARS'
30  validate_var 'PRIVATE_JAVA_ARGS'
31  validate_var 'PRIVATE_ROBOLECTRIC_PATH'
32  validate_var 'PRIVATE_ROBOLECTRIC_SCRIPT_PATH'
33  validate_var 'PRIVATE_RUN_INDIVIDUALLY'
34  validate_var 'PRIVATE_TARGET_MESSAGE'
35  validate_var 'PRIVATE_TESTS'
36  validate_var 'PRIVATE_TIMEOUT'
37
38  validate_var 'XML_OUTPUT_FILE'
39  validate_var 'TEST_WORKSPACE'
40}
41
42# Remove leading and trailing spaces around the given argument.
43function strip() {
44  local value="$1"; shift || fatal "Missing argument: value"
45  test $# = 0 || fatal "Too many arguments"
46
47  echo "$value" | sed -e 's/^ *//' -e 's/ *$//'
48}
49
50# Normalizes a list of paths and turns it into a colon-separated list.
51function normalize-path-list() {
52  echo "$@" | sed -e 's/^ *//' -e 's/ *$//' -e 's/  */ /g' -e 's/ /:/g'
53}
54
55function junit() {
56  # This adds the lib folder to the cp.
57  local classpath="$(strip "$(normalize-path-list "${PRIVATE_JARS}")")"
58  # Setting the DEBUG_ROBOLECTRIC environment variable will print additional logging from
59  # Robolectric and also make it wait for a debugger to be connected.
60  # For Android Studio / IntelliJ the debugger can be connected via the "remote" configuration:
61  #     https://www.jetbrains.com/help/idea/2016.2/run-debug-configuration-remote.html
62  # From command line the debugger can be connected via
63  #     jdb -attach localhost:5005
64  if [ -n ${DEBUG_ROBOLECTRIC:-""} ]; then
65    # The arguments to the JVM needed to debug the tests.
66    # - server: wait for connection rather than connecting to a debugger
67    # - transport: how to accept debugger connections (sockets)
68    # - address: the port on which to accept debugger connections
69    # - timeout: how long (in ms) to wait for a debugger to connect
70    # - suspend: do not start running any code until the debugger connects
71    local debug_java_args="-Drobolectric.logging.enabled=true \
72        -Xdebug -agentlib:jdwp=server=y,transport=dt_socket,address=localhost:5005,suspend=y"
73    # Remove the timeout so Robolectric doesn't get killed while debugging
74    local debug_timeout="0"
75  fi
76  local command=(
77    "${PRIVATE_ROBOLECTRIC_SCRIPT_PATH}/java-timeout"
78    "${debug_timeout:-${PRIVATE_TIMEOUT}}"
79    ${debug_java_args:-${PRIVATE_JAVA_ARGS}}
80    -Drobolectric.dependency.dir="${PRIVATE_ROBOLECTRIC_PATH}"
81    -Drobolectric.offline=true
82    -Drobolectric.logging=stdout
83    -cp "$classpath"
84    com.android.junitxml.JUnitXmlRunner
85  )
86  echo "${command[@]}" "$@"
87  "${command[@]}" "$@"
88}
89
90function runtests() {
91  local tests="$1"; shift || fatal "Missing argument: tests"
92  test $# = 0 || fatal "Too many arguments"
93
94  if [[ "$(strip "${PRIVATE_RUN_INDIVIDUALLY}")" = 'true' ]]; then
95    local result=0
96    for test in ${tests}; do
97      echo "-------------------------------------------------------------------"
98      echo "Running $test:"
99      junit "${test}"
100    done
101    return "$result"
102  else
103    echo "-------------------------------------------------------------------"
104    echo "Running $tests:"
105    junit $tests  # Contains a space-separated list of tests.
106  fi
107}
108
109# Run the robolectric tests
110function run() {
111  test $# = 0 || fatal "Too many arguments"
112
113  [ "${PRIVATE_TARGET_MESSAGE}" == '' ] || echo "${PRIVATE_TARGET_MESSAGE}"
114  local tests="${PRIVATE_TESTS}"
115  if [ "$tests" = '' ]; then
116    # Somehow there are no tests to run. Assume this is failure.
117    echo "No tests to run."
118    exit 1
119  fi
120  local output="${PRIVATE_INTERMEDIATES}/output.out"
121  local failed="${PRIVATE_INTERMEDIATES}/failed.out"
122  local result=0
123  runtests "${tests}" >"$output" 2>&1 || result="$?"
124  echo "$output"
125  cat "$output"
126  if [ "$result" = 0 ]; then
127    return "$result"
128  fi
129  "${PRIVATE_ROBOLECTRIC_SCRIPT_PATH}/list_failed.sh" <"$output" >"$failed"
130  return "$result"
131}
132
133function main() {
134  test $# = 0 || fatal "Too many arguments"
135
136  validate_vars
137  run
138}
139
140main "$@"
141