Handle @afterClass exceptions

We handled @beforeClass previously which works slightly
differently. Test did run with @AfterClass so we have to
report an error since we can't make placeholders.

Test: unit tests
Bug: 209662675
Change-Id: Iaee3684e5eef2c36b9865fef932859b46152f392
diff --git a/javatests/com/android/tradefed/testtype/HostTestTest.java b/javatests/com/android/tradefed/testtype/HostTestTest.java
index e580cc3..f66026e 100644
--- a/javatests/com/android/tradefed/testtype/HostTestTest.java
+++ b/javatests/com/android/tradefed/testtype/HostTestTest.java
@@ -63,6 +63,7 @@
 import junit.framework.TestSuite;
 
 import org.junit.After;
+import org.junit.AfterClass;
 import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.AssumptionViolatedException;
@@ -74,6 +75,7 @@
 import org.junit.runner.RunWith;
 import org.junit.runners.BlockJUnit4ClassRunner;
 import org.junit.runners.JUnit4;
+import org.junit.runners.Parameterized;
 import org.junit.runners.Suite;
 import org.junit.runners.Suite.SuiteClasses;
 import org.junit.runners.model.InitializationError;
@@ -345,6 +347,18 @@
     }
 
     @RunWith(DeviceJUnit4ClassRunner.class)
+    public static class JUnit4TestClassAssumeInStaticAfter {
+
+        @AfterClass
+        public static void afterClass() {
+            Assume.assumeTrue(false);
+        }
+
+        @org.junit.Test
+        public void testPass5() {}
+    }
+
+    @RunWith(DeviceJUnit4ClassRunner.class)
     public static class JUnit4TestClassMultiException {
 
         @org.junit.Test
@@ -566,6 +580,9 @@
         }
     }
 
+    @RunWith(Parameterized.class)
+    public static class ParameterizedTest {}
+
     public static class TestableHostTest extends HostTest {
 
         private IRemoteFileResolver mRemoteFileResolver;
@@ -593,7 +610,6 @@
         }
     }
 
-    /** {@inheritDoc} */
     @Before
     public void setUp() throws Exception {
         MockitoAnnotations.initMocks(this);
@@ -1359,6 +1375,28 @@
         inOrder.verify(mListener)
                 .testRunEnded(Mockito.anyLong(), (HashMap<String, Metric>) Mockito.any());
         inOrder.verifyNoMoreInteractions();
+        Mockito.verifyNoMoreInteractions(mListener);
+    }
+
+    @org.junit.Test
+    public void testRun_junit4style_assumeFailure_after_static() throws Exception {
+        mHostTest.setClassName(JUnit4TestClassAssumeInStaticAfter.class.getName());
+
+        mHostTest.run(mTestInfo, mListener);
+
+        InOrder inOrder = Mockito.inOrder(mListener);
+        inOrder.verify(mListener).testRunStarted((String) Mockito.any(), Mockito.eq(1));
+        TestDescription test1 =
+                new TestDescription(
+                        JUnit4TestClassAssumeInStaticAfter.class.getName(), "testPass5");
+        inOrder.verify(mListener).testStarted(Mockito.eq(test1));
+        inOrder.verify(mListener)
+                .testEnded(Mockito.eq(test1), (HashMap<String, Metric>) Mockito.any());
+        inOrder.verify(mListener).testRunFailed((String) Mockito.any());
+        inOrder.verify(mListener)
+                .testRunEnded(Mockito.anyLong(), (HashMap<String, Metric>) Mockito.any());
+        inOrder.verifyNoMoreInteractions();
+        Mockito.verifyNoMoreInteractions(mListener);
     }
 
     /**
diff --git a/test_framework/com/android/tradefed/testtype/junit4/JUnit4ResultForwarder.java b/test_framework/com/android/tradefed/testtype/junit4/JUnit4ResultForwarder.java
index cd1387b..c6c67bc 100644
--- a/test_framework/com/android/tradefed/testtype/junit4/JUnit4ResultForwarder.java
+++ b/test_framework/com/android/tradefed/testtype/junit4/JUnit4ResultForwarder.java
@@ -47,6 +47,7 @@
     private ITestInvocationListener mListener;
     private List<Throwable> mTestCaseFailures;
     private Description mRunDescription;
+    private boolean mBeforeClass = true;
 
     public JUnit4ResultForwarder(ITestInvocationListener listener) {
         mListener = listener;
@@ -100,19 +101,28 @@
     public void testRunFinished(Result result) throws Exception {
         if (!mTestCaseFailures.isEmpty()) {
             String stack = StreamUtil.getStackTrace(mTestCaseFailures.get(0));
-            for (Description test : mRunDescription.getChildren()) {
-                TestDescription testid =
-                        new TestDescription(
-                                test.getClassName(), test.getMethodName(), test.getAnnotations());
-                mListener.testStarted(testid);
-                mListener.testAssumptionFailure(testid, stack);
-                mListener.testEnded(testid, new HashMap<String, Metric>());
+            if (mBeforeClass) {
+                for (Description test : mRunDescription.getChildren()) {
+                    TestDescription testid =
+                            new TestDescription(
+                                    test.getClassName(),
+                                    test.getMethodName(),
+                                    test.getAnnotations());
+                    mListener.testStarted(testid);
+                    mListener.testAssumptionFailure(testid, stack);
+                    mListener.testEnded(testid, new HashMap<String, Metric>());
+                }
+            } else {
+                // This would be an error in AfterClass, we have no good place to put results today
+                // so report it as a failure for now.
+                mListener.testRunFailed(stack);
             }
         }
     }
 
     @Override
     public void testStarted(Description description) throws Exception {
+        mBeforeClass = false;
         mTestCaseFailures.clear();
         TestDescription testid =
                 new TestDescription(
@@ -149,7 +159,6 @@
                     }
                 }
             }
-            //description.
             mListener.testEnded(testid, metrics);
             mTestCaseFailures.clear();
         }