aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/java_tools/junitrunner/javatests/com/google/testing/junit/runner/stack_trace_integration_tests.sh
blob: 0ff0933dbf227bbc6c9396f36f1fb46d3a13cacc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/bin/bash
#
# Copyright 2010 The Bazel Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Integration testing of stack traces printed to the console during JUnit
# tests. Test runners send a SIGTERM to the test process upon timeout (and
# typically SIGKILL after a grace period).
#
# These tests operate by executing test methods in a testbed program
# and checking the output.
#

DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
unset TEST_PREMATURE_EXIT_FILE

TESTBED="${PWD}/$1"
SUITE_PARAMETER="$2"
JUNIT_VERSION="$3"
SUITE="com.google.testing.junit.runner.testbed.StackTraceExercises"
SUITE_FLAG="-D${SUITE_PARAMETER}=${SUITE}"
SLOW_CREATION_SUITE_FLAG="-D${SUITE_PARAMETER}=com.google.testing.junit.runner.testbed.SuiteMethodTakesForever"

shift 3
source ${DIR}/testenv.sh || { echo "testenv.sh not found!" >&2; exit 1; }

# Usage: COUNT=count_in_log <regex>
function count_in_log() {
  echo $(grep -c "$1" $TEST_log)
}

function check_ge() {
  (( $1 >= $2 )) || fail "$3"
}

function check_le() {
  (( $1 <= $2 )) || fail "$3"
}

function check_eq() {
  (( $1 == $2 )) || fail "$3"
}

# Usage: expect_thread_dumps_in_log <max_number_of_expected_thread_dumps>
function expect_thread_dumps_in_log() {
  local thread_dump_starts=$(count_in_log "Starting full thread dump")
  local thread_dump_ends=$(count_in_log "Done full thread dump")
  check_ge "$thread_dump_starts" 1 "Thread dump generated at least once"
  check_le "$thread_dump_starts" "$1" "Thread dump generated at most $1 times"
  check_eq "$thread_dump_starts" "$thread_dump_ends" \
    "Thread dumps ended successfully"
}

#######################

# Test that we see a stack trace even on shutdown hook slowness.
function test_ShutdownHook() {
  cd $TEST_TMPDIR
  local fifo="${PWD}/tmp/fifo_for_shutdown_hook"
  mkdir -p tmp
  mkfifo $fifo || fail "Couldn't create ${fifo}"

  # Run the test in the background. The test process will report success,
  # but hang in the shutdown hook.
  if [ "$JUNIT_VERSION" = "3" ]; then
    TEST_FILTER_FLAG="${SUITE}#testSneakyShutdownHook"
  else
    TEST_FILTER_FLAG="--test_filter=testSneakyShutdownHook"
  fi

  $TESTBED --jvm_flag=${SUITE_FLAG} --jvm_flag=-Dtest.fifo=${fifo} $TEST_FILTER_FLAG \
    >& $TEST_log & test_pid=$!

  echo "Synchronize to the shutdown hook" > $fifo
  expect_log 'OK.*1 test'
  expect_log "Entered shutdown"

  # Send the SIGTERM and wait 3s (generous) for it to be processed:
  kill -TERM $test_pid
  sleep 3

  expect_log 'INTERRUPTED TEST: SIGTERM'
  expect_log 'Shutdown\.runHooks'
  expect_log 'StackTraceExercises\.handleHook'
  expect_log 'Thread\.sleep'

  # expect threads to be dumped at most 2 times
  expect_thread_dumps_in_log 2

  wait $test_pid || fail "Expected process to finish successfully"
}

# Test that we see a stack trace when the test is interrupted during the test
# suite creation phase.
function test_SlowSuite() {
  cd $TEST_TMPDIR
  local fifo="${PWD}/tmp/fifo_for_slow_suite"
  mkdir -p tmp
  mkfifo $fifo || fail "Couldn't create ${fifo}"

  # Run the test in the background. The test process will hang in the suite
  # creation phase.
  $TESTBED --jvm_flag=${SLOW_CREATION_SUITE_FLAG} --jvm_flag=-Dtest.fifo=${fifo} \
    >& $TEST_log & test_pid=$!
  echo "Synchronize to the suite creation" > $fifo
  expect_log 'Entered suite creation'

  # Send the SIGTERM and wait 3s (generous) for it to be processed:
  kill -TERM $test_pid
  sleep 3

  expect_log "Execution interrupted while running 'TestSuite creation'"

  # expect threads to be dumped exactly once
  expect_thread_dumps_in_log 1
}

# If a test calls System.exit(), make sure it leaves the
# TEST_PREMATURE_EXIT_FILE around.
function test_PrematureExit() {
  cd $TEST_TMPDIR
  mkdir foo
  local no_exit="${PWD}/foo/premature_exit_file"

  [ ! -a "$no_exit" ] || fail "${no_exit} should not exist yet"

  if [ "$JUNIT_VERSION" = "3" ]; then
    TEST_FILTER_FLAG="${SUITE}#testNotSoFastBuddy"
  else
    TEST_FILTER_FLAG="--test_filter=testNotSoFastBuddy"
  fi

  echo "Redirecting output to $TEST_log"
  TEST_PREMATURE_EXIT_FILE=${no_exit} $TESTBED --jvm_flag=${SUITE_FLAG} $TEST_FILTER_FLAG \
    >& $TEST_log || fail "Expected spurious success"

  expect_log 'Hey, not so fast there'
  [ -r "$no_exit" ] || fail "$no_exit is not readable"
}

run_suite "stacktrace"