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.metrics.proto.MetricMeasurement.Metric;
22 import com.android.tradefed.result.ByteArrayInputStreamSource;
23 import com.android.tradefed.result.ITestInvocationListener;
24 import com.android.tradefed.result.LogDataType;
25 import com.android.tradefed.result.TestDescription;
26 import com.android.tradefed.testtype.IAbi;
27 import com.android.tradefed.testtype.IAbiReceiver;
28 import com.android.tradefed.testtype.IRemoteTest;
29 import com.android.tradefed.testtype.IRuntimeHintProvider;
30 import com.android.tradefed.testtype.IShardableTest;
31 import com.android.tradefed.testtype.ITestCollector;
32 import com.android.tradefed.testtype.ITestFilterReceiver;
33 
34 import java.util.ArrayList;
35 import java.util.Collection;
36 import java.util.HashMap;
37 import java.util.List;
38 import java.util.Set;
39 
40 /** A test Stub that can be used to fake some runs for suite's testing. */
41 public class TestSuiteStub
42         implements IRemoteTest,
43                 IAbiReceiver,
44                 IRuntimeHintProvider,
45                 ITestCollector,
46                 ITestFilterReceiver,
47                 IShardableTest {
48 
49     @Option(name = "module")
50     private String mModule;
51 
52     @Option(name = "foo")
53     protected String mFoo;
54 
55     @Option(name = "blah")
56     protected String mBlah;
57 
58     @Option(name = "report-test")
59     protected boolean mReportTest = false;
60 
61     @Option(name = "run-complete")
62     protected boolean mIsComplete = true;
63 
64     @Option(name = "test-fail")
65     protected boolean mDoesOneTestFail = true;
66 
67     @Option(name = "internal-retry")
68     protected boolean mRetry = false;
69 
70     @Option(name = "throw-device-not-available")
71     protected boolean mThrow = false;
72 
73     @Option(name = "log-fake-files")
74     protected boolean mLogFiles = false;
75 
76     protected List<TestDescription> mShardedTestToRun;
77     protected Integer mShardIndex = null;
78 
79     /** Tests attempt. */
testAttempt(ITestInvocationListener listener)80     private void testAttempt(ITestInvocationListener listener) throws DeviceNotAvailableException {
81         listener.testRunStarted(mModule, 3);
82         TestDescription tid = new TestDescription("TestStub", "test1");
83         listener.testStarted(tid);
84         if (mLogFiles) {
85             listener.testLog(
86                     tid.toString() + "-file",
87                     LogDataType.LOGCAT,
88                     new ByteArrayInputStreamSource("test".getBytes()));
89         }
90         listener.testEnded(tid, new HashMap<String, Metric>());
91 
92         if (mIsComplete) {
93             // possibly skip this one to create some not_executed case.
94             TestDescription tid2 = new TestDescription("TestStub", "test2");
95             listener.testStarted(tid2);
96             if (mThrow) {
97                 throw new DeviceNotAvailableException();
98             }
99             if (mLogFiles) {
100                 listener.testLog(
101                         tid2.toString() + "-file",
102                         LogDataType.BUGREPORT,
103                         new ByteArrayInputStreamSource("test".getBytes()));
104             }
105             listener.testEnded(tid2, new HashMap<String, Metric>());
106         }
107 
108         TestDescription tid3 = new TestDescription("TestStub", "test3");
109         listener.testStarted(tid3);
110         if (mDoesOneTestFail) {
111             listener.testFailed(tid3, "ouch this is bad.");
112         }
113         if (mLogFiles) {
114             listener.testLog(
115                     tid3.toString() + "-file",
116                     LogDataType.BUGREPORT,
117                     new ByteArrayInputStreamSource("test".getBytes()));
118         }
119         listener.testEnded(tid3, new HashMap<String, Metric>());
120 
121         if (mLogFiles) {
122             // One file logged at run level
123             listener.testLog(
124                     mModule + "-file",
125                     LogDataType.EAR,
126                     new ByteArrayInputStreamSource("test".getBytes()));
127         }
128         listener.testRunEnded(0, new HashMap<String, Metric>());
129     }
130 
131     /** {@inheritDoc} */
132     @Override
run(ITestInvocationListener listener)133     public void run(ITestInvocationListener listener) throws DeviceNotAvailableException {
134         if (mReportTest) {
135             if (mShardedTestToRun == null) {
136                 if (!mRetry) {
137                     testAttempt(listener);
138                 } else {
139                     // We fake an internal retry by calling testRunStart/Ended again.
140                     listener.testRunStarted(mModule, 3);
141                     listener.testRunEnded(0, new HashMap<String, Metric>());
142                     testAttempt(listener);
143                 }
144             } else {
145                 // Run the shard
146                 if (mDoesOneTestFail) {
147                     listener.testRunStarted(mModule, mShardedTestToRun.size() + 1);
148                 } else {
149                     listener.testRunStarted(mModule, mShardedTestToRun.size());
150                 }
151 
152                 if (mIsComplete) {
153                     for (TestDescription tid : mShardedTestToRun) {
154                         listener.testStarted(tid);
155                         listener.testEnded(tid, new HashMap<String, Metric>());
156                     }
157                 } else {
158                     TestDescription tid = mShardedTestToRun.get(0);
159                     listener.testStarted(tid);
160                     listener.testEnded(tid, new HashMap<String, Metric>());
161                 }
162 
163                 if (mDoesOneTestFail) {
164                     TestDescription tid = new TestDescription("TestStub", "failed" + mShardIndex);
165                     listener.testStarted(tid);
166                     listener.testFailed(tid, "shard failed this one.");
167                     listener.testEnded(tid, new HashMap<String, Metric>());
168                 }
169                 listener.testRunEnded(0, new HashMap<String, Metric>());
170             }
171         }
172     }
173 
174     @Override
split(int shardCountHint)175     public Collection<IRemoteTest> split(int shardCountHint) {
176         if (mShardedTestToRun == null) {
177             return null;
178         }
179         Collection<IRemoteTest> listTest = new ArrayList<>();
180         for (TestDescription id : mShardedTestToRun) {
181             TestSuiteStub stub = new TestSuiteStub();
182             OptionCopier.copyOptionsNoThrow(this, stub);
183             stub.mShardedTestToRun = new ArrayList<>();
184             stub.mShardedTestToRun.add(id);
185             listTest.add(stub);
186         }
187         return listTest;
188     }
189 
190     @Override
setAbi(IAbi abi)191     public void setAbi(IAbi abi) {
192         // Do nothing
193     }
194 
195     @Override
getAbi()196     public IAbi getAbi() {
197         return null;
198     }
199 
200     @Override
getRuntimeHint()201     public long getRuntimeHint() {
202         return 1L;
203     }
204 
205     @Override
setCollectTestsOnly(boolean shouldCollectTest)206     public void setCollectTestsOnly(boolean shouldCollectTest) {
207         // Do nothing
208     }
209 
210     @Override
addIncludeFilter(String filter)211     public void addIncludeFilter(String filter) {}
212 
213     @Override
addAllIncludeFilters(Set<String> filters)214     public void addAllIncludeFilters(Set<String> filters) {}
215 
216     @Override
addExcludeFilter(String filter)217     public void addExcludeFilter(String filter) {}
218 
219     @Override
addAllExcludeFilters(Set<String> filters)220     public void addAllExcludeFilters(Set<String> filters) {}
221 }
222