• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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.result;
17 
18 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
19 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.LogAnnotation;
20 import com.android.tradefed.testtype.DeviceJUnit4ClassRunner.MetricAnnotation;
21 import com.android.tradefed.testtype.MetricTestCase.LogHolder;
22 import com.android.tradefed.testtype.junit4.CarryDnaeError;
23 import com.android.tradefed.util.StreamUtil;
24 
25 import org.junit.AssumptionViolatedException;
26 import org.junit.runner.Description;
27 import org.junit.runner.notification.Failure;
28 import org.junit.runner.notification.RunListener;
29 import org.junit.runners.model.MultipleFailureException;
30 
31 import java.lang.annotation.Annotation;
32 import java.util.ArrayList;
33 import java.util.HashMap;
34 import java.util.List;
35 
36 /**
37  * Result forwarder from JUnit4 Runner.
38  */
39 public class JUnit4ResultForwarder extends RunListener {
40 
41     private ITestInvocationListener mListener;
42     private List<Throwable> mTestCaseFailures;
43 
JUnit4ResultForwarder(ITestInvocationListener listener)44     public JUnit4ResultForwarder(ITestInvocationListener listener) {
45         mListener = listener;
46         mTestCaseFailures = new ArrayList<>();
47     }
48 
49     @Override
testFailure(Failure failure)50     public void testFailure(Failure failure) throws Exception {
51         Description description = failure.getDescription();
52         if (description.getMethodName() == null) {
53             // In case of exception in @BeforeClass, the method name will be null
54             mListener.testRunFailed(String.format("Failed with trace: %s", failure.getTrace()));
55             // If the exception is ours thrown from before, rethrow it
56             if (failure.getException() instanceof CarryDnaeError) {
57                 throw ((CarryDnaeError) failure.getException()).getDeviceNotAvailableException();
58             }
59             return;
60         }
61         mTestCaseFailures.add(failure.getException());
62     }
63 
64     @Override
testAssumptionFailure(Failure failure)65     public void testAssumptionFailure(Failure failure) {
66         mTestCaseFailures.add(failure.getException());
67     }
68 
69     @Override
testStarted(Description description)70     public void testStarted(Description description) throws Exception {
71         mTestCaseFailures.clear();
72         TestDescription testid =
73                 new TestDescription(
74                         description.getClassName(),
75                         description.getMethodName(),
76                         description.getAnnotations());
77         mListener.testStarted(testid);
78     }
79 
80     @Override
testFinished(Description description)81     public void testFinished(Description description) throws Exception {
82         TestDescription testid =
83                 new TestDescription(
84                         description.getClassName(),
85                         description.getMethodName(),
86                         description.getAnnotations());
87         try {
88             handleFailures(testid);
89         } finally {
90             // Explore the Description to see if we find any Annotation metrics carrier
91             HashMap<String, Metric> metrics = new HashMap<>();
92             for (Description child : description.getChildren()) {
93                 for (Annotation a : child.getAnnotations()) {
94                     if (a instanceof MetricAnnotation) {
95                         metrics.putAll(((MetricAnnotation) a).mMetrics);
96                     }
97                     if (a instanceof LogAnnotation) {
98                         // Log all the logs found.
99                         for (LogHolder log : ((LogAnnotation) a).mLogs) {
100                             mListener.testLog(log.mDataName, log.mDataType, log.mDataStream);
101                             StreamUtil.cancel(log.mDataStream);
102                         }
103                         ((LogAnnotation) a).mLogs.clear();
104                     }
105                 }
106             }
107             //description.
108             mListener.testEnded(testid, metrics);
109         }
110     }
111 
112     @Override
testIgnored(Description description)113     public void testIgnored(Description description) throws Exception {
114         TestDescription testid =
115                 new TestDescription(
116                         description.getClassName(),
117                         description.getMethodName(),
118                         description.getAnnotations());
119         // We complete the event life cycle since JUnit4 fireIgnored is not within fireTestStarted
120         // and fireTestEnded.
121         mListener.testStarted(testid);
122         mListener.testIgnored(testid);
123         mListener.testEnded(testid, new HashMap<String, Metric>());
124     }
125 
126     /**
127      * Handle all the failure received from the JUnit4 tests, if a single
128      * AssumptionViolatedException is received then treat the test as assumption failure. Otherwise
129      * treat everything else as failure.
130      */
handleFailures(TestDescription testid)131     private void handleFailures(TestDescription testid) {
132         if (mTestCaseFailures.isEmpty()) {
133             return;
134         }
135         if (mTestCaseFailures.size() == 1) {
136             Throwable t = mTestCaseFailures.get(0);
137             if (t instanceof AssumptionViolatedException) {
138                 mListener.testAssumptionFailure(testid, StreamUtil.getStackTrace(t));
139             } else {
140                 mListener.testFailed(testid, StreamUtil.getStackTrace(t));
141             }
142         } else {
143             MultipleFailureException multiException =
144                     new MultipleFailureException(mTestCaseFailures);
145             mListener.testFailed(testid, StreamUtil.getStackTrace(multiException));
146         }
147     }
148 }
149