aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java
diff options
context:
space:
mode:
authorGravatar Han-Wen Nienhuys <hanwen@google.com>2015-10-26 16:57:27 +0000
committerGravatar Florian Weikert <fwe@google.com>2015-10-27 11:48:29 +0000
commit81b9083ef06972b2fa20f6cfb124d1cf41214e2f (patch)
tree66f58a0c9048dbe79ea26c06d17ee6b8d58d208f /src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java
parent474496336197c0ab2b9a2c1f632d9b231c7f6acc (diff)
Open source some skyframe/bazel tests.
-- MOS_MIGRATED_REVID=106308990
Diffstat (limited to 'src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java')
-rw-r--r--src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java167
1 files changed, 167 insertions, 0 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java b/src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java
new file mode 100644
index 0000000000..8c15b6c8d9
--- /dev/null
+++ b/src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java
@@ -0,0 +1,167 @@
+// Copyright 2015 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.skyframe;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import com.google.devtools.build.lib.skyframe.ActionExecutionInactivityWatchdog.InactivityMonitor;
+import com.google.devtools.build.lib.skyframe.ActionExecutionInactivityWatchdog.InactivityReporter;
+import com.google.devtools.build.lib.testutil.MoreAsserts;
+
+import junit.framework.TestCase;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/** Tests for ActionExecutionInactivityWatchdog. */
+public final class ActionExecutionInactivityWatchdogTest extends TestCase {
+
+ private void assertInactivityWatchdogReports(final boolean shouldReport) throws Exception {
+ // The monitor implementation below is a state machine. This variable indicates which state
+ // it is in.
+ final int[] monitorState = new int[] {0};
+
+ // Object that the test thread will wait on.
+ final Object monitorFinishedIndicator = new Object();
+
+ // Reported number of action completions in each call to waitForNextCompletion.
+ final int[] actionCompletions = new int[] {1, 0, 3, 0, 0, 0, 0, 2};
+
+ // Simulated delay of action completions in each call to waitForNextCompletion.
+ final int[] waits = new int[] {5, 10, 3, 10, 30, 60, 60, 1};
+
+ // Log of all Sleep.sleep and InactivityMonitor.waitForNextCompletion calls.
+ final List<String> sleepsAndWaits = new ArrayList<>();
+
+ // Mock monitor for this test.
+ InactivityMonitor monitor =
+ new InactivityMonitor() {
+ @Override
+ public int waitForNextCompletion(int timeoutMilliseconds) throws InterruptedException {
+ // Simulate the following sequence of events (see actionCompletions):
+ // 1. return in 5s (within timeout), 1 action completed; caller will sleep
+ // 2. return in 10s (after timeout), 0 action completed; caller will wait
+ // 3. return in 3s (within timeout), 3 actions completed (this is possible, since the
+ // waiting (thread doesn't necessarily wake up immediately); caller will sleep
+ // 4. return in 10s (after timeout), 0 action completed; caller will wait 30s
+ // 5. return in 30s (after timeout), 0 action completed still; caller will wait 60s
+ // 6. return in 60s (after timeout), 0 action completed still; caller will wait 60s
+ // 7. return in 60s (after timeout), 0 action completed still; caller will wait 60s
+ // 8. return in 1s (within timeout), 2 actions completed; caller will sleep, but we
+ // won't record that, because monitorState reached its maximum
+ synchronized (monitorFinishedIndicator) {
+ if (monitorState[0] >= actionCompletions.length) {
+ // Notify the test thread that the test is over.
+ monitorFinishedIndicator.notify();
+ return 1;
+ } else {
+ int index = monitorState[0];
+ sleepsAndWaits.add("wait:" + waits[index]);
+ ++monitorState[0];
+ return actionCompletions[index];
+ }
+ }
+ }
+
+ @Override
+ public boolean hasStarted() {
+ return true;
+ }
+
+ @Override
+ public int getPending() {
+ int index = monitorState[0];
+ if (index >= actionCompletions.length) {
+ return 0;
+ }
+ int result = actionCompletions[index];
+ while (result == 0) {
+ ++index;
+ result = actionCompletions[index];
+ }
+ return result;
+ }
+ };
+
+ final boolean[] didReportInactivity = new boolean[] {false};
+ InactivityReporter reporter =
+ new InactivityReporter() {
+ @Override
+ public void maybeReportInactivity() {
+ if (shouldReport) {
+ didReportInactivity[0] = true;
+ }
+ }
+ };
+
+ // Mock sleep object; just logs how much the caller's thread would've slept.
+ ActionExecutionInactivityWatchdog.Sleep sleep =
+ new ActionExecutionInactivityWatchdog.Sleep() {
+ @Override
+ public void sleep(int durationMilliseconds) throws InterruptedException {
+ if (monitorState[0] < actionCompletions.length) {
+ sleepsAndWaits.add("sleep:" + durationMilliseconds);
+ }
+ }
+ };
+
+ ActionExecutionInactivityWatchdog watchdog =
+ new ActionExecutionInactivityWatchdog(monitor, reporter, 0, sleep);
+ try {
+ synchronized (monitorFinishedIndicator) {
+ watchdog.start();
+
+ long startTime = System.currentTimeMillis();
+ boolean done = false;
+ while (!done) {
+ try {
+ monitorFinishedIndicator.wait(5000);
+ done = true;
+ MoreAsserts.assertLessThan(
+ "test didn't finish under 5 seconds",
+ 5000L,
+ System.currentTimeMillis() - startTime);
+ } catch (InterruptedException ie) {
+ // so-called Spurious Wakeup; ignore
+ }
+ }
+ }
+ } finally {
+ watchdog.stop();
+ }
+
+ assertEquals(shouldReport, didReportInactivity[0]);
+ assertThat(sleepsAndWaits)
+ .containsExactly(
+ "wait:5",
+ "sleep:1000",
+ "wait:10",
+ "wait:3",
+ "sleep:1000",
+ "wait:10",
+ "wait:30",
+ "wait:60",
+ "wait:60",
+ "wait:1")
+ .inOrder();
+ }
+
+ public void testInactivityWatchdogReportsWhenItShould() throws Exception {
+ assertInactivityWatchdogReports(true);
+ }
+
+ public void testInactivityWatchdogDoesNotReportWhenItShouldNot() throws Exception {
+ assertInactivityWatchdogReports(false);
+ }
+}