Home | History | Annotate | Download | only in robolectric-shadows
      1 #!/bin/bash
      2 #
      3 # Runs robolectric tests.
      4 
      5 set -euo pipefail
      6 
      7 # Terminate with a fatal error.
      8 function fatal() {
      9   echo "Fatal: $*"
     10   exit 113
     11 }
     12 
     13 # Ensures that the given variable is set.
     14 function 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.
     25 function 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.
     43 function 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.
     51 function normalize-path-list() {
     52   echo "$@" | sed -e 's/^ *//' -e 's/ *$//' -e 's/  */ /g' -e 's/ /:/g'
     53 }
     54 
     55 function 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 
     90 function 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
    110 function 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 
    133 function main() {
    134   test $# = 0 || fatal "Too many arguments"
    135 
    136   validate_vars
    137   run
    138 }
    139 
    140 main "$@"
    141