diff options
author | 2015-10-26 16:57:27 +0000 | |
---|---|---|
committer | 2015-10-27 11:48:29 +0000 | |
commit | 81b9083ef06972b2fa20f6cfb124d1cf41214e2f (patch) | |
tree | 66f58a0c9048dbe79ea26c06d17ee6b8d58d208f /src/test/java/com/google/devtools/build/lib/skyframe/ActionExecutionInactivityWatchdogTest.java | |
parent | 474496336197c0ab2b9a2c1f632d9b231c7f6acc (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.java | 167 |
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); + } +} |