• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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.command;
17 
18 import com.android.tradefed.config.ConfigurationException;
19 import com.android.tradefed.config.Option;
20 import com.android.tradefed.config.Option.Importance;
21 import com.android.tradefed.device.metric.AutoLogCollector;
22 import com.android.tradefed.config.OptionCopier;
23 import com.android.tradefed.config.OptionUpdateRule;
24 import com.android.tradefed.log.LogUtil.CLog;
25 import com.android.tradefed.util.UniqueMultiMap;
26 
27 import java.util.LinkedHashSet;
28 import java.util.Set;
29 
30 /**
31  * Implementation of {@link ICommandOptions}.
32  */
33 public class CommandOptions implements ICommandOptions {
34 
35     @Option(name = "help", description =
36         "display the help text for the most important/critical options.",
37         importance = Importance.ALWAYS)
38     private boolean mHelpMode = false;
39 
40     @Option(name = "help-all", description = "display the full help text for all options.",
41             importance = Importance.ALWAYS)
42     private boolean mFullHelpMode = false;
43 
44     @Option(name = "json-help", description = "display the full help in json format.")
45     private boolean mJsonHelpMode = false;
46 
47     public static final String DRY_RUN_OPTION = "dry-run";
48     public static final String NOISY_DRY_RUN_OPTION = "noisy-dry-run";
49 
50     @Option(
51         name = DRY_RUN_OPTION,
52         description =
53                 "build but don't actually run the command.  Intended as a quick check "
54                         + "to ensure that a command is runnable.",
55         importance = Importance.ALWAYS
56     )
57     private boolean mDryRunMode = false;
58 
59     @Option(
60         name = NOISY_DRY_RUN_OPTION,
61         description =
62                 "build but don't actually run the command.  This version prints the "
63                         + "command to the console.  Intended for cmdfile debugging.",
64         importance = Importance.ALWAYS
65     )
66     private boolean mNoisyDryRunMode = false;
67 
68     @Option(name = "min-loop-time", description =
69             "the minimum invocation time in ms when in loop mode.")
70     private Long mMinLoopTime = 10L * 60L * 1000L;
71 
72     @Option(name = "max-random-loop-time", description =
73             "the maximum time to wait between invocation attempts when in loop mode. " +
74             "when set, the actual value will be a random number between min-loop-time and this " +
75             "number.",
76             updateRule = OptionUpdateRule.LEAST)
77     private Long mMaxRandomLoopTime = null;
78 
79     @Option(name = "test-tag", description = "Identifier for the invocation during reporting.")
80     private String mTestTag = "stub";
81 
82     @Option(name = "test-tag-suffix", description = "suffix for test-tag. appended to test-tag to "
83             + "represents some variants of one test.")
84     private String mTestTagSuffix = null;
85 
86     @Option(name = "loop", description = "keep running continuously.",
87             importance = Importance.ALWAYS)
88     private boolean mLoopMode = false;
89 
90     @Option(name = "all-devices", description =
91             "fork this command to run on all connected devices.")
92     private boolean mAllDevices = false;
93 
94     @Option(name = "bugreport-on-invocation-ended", description =
95             "take a bugreport when the test invocation has ended")
96     private boolean mTakeBugreportOnInvocationEnded = false;
97 
98     @Option(name = "bugreportz-on-invocation-ended", description = "Attempt to take a bugreportz "
99             + "instead of bugreport during the test invocation final bugreport.")
100     private boolean mTakeBugreportzOnInvocationEnded = false;
101 
102     @Option(name = "invocation-timeout", description =
103             "the maximum time to wait for an invocation to terminate before attempting to force"
104             + "stop it.", isTimeVal = true)
105     private long mInvocationTimeout = 0;
106 
107     @Option(name = "shard-count", description =
108             "the number of total shards to run. Without --shard-index option, this will cause " +
109             "the command to spawn multiple shards in the current TF instance. With --shard-index " +
110             "option, it will cause the command to run a single shard of tests only.")
111     private Integer mShardCount;
112 
113     @Option(name = "shard-index", description =
114             "the index of shard to run. Only set if shard-count > 1 and the value is in range " +
115             "[0, shard-count)")
116     private Integer mShardIndex;
117 
118     @Option(
119         name = "enable-token-sharding",
120         description = "Whether or not to allow sharding with the token support enabled."
121     )
122     private boolean mTokenSharding = false;
123 
124     @Option(
125         name = "skip-pre-device-setup",
126         description =
127                 "allow TestInvocation to skip calling device.preInvocationSetup. This is for "
128                         + "delaying device setup when the test runs with VersionedTfLauncher."
129     )
130     private boolean mSkipPreDeviceSetup = false;
131 
132     @Option(
133         name = "dynamic-sharding",
134         description =
135                 "Allow to dynamically move IRemoteTest from one shard to another. Only for local "
136                         + "sharding."
137     )
138     private boolean mDynamicSharding = true;
139 
140     public static final String INVOCATION_DATA = "invocation-data";
141 
142     @Option(
143             name = INVOCATION_DATA,
144             description =
145                     "A map of values that describe the invocation, these values will be added to the "
146                             + "invocation context.")
147     private UniqueMultiMap<String, String> mInvocationData = new UniqueMultiMap<>();
148 
149     public static final String USE_SANDBOX = "use-sandbox";
150     public static final String ENABLE_SANDBOX_TEST_MODE = "sandbox-test-mode";
151     public static final String USE_REMOTE_SANDBOX = "use-remote-sandbox";
152 
153     @Option(
154         name = USE_SANDBOX,
155         description = "Set if the invocation should use a sandbox to run or not."
156     )
157     private boolean mUseSandbox = false;
158 
159     @Option(
160             name = ENABLE_SANDBOX_TEST_MODE,
161             description =
162                     "Sandbox test mode where the sandbox will use itself to generate another layer "
163                             + "of sandboxing. This is used for the sandbox to validate itself.")
164     private boolean mSandboxTestMode = false;
165 
166     @Option(
167         name = USE_REMOTE_SANDBOX,
168         description = "Whether or not to trigger --use-sandbox in the remote invocation."
169     )
170     private boolean mUseRemoteSandbox = false;
171 
172     @Option(
173         name = "parallel-remote-setup",
174         description =
175                 "For remote sharded invocation, whether or not to attempt the setup in parallel."
176     )
177     private boolean mUseParallelRemoteSetup = false;
178 
179     @Option(
180         name = "auto-collect",
181         description =
182                 "Specify a set of collectors that will be automatically managed by the harness "
183                         + "to collect logs."
184     )
185     private Set<AutoLogCollector> mAutoCollectors = new LinkedHashSet<>();
186 
187     @Deprecated
188     @Option(
189         name = "logcat-on-failure",
190         description = "take a logcat snapshot on every test failure."
191     )
192     private boolean mLogcatOnFailure = false;
193 
194     @Deprecated
195     @Option(name = "screenshot-on-failure", description = "Take a screenshot on every test failure")
196     private boolean mScreenshotOnFailure = false;
197 
198     @Option(
199         name = "host-log-suffix",
200         description = "Suffix to add to Tradefed host_log before logging it."
201     )
202     private String mHostLogSuffix = null;
203 
204     /**
205      * Set the help mode for the config.
206      * <p/>
207      * Exposed for testing.
208      */
setHelpMode(boolean helpMode)209     void setHelpMode(boolean helpMode) {
210         mHelpMode = helpMode;
211     }
212 
213     /**
214      * {@inheritDoc}
215      */
216     @Override
isHelpMode()217     public boolean isHelpMode() {
218         return mHelpMode;
219     }
220 
221     /**
222      * {@inheritDoc}
223      */
224     @Override
isFullHelpMode()225     public boolean isFullHelpMode() {
226         return mFullHelpMode;
227     }
228 
229     /**
230      * Set the json help mode for the config.
231      * <p/>
232      * Exposed for testing.
233      */
setJsonHelpMode(boolean jsonHelpMode)234     void setJsonHelpMode(boolean jsonHelpMode) {
235         mJsonHelpMode = jsonHelpMode;
236     }
237 
238     /**
239      * {@inheritDoc}
240      */
241     @Override
isJsonHelpMode()242     public boolean isJsonHelpMode() {
243         return mJsonHelpMode;
244     }
245 
246     /**
247      * Set the dry run mode for the config.
248      * <p/>
249      * Exposed for testing.
250      */
setDryRunMode(boolean dryRunMode)251     void setDryRunMode(boolean dryRunMode) {
252         mDryRunMode = dryRunMode;
253     }
254 
255     /**
256      * {@inheritDoc}
257      */
258     @Override
isDryRunMode()259     public boolean isDryRunMode() {
260         return mDryRunMode || mNoisyDryRunMode;
261     }
262 
263     /**
264      * {@inheritDoc}
265      */
266     @Override
isNoisyDryRunMode()267     public boolean isNoisyDryRunMode() {
268         return mNoisyDryRunMode;
269     }
270 
271     /**
272      * Set the loop mode for the config.
273      */
274     @Override
setLoopMode(boolean loopMode)275     public void setLoopMode(boolean loopMode) {
276         mLoopMode = loopMode;
277     }
278 
279     /**
280      * {@inheritDoc}
281      */
282     @Override
isLoopMode()283     public boolean isLoopMode() {
284         return mLoopMode;
285     }
286 
287     /**
288      * Set the min loop time for the config.
289      * <p/>
290      * Exposed for testing.
291      */
setMinLoopTime(long loopTime)292     void setMinLoopTime(long loopTime) {
293         mMinLoopTime = loopTime;
294     }
295 
296     /**
297      * {@inheritDoc}
298      * @deprecated use {@link #getLoopTime()} instead
299      */
300     @Deprecated
301     @Override
getMinLoopTime()302     public long getMinLoopTime() {
303         return mMinLoopTime;
304     }
305 
306     /**
307      * {@inheritDoc}
308      */
309     @Override
getLoopTime()310     public long getLoopTime() {
311         if (mMaxRandomLoopTime != null) {
312             long randomizedValue = mMaxRandomLoopTime - mMinLoopTime;
313             if (randomizedValue > 0) {
314                 return mMinLoopTime + Math.round(randomizedValue * Math.random());
315             } else {
316                 CLog.e("max loop time %d is less than min loop time %d", mMaxRandomLoopTime,
317                         mMinLoopTime);
318             }
319         }
320         return mMinLoopTime;
321     }
322 
323 
324     @Override
clone()325     public ICommandOptions clone() {
326         CommandOptions clone = new CommandOptions();
327         try {
328             OptionCopier.copyOptions(this, clone);
329         } catch (ConfigurationException e) {
330             CLog.e("failed to clone command options: %s", e.getMessage());
331         }
332         return clone;
333     }
334 
335     /**
336      * {@inheritDoc}
337      */
338     @Override
runOnAllDevices()339     public boolean runOnAllDevices() {
340         return mAllDevices;
341     }
342 
343     /**
344      * {@inheritDoc}
345      */
346     @Override
takeBugreportOnInvocationEnded()347     public boolean takeBugreportOnInvocationEnded() {
348         return mTakeBugreportOnInvocationEnded;
349     }
350 
351     /** {@inheritDoc} */
352     @Override
setBugreportOnInvocationEnded(boolean takeBugreport)353     public void setBugreportOnInvocationEnded(boolean takeBugreport) {
354         mTakeBugreportOnInvocationEnded = takeBugreport;
355     }
356 
357     /**
358      * {@inheritDoc}
359      */
360     @Override
takeBugreportzOnInvocationEnded()361     public boolean takeBugreportzOnInvocationEnded() {
362         return mTakeBugreportzOnInvocationEnded;
363     }
364 
365     /** {@inheritDoc} */
366     @Override
setBugreportzOnInvocationEnded(boolean takeBugreportz)367     public void setBugreportzOnInvocationEnded(boolean takeBugreportz) {
368         mTakeBugreportzOnInvocationEnded = takeBugreportz;
369     }
370 
371     /**
372      * {@inheritDoc}
373      */
374     @Override
getInvocationTimeout()375     public long getInvocationTimeout() {
376         return mInvocationTimeout;
377     }
378 
379     /**
380      * {@inheritDoc}
381      */
382     @Override
setInvocationTimeout(Long invocationTimeout)383     public void setInvocationTimeout(Long invocationTimeout) {
384         mInvocationTimeout = invocationTimeout;
385     }
386 
387     /**
388      * {@inheritDoc}
389      */
390     @Override
getShardCount()391     public Integer getShardCount() {
392         return mShardCount;
393     }
394 
395     /**
396      * {@inheritDoc}
397      */
398     @Override
setShardCount(Integer shardCount)399     public void setShardCount(Integer shardCount) {
400         mShardCount = shardCount;
401     }
402 
403     /**
404      * {@inheritDoc}
405      */
406     @Override
getShardIndex()407     public Integer getShardIndex() {
408         return mShardIndex;
409     }
410 
411     /**
412      * {@inheritDoc}
413      */
414     @Override
setShardIndex(Integer shardIndex)415     public void setShardIndex(Integer shardIndex) {
416         mShardIndex = shardIndex;
417     }
418 
419     /** {@inheritDoc} */
420     @Override
shouldUseTokenSharding()421     public boolean shouldUseTokenSharding() {
422         return mTokenSharding;
423     }
424 
425     /**
426      * {@inheritDoc}
427      */
428     @Override
setTestTag(String testTag)429     public void setTestTag(String testTag) {
430        mTestTag = testTag;
431     }
432 
433     /**
434      * {@inheritDoc}
435      */
436     @Override
getTestTag()437     public String getTestTag() {
438         return mTestTag;
439     }
440 
441     /**
442      * {@inheritDoc}
443      */
444     @Override
getTestTagSuffix()445     public String getTestTagSuffix() {
446         return mTestTagSuffix;
447     }
448 
449     /** {@inheritDoc} */
450     @Override
451 
shouldSkipPreDeviceSetup()452     public boolean shouldSkipPreDeviceSetup() {
453         return mSkipPreDeviceSetup;
454     }
455 
456     /** {@inheritDoc} */
457     @Override
shouldUseDynamicSharding()458     public boolean shouldUseDynamicSharding() {
459         return mDynamicSharding;
460     }
461 
462     /** {@inheritDoc} */
463     @Override
getInvocationData()464     public UniqueMultiMap<String, String> getInvocationData() {
465         return mInvocationData;
466     }
467 
468     /** {@inheritDoc} */
469     @Override
shouldUseSandboxing()470     public boolean shouldUseSandboxing() {
471         return mUseSandbox;
472     }
473 
474     /** {@inheritDoc} */
475     @Override
setShouldUseSandboxing(boolean use)476     public void setShouldUseSandboxing(boolean use) {
477         mUseSandbox = use;
478     }
479 
480     /** {@inheritDoc} */
481     @Override
shouldUseSandboxTestMode()482     public boolean shouldUseSandboxTestMode() {
483         return mSandboxTestMode;
484     }
485 
486     /** {@inheritDoc} */
487     @Override
setUseSandboxTestMode(boolean use)488     public void setUseSandboxTestMode(boolean use) {
489         mSandboxTestMode = use;
490     }
491 
492     /** {@inheritDoc} */
493     @Override
shouldUseRemoteSandboxMode()494     public boolean shouldUseRemoteSandboxMode() {
495         return mUseRemoteSandbox;
496     }
497 
498     /** {@inheritDoc} */
499     @Override
getAutoLogCollectors()500     public Set<AutoLogCollector> getAutoLogCollectors() {
501         return mAutoCollectors;
502     }
503 
504     /** {@inheritDoc} */
505     @Override
setAutoLogCollectors(Set<AutoLogCollector> autoLogCollectors)506     public void setAutoLogCollectors(Set<AutoLogCollector> autoLogCollectors) {
507         mAutoCollectors = autoLogCollectors;
508     }
509 
510     /** {@inheritDoc} */
511     @Override
captureScreenshotOnFailure()512     public boolean captureScreenshotOnFailure() {
513         return mScreenshotOnFailure;
514     }
515 
516     /** {@inheritDoc} */
517     @Override
captureLogcatOnFailure()518     public boolean captureLogcatOnFailure() {
519         return mLogcatOnFailure;
520     }
521 
522     /** {@inheritDoc} */
523     @Override
getHostLogSuffix()524     public String getHostLogSuffix() {
525         return mHostLogSuffix;
526     }
527 
528     /** {@inheritDoc} */
529     @Override
setHostLogSuffix(String suffix)530     public void setHostLogSuffix(String suffix) {
531         mHostLogSuffix = suffix;
532     }
533 
534     /** {@inheritDoc} */
535     @Override
shouldUseParallelRemoteSetup()536     public boolean shouldUseParallelRemoteSetup() {
537         return mUseParallelRemoteSetup;
538     }
539 }
540