• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2010 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.tradefed.testtype;
17 
18 import static org.mockito.Mockito.doReturn;
19 
20 import com.android.tradefed.build.IBuildInfo;
21 import com.android.tradefed.config.ConfigurationException;
22 import com.android.tradefed.config.DynamicRemoteFileResolver;
23 import com.android.tradefed.config.Option;
24 import com.android.tradefed.config.OptionSetter;
25 import com.android.tradefed.config.remote.GcsRemoteFileResolver;
26 import com.android.tradefed.config.remote.IRemoteFileResolver;
27 import com.android.tradefed.device.DeviceNotAvailableException;
28 import com.android.tradefed.device.ITestDevice;
29 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
30 import com.android.tradefed.result.ByteArrayInputStreamSource;
31 import com.android.tradefed.result.ITestInvocationListener;
32 import com.android.tradefed.result.InputStreamSource;
33 import com.android.tradefed.result.LogDataType;
34 import com.android.tradefed.result.TestDescription;
35 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestLogData;
36 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.TestMetrics;
37 import com.android.tradefed.util.StreamUtil;
38 import com.android.tradefed.util.proto.TfMetricProtoUtil;
39 
40 import junit.framework.Test;
41 import junit.framework.TestCase;
42 import junit.framework.TestSuite;
43 
44 import org.easymock.Capture;
45 import org.easymock.EasyMock;
46 import org.junit.After;
47 import org.junit.Assert;
48 import org.junit.Assume;
49 import org.junit.AssumptionViolatedException;
50 import org.junit.Before;
51 import org.junit.BeforeClass;
52 import org.junit.Ignore;
53 import org.junit.Rule;
54 import org.junit.runner.RunWith;
55 import org.junit.runners.BlockJUnit4ClassRunner;
56 import org.junit.runners.JUnit4;
57 import org.junit.runners.Suite.SuiteClasses;
58 import org.junit.runners.model.InitializationError;
59 import org.mockito.Mockito;
60 
61 import java.io.File;
62 import java.lang.annotation.Retention;
63 import java.lang.annotation.RetentionPolicy;
64 import java.lang.reflect.AnnotatedElement;
65 import java.util.ArrayList;
66 import java.util.Collection;
67 import java.util.HashMap;
68 import java.util.List;
69 import java.util.Map;
70 
71 /**
72  * Unit tests for {@link HostTest}.
73  */
74 @SuppressWarnings("unchecked")
75 public class HostTestTest extends TestCase {
76 
77     private static final File FAKE_REMOTE_FILE_PATH = new File("gs://bucket/path/file");
78 
79     private HostTest mHostTest;
80     private ITestInvocationListener mListener;
81     private ITestDevice mMockDevice;
82     private IBuildInfo mMockBuildInfo;
83 
84     private IRemoteFileResolver mMockResolver;
85 
86     @MyAnnotation
87     @MyAnnotation3
88     public static class SuccessTestCase extends TestCase {
89 
SuccessTestCase()90         public SuccessTestCase() {}
91 
SuccessTestCase(String name)92         public SuccessTestCase(String name) {
93             super(name);
94         }
95 
96         @MyAnnotation
testPass()97         public void testPass() {
98         }
99 
100         @MyAnnotation
101         @MyAnnotation2
testPass2()102         public void testPass2() {
103         }
104     }
105 
106     public static class DynamicTestCase extends TestCase {
107 
108         @Option(name = "dynamic-option")
109         private File mDynamicFile = FAKE_REMOTE_FILE_PATH;
110 
DynamicTestCase()111         public DynamicTestCase() {}
112 
DynamicTestCase(String name)113         public DynamicTestCase(String name) {
114             super(name);
115         }
116 
testPass()117         public void testPass() {
118             assertFalse(mDynamicFile.equals(new File("gs://bucket/path/file")));
119         }
120     }
121 
122     public static class TestMetricTestCase extends MetricTestCase {
123 
124         @Option(name = "test-option")
125         public String testOption = null;
126 
127         @Option(name = "list-option")
128         public List<String> listOption = new ArrayList<>();
129 
130         @Option(name = "map-option")
131         public Map<String, String> mapOption = new HashMap<>();
132 
testPass()133         public void testPass() {
134             addTestMetric("key1", "metric1");
135         }
136 
testPass2()137         public void testPass2() {
138             addTestMetric("key2", "metric2");
139             if (testOption != null) {
140                 addTestMetric("test-option", testOption);
141             }
142             if (!listOption.isEmpty()) {
143                 addTestMetric("list-option", listOption.toString());
144             }
145             if (!mapOption.isEmpty()) {
146                 addTestMetric("map-option", mapOption.toString());
147             }
148         }
149     }
150 
151     public static class LogMetricTestCase extends MetricTestCase {
152 
testPass()153         public void testPass() {}
154 
testPass2()155         public void testPass2() {
156             addTestLog(
157                     "test2_log",
158                     LogDataType.TEXT,
159                     new ByteArrayInputStreamSource("test_log".getBytes()));
160             addTestMetric("key2", "metric2");
161         }
162     }
163 
164     @MyAnnotation
165     public static class AnotherTestCase extends TestCase {
AnotherTestCase()166         public AnotherTestCase() {
167         }
168 
AnotherTestCase(String name)169         public AnotherTestCase(String name) {
170             super(name);
171         }
172 
173         @MyAnnotation
174         @MyAnnotation2
175         @MyAnnotation3
testPass3()176         public void testPass3() {}
177 
178         @MyAnnotation
testPass4()179         public void testPass4() {
180         }
181     }
182 
183     /**
184      * Test class, we have to annotate with full org.junit.Test to avoid name collision in import.
185      */
186     @RunWith(DeviceJUnit4ClassRunner.class)
187     public static class Junit4TestClass {
188 
Junit4TestClass()189         public Junit4TestClass() {}
190 
191         @Option(name = "junit4-option")
192         public boolean mOption = false;
193 
194         @Option(name = "map-option")
195         public Map<String, String> mapOption = new HashMap<>();
196 
197         @Rule public TestMetrics metrics = new TestMetrics();
198 
199         @MyAnnotation
200         @MyAnnotation2
201         @org.junit.Test
testPass5()202         public void testPass5() {
203             // test log through the rule.
204             metrics.addTestMetric("key", "value");
205         }
206 
207         @MyAnnotation
208         @org.junit.Test
testPass6()209         public void testPass6() {
210             metrics.addTestMetric("key2", "value2");
211             if (mOption) {
212                 metrics.addTestMetric("junit4-option", "true");
213             }
214             if (!mapOption.isEmpty()) {
215                 metrics.addTestMetric("map-option", mapOption.values().toString());
216             }
217         }
218     }
219 
220     /**
221      * Test class, we have to annotate with full org.junit.Test to avoid name collision in import.
222      */
223     @RunWith(DeviceJUnit4ClassRunner.class)
224     public static class Junit4TestLogClass {
225 
Junit4TestLogClass()226         public Junit4TestLogClass() {}
227 
228         @Rule public TestLogData logs = new TestLogData();
229 
230         @org.junit.Test
testPass1()231         public void testPass1() {
232             ByteArrayInputStreamSource source = new ByteArrayInputStreamSource("test".getBytes());
233             logs.addTestLog("TEST", LogDataType.TEXT, source);
234             // Always cancel streams.
235             StreamUtil.cancel(source);
236         }
237 
238         @org.junit.Test
testPass2()239         public void testPass2() {
240             ByteArrayInputStreamSource source = new ByteArrayInputStreamSource("test2".getBytes());
241             logs.addTestLog("TEST2", LogDataType.TEXT, source);
242             // Always cancel streams.
243             StreamUtil.cancel(source);
244         }
245     }
246 
247     /**
248      * Test class, we have to annotate with full org.junit.Test to avoid name collision in import.
249      * And with one test marked as Ignored
250      */
251     @RunWith(DeviceJUnit4ClassRunner.class)
252     public static class Junit4TestClassWithIgnore implements IDeviceTest {
253         private ITestDevice mDevice;
254 
Junit4TestClassWithIgnore()255         public Junit4TestClassWithIgnore() {}
256 
257         @org.junit.Test
testPass5()258         public void testPass5() {}
259 
260         @Ignore
261         @org.junit.Test
testPass6()262         public void testPass6() {}
263 
264         @Override
setDevice(ITestDevice device)265         public void setDevice(ITestDevice device) {
266             mDevice = device;
267         }
268 
269         @Override
getDevice()270         public ITestDevice getDevice() {
271             return mDevice;
272         }
273     }
274 
275     /**
276      * Test class that run a test throwing an {@link AssumptionViolatedException} which should be
277      * handled as the testAssumptionFailure.
278      */
279     @RunWith(DeviceJUnit4ClassRunner.class)
280     public static class JUnit4TestClassAssume {
281 
282         @org.junit.Test
testPass5()283         public void testPass5() {
284             Assume.assumeTrue(false);
285         }
286     }
287 
288     @RunWith(DeviceJUnit4ClassRunner.class)
289     public static class JUnit4TestClassMultiException {
290 
291         @org.junit.Test
testPass5()292         public void testPass5() {
293             Assume.assumeTrue(false);
294         }
295 
296         @After
tearDown()297         public void tearDown() {
298             Assert.assertTrue(false);
299         }
300     }
301 
302     @RunWith(DeviceJUnit4ClassRunner.class)
303     public static class JUnit4TestClassMultiExceptionDnae {
304 
305         @org.junit.Test
testPass5()306         public void testPass5() {
307             Assume.assumeTrue(false);
308         }
309 
310         @After
tearDown()311         public void tearDown() throws Exception {
312             throw new DeviceNotAvailableException("dnae", "serial");
313         }
314     }
315 
316     @RunWith(DeviceJUnit4ClassRunner.class)
317     public static class Junit4TestClassMulti implements IMultiDeviceTest {
318         private Map<ITestDevice, IBuildInfo> mDeviceMap;
319 
Junit4TestClassMulti()320         public Junit4TestClassMulti() {}
321 
322         @org.junit.Test
testPass5()323         public void testPass5() {
324             assertNotNull(mDeviceMap);
325         }
326 
327         @Override
setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos)328         public void setDeviceInfos(Map<ITestDevice, IBuildInfo> deviceInfos) {
329             mDeviceMap = deviceInfos;
330         }
331     }
332 
333     @RunWith(DeviceSuite.class)
334     @SuiteClasses({
335         Junit4TestClass.class,
336         SuccessTestCase.class,
337     })
338     public class Junit4SuiteClass {
339     }
340 
341     /**
342      * JUnit4 runner that implements {@link ISetOptionReceiver} but does not actually have the
343      * set-option.
344      */
345     public static class InvalidJunit4Runner extends BlockJUnit4ClassRunner
346             implements ISetOptionReceiver {
InvalidJunit4Runner(Class<?> klass)347         public InvalidJunit4Runner(Class<?> klass) throws InitializationError {
348             super(klass);
349         }
350     }
351 
352     @RunWith(InvalidJunit4Runner.class)
353     public static class Junit4RegularClass {
354         @Option(name = "option")
355         private String mOption = null;
356 
357         @org.junit.Test
testPass()358         public void testPass() {}
359     }
360 
361     /**
362      * Malformed on purpose test class.
363      */
364     public static class Junit4MalformedTestClass {
Junit4MalformedTestClass()365         public Junit4MalformedTestClass() {
366         }
367 
368         @Before
setUp()369         protected void setUp() {
370             // @Before should be on a public method.
371         }
372 
373         @org.junit.Test
testPass()374         public void testPass() {
375         }
376     }
377 
378     /**
379      * Simple Annotation class for testing
380      */
381     @Retention(RetentionPolicy.RUNTIME)
382     public @interface MyAnnotation {
383     }
384 
385     /**
386      * Simple Annotation class for testing
387      */
388     @Retention(RetentionPolicy.RUNTIME)
389     public @interface MyAnnotation2 {
390     }
391 
392     /** Simple Annotation class for testing */
393     @Retention(RetentionPolicy.RUNTIME)
394     public @interface MyAnnotation3 {}
395 
396     public static class SuccessTestSuite extends TestSuite {
SuccessTestSuite()397         public SuccessTestSuite() {
398             super(SuccessTestCase.class);
399         }
400     }
401 
402     public static class SuccessHierarchySuite extends TestSuite {
SuccessHierarchySuite()403         public SuccessHierarchySuite() {
404             super();
405             addTestSuite(SuccessTestCase.class);
406         }
407     }
408 
409     public static class SuccessDeviceTest extends DeviceTestCase {
410 
411         @Option(name = "option")
412         public String mOption = null;
413 
SuccessDeviceTest()414         public SuccessDeviceTest() {
415             super();
416         }
417 
testPass()418         public void testPass() {
419             assertNotNull(getDevice());
420             if (mOption != null) {
421                 addTestMetric("option", mOption);
422             }
423         }
424     }
425 
426     @MyAnnotation
427     public static class SuccessDeviceTest2 extends DeviceTestCase {
SuccessDeviceTest2()428         public SuccessDeviceTest2() {
429             super();
430         }
431 
432         @MyAnnotation3
testPass1()433         public void testPass1() {
434             assertNotNull(getDevice());
435         }
436 
testPass2()437         public void testPass2() {
438             assertNotNull(getDevice());
439         }
440     }
441 
442     @MyAnnotation
443     public static class InheritedDeviceTest3 extends SuccessDeviceTest2 {
InheritedDeviceTest3()444         public InheritedDeviceTest3() {
445             super();
446         }
447 
448         @Override
testPass1()449         public void testPass1() {
450             super.testPass1();
451         }
452 
453         @MyAnnotation3
testPass3()454         public void testPass3() {}
455     }
456 
457     public static class TestRemoteNotCollector implements IDeviceTest, IRemoteTest {
458         @Override
run(ITestInvocationListener listener)459         public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {}
460 
461         @Override
setDevice(ITestDevice device)462         public void setDevice(ITestDevice device) {}
463 
464         @Override
getDevice()465         public ITestDevice getDevice() {
466             return null;
467         }
468     }
469 
470     /** Non-public class; should fail to load. */
471     private static class PrivateTest extends TestCase {
472         @SuppressWarnings("unused")
testPrivate()473         public void testPrivate() {
474         }
475     }
476 
477     /** class without default constructor; should fail to load */
478     public static class NoConstructorTest extends TestCase {
NoConstructorTest(String name)479         public NoConstructorTest(String name) {
480             super(name);
481         }
testNoConstructor()482         public void testNoConstructor() {
483         }
484     }
485 
486     public static class TestableHostTest extends HostTest {
487 
488         private IRemoteFileResolver mRemoteFileResolver;
489 
TestableHostTest()490         public TestableHostTest() {
491             mRemoteFileResolver = null;
492         }
493 
TestableHostTest(IRemoteFileResolver remoteFileResolver)494         public TestableHostTest(IRemoteFileResolver remoteFileResolver) {
495             mRemoteFileResolver = remoteFileResolver;
496         }
497 
498         @Override
createOptionSetter(Object obj)499         OptionSetter createOptionSetter(Object obj) throws ConfigurationException {
500             return new OptionSetter(obj) {
501                 @Override
502                 protected DynamicRemoteFileResolver createResolver() {
503                     DynamicRemoteFileResolver mResolver =
504                             new DynamicRemoteFileResolver() {
505                                 @Override
506                                 protected IRemoteFileResolver getResolver(String protocol) {
507                                     if (protocol.equals(GcsRemoteFileResolver.PROTOCOL)) {
508                                         return mRemoteFileResolver;
509                                     }
510                                     return null;
511                                 }
512 
513                                 @Override
514                                 protected boolean updateProtocols() {
515                                     // Do not set the static variable
516                                     return false;
517                                 }
518                             };
519                     return mResolver;
520                 }
521             };
522         }
523     }
524 
525     /**
526      * {@inheritDoc}
527      */
528     @Override
529     protected void setUp() throws Exception {
530         super.setUp();
531         mMockResolver = Mockito.mock(IRemoteFileResolver.class);
532         mHostTest = new TestableHostTest(mMockResolver);
533         mListener = EasyMock.createMock(ITestInvocationListener.class);
534         mMockDevice = EasyMock.createMock(ITestDevice.class);
535         mMockBuildInfo = EasyMock.createMock(IBuildInfo.class);
536         mHostTest.setDevice(mMockDevice);
537         mHostTest.setBuild(mMockBuildInfo);
538         OptionSetter setter = new OptionSetter(mHostTest);
539         // Disable pretty logging for testing
540         setter.setOptionValue("enable-pretty-logs", "false");
541     }
542 
543     /**
544      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
545      * {@link TestCase}.
546      */
547     public void testRun_testcase() throws Exception {
548         mHostTest.setClassName(SuccessTestCase.class.getName());
549         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
550         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
551         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
552         mListener.testStarted(EasyMock.eq(test1));
553         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
554         mListener.testStarted(EasyMock.eq(test2));
555         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
556         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
557         EasyMock.replay(mListener);
558         mHostTest.run(mListener);
559         EasyMock.verify(mListener);
560     }
561 
562     /**
563      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
564      * {@link MetricTestCase}.
565      */
566     public void testRun_MetricTestCase() throws Exception {
567         mHostTest.setClassName(TestMetricTestCase.class.getName());
568         TestDescription test1 = new TestDescription(TestMetricTestCase.class.getName(), "testPass");
569         TestDescription test2 =
570                 new TestDescription(TestMetricTestCase.class.getName(), "testPass2");
571         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
572         mListener.testStarted(EasyMock.eq(test1));
573         // test1 should only have its metrics
574         Map<String, String> metric1 = new HashMap<>();
575         metric1.put("key1", "metric1");
576         mListener.testEnded(test1, TfMetricProtoUtil.upgradeConvert(metric1));
577         // test2 should only have its metrics
578         mListener.testStarted(EasyMock.eq(test2));
579         Map<String, String> metric2 = new HashMap<>();
580         metric2.put("key2", "metric2");
581         mListener.testEnded(test2, TfMetricProtoUtil.upgradeConvert(metric2));
582         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
583         EasyMock.replay(mListener);
584         mHostTest.run(mListener);
585         EasyMock.verify(mListener);
586     }
587 
588     /**
589      * Test a case where a test use {@link MetricTestCase#addTestLog(String, LogDataType,
590      * InputStreamSource)} in order to log data for all the reporters to know about.
591      */
592     public void testRun_LogMetricTestCase() throws Exception {
593         mHostTest.setClassName(LogMetricTestCase.class.getName());
594         TestDescription test1 = new TestDescription(LogMetricTestCase.class.getName(), "testPass");
595         TestDescription test2 = new TestDescription(LogMetricTestCase.class.getName(), "testPass2");
596         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
597         mListener.testStarted(EasyMock.eq(test1));
598         // test1 should only have its metrics
599         mListener.testEnded(test1, new HashMap<String, Metric>());
600         // test2 should only have its metrics
601         mListener.testStarted(EasyMock.eq(test2));
602         Map<String, String> metric2 = new HashMap<>();
603         metric2.put("key2", "metric2");
604         mListener.testLog(
605                 EasyMock.eq("test2_log"), EasyMock.eq(LogDataType.TEXT), EasyMock.anyObject());
606         mListener.testEnded(test2, TfMetricProtoUtil.upgradeConvert(metric2));
607         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
608         EasyMock.replay(mListener);
609         mHostTest.run(mListener);
610         EasyMock.verify(mListener);
611     }
612 
613     /**
614      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
615      * {@link MetricTestCase} and where an option is set to get extra metrics.
616      */
617     public void testRun_MetricTestCase_withOption() throws Exception {
618         OptionSetter setter = new OptionSetter(mHostTest);
619         setter.setOptionValue("set-option", "test-option:test");
620         // List option can take several values.
621         setter.setOptionValue("set-option", "list-option:test1");
622         setter.setOptionValue("set-option", "list-option:test2");
623         // Map option
624         setter.setOptionValue("set-option", "map-option:key=value");
625         mHostTest.setClassName(TestMetricTestCase.class.getName());
626         TestDescription test1 = new TestDescription(TestMetricTestCase.class.getName(), "testPass");
627         TestDescription test2 =
628                 new TestDescription(TestMetricTestCase.class.getName(), "testPass2");
629         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
630         mListener.testStarted(EasyMock.eq(test1));
631         // test1 should only have its metrics
632         Map<String, String> metric1 = new HashMap<>();
633         metric1.put("key1", "metric1");
634         mListener.testEnded(test1, TfMetricProtoUtil.upgradeConvert(metric1));
635         // test2 should only have its metrics
636         mListener.testStarted(EasyMock.eq(test2));
637         Map<String, String> metric2 = new HashMap<>();
638         metric2.put("key2", "metric2");
639         metric2.put("test-option", "test");
640         metric2.put("list-option", "[test1, test2]");
641         metric2.put("map-option", "{key=value}");
642         mListener.testEnded(test2, TfMetricProtoUtil.upgradeConvert(metric2));
643         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
644         EasyMock.replay(mListener);
645         mHostTest.run(mListener);
646         EasyMock.verify(mListener);
647     }
648 
649     /**
650      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
651      * {@link TestSuite}.
652      */
653     public void testRun_testSuite() throws Exception {
654         mHostTest.setClassName(SuccessTestSuite.class.getName());
655         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
656         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
657         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
658         mListener.testStarted(EasyMock.eq(test1));
659         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
660         mListener.testStarted(EasyMock.eq(test2));
661         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
662         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
663         EasyMock.replay(mListener);
664         mHostTest.run(mListener);
665         EasyMock.verify(mListener);
666     }
667 
668     /**
669      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
670      * {@link TestSuite} and has dynamic options.
671      */
672     public void testRun_junit3TestSuite_dynamicOptions() throws Exception {
673         doReturn(new File("/downloaded/somewhere"))
674                 .when(mMockResolver)
675                 .resolveRemoteFiles(Mockito.eq(FAKE_REMOTE_FILE_PATH), Mockito.any());
676         mHostTest.setClassName(DynamicTestCase.class.getName());
677         TestDescription test1 = new TestDescription(DynamicTestCase.class.getName(), "testPass");
678         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
679         mListener.testStarted(EasyMock.eq(test1));
680         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
681         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
682         EasyMock.replay(mListener);
683         mHostTest.run(mListener);
684         EasyMock.verify(mListener);
685     }
686 
687     /**
688      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
689      * hierarchy of {@link TestSuite}s.
690      */
691     public void testRun_testHierarchySuite() throws Exception {
692         mHostTest.setClassName(SuccessHierarchySuite.class.getName());
693         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
694         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
695         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
696         mListener.testStarted(EasyMock.eq(test1));
697         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
698         mListener.testStarted(EasyMock.eq(test2));
699         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
700         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
701         EasyMock.replay(mListener);
702         mHostTest.run(mListener);
703         EasyMock.verify(mListener);
704     }
705 
706     /**
707      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
708      * {@link TestCase} and methodName is set.
709      */
710     public void testRun_testMethod() throws Exception {
711         mHostTest.setClassName(SuccessTestCase.class.getName());
712         mHostTest.setMethodName("testPass");
713         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
714         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
715         mListener.testStarted(EasyMock.eq(test1));
716         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
717         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
718         EasyMock.replay(mListener);
719         mHostTest.run(mListener);
720         EasyMock.verify(mListener);
721     }
722 
723     /**
724      * Test for {@link HostTest#run(ITestInvocationListener)}, where className is not set.
725      */
726     public void testRun_missingClass() throws Exception {
727         try {
728             mHostTest.run(mListener);
729             fail("IllegalArgumentException not thrown");
730         } catch (IllegalArgumentException e) {
731             // expected
732         }
733     }
734 
735     /**
736      * Test for {@link HostTest#run(ITestInvocationListener)}, for an invalid class.
737      */
738     public void testRun_invalidClass() throws Exception {
739         try {
740             mHostTest.setClassName("foo");
741             mHostTest.run(mListener);
742             fail("IllegalArgumentException not thrown");
743         } catch (IllegalArgumentException e) {
744             // expected
745         }
746     }
747 
748     /**
749      * Test for {@link HostTest#run(ITestInvocationListener)},
750      * for a valid class that is not a {@link Test}.
751      */
752     public void testRun_notTestClass() throws Exception {
753         try {
754             mHostTest.setClassName(String.class.getName());
755             mHostTest.run(mListener);
756             fail("IllegalArgumentException not thrown");
757         } catch (IllegalArgumentException e) {
758             // expected
759         }
760     }
761 
762     /**
763      * Test for {@link HostTest#run(ITestInvocationListener)},
764      * for a private class.
765      */
766     public void testRun_privateClass() throws Exception {
767         try {
768             mHostTest.setClassName(PrivateTest.class.getName());
769             mHostTest.run(mListener);
770             fail("IllegalArgumentException not thrown");
771         } catch (IllegalArgumentException e) {
772             // expected
773         }
774     }
775 
776     /**
777      * Test for {@link HostTest#run(ITestInvocationListener)},
778      * for a test class with no default constructor.
779      */
780     public void testRun_noConstructorClass() throws Exception {
781         try {
782             mHostTest.setClassName(NoConstructorTest.class.getName());
783             mHostTest.run(mListener);
784             fail("IllegalArgumentException not thrown");
785         } catch (IllegalArgumentException e) {
786             // expected
787         }
788     }
789 
790     /**
791      * Test for {@link HostTest#run(ITestInvocationListener)}, for multiple test classes.
792      */
793     public void testRun_multipleClass() throws Exception {
794         OptionSetter setter = new OptionSetter(mHostTest);
795         setter.setOptionValue("class", SuccessTestCase.class.getName());
796         setter.setOptionValue("class", AnotherTestCase.class.getName());
797         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
798         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
799         TestDescription test3 = new TestDescription(AnotherTestCase.class.getName(), "testPass3");
800         TestDescription test4 = new TestDescription(AnotherTestCase.class.getName(), "testPass4");
801         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
802         mListener.testStarted(EasyMock.eq(test1));
803         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
804         mListener.testStarted(EasyMock.eq(test2));
805         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
806         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
807         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
808         mListener.testStarted(EasyMock.eq(test3));
809         mListener.testEnded(EasyMock.eq(test3), (HashMap<String, Metric>) EasyMock.anyObject());
810         mListener.testStarted(EasyMock.eq(test4));
811         mListener.testEnded(EasyMock.eq(test4), (HashMap<String, Metric>) EasyMock.anyObject());
812         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
813         EasyMock.replay(mListener);
814         mHostTest.run(mListener);
815         EasyMock.verify(mListener);
816     }
817 
818     /**
819      * Test for {@link HostTest#run(ITestInvocationListener)},
820      * for multiple test classes with a method name.
821      */
822     public void testRun_multipleClassAndMethodName() throws Exception {
823         try {
824             OptionSetter setter = new OptionSetter(mHostTest);
825             setter.setOptionValue("class", SuccessTestCase.class.getName());
826             setter.setOptionValue("class", AnotherTestCase.class.getName());
827             mHostTest.setMethodName("testPass3");
828             mHostTest.run(mListener);
829             fail("IllegalArgumentException not thrown");
830         } catch (IllegalArgumentException e) {
831             // expected
832         }
833     }
834 
835     /**
836      * Test for {@link HostTest#run(ITestInvocationListener)}, for a {@link IDeviceTest}.
837      */
838     public void testRun_deviceTest() throws Exception {
839         final ITestDevice device = EasyMock.createMock(ITestDevice.class);
840         mHostTest.setClassName(SuccessDeviceTest.class.getName());
841         mHostTest.setDevice(device);
842         OptionSetter setter = new OptionSetter(mHostTest);
843         setter.setOptionValue("set-option", "option:value");
844 
845         TestDescription test1 = new TestDescription(SuccessDeviceTest.class.getName(), "testPass");
846         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
847         mListener.testStarted(EasyMock.eq(test1));
848         Map<String, String> expected = new HashMap<>();
849         expected.put("option", "value");
850         mListener.testEnded(
851                 EasyMock.eq(test1), EasyMock.eq(TfMetricProtoUtil.upgradeConvert(expected)));
852         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
853         EasyMock.replay(mListener);
854         mHostTest.run(mListener);
855         EasyMock.verify(mListener);
856     }
857 
858     /**
859      * Test for {@link HostTest#run(ITestInvocationListener)},
860      * for a {@link IDeviceTest} where no device has been provided.
861      */
862     public void testRun_missingDevice() throws Exception {
863         mHostTest.setClassName(SuccessDeviceTest.class.getName());
864         mHostTest.setDevice(null);
865         try {
866             mHostTest.run(mListener);
867             fail("expected IllegalArgumentException not thrown");
868         } catch (IllegalArgumentException e) {
869             // expected
870         }
871     }
872 
873     /**
874      * Test for {@link HostTest#countTestCases()}
875      */
876     public void testCountTestCases() throws Exception {
877         mHostTest.setClassName(SuccessTestCase.class.getName());
878         assertEquals("Incorrect test case count", 2, mHostTest.countTestCases());
879     }
880 
881     /** Test for {@link HostTest#countTestCases()} */
882     public void testCountTestCases_dirtyCount() throws Exception {
883         mHostTest.setClassName(SuccessTestCase.class.getName());
884         assertEquals("Incorrect test case count", 2, mHostTest.countTestCases());
885         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
886         mHostTest.addIncludeFilter(test1.toString());
887         assertEquals("Incorrect test case count", 1, mHostTest.countTestCases());
888     }
889 
890     /**
891      * Test for {@link HostTest#countTestCases()} with filtering on JUnit4 tests
892      */
893     public void testCountTestCasesJUnit4WithFiltering() throws Exception {
894         mHostTest.setClassName(Junit4TestClass.class.getName());
895         mHostTest.addIncludeFilter(
896                 "com.android.tradefed.testtype.HostTestTest$Junit4TestClass#testPass5");
897         assertEquals("Incorrect test case count", 1, mHostTest.countTestCases());
898     }
899 
900     /**
901      * Test for {@link HostTest#countTestCases()}, if JUnit4 test class is malformed it will
902      * count as 1 in the total number of tests.
903      */
904     public void testCountTestCasesJUnit4Malformed() throws Exception {
905         mHostTest.setClassName(Junit4MalformedTestClass.class.getName());
906         assertEquals("Incorrect test case count", 1, mHostTest.countTestCases());
907     }
908 
909     /**
910      * Test for {@link HostTest#countTestCases()} with filtering on JUnit4 tests and no test
911      * remain.
912      */
913     public void testCountTestCasesJUnit4WithFiltering_no_more_tests() throws Exception {
914         mHostTest.setClassName(Junit4TestClass.class.getName());
915         mHostTest.addExcludeFilter(
916                 "com.android.tradefed.testtype.HostTestTest$Junit4TestClass#testPass5");
917         mHostTest.addExcludeFilter(
918                 "com.android.tradefed.testtype.HostTestTest$Junit4TestClass#testPass6");
919         assertEquals("Incorrect test case count", 0, mHostTest.countTestCases());
920     }
921 
922     /**
923      * Test for {@link HostTest#countTestCases()} with tests of varying JUnit versions
924      */
925     public void testCountTestCasesJUnitVersionMixed() throws Exception {
926         OptionSetter setter = new OptionSetter(mHostTest);
927         setter.setOptionValue("class", SuccessTestCase.class.getName()); // 2 tests
928         setter.setOptionValue("class", Junit4TestClass.class.getName()); // 2 tests
929         setter.setOptionValue("class", Junit4SuiteClass.class.getName()); // 4 tests
930         assertEquals("Incorrect test case count", 8, mHostTest.countTestCases());
931     }
932 
933     /**
934      * Test for {@link HostTest#countTestCases()} with filtering on tests of varying JUnit versions
935      */
936     public void testCountTestCasesJUnitVersionMixedWithFiltering() throws Exception {
937         OptionSetter setter = new OptionSetter(mHostTest);
938         setter.setOptionValue("class", SuccessTestCase.class.getName()); // 2 tests
939         setter.setOptionValue("class", Junit4TestClass.class.getName()); // 2 tests
940         mHostTest.addIncludeFilter(
941                 "com.android.tradefed.testtype.HostTestTest$SuccessTestCase#testPass");
942         mHostTest.addIncludeFilter(
943                 "com.android.tradefed.testtype.HostTestTest$Junit4TestClass#testPass5");
944         assertEquals("Incorrect test case count", 2, mHostTest.countTestCases());
945     }
946 
947     /**
948      * Test for {@link HostTest#countTestCases()} with annotation filtering
949      */
950     public void testCountTestCasesAnnotationFiltering() throws Exception {
951         mHostTest.setClassName(SuccessTestCase.class.getName());
952         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
953         assertEquals("Incorrect test case count", 1, mHostTest.countTestCases());
954     }
955 
956     /**
957      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
958      * {@link TestCase} with annotation filtering.
959      */
960     public void testRun_testcaseAnnotationFiltering() throws Exception {
961         mHostTest.setClassName(SuccessTestCase.class.getName());
962         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
963         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
964         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
965         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
966         mListener.testStarted(EasyMock.eq(test1));
967         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
968         mListener.testStarted(EasyMock.eq(test2));
969         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
970         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
971         EasyMock.replay(mListener);
972         mHostTest.run(mListener);
973         EasyMock.verify(mListener);
974     }
975 
976     /**
977      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
978      * {@link TestCase} with notAnnotationFiltering
979      */
980     public void testRun_testcaseNotAnnotationFiltering() throws Exception {
981         mHostTest.setClassName(SuccessTestCase.class.getName());
982         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
983         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
984         // Only test1 will run, test2 should be filtered out.
985         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
986         mListener.testStarted(EasyMock.eq(test1));
987         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
988         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
989         EasyMock.replay(mListener);
990         mHostTest.run(mListener);
991         EasyMock.verify(mListener);
992     }
993 
994     /**
995      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
996      * {@link TestCase} with both annotation filtering.
997      */
998     public void testRun_testcaseBothAnnotationFiltering() throws Exception {
999         mHostTest.setClassName(AnotherTestCase.class.getName());
1000         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1001         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1002         TestDescription test4 = new TestDescription(AnotherTestCase.class.getName(), "testPass4");
1003         // Only a test with MyAnnotation and Without MyAnnotation2 will run. Here testPass4
1004         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
1005         mListener.testStarted(EasyMock.eq(test4));
1006         mListener.testEnded(EasyMock.eq(test4), (HashMap<String, Metric>) EasyMock.anyObject());
1007         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1008         EasyMock.replay(mListener);
1009         mHostTest.run(mListener);
1010         EasyMock.verify(mListener);
1011     }
1012 
1013     /**
1014      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
1015      * {@link TestCase} with multiple include annotation, test must contains them all.
1016      */
1017     public void testRun_testcaseMultiInclude() throws Exception {
1018         mHostTest.setClassName(AnotherTestCase.class.getName());
1019         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1020         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1021         TestDescription test3 = new TestDescription(AnotherTestCase.class.getName(), "testPass3");
1022         // Only a test with MyAnnotation and with MyAnnotation2 will run. Here testPass3
1023         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
1024         mListener.testStarted(EasyMock.eq(test3));
1025         mListener.testEnded(EasyMock.eq(test3), (HashMap<String, Metric>) EasyMock.anyObject());
1026         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1027         EasyMock.replay(mListener);
1028         mHostTest.run(mListener);
1029         EasyMock.verify(mListener);
1030     }
1031 
1032     /**
1033      * Test success case for {@link HostTest#shouldTestRun(AnnotatedElement)}, where a class is
1034      * properly annotated to run.
1035      */
1036     public void testRun_shouldTestRun_Success() throws Exception {
1037         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1038         assertTrue(mHostTest.shouldTestRun(SuccessTestCase.class));
1039     }
1040 
1041     /**
1042      * Test success case for {@link HostTest#shouldTestRun(AnnotatedElement)}, where a class is
1043      * properly annotated to run with multiple annotation expected.
1044      */
1045     public void testRun_shouldTestRunMulti_Success() throws Exception {
1046         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1047         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1048         assertTrue(mHostTest.shouldTestRun(AnotherTestCase.class));
1049     }
1050 
1051     /**
1052      * Test case for {@link HostTest#shouldTestRun(AnnotatedElement)}, where a class is
1053      * properly annotated to be filtered.
1054      */
1055     public void testRun_shouldNotRun() throws Exception {
1056         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1057         assertFalse(mHostTest.shouldTestRun(SuccessTestCase.class));
1058     }
1059 
1060     /**
1061      * Test case for {@link HostTest#shouldTestRun(AnnotatedElement)}, where a class is
1062      * properly annotated to be filtered because one of its two annotations is part of the exclude.
1063      */
1064     public void testRun_shouldNotRunMulti() throws Exception {
1065         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1066         assertFalse(mHostTest.shouldTestRun(SuccessTestCase.class));
1067         mHostTest = new HostTest();
1068         // If only the other annotation is excluded.
1069         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1070         assertFalse(mHostTest.shouldTestRun(SuccessTestCase.class));
1071     }
1072 
1073     /**
1074      * Test success case for {@link HostTest#shouldTestRun(AnnotatedElement)}, where a class is
1075      * annotated with a different annotation from the exclude filter.
1076      */
1077     public void testRun_shouldRun_exclude() throws Exception {
1078         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1079         assertTrue(mHostTest.shouldTestRun(SuccessTestCase.class));
1080     }
1081 
1082     /**
1083      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where test to run is a
1084      * {@link TestCase} with annotation filtering.
1085      */
1086     public void testRun_testcaseCollectMode() throws Exception {
1087         mHostTest.setClassName(SuccessTestCase.class.getName());
1088         mHostTest.setCollectTestsOnly(true);
1089         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
1090         mListener.testStarted((TestDescription) EasyMock.anyObject());
1091         mListener.testEnded(
1092                 (TestDescription) EasyMock.anyObject(),
1093                 (HashMap<String, Metric>) EasyMock.anyObject());
1094         mListener.testStarted((TestDescription) EasyMock.anyObject());
1095         mListener.testEnded(
1096                 (TestDescription) EasyMock.anyObject(),
1097                 (HashMap<String, Metric>) EasyMock.anyObject());
1098         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1099         EasyMock.replay(mListener);
1100         mHostTest.run(mListener);
1101         EasyMock.verify(mListener);
1102     }
1103 
1104     /**
1105      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where the
1106      * {@link IRemoteTest} does not implements {@link ITestCollector}
1107      */
1108     public void testRun_testcaseCollectMode_IRemotedevice() throws Exception {
1109         final ITestDevice device = EasyMock.createMock(ITestDevice.class);
1110         mHostTest.setClassName(TestRemoteNotCollector.class.getName());
1111         mHostTest.setDevice(device);
1112         mHostTest.setCollectTestsOnly(true);
1113         EasyMock.replay(mListener);
1114         try {
1115             mHostTest.run(mListener);
1116         } catch (IllegalArgumentException expected) {
1117             EasyMock.verify(mListener);
1118             return;
1119         }
1120         fail("HostTest run() should have thrown an exception.");
1121     }
1122 
1123     /**
1124      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style.
1125      */
1126     public void testRun_junit4style() throws Exception {
1127         mHostTest.setClassName(Junit4TestClass.class.getName());
1128         TestDescription test1 = new TestDescription(Junit4TestClass.class.getName(), "testPass5");
1129         TestDescription test2 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1130         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
1131         mListener.testStarted(EasyMock.eq(test1));
1132         Map<String, String> metrics = new HashMap<>();
1133         metrics.put("key", "value");
1134         mListener.testEnded(test1, TfMetricProtoUtil.upgradeConvert(metrics));
1135         mListener.testStarted(EasyMock.eq(test2));
1136         // test cases do not share metrics.
1137         Map<String, String> metrics2 = new HashMap<>();
1138         metrics2.put("key2", "value2");
1139         mListener.testEnded(
1140                 EasyMock.eq(test2), EasyMock.eq(TfMetricProtoUtil.upgradeConvert(metrics2)));
1141         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1142         EasyMock.replay(mListener);
1143         mHostTest.run(mListener);
1144         EasyMock.verify(mListener);
1145     }
1146 
1147     /**
1148      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style and
1149      * handling of @Ignored.
1150      */
1151     public void testRun_junit4style_ignored() throws Exception {
1152         mHostTest.setClassName(Junit4TestClassWithIgnore.class.getName());
1153         TestDescription test1 =
1154                 new TestDescription(Junit4TestClassWithIgnore.class.getName(), "testPass5");
1155         TestDescription test2 =
1156                 new TestDescription(Junit4TestClassWithIgnore.class.getName(), "testPass6");
1157         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
1158         mListener.testStarted(EasyMock.eq(test1));
1159         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1160         mListener.testStarted(EasyMock.eq(test2));
1161         mListener.testIgnored(EasyMock.eq(test2));
1162         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
1163         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1164         EasyMock.replay(mListener);
1165         mHostTest.run(mListener);
1166         EasyMock.verify(mListener);
1167     }
1168 
1169     /**
1170      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style and
1171      * handling of Assume.
1172      */
1173     public void testRun_junit4style_assumeFailure() throws Exception {
1174         mHostTest.setClassName(JUnit4TestClassAssume.class.getName());
1175         TestDescription test1 =
1176                 new TestDescription(JUnit4TestClassAssume.class.getName(), "testPass5");
1177         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1178         mListener.testStarted(EasyMock.eq(test1));
1179         mListener.testAssumptionFailure(EasyMock.eq(test1), EasyMock.anyObject());
1180         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1181         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1182         EasyMock.replay(mListener);
1183         mHostTest.run(mListener);
1184         EasyMock.verify(mListener);
1185     }
1186 
1187     /**
1188      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style and
1189      * handling of Multiple exception one from @Test one from @After. Junit replay both as failure.
1190      */
1191     public void testRun_junit4style_multiException() throws Exception {
1192         mListener = EasyMock.createStrictMock(ITestInvocationListener.class);
1193         mHostTest.setClassName(JUnit4TestClassMultiException.class.getName());
1194         TestDescription test1 =
1195                 new TestDescription(JUnit4TestClassMultiException.class.getName(), "testPass5");
1196         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1197         mListener.testStarted(EasyMock.eq(test1));
1198         mListener.testFailed(
1199                 EasyMock.eq(test1),
1200                 EasyMock.contains("MultipleFailureException: There were 2 errors:"));
1201         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1202         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1203         EasyMock.replay(mListener);
1204         mHostTest.run(mListener);
1205         EasyMock.verify(mListener);
1206     }
1207 
1208     public void testRun_junit4style_multiException_dnae() throws Exception {
1209         mListener = EasyMock.createStrictMock(ITestInvocationListener.class);
1210         mHostTest.setClassName(JUnit4TestClassMultiExceptionDnae.class.getName());
1211         TestDescription test1 =
1212                 new TestDescription(JUnit4TestClassMultiExceptionDnae.class.getName(), "testPass5");
1213         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1214         mListener.testStarted(EasyMock.eq(test1));
1215         mListener.testFailed(
1216                 EasyMock.eq(test1),
1217                 EasyMock.contains("MultipleFailureException: There were 2 errors:"));
1218         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1219         mListener.testRunFailed(EasyMock.anyObject());
1220         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1221         EasyMock.replay(mListener);
1222         try {
1223             mHostTest.run(mListener);
1224             fail("Should have thrown an exception.");
1225         } catch (DeviceNotAvailableException expected) {
1226 
1227         }
1228         EasyMock.verify(mListener);
1229     }
1230 
1231     /**
1232      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style properly
1233      * pass to the test the {@link IMultiDeviceTest} information.
1234      */
1235     public void testRun_junit4style_multiDevice() throws Exception {
1236         mHostTest.setClassName(Junit4TestClassMulti.class.getName());
1237         mHostTest.setDeviceInfos(new HashMap<>());
1238         TestDescription test1 =
1239                 new TestDescription(Junit4TestClassMulti.class.getName(), "testPass5");
1240         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1241         mListener.testStarted(EasyMock.eq(test1));
1242         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1243         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1244         EasyMock.replay(mListener);
1245         mHostTest.run(mListener);
1246         EasyMock.verify(mListener);
1247     }
1248 
1249     /**
1250      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style and with
1251      * method filtering. Only run the expected method.
1252      */
1253     public void testRun_junit4_withMethodFilter() throws Exception {
1254         mHostTest.setClassName(Junit4TestClass.class.getName());
1255         TestDescription test2 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1256         mHostTest.setMethodName("testPass6");
1257         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
1258         mListener.testStarted(EasyMock.eq(test2));
1259         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
1260         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1261         EasyMock.replay(mListener);
1262         mHostTest.run(mListener);
1263         EasyMock.verify(mListener);
1264     }
1265 
1266     /**
1267      * Test for {@link HostTest#run(ITestInvocationListener)}, for a mix of test junit3 and 4
1268      */
1269     public void testRun_junit_version_mix() throws Exception {
1270         OptionSetter setter = new OptionSetter(mHostTest);
1271         setter.setOptionValue("class", SuccessTestCase.class.getName());
1272         setter.setOptionValue("class", Junit4TestClass.class.getName());
1273         runMixJunitTest(mHostTest, 2, 2);
1274     }
1275 
1276     /**
1277      * Test for {@link HostTest#run(ITestInvocationListener)}, for a mix of test junit3 and 4 in
1278      * collect only mode
1279      */
1280     public void testRun_junit_version_mix_collect() throws Exception {
1281         OptionSetter setter = new OptionSetter(mHostTest);
1282         setter.setOptionValue("class", SuccessTestCase.class.getName());
1283         setter.setOptionValue("class", Junit4TestClass.class.getName());
1284         setter.setOptionValue("collect-tests-only", "true");
1285         runMixJunitTest(mHostTest, 2, 2);
1286     }
1287 
1288     /**
1289      * Test for {@link HostTest#run(ITestInvocationListener)}, for a mix of test junit3 and 4 in
1290      * a Junit 4 suite class.
1291      */
1292     public void testRun_junit_suite_mix() throws Exception {
1293         OptionSetter setter = new OptionSetter(mHostTest);
1294         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1295         runMixJunitTest(mHostTest, 4, 1);
1296     }
1297 
1298     /**
1299      * Test for {@link HostTest#run(ITestInvocationListener)}, for a mix of test junit3 and 4 in
1300      * a Junit 4 suite class, in collect only mode.
1301      */
1302     public void testRun_junit_suite_mix_collect() throws Exception {
1303         OptionSetter setter = new OptionSetter(mHostTest);
1304         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1305         setter.setOptionValue("collect-tests-only", "true");
1306         runMixJunitTest(mHostTest, 4, 1);
1307     }
1308 
1309     /**
1310      * Helper for test option variation and avoid repeating the same setup
1311      */
1312     private void runMixJunitTest(HostTest hostTest, int expectedTest, int expectedRun)
1313             throws Exception {
1314         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
1315         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
1316         TestDescription test3 = new TestDescription(Junit4TestClass.class.getName(), "testPass5");
1317         TestDescription test4 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1318         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(expectedTest));
1319         EasyMock.expectLastCall().times(expectedRun);
1320         mListener.testStarted(EasyMock.eq(test1));
1321         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1322         mListener.testStarted(EasyMock.eq(test2));
1323         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
1324         mListener.testStarted(EasyMock.eq(test3));
1325         mListener.testEnded(EasyMock.eq(test3), (HashMap<String, Metric>) EasyMock.anyObject());
1326         mListener.testStarted(EasyMock.eq(test4));
1327         mListener.testEnded(EasyMock.eq(test4), (HashMap<String, Metric>) EasyMock.anyObject());
1328         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1329         EasyMock.expectLastCall().times(expectedRun);
1330         EasyMock.replay(mListener);
1331         hostTest.run(mListener);
1332         EasyMock.verify(mListener);
1333     }
1334 
1335     /**
1336      * Test success case for {@link HostTest#run(ITestInvocationListener)} with a filtering and
1337      * junit 4 handling.
1338      */
1339     public void testRun_testcase_Junit4TestNotAnnotationFiltering() throws Exception {
1340         mHostTest.setClassName(Junit4TestClass.class.getName());
1341         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1342         OptionSetter setter = new OptionSetter(mHostTest);
1343         setter.setOptionValue("set-option", "junit4-option:true");
1344         TestDescription test1 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1345         // Only test1 will run, test2 should be filtered out.
1346         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
1347         mListener.testStarted(EasyMock.eq(test1));
1348         Map<String, String> metrics = new HashMap<>();
1349         metrics.put("key2", "value2");
1350         // If the option was correctly set, this metric should be true.
1351         metrics.put("junit4-option", "true");
1352         mListener.testEnded(
1353                 EasyMock.eq(test1), EasyMock.eq(TfMetricProtoUtil.upgradeConvert(metrics)));
1354         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1355         EasyMock.replay(mListener);
1356         mHostTest.run(mListener);
1357         EasyMock.verify(mListener);
1358     }
1359 
1360     /**
1361      * Test success case for {@link HostTest#run(ITestInvocationListener)} when passing a dedicated
1362      * option to it.
1363      */
1364     public void testRun_testcase_TargetedOptionPassing() throws Exception {
1365         mHostTest.setClassName(Junit4TestClass.class.getName());
1366         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1367         OptionSetter setter = new OptionSetter(mHostTest);
1368         setter.setOptionValue(
1369                 "set-option", Junit4TestClass.class.getName() + ":junit4-option:true");
1370         setter.setOptionValue(
1371                 "set-option", Junit4TestClass.class.getName() + ":map-option:key=test");
1372         TestDescription test1 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1373         // Only test1 will run, test2 should be filtered out.
1374         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1375         mListener.testStarted(EasyMock.eq(test1));
1376         Map<String, String> metrics = new HashMap<>();
1377         metrics.put("key2", "value2");
1378         // If the option was correctly set, this metric should be true.
1379         metrics.put("junit4-option", "true");
1380         metrics.put("map-option", "[test]");
1381         mListener.testEnded(
1382                 EasyMock.eq(test1), EasyMock.eq(TfMetricProtoUtil.upgradeConvert(metrics)));
1383         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1384         EasyMock.replay(mListener);
1385         mHostTest.run(mListener);
1386         EasyMock.verify(mListener);
1387     }
1388 
1389     /**
1390      * Test success case for {@link HostTest#run(ITestInvocationListener)} when passing a dedicated
1391      * option to it. The class without the option doesn't throw an exception since it's not
1392      * targeted.
1393      */
1394     public void testRun_testcase_multiTargetedOptionPassing() throws Exception {
1395         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1396         OptionSetter setter = new OptionSetter(mHostTest);
1397         setter.setOptionValue("class", Junit4TestClass.class.getName());
1398         setter.setOptionValue("class", Junit4TestLogClass.class.getName());
1399         setter.setOptionValue(
1400                 "set-option", Junit4TestClass.class.getName() + ":junit4-option:true");
1401 
1402         TestDescription test1 =
1403                 new TestDescription(Junit4TestLogClass.class.getName(), "testPass1");
1404         TestDescription test2 =
1405                 new TestDescription(Junit4TestLogClass.class.getName(), "testPass2");
1406         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
1407         mListener.testStarted(EasyMock.eq(test1));
1408         mListener.testLog(EasyMock.eq("TEST"), EasyMock.eq(LogDataType.TEXT), EasyMock.anyObject());
1409         mListener.testEnded(test1, new HashMap<String, Metric>());
1410         mListener.testStarted(EasyMock.eq(test2));
1411         // test cases do not share logs, only the second test logs are seen.
1412         mListener.testLog(
1413                 EasyMock.eq("TEST2"), EasyMock.eq(LogDataType.TEXT), EasyMock.anyObject());
1414         mListener.testEnded(test2, new HashMap<String, Metric>());
1415         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1416 
1417         TestDescription test6 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1418         // Only test1 will run, test2 should be filtered out.
1419         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1420         mListener.testStarted(EasyMock.eq(test6));
1421         Map<String, String> metrics = new HashMap<>();
1422         metrics.put("key2", "value2");
1423         // If the option was correctly set, this metric should be true.
1424         metrics.put("junit4-option", "true");
1425         mListener.testEnded(
1426                 EasyMock.eq(test6), EasyMock.eq(TfMetricProtoUtil.upgradeConvert(metrics)));
1427         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1428         EasyMock.replay(mListener);
1429         mHostTest.run(mListener);
1430         EasyMock.verify(mListener);
1431     }
1432 
1433     /**
1434      * Test success case for {@link HostTest#run(ITestInvocationListener)}, where filtering is
1435      * applied and results in 0 tests to run.
1436      */
1437     public void testRun_testcase_Junit4Test_filtering_no_more_tests() throws Exception {
1438         mHostTest.setClassName(Junit4TestClass.class.getName());
1439         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1440         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(0));
1441         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1442         EasyMock.replay(mListener);
1443         mHostTest.run(mListener);
1444         EasyMock.verify(mListener);
1445     }
1446 
1447     /**
1448      * Test that in case the class attempted to be ran is malformed we bubble up the test failure.
1449      */
1450     public void testRun_Junit4Test_malformed() throws Exception {
1451         mHostTest.setClassName(Junit4MalformedTestClass.class.getName());
1452         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(1));
1453         Capture<TestDescription> captured = new Capture<>();
1454         mListener.testStarted(EasyMock.capture(captured));
1455         mListener.testFailed((TestDescription) EasyMock.anyObject(), (String) EasyMock.anyObject());
1456         mListener.testEnded(
1457                 (TestDescription) EasyMock.anyObject(),
1458                 (HashMap<String, Metric>) EasyMock.anyObject());
1459         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1460         EasyMock.replay(mListener);
1461         mHostTest.run(mListener);
1462         assertEquals(Junit4MalformedTestClass.class.getName(), captured.getValue().getClassName());
1463         assertEquals("initializationError", captured.getValue().getTestName());
1464         EasyMock.verify(mListener);
1465     }
1466 
1467     /**
1468      * Test for {@link HostTest#run(ITestInvocationListener)}, for a mix of test junit3 and 4 in
1469      * a Junit 4 suite class, and filtering is applied.
1470      */
1471     public void testRun_junit_suite_mix_filtering() throws Exception {
1472         OptionSetter setter = new OptionSetter(mHostTest);
1473         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1474         runMixJunitTestWithFilter(mHostTest);
1475     }
1476 
1477     /**
1478      * Test for {@link HostTest#run(ITestInvocationListener)}, for a mix of test junit3 and 4 in
1479      * a Junit 4 suite class, and filtering is applied, in collect mode
1480      */
1481     public void testRun_junit_suite_mix_filtering_collect() throws Exception {
1482         OptionSetter setter = new OptionSetter(mHostTest);
1483         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1484         setter.setOptionValue("collect-tests-only", "true");
1485         runMixJunitTestWithFilter(mHostTest);
1486     }
1487 
1488     /**
1489      * Helper for test option variation and avoid repeating the same setup
1490      */
1491     private void runMixJunitTestWithFilter(HostTest hostTest) throws Exception {
1492         hostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation2");
1493         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
1494         TestDescription test4 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1495         mListener.testRunStarted((String)EasyMock.anyObject(), EasyMock.eq(2));
1496         EasyMock.expectLastCall().times(1);
1497         mListener.testStarted(EasyMock.eq(test1));
1498         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1499         mListener.testStarted(EasyMock.eq(test4));
1500         mListener.testEnded(EasyMock.eq(test4), (HashMap<String, Metric>) EasyMock.anyObject());
1501         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1502         EasyMock.expectLastCall().times(1);
1503         EasyMock.replay(mListener);
1504         hostTest.run(mListener);
1505         EasyMock.verify(mListener);
1506     }
1507 
1508     /**
1509      * Test for {@link HostTest#split(int)} making sure each test type is properly handled and added
1510      * with a container or directly.
1511      */
1512     public void testRun_junit_suite_split() throws Exception {
1513         OptionSetter setter = new OptionSetter(mHostTest);
1514         mHostTest.setDevice(mMockDevice);
1515         mHostTest.setBuild(mMockBuildInfo);
1516         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1517         setter.setOptionValue("class", SuccessTestSuite.class.getName());
1518         setter.setOptionValue("class", TestRemoteNotCollector.class.getName());
1519         List<IRemoteTest> list = (ArrayList<IRemoteTest>) mHostTest.split(1);
1520         // split by class; numShards parameter should be ignored
1521         assertEquals(3, list.size());
1522         assertEquals(
1523                 "com.android.tradefed.testtype.HostTestTest$TestableHostTest",
1524                 list.get(0).getClass().getName());
1525         assertEquals(
1526                 "com.android.tradefed.testtype.HostTestTest$TestableHostTest",
1527                 list.get(1).getClass().getName());
1528         assertEquals(
1529                 "com.android.tradefed.testtype.HostTestTest$TestableHostTest",
1530                 list.get(2).getClass().getName());
1531 
1532         // We expect all the test from the JUnit4 suite to run under the original suite classname
1533         // not under the container class name.
1534         mListener.testRunStarted(
1535                 EasyMock.eq("com.android.tradefed.testtype.HostTestTest$Junit4SuiteClass"),
1536                 EasyMock.eq(4));
1537         TestDescription test1 = new TestDescription(Junit4TestClass.class.getName(), "testPass5");
1538         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
1539         TestDescription test3 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
1540         TestDescription test4 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
1541         mListener.testStarted(test1);
1542         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1543         mListener.testStarted(EasyMock.eq(test2));
1544         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
1545         mListener.testStarted(EasyMock.eq(test3));
1546         mListener.testEnded(EasyMock.eq(test3), (HashMap<String, Metric>) EasyMock.anyObject());
1547         mListener.testStarted(EasyMock.eq(test4));
1548         mListener.testEnded(EasyMock.eq(test4), (HashMap<String, Metric>) EasyMock.anyObject());
1549         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1550         EasyMock.replay(mListener);
1551         // Run the JUnit4 Container
1552         ((IBuildReceiver)list.get(0)).setBuild(mMockBuildInfo);
1553         ((IDeviceTest)list.get(0)).setDevice(mMockDevice);
1554         list.get(0).run(mListener);
1555         EasyMock.verify(mListener);
1556     }
1557 
1558     /**
1559      * Similar to {@link #testRun_junit_suite_split()} but with shard-unit set to method
1560      */
1561     public void testRun_junit_suite_split_by_method() throws Exception {
1562         OptionSetter setter = new OptionSetter(mHostTest);
1563         mHostTest.setDevice(mMockDevice);
1564         mHostTest.setBuild(mMockBuildInfo);
1565         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1566         setter.setOptionValue("class", SuccessTestSuite.class.getName());
1567         setter.setOptionValue("class", TestRemoteNotCollector.class.getName());
1568         setter.setOptionValue("shard-unit", "method");
1569         final Class<?>[] expectedTestCaseClasses = new Class<?>[] {
1570             Junit4TestClass.class,
1571             Junit4TestClass.class,
1572             SuccessTestCase.class,
1573             SuccessTestCase.class,
1574             SuccessTestSuite.class,
1575             SuccessTestSuite.class,
1576             TestRemoteNotCollector.class,
1577         };
1578         List<IRemoteTest> list = (ArrayList<IRemoteTest>) mHostTest.split(expectedTestCaseClasses.length);
1579         assertEquals(expectedTestCaseClasses.length, list.size());
1580         for (int i = 0; i < expectedTestCaseClasses.length; i++) {
1581             IRemoteTest shard = list.get(i);
1582             assertTrue(HostTest.class.isInstance(shard));
1583             HostTest hostTest = (HostTest)shard;
1584             assertEquals(1, hostTest.getClasses().size());
1585             assertEquals(1, hostTest.countTestCases());
1586             assertEquals(expectedTestCaseClasses[i], hostTest.getClasses().get(0));
1587         }
1588 
1589         // We expect all the test from the JUnit4 suite to run under the original suite classname
1590         // not under the container class name.
1591         TestDescription test = new TestDescription(Junit4TestClass.class.getName(), "testPass5");
1592         mListener.testRunStarted(test.getClassName(), 1);
1593         mListener.testStarted(test);
1594         mListener.testEnded(EasyMock.eq(test), (HashMap<String, Metric>) EasyMock.anyObject());
1595         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1596         EasyMock.replay(mListener);
1597         // Run the JUnit4 Container
1598         ((IBuildReceiver)list.get(0)).setBuild(mMockBuildInfo);
1599         ((IDeviceTest)list.get(0)).setDevice(mMockDevice);
1600         list.get(0).run(mListener);
1601         EasyMock.verify(mListener);
1602     }
1603 
1604     /**
1605      * Test for {@link HostTest#split(int)} when no class is specified throws an exception
1606      */
1607     public void testSplit_noClass() throws Exception {
1608         try {
1609             mHostTest.split(1);
1610             fail("Should have thrown an exception");
1611         } catch (IllegalArgumentException e) {
1612             assertEquals("Missing Test class name", e.getMessage());
1613         }
1614     }
1615 
1616     /**
1617      * Test for {@link HostTest#split(int)} when multiple classes are specified with a method option
1618      * too throws an exception
1619      */
1620     public void testSplit_methodAndMultipleClass() throws Exception {
1621         OptionSetter setter = new OptionSetter(mHostTest);
1622         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1623         setter.setOptionValue("class", SuccessTestSuite.class.getName());
1624         mHostTest.setMethodName("testPass2");
1625         try {
1626             mHostTest.split(1);
1627             fail("Should have thrown an exception");
1628         } catch (IllegalArgumentException e) {
1629             assertEquals("Method name given with multiple test classes", e.getMessage());
1630         }
1631     }
1632 
1633     /**
1634      * Test for {@link HostTest#split(int)} when a single class is specified, no splitting can occur
1635      * and it returns null.
1636      */
1637     public void testSplit_singleClass() throws Exception {
1638         OptionSetter setter = new OptionSetter(mHostTest);
1639         setter.setOptionValue("class", SuccessTestSuite.class.getName());
1640         mHostTest.setMethodName("testPass2");
1641         assertNull(mHostTest.split(1));
1642     }
1643 
1644     /** Test {@link IShardableTest} interface and check the sharding is correct. */
1645     public void testGetTestShardable_wrapping_shardUnit_method() throws Exception {
1646         final ITestDevice device = EasyMock.createMock(ITestDevice.class);
1647         mHostTest.setDevice(device);
1648         OptionSetter setter = new OptionSetter(mHostTest);
1649         setter.setOptionValue("class", Junit4SuiteClass.class.getName());
1650         setter.setOptionValue("class", SuccessTestSuite.class.getName());
1651         setter.setOptionValue("class", TestRemoteNotCollector.class.getName());
1652         setter.setOptionValue("class", SuccessHierarchySuite.class.getName());
1653         setter.setOptionValue("class", SuccessDeviceTest.class.getName());
1654         setter.setOptionValue("runtime-hint", "2m");
1655         setter.setOptionValue("shard-unit", "method");
1656         final Class<?>[] expectedTestCaseClasses = new Class<?>[] {
1657             Junit4TestClass.class,
1658             SuccessTestCase.class,
1659             TestRemoteNotCollector.class,
1660             SuccessDeviceTest.class,
1661             Junit4TestClass.class,
1662             SuccessTestSuite.class,
1663             SuccessHierarchySuite.class,
1664             SuccessTestCase.class,
1665             SuccessTestSuite.class,
1666             SuccessHierarchySuite.class,
1667         };
1668         final int numShards = 3;
1669         final long runtimeHint = 2 * 60 * 1000; // 2 minutes in microseconds
1670         int numTestCases = mHostTest.countTestCases();
1671         assertEquals(expectedTestCaseClasses.length, numTestCases);
1672         for (int i = 0, j = 0; i < numShards ; i++) {
1673             IRemoteTest shard;
1674             shard = new ArrayList<>(mHostTest.split(numShards)).get(i);
1675             assertTrue(shard instanceof HostTest);
1676             HostTest hostTest = (HostTest)shard;
1677             int q = numTestCases / numShards;
1678             int r = numTestCases % numShards;
1679             int n = q + (i < r ? 1 : 0);
1680             assertEquals(n, hostTest.countTestCases());
1681             assertEquals(n, hostTest.getClasses().size());
1682             assertEquals(runtimeHint * n / numTestCases, hostTest.getRuntimeHint());
1683             for (int k = 0; k < n; k++) {
1684                 assertEquals(expectedTestCaseClasses[j++], hostTest.getClasses().get(k));
1685             }
1686         }
1687     }
1688 
1689     /** An annotation on the class exclude it. All the method of the class should be excluded. */
1690     public void testClassAnnotation_excludeAll() throws Exception {
1691         mHostTest.setClassName(SuccessTestCase.class.getName());
1692         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1693         assertEquals(0, mHostTest.countTestCases());
1694         // nothing run.
1695         EasyMock.replay(mListener);
1696         mHostTest.run(mListener);
1697         EasyMock.verify(mListener);
1698     }
1699 
1700     /** An annotation on the class include it. We include all the method inside it. */
1701     public void testClassAnnotation_includeAll() throws Exception {
1702         mHostTest.setClassName(SuccessTestCase.class.getName());
1703         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1704         assertEquals(2, mHostTest.countTestCases());
1705         TestDescription test1 = new TestDescription(SuccessTestCase.class.getName(), "testPass");
1706         TestDescription test2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
1707         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
1708         mListener.testStarted(EasyMock.eq(test1));
1709         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1710         mListener.testStarted(EasyMock.eq(test2));
1711         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
1712         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1713         EasyMock.replay(mListener);
1714         mHostTest.run(mListener);
1715         EasyMock.verify(mListener);
1716     }
1717 
1718     /**
1719      * An annotation on the method (no annotation on class) exclude it. This method does not run.
1720      */
1721     public void testMethodAnnotation_excludeAll() throws Exception {
1722         mHostTest.setClassName(AnotherTestCase.class.getName());
1723         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1724         assertEquals(1, mHostTest.countTestCases());
1725         TestDescription test1 = new TestDescription(AnotherTestCase.class.getName(), "testPass4");
1726         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1727         mListener.testStarted(EasyMock.eq(test1));
1728         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1729         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1730         EasyMock.replay(mListener);
1731         mHostTest.run(mListener);
1732         EasyMock.verify(mListener);
1733     }
1734 
1735     /** An annotation on the method (no annotation on class) include it. Only this method run. */
1736     public void testMethodAnnotation_includeAll() throws Exception {
1737         mHostTest.setClassName(AnotherTestCase.class.getName());
1738         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1739         assertEquals(1, mHostTest.countTestCases());
1740         TestDescription test1 = new TestDescription(AnotherTestCase.class.getName(), "testPass3");
1741         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1742         mListener.testStarted(EasyMock.eq(test1));
1743         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1744         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1745         EasyMock.replay(mListener);
1746         mHostTest.run(mListener);
1747         EasyMock.verify(mListener);
1748     }
1749 
1750     /**
1751      * Check that a method annotation in a {@link DeviceTestCase} is properly included with an
1752      * include filter during collect-tests-only
1753      */
1754     public void testMethodAnnotation_includeAll_collect() throws Exception {
1755         mHostTest.setCollectTestsOnly(true);
1756         mHostTest.setClassName(SuccessDeviceTest2.class.getName());
1757         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1758         assertEquals(1, mHostTest.countTestCases());
1759         TestDescription test1 =
1760                 new TestDescription(SuccessDeviceTest2.class.getName(), "testPass1");
1761         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1762         mListener.testStarted(EasyMock.eq(test1));
1763         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1764         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1765         EasyMock.replay(mListener);
1766         mHostTest.run(mListener);
1767         EasyMock.verify(mListener);
1768     }
1769 
1770     /**
1771      * Test that a method annotated and overridden is not included because the child method is not
1772      * annotated (annotation are not inherited).
1773      */
1774     public void testMethodAnnotation_inherited() throws Exception {
1775         mHostTest.setCollectTestsOnly(true);
1776         mHostTest.setClassName(InheritedDeviceTest3.class.getName());
1777         mHostTest.addIncludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1778         assertEquals(1, mHostTest.countTestCases());
1779         TestDescription test1 =
1780                 new TestDescription(InheritedDeviceTest3.class.getName(), "testPass3");
1781         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(1));
1782         mListener.testStarted(EasyMock.eq(test1));
1783         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1784         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1785         EasyMock.replay(mListener);
1786         mHostTest.run(mListener);
1787         EasyMock.verify(mListener);
1788     }
1789 
1790     /**
1791      * Test that a method annotated and overridden is not excluded if the child method does not have
1792      * the annotation.
1793      */
1794     public void testMethodAnnotation_inherited_exclude() throws Exception {
1795         mHostTest.setCollectTestsOnly(true);
1796         mHostTest.setClassName(InheritedDeviceTest3.class.getName());
1797         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation3");
1798         assertEquals(2, mHostTest.countTestCases());
1799         TestDescription test1 =
1800                 new TestDescription(InheritedDeviceTest3.class.getName(), "testPass1");
1801         TestDescription test2 =
1802                 new TestDescription(InheritedDeviceTest3.class.getName(), "testPass2");
1803         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
1804         mListener.testStarted(EasyMock.eq(test1));
1805         mListener.testEnded(EasyMock.eq(test1), (HashMap<String, Metric>) EasyMock.anyObject());
1806         mListener.testStarted(EasyMock.eq(test2));
1807         mListener.testEnded(EasyMock.eq(test2), (HashMap<String, Metric>) EasyMock.anyObject());
1808         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1809         EasyMock.replay(mListener);
1810         mHostTest.run(mListener);
1811         EasyMock.verify(mListener);
1812     }
1813 
1814     /** Check that a {@link DeviceTestCase} is properly excluded when the class is excluded. */
1815     public void testDeviceTestCase_excludeClass() throws Exception {
1816         mHostTest.setClassName(SuccessDeviceTest2.class.getName());
1817         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1818         assertEquals(0, mHostTest.countTestCases());
1819         EasyMock.replay(mListener);
1820         mHostTest.run(mListener);
1821         EasyMock.verify(mListener);
1822     }
1823 
1824     /**
1825      * Check that a {@link DeviceTestCase} is properly excluded when the class is excluded in
1826      * collect-tests-only mode (yielding the same result as above).
1827      */
1828     public void testDeviceTestCase_excludeClass_collect() throws Exception {
1829         mHostTest.setCollectTestsOnly(true);
1830         mHostTest.setClassName(SuccessDeviceTest2.class.getName());
1831         mHostTest.addExcludeAnnotation("com.android.tradefed.testtype.HostTestTest$MyAnnotation");
1832         assertEquals(0, mHostTest.countTestCases());
1833         EasyMock.replay(mListener);
1834         mHostTest.run(mListener);
1835         EasyMock.verify(mListener);
1836     }
1837 
1838     /**
1839      * Test for {@link HostTest#split(int)} when the exclude-filter is set, it should be carried over
1840      * to shards.
1841      */
1842     public void testSplit_withExclude() throws Exception {
1843         OptionSetter setter = new OptionSetter(mHostTest);
1844         setter.setOptionValue("class", SuccessTestCase.class.getName());
1845         setter.setOptionValue("class", AnotherTestCase.class.getName());
1846         mHostTest.addExcludeFilter(
1847                 "com.android.tradefed.testtype.HostTestTest$SuccessTestCase#testPass");
1848         Collection<IRemoteTest> res = mHostTest.split(1);
1849         // split by class; numShards parameter should be ignored
1850         assertEquals(2, res.size());
1851 
1852         // only one tests in the SuccessTestCase because it's been filtered out.
1853         mListener.testRunStarted(
1854                 EasyMock.eq("com.android.tradefed.testtype.HostTestTest$SuccessTestCase"),
1855                 EasyMock.eq(1));
1856         TestDescription tid2 =
1857                 new TestDescription(
1858                         "com.android.tradefed.testtype.HostTestTest$SuccessTestCase", "testPass2");
1859         mListener.testStarted(tid2);
1860         mListener.testEnded(tid2, new HashMap<String, Metric>());
1861         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1862 
1863         mListener.testRunStarted(
1864                 EasyMock.eq("com.android.tradefed.testtype.HostTestTest$AnotherTestCase"),
1865                 EasyMock.eq(2));
1866         TestDescription tid3 =
1867                 new TestDescription(
1868                         "com.android.tradefed.testtype.HostTestTest$AnotherTestCase", "testPass3");
1869         mListener.testStarted(tid3);
1870         mListener.testEnded(tid3, new HashMap<String, Metric>());
1871         TestDescription tid4 =
1872                 new TestDescription(
1873                         "com.android.tradefed.testtype.HostTestTest$AnotherTestCase", "testPass4");
1874         mListener.testStarted(tid4);
1875         mListener.testEnded(tid4, new HashMap<String, Metric>());
1876         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1877 
1878         EasyMock.replay(mListener, mMockDevice);
1879         for (IRemoteTest test : res) {
1880             assertTrue(test instanceof HostTest);
1881             ((HostTest) test).setDevice(mMockDevice);
1882             test.run(mListener);
1883         }
1884         EasyMock.verify(mListener, mMockDevice);
1885     }
1886 
1887     /**
1888      * Test that when the 'set-option' format is not respected, an exception is thrown. Only one '='
1889      * is allowed in the value.
1890      */
1891     public void testRun_setOption_invalid() throws Exception {
1892         OptionSetter setter = new OptionSetter(mHostTest);
1893         // Map option with invalid format
1894         setter.setOptionValue("set-option", "map-option:key=value=2");
1895         mHostTest.setClassName(TestMetricTestCase.class.getName());
1896         EasyMock.replay(mListener);
1897         try {
1898             mHostTest.run(mListener);
1899             fail("Should have thrown an exception.");
1900         } catch (RuntimeException expected) {
1901             // expected
1902         }
1903         EasyMock.verify(mListener);
1904     }
1905 
1906     /**
1907      * Test that when a JUnit runner implements {@link ISetOptionReceiver} we attempt to pass it the
1908      * hostTest set-option.
1909      */
1910     public void testSetOption_regularJUnit4_fail() throws Exception {
1911         OptionSetter setter = new OptionSetter(mHostTest);
1912         // Map option with invalid format
1913         setter.setOptionValue("set-option", "option:value");
1914         mHostTest.setClassName(Junit4RegularClass.class.getName());
1915         mListener.testRunStarted(
1916                 EasyMock.eq("com.android.tradefed.testtype.HostTestTest$Junit4RegularClass"),
1917                 EasyMock.eq(1));
1918         mListener.testRunEnded(EasyMock.anyLong(), EasyMock.<HashMap<String, Metric>>anyObject());
1919         EasyMock.replay(mListener);
1920         try {
1921             mHostTest.run(mListener);
1922             fail("Should have thrown an exception.");
1923         } catch (RuntimeException expected) {
1924             // expected
1925         }
1926         EasyMock.verify(mListener);
1927     }
1928 
1929     /**
1930      * Test for {@link HostTest#run(ITestInvocationListener)}, for test with Junit4 style that log
1931      * some data.
1932      */
1933     public void testRun_junit4style_log() throws Exception {
1934         mHostTest.setClassName(Junit4TestLogClass.class.getName());
1935         TestDescription test1 =
1936                 new TestDescription(Junit4TestLogClass.class.getName(), "testPass1");
1937         TestDescription test2 =
1938                 new TestDescription(Junit4TestLogClass.class.getName(), "testPass2");
1939         mListener.testRunStarted((String) EasyMock.anyObject(), EasyMock.eq(2));
1940         mListener.testStarted(EasyMock.eq(test1));
1941         mListener.testLog(EasyMock.eq("TEST"), EasyMock.eq(LogDataType.TEXT), EasyMock.anyObject());
1942         mListener.testEnded(test1, new HashMap<String, Metric>());
1943         mListener.testStarted(EasyMock.eq(test2));
1944         // test cases do not share logs, only the second test logs are seen.
1945         mListener.testLog(
1946                 EasyMock.eq("TEST2"), EasyMock.eq(LogDataType.TEXT), EasyMock.anyObject());
1947         mListener.testEnded(test2, new HashMap<String, Metric>());
1948         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
1949         EasyMock.replay(mListener);
1950         mHostTest.run(mListener);
1951         EasyMock.verify(mListener);
1952     }
1953 
1954     /**
1955      * Similar to {@link #testSplit_withExclude()} but with shard-unit set to method
1956      */
1957     public void testSplit_excludeTestCase_shardUnit_method() throws Exception {
1958         OptionSetter setter = new OptionSetter(mHostTest);
1959         setter.setOptionValue("class", SuccessTestCase.class.getName());
1960         setter.setOptionValue("class", AnotherTestCase.class.getName());
1961 
1962         // only one tests in the SuccessTestCase because it's been filtered out.
1963         TestDescription tid2 = new TestDescription(SuccessTestCase.class.getName(), "testPass2");
1964         TestDescription tid3 = new TestDescription(AnotherTestCase.class.getName(), "testPass3");
1965         TestDescription tid4 = new TestDescription(AnotherTestCase.class.getName(), "testPass4");
1966         testSplit_excludeFilter_shardUnit_Method(
1967                 SuccessTestCase.class.getName() + "#testPass",
1968                 new TestDescription[] {tid2, tid3, tid4});
1969     }
1970 
1971     /**
1972      * Similar to {@link #testSplit_excludeTestCase_shardUnit_method()} but exclude class
1973      */
1974     public void testSplit_excludeTestClass_shardUnit_method() throws Exception {
1975         OptionSetter setter = new OptionSetter(mHostTest);
1976         setter.setOptionValue("class", SuccessTestCase.class.getName());
1977         setter.setOptionValue("class", AnotherTestCase.class.getName());
1978 
1979         TestDescription tid3 = new TestDescription(AnotherTestCase.class.getName(), "testPass3");
1980         TestDescription tid4 = new TestDescription(AnotherTestCase.class.getName(), "testPass4");
1981         testSplit_excludeFilter_shardUnit_Method(
1982                 SuccessTestCase.class.getName(), new TestDescription[] {tid3, tid4});
1983     }
1984 
1985     private void testSplit_excludeFilter_shardUnit_Method(
1986             String excludeFilter, TestDescription[] expectedTids)
1987             throws DeviceNotAvailableException, ConfigurationException {
1988         mHostTest.addExcludeFilter(excludeFilter);
1989         OptionSetter setter = new OptionSetter(mHostTest);
1990         setter.setOptionValue("shard-unit", "method");
1991 
1992         Collection<IRemoteTest> res = mHostTest.split(expectedTids.length);
1993         assertEquals(expectedTids.length, res.size());
1994 
1995         for (TestDescription tid : expectedTids) {
1996             mListener.testRunStarted(tid.getClassName(), 1);
1997             mListener.testStarted(tid);
1998             mListener.testEnded(tid, new HashMap<String, Metric>());
1999             mListener.testRunEnded(
2000                     EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
2001         }
2002 
2003         EasyMock.replay(mListener, mMockDevice);
2004         for (IRemoteTest test : res) {
2005             assertTrue(test instanceof HostTest);
2006             ((HostTest) test).setDevice(mMockDevice);
2007             test.run(mListener);
2008         }
2009         EasyMock.verify(mListener, mMockDevice);
2010     }
2011 
2012     /** JUnit 4 class that throws within its @BeforeClass */
2013     @RunWith(JUnit4.class)
2014     public static class JUnit4FailedBeforeClass {
2015         @BeforeClass
2016         public static void beforeClass() {
2017             throw new RuntimeException();
2018         }
2019 
2020         @org.junit.Test
2021         public void test1() {}
2022     }
2023 
2024     /**
2025      * Test that when an exception is thrown from within @BeforeClass, we correctly report a failure
2026      * since we cannot run each individual test.
2027      */
2028     public void testRun_junit4ExceptionBeforeClass() throws Exception {
2029         OptionSetter setter = new OptionSetter(mHostTest);
2030         setter.setOptionValue("class", JUnit4FailedBeforeClass.class.getName());
2031         setter.setOptionValue("class", Junit4TestClass.class.getName());
2032         // First class fail with the run failure
2033         mListener.testRunStarted(EasyMock.anyObject(), EasyMock.eq(1));
2034         mListener.testRunFailed(EasyMock.contains("Failed with trace:"));
2035         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
2036 
2037         // Second class run properly
2038         mListener.testRunStarted(EasyMock.anyObject(), EasyMock.eq(2));
2039         TestDescription tid2 = new TestDescription(Junit4TestClass.class.getName(), "testPass5");
2040         mListener.testStarted(EasyMock.eq(tid2));
2041         mListener.testEnded(EasyMock.eq(tid2), (HashMap<String, Metric>) EasyMock.anyObject());
2042         TestDescription tid3 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
2043         mListener.testStarted(EasyMock.eq(tid3));
2044         mListener.testEnded(EasyMock.eq(tid3), (HashMap<String, Metric>) EasyMock.anyObject());
2045         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
2046 
2047         EasyMock.replay(mListener);
2048         assertEquals(3, mHostTest.countTestCases());
2049         mHostTest.run(mListener);
2050         EasyMock.verify(mListener);
2051     }
2052 
2053     /** JUnit4 class that throws within its @Before */
2054     @RunWith(JUnit4.class)
2055     public static class JUnit4FailedBefore {
2056         @Before
2057         public void before() {
2058             throw new RuntimeException();
2059         }
2060 
2061         @org.junit.Test
2062         public void test1() {}
2063     }
2064 
2065     /**
2066      * Test that when an exception is thrown within @Before, the test are reported and failed with
2067      * the exception.
2068      */
2069     public void testRun_junit4ExceptionBefore() throws Exception {
2070         OptionSetter setter = new OptionSetter(mHostTest);
2071         setter.setOptionValue("class", JUnit4FailedBefore.class.getName());
2072         setter.setOptionValue("class", Junit4TestClass.class.getName());
2073         // First class has a test failure because of the @Before
2074         mListener.testRunStarted(EasyMock.anyObject(), EasyMock.eq(1));
2075         TestDescription tid = new TestDescription(JUnit4FailedBefore.class.getName(), "test1");
2076         mListener.testStarted(EasyMock.eq(tid));
2077         mListener.testFailed(EasyMock.eq(tid), EasyMock.anyObject());
2078         mListener.testEnded(EasyMock.eq(tid), (HashMap<String, Metric>) EasyMock.anyObject());
2079         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
2080 
2081         // Second class run properly
2082         mListener.testRunStarted(EasyMock.anyObject(), EasyMock.eq(2));
2083         TestDescription tid2 = new TestDescription(Junit4TestClass.class.getName(), "testPass5");
2084         mListener.testStarted(EasyMock.eq(tid2));
2085         mListener.testEnded(EasyMock.eq(tid2), (HashMap<String, Metric>) EasyMock.anyObject());
2086         TestDescription tid3 = new TestDescription(Junit4TestClass.class.getName(), "testPass6");
2087         mListener.testStarted(EasyMock.eq(tid3));
2088         mListener.testEnded(EasyMock.eq(tid3), (HashMap<String, Metric>) EasyMock.anyObject());
2089         mListener.testRunEnded(EasyMock.anyLong(), (HashMap<String, Metric>) EasyMock.anyObject());
2090 
2091         EasyMock.replay(mListener);
2092         assertEquals(3, mHostTest.countTestCases());
2093         mHostTest.run(mListener);
2094         EasyMock.verify(mListener);
2095     }
2096 
2097     /**
2098      * Test that when all tests are filtered out, we properly shard them with 0 runtime, and they
2099      * will be completely skipped during execution.
2100      */
2101     public void testSplit_withFilter() throws Exception {
2102         OptionSetter setter = new OptionSetter(mHostTest);
2103         setter.setOptionValue("class", Junit4TestClass.class.getName());
2104         setter.setOptionValue("class", AnotherTestCase.class.getName());
2105         // Filter everything out
2106         mHostTest.addExcludeFilter(Junit4TestClass.class.getName());
2107         mHostTest.addExcludeFilter(AnotherTestCase.class.getName());
2108 
2109         Collection<IRemoteTest> tests = mHostTest.split(6);
2110         assertEquals(2, tests.size());
2111         for (IRemoteTest test : tests) {
2112             assertTrue(test instanceof HostTest);
2113             assertEquals(0L, ((HostTest) test).getRuntimeHint());
2114             assertEquals(0, ((HostTest) test).countTestCases());
2115         }
2116     }
2117 
2118     public void testEarlyFailure() throws Exception {
2119         OptionSetter setter = new OptionSetter(mHostTest);
2120         setter.setOptionValue("class", "i.cannot.be.resolved");
2121 
2122         mListener.testRunStarted(HostTestTest.class.getName() + ".TestableHostTest", 0);
2123         mListener.testRunFailed("Could not load Test class i.cannot.be.resolved");
2124         mListener.testRunEnded(0L, new HashMap<String, Metric>());
2125 
2126         EasyMock.replay(mListener);
2127         try {
2128             mHostTest.run(mListener);
2129             fail("Should have thrown an exception");
2130         } catch (IllegalArgumentException expected) {
2131             // expected
2132         }
2133         EasyMock.verify(mListener);
2134     }
2135 }
2136