1 /*
2  * Copyright (C) 2017 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.suite;
17 
18 import com.android.tradefed.config.Option;
19 import com.android.tradefed.config.OptionCopier;
20 import com.android.tradefed.device.DeviceNotAvailableException;
21 import com.android.tradefed.invoker.TestInformation;
22 import com.android.tradefed.metrics.proto.MetricMeasurement.Metric;
23 import com.android.tradefed.result.ByteArrayInputStreamSource;
24 import com.android.tradefed.result.ITestInvocationListener;
25 import com.android.tradefed.result.LogDataType;
26 import com.android.tradefed.result.TestDescription;
27 import com.android.tradefed.testtype.IAbi;
28 import com.android.tradefed.testtype.IAbiReceiver;
29 import com.android.tradefed.testtype.IRemoteTest;
30 import com.android.tradefed.testtype.IRuntimeHintProvider;
31 import com.android.tradefed.testtype.IShardableTest;
32 import com.android.tradefed.testtype.ITestAnnotationFilterReceiver;
33 import com.android.tradefed.testtype.ITestCollector;
34 import com.android.tradefed.testtype.ITestFilterReceiver;
35 
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.HashMap;
39 import java.util.HashSet;
40 import java.util.List;
41 import java.util.Set;
42 
43 /** A test Stub that can be used to fake some runs for suite's testing. */
44 public class TestSuiteStub
45         implements IRemoteTest,
46                 IAbiReceiver,
47                 IRuntimeHintProvider,
48                 ITestCollector,
49                 ITestFilterReceiver,
50                 IShardableTest,
51                 ITestAnnotationFilterReceiver {
52 
53     @Option(name = "module")
54     private String mModule;
55 
56     @Option(name = "foo")
57     protected String mFoo;
58 
59     @Option(name = "blah")
60     protected String mBlah;
61 
62     @Option(name = "report-test")
63     protected boolean mReportTest = false;
64 
65     @Option(name = "run-complete")
66     protected boolean mIsComplete = true;
67 
68     @Option(name = "test-fail")
69     protected boolean mDoesOneTestFail = true;
70 
71     @Option(name = "internal-retry")
72     protected boolean mRetry = false;
73 
74     @Option(name = "throw-device-not-available")
75     protected boolean mThrow = false;
76 
77     @Option(name = "log-fake-files")
78     protected boolean mLogFiles = false;
79 
80     protected List<TestDescription> mShardedTestToRun;
81     protected Integer mShardIndex = null;
82 
83     private Set<String> mIncludeAnnotationFilter = new HashSet<>();
84 
85     @Option(
86             name = "exclude-annotation",
87             description = "The notAnnotation class name of the test name to run, can be repeated")
88     private Set<String> mExcludeAnnotationFilter = new HashSet<>();
89 
90     private Set<String> mExcludeFilters = new HashSet<>();
91 
92     /** Tests attempt. */
testAttempt(ITestInvocationListener listener)93     private void testAttempt(ITestInvocationListener listener) throws DeviceNotAvailableException {
94         listener.testRunStarted(mModule, 3);
95         TestDescription tid = new TestDescription("TestStub", "test1");
96         listener.testStarted(tid);
97         if (mLogFiles) {
98             listener.testLog(
99                     tid.toString() + "-file",
100                     LogDataType.LOGCAT,
101                     new ByteArrayInputStreamSource("test".getBytes()));
102         }
103         listener.testEnded(tid, new HashMap<String, Metric>());
104 
105         if (mIsComplete) {
106             // possibly skip this one to create some not_executed case.
107             TestDescription tid2 = new TestDescription("TestStub", "test2");
108             listener.testStarted(tid2);
109             if (mThrow) {
110                 throw new DeviceNotAvailableException("test", "serial");
111             }
112             if (mLogFiles) {
113                 listener.testLog(
114                         tid2.toString() + "-file",
115                         LogDataType.BUGREPORT,
116                         new ByteArrayInputStreamSource("test".getBytes()));
117             }
118             listener.testEnded(tid2, new HashMap<String, Metric>());
119         }
120 
121         TestDescription tid3 = new TestDescription("TestStub", "test3");
122         listener.testStarted(tid3);
123         if (mDoesOneTestFail) {
124             listener.testFailed(tid3, "ouch this is bad.");
125         }
126         if (mLogFiles) {
127             listener.testLog(
128                     tid3.toString() + "-file",
129                     LogDataType.BUGREPORT,
130                     new ByteArrayInputStreamSource("test".getBytes()));
131         }
132         listener.testEnded(tid3, new HashMap<String, Metric>());
133 
134         if (mLogFiles) {
135             // One file logged at run level
136             listener.testLog(
137                     mModule + "-file",
138                     LogDataType.EAR,
139                     new ByteArrayInputStreamSource("test".getBytes()));
140         }
141         listener.testRunEnded(0, new HashMap<String, Metric>());
142     }
143 
144     /** {@inheritDoc} */
145     @Override
run(TestInformation testInfo, ITestInvocationListener listener)146     public void run(TestInformation testInfo, ITestInvocationListener listener)
147             throws DeviceNotAvailableException {
148         if (mReportTest) {
149             if (mShardedTestToRun == null) {
150                 if (!mRetry) {
151                     testAttempt(listener);
152                 } else {
153                     // We fake an internal retry by calling testRunStart/Ended again.
154                     listener.testRunStarted(mModule, 3);
155                     listener.testRunEnded(0, new HashMap<String, Metric>());
156                     testAttempt(listener);
157                 }
158             } else {
159                 // Run the shard
160                 if (mDoesOneTestFail) {
161                     listener.testRunStarted(mModule, mShardedTestToRun.size() + 1);
162                 } else {
163                     listener.testRunStarted(mModule, mShardedTestToRun.size());
164                 }
165 
166                 if (mIsComplete) {
167                     for (TestDescription tid : mShardedTestToRun) {
168                         listener.testStarted(tid);
169                         listener.testEnded(tid, new HashMap<String, Metric>());
170                     }
171                 } else {
172                     TestDescription tid = mShardedTestToRun.get(0);
173                     listener.testStarted(tid);
174                     listener.testEnded(tid, new HashMap<String, Metric>());
175                 }
176 
177                 if (mDoesOneTestFail) {
178                     TestDescription tid = new TestDescription("TestStub", "failed" + mShardIndex);
179                     listener.testStarted(tid);
180                     listener.testFailed(tid, "shard failed this one.");
181                     listener.testEnded(tid, new HashMap<String, Metric>());
182                 }
183                 listener.testRunEnded(0, new HashMap<String, Metric>());
184             }
185         }
186     }
187 
188     @Override
split(int shardCountHint)189     public Collection<IRemoteTest> split(int shardCountHint) {
190         if (mShardedTestToRun == null) {
191             return null;
192         }
193         Collection<IRemoteTest> listTest = new ArrayList<>();
194         for (TestDescription id : mShardedTestToRun) {
195             TestSuiteStub stub = new TestSuiteStub();
196             OptionCopier.copyOptionsNoThrow(this, stub);
197             stub.mShardedTestToRun = new ArrayList<>();
198             stub.mShardedTestToRun.add(id);
199             listTest.add(stub);
200         }
201         return listTest;
202     }
203 
204     @Override
setAbi(IAbi abi)205     public void setAbi(IAbi abi) {
206         // Do nothing
207     }
208 
209     @Override
getAbi()210     public IAbi getAbi() {
211         return null;
212     }
213 
214     @Override
getRuntimeHint()215     public long getRuntimeHint() {
216         return 1L;
217     }
218 
219     @Override
setCollectTestsOnly(boolean shouldCollectTest)220     public void setCollectTestsOnly(boolean shouldCollectTest) {
221         // Do nothing
222     }
223 
224     @Override
addIncludeFilter(String filter)225     public void addIncludeFilter(String filter) {}
226 
227     @Override
addAllIncludeFilters(Set<String> filters)228     public void addAllIncludeFilters(Set<String> filters) {}
229 
230     @Override
addExcludeFilter(String filter)231     public void addExcludeFilter(String filter) {
232         mExcludeFilters.add(filter);
233     }
234 
235     @Override
addAllExcludeFilters(Set<String> filters)236     public void addAllExcludeFilters(Set<String> filters) {
237         mExcludeFilters.addAll(filters);
238     }
239 
240     @Override
clearIncludeFilters()241     public void clearIncludeFilters() {}
242 
243     @Override
getIncludeFilters()244     public Set<String> getIncludeFilters() {
245         return new HashSet<>();
246     }
247 
248     @Override
getExcludeFilters()249     public Set<String> getExcludeFilters() {
250         return mExcludeFilters;
251     }
252 
253     @Override
clearExcludeFilters()254     public void clearExcludeFilters() {
255         mExcludeFilters.clear();
256     }
257 
258     @Override
addIncludeAnnotation(String annotation)259     public void addIncludeAnnotation(String annotation) {
260         mIncludeAnnotationFilter.add(annotation);
261     }
262 
263     @Override
addExcludeAnnotation(String notAnnotation)264     public void addExcludeAnnotation(String notAnnotation) {
265         mExcludeAnnotationFilter.add(notAnnotation);
266     }
267 
268     @Override
addAllIncludeAnnotation(Set<String> annotations)269     public void addAllIncludeAnnotation(Set<String> annotations) {
270         mIncludeAnnotationFilter.addAll(annotations);
271     }
272 
273     @Override
addAllExcludeAnnotation(Set<String> notAnnotations)274     public void addAllExcludeAnnotation(Set<String> notAnnotations) {
275         mExcludeAnnotationFilter.addAll(notAnnotations);
276     }
277 
278     @Override
getIncludeAnnotations()279     public Set<String> getIncludeAnnotations() {
280         return mIncludeAnnotationFilter;
281     }
282 
283     @Override
getExcludeAnnotations()284     public Set<String> getExcludeAnnotations() {
285         return mExcludeAnnotationFilter;
286     }
287 
288     @Override
clearIncludeAnnotations()289     public void clearIncludeAnnotations() {
290         mIncludeAnnotationFilter.clear();
291     }
292 
293     @Override
clearExcludeAnnotations()294     public void clearExcludeAnnotations() {
295         mExcludeAnnotationFilter.clear();
296     }
297 }
298