Fix the timeout functionality for the longevity library.

Test: updated
Bug: 123307436
Change-Id: I1dec29a6452d9c3601b19c9946cb236db3d33f71
diff --git a/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java b/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java
index 5204e44..65e6a0d 100644
--- a/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java
+++ b/libraries/health/runners/longevity/host/src/android/host/test/longevity/listener/TimeoutTerminator.java
@@ -44,7 +44,7 @@
      * <p>Note: this initializes the countdown timer if unset.
      */
     @Override
-    public void testRunStarted(Description description) {
+    public void testStarted(Description description) {
         if (mStartTimestamp == UNSET_TIMESTAMP) {
             mStartTimestamp = getCurrentTimestamp();
         }
diff --git a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java
index 261a87d..d21a61f 100644
--- a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java
+++ b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/LongevitySuiteTest.java
@@ -18,6 +18,8 @@
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.fail;
 
+import android.host.test.longevity.listener.TimeoutTerminator;
+
 import java.util.HashMap;
 import java.util.Map;
 
@@ -81,7 +83,7 @@
                         FailingTestSuite.class, new AllDefaultPossibilitiesBuilder(true), args);
         try {
             suite.run(new RunNotifier());
-            fail("This run should be invalidated by test failures.");
+            fail("This run should be invalidated by test failure.");
         } catch (StoppedByUserException e) {
             // Expect this failure for an invalid, erroring test run.
         }
@@ -91,9 +93,7 @@
     @SuiteClasses({
         FailingTestSuite.FailingTest.class,
     })
-    /**
-     * Sample device-side test cases.
-     */
+    /** Sample device-side test case that fails. */
     public static class FailingTestSuite {
         public static class FailingTest {
             @Test
@@ -103,6 +103,38 @@
         }
     }
 
+    /** Tests that test runs are timing out if the tests run over the allotted suite time. */
+    @Test
+    public void testTimeoutTestRuns() throws InitializationError {
+        Map<String, String> args = new HashMap();
+        args.put(LongevitySuite.INVALIDATE_OPTION, "true");
+        args.put(TimeoutTerminator.OPTION, "25");
+        args.put(ITERATIONS_OPTION_NAME, String.valueOf(10));
+        LongevitySuite suite =
+                new LongevitySuite(
+                        TimeoutTestSuite.class, new AllDefaultPossibilitiesBuilder(true), args);
+        try {
+            suite.run(new RunNotifier());
+            fail("This run should be ended by a timeout failure.");
+        } catch (StoppedByUserException e) {
+            // Expect this failure for an invalid, erroring test run.
+        }
+    }
+
+    @RunWith(LongevitySuite.class)
+    @SuiteClasses({
+        TimeoutTestSuite.TimedTest.class,
+    })
+    /** Sample device-side test case that takes time. */
+    public static class TimeoutTestSuite {
+        public static class TimedTest {
+            @Test
+            public void testSleep() throws InterruptedException {
+                Thread.sleep(10);
+            }
+        }
+    }
+
     /**
      * Tests that the {@link LongevitySuite} properly accounts for the number of tests in children.
      */
diff --git a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java
index 1862e11..c439721 100644
--- a/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java
+++ b/libraries/health/runners/longevity/host/tests/src/android/host/test/longevity/listener/TimeoutTerminatorTest.java
@@ -50,7 +50,7 @@
      */
     @Test
     public void testTimeoutTerminator_pass() throws Exception {
-        mListener.testRunStarted(Description.EMPTY);
+        mListener.testStarted(Description.EMPTY);
         Thread.sleep(10L);
         mListener.testFinished(Description.EMPTY);
         verify(mNotifier, never()).pleaseStop();
@@ -61,7 +61,7 @@
      */
     @Test
     public void testTimeoutTerminator_timeout() throws Exception {
-        mListener.testRunStarted(Description.EMPTY);
+        mListener.testStarted(Description.EMPTY);
         Thread.sleep(60L);
         mListener.testFinished(Description.EMPTY);
         verify(mNotifier).pleaseStop();
diff --git a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java
index e565427..f1cc67d 100644
--- a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java
+++ b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevityClassRunner.java
@@ -38,6 +38,7 @@
 import org.junit.runners.model.InitializationError;
 import org.junit.runners.model.MultipleFailureException;
 import org.junit.runners.model.Statement;
+import org.junit.runner.notification.StoppedByUserException;
 
 /**
  * A {@link BlockJUnit4ClassRunner} that runs the test class's {@link BeforeClass} methods as {@link
@@ -229,12 +230,16 @@
         @Override
         public void evaluate() throws Throwable {
             List<Throwable> errors = new ArrayList<>();
+            boolean stoppedByUser = false;
             try {
                 mStatement.evaluate();
             } catch (Throwable e) {
+                if (e instanceof StoppedByUserException) {
+                    stoppedByUser = true;
+                }
                 errors.add(e);
             } finally {
-                if (LongevityClassRunner.this.hasTestFailed()) {
+                if (!stoppedByUser && LongevityClassRunner.this.hasTestFailed()) {
                     errors.addAll(invokeAndCollectErrors(mAfterClassMethods, mTarget));
                 }
             }
diff --git a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java
index ced6874..2e0df1c 100644
--- a/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java
+++ b/libraries/health/runners/longevity/platform/src/android/platform/test/longevity/LongevitySuite.java
@@ -201,9 +201,7 @@
         super.runChild(suiteRunner, notifier);
     }
 
-    /**
-     * Returns the platform-specific {@link TimeoutTerminator} for Android devices.
-     */
+    /** Returns the platform-specific {@link ErrorTerminator} for an Android device. */
     @Override
     public android.host.test.longevity.listener.ErrorTerminator getErrorTerminator(
             final RunNotifier notifier) {
@@ -211,7 +209,7 @@
     }
 
     /**
-     * Returns the platform-specific {@link TimeoutTerminator} for Android devices.
+     * Returns the platform-specific {@link TimeoutTerminator} for an Android device.
      *
      * <p>This method will always return the same {@link TimeoutTerminator} instance.
      */
diff --git a/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java b/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java
index 76749ff..a6dfb79 100644
--- a/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java
+++ b/libraries/health/runners/longevity/platform/tests/src/android/platform/test/longevity/listener/TimeoutTerminatorTest.java
@@ -53,7 +53,7 @@
      */
     @Test
     public void testTimeoutTerminator_pass() throws Exception {
-        mListener.testRunStarted(Description.EMPTY);
+        mListener.testStarted(Description.EMPTY);
         SystemClock.sleep(10L);
         verify(mNotifier, never()).pleaseStop();
     }
@@ -63,7 +63,7 @@
      */
     @Test
     public void testTimeoutTerminator_timeout() throws Exception {
-        mListener.testRunStarted(Description.EMPTY);
+        mListener.testStarted(Description.EMPTY);
         SystemClock.sleep(60L);
         mListener.testFinished(Description.EMPTY);
         verify(mNotifier).pleaseStop();