1 /*
2  * Copyright (C) 2017 Google Inc.
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.junit4;
17 
18 import com.android.tradefed.device.ITestDevice;
19 import com.android.tradefed.result.ITestLifeCycleReceiver;
20 
21 import java.util.ArrayList;
22 import java.util.LinkedHashMap;
23 import java.util.List;
24 import java.util.Map;
25 
26 /** A builder class for options related to running device tests through BaseHostJUnit4Test. */
27 public class DeviceTestRunOptions {
28     private ITestDevice mDevice; // optional
29     private String mRunner = null; // optional
30     private final String mPackageName; // required
31 
32     private String mTestClassName; // optional
33     private String mTestMethodName; // optional
34     private String mApkFileName; // optional
35     private String[] mInstallArgs; // optional
36     private Integer mUserId; // optional
37     private Long mTestTimeoutMs = BaseHostJUnit4Test.DEFAULT_TEST_TIMEOUT_MS; // optional
38     private Long mMaxTimeToOutputMs =
39             BaseHostJUnit4Test.DEFAULT_MAX_TIMEOUT_TO_OUTPUT_MS; // optional
40     private Long mMaxInstrumentationTimeoutMs; // optional
41     private boolean mCheckResults = true; // optional
42     private boolean mDisableHiddenApiCheck = false; // optional
43     private boolean mDisableTestApiCheck = true; // optional
44     private boolean mDisableIsolatedStorage = false; // optional
45     private boolean mDisableWindowAnimation = false; // optional
46     private boolean mDisableRestart = false; // optional
47     private boolean mGrantPermission = false; // optional
48     private boolean mForceQueryable = true; // optional
49     private Map<String, String> mInstrumentationArgs = new LinkedHashMap<>(); // optional
50     private List<ITestLifeCycleReceiver> mExtraListeners = new ArrayList<>(); // optional
51 
DeviceTestRunOptions(String packageName)52     public DeviceTestRunOptions(String packageName) {
53         this.mPackageName = packageName;
54     }
55 
getDevice()56     public ITestDevice getDevice() {
57         return mDevice;
58     }
59 
setDevice(ITestDevice device)60     public DeviceTestRunOptions setDevice(ITestDevice device) {
61         this.mDevice = device;
62         return this;
63     }
64 
getRunner()65     public String getRunner() {
66         return mRunner;
67     }
68 
69     /**
70      * Sets the instrumentation runner that should be used to run the instrumentation. Default
71      * runner is 'android.support.test.runner.AndroidJUnitRunner'. Optional.
72      */
setRunner(String runner)73     public DeviceTestRunOptions setRunner(String runner) {
74         this.mRunner = runner;
75         return this;
76     }
77 
getPackageName()78     public String getPackageName() {
79         return mPackageName;
80     }
81 
getTestClassName()82     public String getTestClassName() {
83         return mTestClassName;
84     }
85 
86     /**
87      * Sets the classname that the instrumentation should run. The instrumentation will be filtered
88      * to only run the class. Can be used with {@link #setTestMethodName(String)}. Optional.
89      */
setTestClassName(String testClassName)90     public DeviceTestRunOptions setTestClassName(String testClassName) {
91         this.mTestClassName = testClassName;
92         return this;
93     }
94 
getTestMethodName()95     public String getTestMethodName() {
96         return mTestMethodName;
97     }
98 
99     /**
100      * Sets the method name that the instrumentation should run. Requires {@link
101      * #setTestClassName(String)} to be set in order to work properly. Optional.
102      */
setTestMethodName(String testMethodName)103     public DeviceTestRunOptions setTestMethodName(String testMethodName) {
104         this.mTestMethodName = testMethodName;
105         return this;
106     }
107 
getUserId()108     public Integer getUserId() {
109         return mUserId;
110     }
111 
112     /** Sets the user id against which the instrumentation should run. Optional. */
setUserId(Integer userId)113     public DeviceTestRunOptions setUserId(Integer userId) {
114         this.mUserId = userId;
115         return this;
116     }
117 
getTestTimeoutMs()118     public Long getTestTimeoutMs() {
119         return mTestTimeoutMs;
120     }
121 
122     /**
123      * Sets the maximum time (in milliseconds) a test can run before being interrupted. Set to 0 for
124      * no timeout. Optional.
125      */
setTestTimeoutMs(Long testTimeoutMs)126     public DeviceTestRunOptions setTestTimeoutMs(Long testTimeoutMs) {
127         this.mTestTimeoutMs = testTimeoutMs;
128         return this;
129     }
130 
getMaxTimeToOutputMs()131     public Long getMaxTimeToOutputMs() {
132         return mMaxTimeToOutputMs;
133     }
134 
135     /**
136      * Sets the maximum time (in milliseconds) the instrumentation can stop outputting before being
137      * stopped. Set to 0 for no timeout. Optional.
138      */
setMaxTimeToOutputMs(Long maxTimeToOutputMs)139     public DeviceTestRunOptions setMaxTimeToOutputMs(Long maxTimeToOutputMs) {
140         this.mMaxTimeToOutputMs = maxTimeToOutputMs;
141         return this;
142     }
143 
getMaxInstrumentationTimeoutMs()144     public Long getMaxInstrumentationTimeoutMs() {
145         return mMaxInstrumentationTimeoutMs;
146     }
147 
148     /**
149      * Sets the maximum time (in milliseconds) the complete instrumentation will have to run and
150      * complete. Set to 0 for no timeout. Optional.
151      */
setMaxInstrumentationTimeoutMs(Long maxInstrumentationTimeoutMs)152     public DeviceTestRunOptions setMaxInstrumentationTimeoutMs(Long maxInstrumentationTimeoutMs) {
153         this.mMaxInstrumentationTimeoutMs = maxInstrumentationTimeoutMs;
154         return this;
155     }
156 
shouldCheckResults()157     public boolean shouldCheckResults() {
158         return mCheckResults;
159     }
160 
161     /**
162      * Sets whether or not the results of the instrumentation run should be checked and ensure no
163      * failures occured.
164      */
setCheckResults(boolean checkResults)165     public DeviceTestRunOptions setCheckResults(boolean checkResults) {
166         this.mCheckResults = checkResults;
167         return this;
168     }
169 
170     /**
171      * sets whether or not to add the --no-hidden-api-checks to the 'am instrument' used from the
172      * host side.
173      */
setDisableHiddenApiCheck(boolean disableHiddenApiCheck)174     public DeviceTestRunOptions setDisableHiddenApiCheck(boolean disableHiddenApiCheck) {
175         this.mDisableHiddenApiCheck = disableHiddenApiCheck;
176         return this;
177     }
178 
isHiddenApiCheckDisabled()179     public boolean isHiddenApiCheckDisabled() {
180         return mDisableHiddenApiCheck;
181     }
182 
183     /**
184      * sets whether or not to add the --no-test-api-access to the 'am instrument' used from the host
185      * side.
186      */
setDisableTestApiCheck(boolean disableTestApiCheck)187     public DeviceTestRunOptions setDisableTestApiCheck(boolean disableTestApiCheck) {
188         this.mDisableTestApiCheck = disableTestApiCheck;
189         return this;
190     }
191 
isTestApiCheckDisabled()192     public boolean isTestApiCheckDisabled() {
193         return mDisableTestApiCheck;
194     }
195 
196     /**
197      * sets whether or not to add the --no-isolated-storage to the 'am instrument' used from the
198      * host side.
199      */
setDisableIsolatedStorage(boolean disableIsolatedStorage)200     public DeviceTestRunOptions setDisableIsolatedStorage(boolean disableIsolatedStorage) {
201         this.mDisableIsolatedStorage = disableIsolatedStorage;
202         return this;
203     }
204 
isIsolatedStorageDisabled()205     public boolean isIsolatedStorageDisabled() {
206         return mDisableIsolatedStorage;
207     }
208 
209     /**
210      * sets whether or not to add the --no-window-animation to the 'am instrument' used from the
211      * host side.
212      */
setDisableWindowAnimation(boolean disableWindowAnimation)213     public DeviceTestRunOptions setDisableWindowAnimation(boolean disableWindowAnimation) {
214         this.mDisableWindowAnimation = disableWindowAnimation;
215         return this;
216     }
217 
isWindowAnimationDisabled()218     public boolean isWindowAnimationDisabled() {
219         return mDisableWindowAnimation;
220     }
221 
222     /** Sets whether or not to add --no-restart to the 'am instrument' used from the host side. */
setDisableRestart(boolean disableRestart)223     public DeviceTestRunOptions setDisableRestart(boolean disableRestart) {
224         this.mDisableRestart = disableRestart;
225         return this;
226     }
227 
isRestartDisabled()228     public boolean isRestartDisabled() {
229         return mDisableRestart;
230     }
231 
232     /** Add an argument that will be passed to the instrumentation. */
addInstrumentationArg(String key, String value)233     public DeviceTestRunOptions addInstrumentationArg(String key, String value) {
234         this.mInstrumentationArgs.put(key, value);
235         return this;
236     }
237 
238     /** Add an extra listener to the instrumentation being run. */
addExtraListener(ITestLifeCycleReceiver listener)239     public DeviceTestRunOptions addExtraListener(ITestLifeCycleReceiver listener) {
240         this.mExtraListeners.add(listener);
241         return this;
242     }
243 
244     /**
245      * Clear all instrumentation arguments that have been set with {@link
246      * #addInstrumentationArg(String, String)} previously.
247      */
clearInstrumentationArgs()248     public void clearInstrumentationArgs() {
249         mInstrumentationArgs.clear();
250     }
251 
getInstrumentationArgs()252     public Map<String, String> getInstrumentationArgs() {
253         return mInstrumentationArgs;
254     }
255 
getExtraListeners()256     public List<ITestLifeCycleReceiver> getExtraListeners() {
257         return mExtraListeners;
258     }
259 
clearExtraListeners()260     public void clearExtraListeners() {
261         mExtraListeners.clear();
262     }
263 
264     /** Returns the name of the apk file for the apk installation. */
getApkFileName()265     public String getApkFileName() {
266         return mApkFileName;
267     }
268 
269     /** Sets the name of the apk file for the apk installation. */
setApkFileName(String apkFileName)270     public DeviceTestRunOptions setApkFileName(String apkFileName) {
271         mApkFileName = apkFileName;
272         return this;
273     }
274 
275     /** Returns extra options of the install command. */
getInstallArgs()276     public String[] getInstallArgs() {
277         if (mInstallArgs == null) {
278             return new String[] {};
279         }
280         return mInstallArgs;
281     }
282 
283     /** Sets extra options of the install command. */
setInstallArgs(String... installArgs)284     public DeviceTestRunOptions setInstallArgs(String... installArgs) {
285         mInstallArgs = installArgs;
286         return this;
287     }
288 
289     /** Whether to grant permissions for the apk installation. */
isGrantPermission()290     public boolean isGrantPermission() {
291         return mGrantPermission;
292     }
293 
294     /** Grants permissions for the apk installation. */
setGrantPermission(boolean grantPermission)295     public DeviceTestRunOptions setGrantPermission(boolean grantPermission) {
296         mGrantPermission = grantPermission;
297         return this;
298     }
299 
300     /** Whether or not the apk to be installed should be queryable. The default value is true. */
isForceQueryable()301     public boolean isForceQueryable() {
302         return mForceQueryable;
303     }
304 
305     /** Sets {@code false} if the apk to be installed should not be queryable. */
setForceQueryable(boolean forceQueryable)306     public DeviceTestRunOptions setForceQueryable(boolean forceQueryable) {
307         mForceQueryable = forceQueryable;
308         return this;
309     }
310 }
311