aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build
diff options
context:
space:
mode:
authorGravatar Irina Chernushina <ichern@google.com>2018-06-26 07:10:47 -0700
committerGravatar Copybara-Service <copybara-piper@google.com>2018-06-26 07:12:24 -0700
commitd82b8ab5a2da6949a8d87e28367dc789a6785291 (patch)
tree287a50bed963e93d3600774c9b7a9749a4cd9c04 /src/test/java/com/google/devtools/build
parentaf0825dd2d588e4074f84392af16f4799895f6c4 (diff)
add helper JUnit TestWrapper class to do some action on test timeout
add helper JUnit TestWrapper class to do some action on test timeout i.e. we want to dump the current state of the test on timeout before exit for the new junit integration test framework Closes #5436. PiperOrigin-RevId: 202123320
Diffstat (limited to 'src/test/java/com/google/devtools/build')
-rw-r--r--src/test/java/com/google/devtools/build/lib/BUILD2
-rw-r--r--src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/BUILD29
-rw-r--r--src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcher.java94
-rw-r--r--src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherBaseTest.java42
-rw-r--r--src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherTest.java51
5 files changed, 218 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/BUILD b/src/test/java/com/google/devtools/build/lib/BUILD
index a5944fac08..33748a634f 100644
--- a/src/test/java/com/google/devtools/build/lib/BUILD
+++ b/src/test/java/com/google/devtools/build/lib/BUILD
@@ -62,6 +62,7 @@ filegroup(
"//src/test/java/com/google/devtools/build/lib/skylarkdebug/server:srcs",
"//src/test/java/com/google/devtools/build/lib/skylarkinterface/processor:srcs",
"//src/test/java/com/google/devtools/build/lib/unsafe:srcs",
+ "//src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit:srcs",
],
visibility = ["//src:__pkg__"],
)
@@ -1559,6 +1560,7 @@ java_test(
"//third_party:guava",
"//third_party:jsr305",
"//third_party:junit4",
+ "//third_party:truth",
],
)
diff --git a/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/BUILD b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/BUILD
new file mode 100644
index 0000000000..1f81853fec
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/BUILD
@@ -0,0 +1,29 @@
+java_test(
+ name = "TimeoutTestWatcherTest",
+ srcs = [
+ "TimeoutTestWatcher.java",
+ "TimeoutTestWatcherBaseTest.java",
+ "TimeoutTestWatcherTest.java",
+ ],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//third_party:guava",
+ "//third_party:junit4",
+ "//third_party:truth",
+ ],
+)
+
+filegroup(
+ name = "srcs",
+ srcs = glob(["**/*"]),
+ visibility = ["//src/test/java/com/google/devtools/build/lib:__pkg__"],
+)
+
+java_library(
+ name = "timeout_watcher",
+ srcs = ["TimeoutTestWatcher.java"],
+ visibility = ["//visibility:public"],
+ deps = [
+ "//third_party:junit4",
+ ],
+)
diff --git a/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcher.java b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcher.java
new file mode 100644
index 0000000000..c0e87f7093
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcher.java
@@ -0,0 +1,94 @@
+// Copyright 2018 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.
+
+package com.google.devtools.build.lib.integration.blackbox.framework.junit;
+
+import java.util.concurrent.TimeoutException;
+import org.junit.rules.TestWatcher;
+import org.junit.rules.Timeout;
+import org.junit.runner.Description;
+import org.junit.runners.model.Statement;
+
+/**
+ * Test watcher, which sets a timeout for the JUnit test and allows to execute some action on
+ * timeout. Uses JUnit's org.junit.rules.Timeout rule to set up a timeout; catches timeout exception
+ * thrown fromTimeout rule, calls the {@link onTimeout} method, and re-throws the exception.
+ *
+ * <p>Useful to dump test state information before failing on timeout.
+ */
+public abstract class TimeoutTestWatcher extends TestWatcher {
+ private String name;
+
+ protected abstract long getTimeoutMillis();
+
+ protected abstract boolean onTimeout();
+
+ @Override
+ protected void starting(Description description) {
+ name = description.getMethodName();
+ }
+
+ @Override
+ protected void finished(Description description) {
+ name = null;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public Statement apply(Statement base, Description description) {
+ // we are using exception wrapping, because unfortunately JUnit's Timeout throws
+ // java.util.Exception on timeout, which is hard to distinguish from other cases
+ Statement wrapper =
+ new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ base.evaluate();
+ } catch (Throwable th) {
+ throw new ExceptionWrapper(th);
+ }
+ }
+ };
+
+ return new Statement() {
+ @Override
+ public void evaluate() throws Throwable {
+ try {
+ new Timeout((int) getTimeoutMillis()).apply(wrapper, description).evaluate();
+ } catch (ExceptionWrapper wrapper) {
+ // original test exception
+ throw wrapper.getCause();
+ } catch (Exception e) {
+ // timeout exception
+ if (!onTimeout()) {
+ throw new TimeoutException(e.getMessage());
+ }
+ }
+ }
+ };
+ }
+
+ /**
+ * Exception wrapper wrap-and-caught any exception from the test; this guarantees that we
+ * differentiate timeout exception thrown just as java.util.Exception from the test exceptions
+ */
+ private static class ExceptionWrapper extends Throwable {
+ ExceptionWrapper(Throwable cause) {
+ super(cause);
+ }
+ }
+}
diff --git a/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherBaseTest.java b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherBaseTest.java
new file mode 100644
index 0000000000..9c61301904
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherBaseTest.java
@@ -0,0 +1,42 @@
+// Copyright 2018 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.
+
+package com.google.devtools.build.lib.integration.blackbox.framework.junit;
+
+import org.junit.Rule;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Base test class for testing {@link TimeoutTestWatcher}; it is a base class since we want to
+ * imitate the usage of test watcher from the base class.
+ */
+@RunWith(JUnit4.class)
+public abstract class TimeoutTestWatcherBaseTest {
+ boolean timeoutCaught = false;
+
+ @Rule
+ public TimeoutTestWatcher testWatcher =
+ new TimeoutTestWatcher() {
+ @Override
+ protected long getTimeoutMillis() {
+ return 100;
+ }
+
+ @Override
+ protected boolean onTimeout() {
+ return timeoutCaught = true;
+ }
+ };
+}
diff --git a/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherTest.java b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherTest.java
new file mode 100644
index 0000000000..c5f41bfc99
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/integration/blackbox/framework/junit/TimeoutTestWatcherTest.java
@@ -0,0 +1,51 @@
+// Copyright 2018 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.
+
+package com.google.devtools.build.lib.integration.blackbox.framework.junit;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for {@link TimeoutTestWatcher}. Tests both that the timeout was intercepted, and the
+ * assertion from the test was not blocked.
+ */
+@RunWith(JUnit4.class)
+public class TimeoutTestWatcherTest extends TimeoutTestWatcherBaseTest {
+ @After
+ public void tearDown() {
+ if ("testTimeoutCaught".equals(testWatcher.getName())) {
+ assertThat(timeoutCaught).isTrue();
+ }
+ }
+
+ /** Test that timeout handler is called */
+ @Test
+ public void testTimeoutCaught() throws Exception {
+ for (int i = 0; i < 10; i++) {
+ Thread.sleep(500);
+ }
+ }
+
+ /** Test that normal test failures are not blocked */
+ @Test(expected = AssertionError.class)
+ public void testFailure() {
+ Assert.fail();
+ }
+}