Home | History | Annotate | Download | only in command
      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.config.OptionCopier;
     22 import com.android.tradefed.config.OptionUpdateRule;
     23 import com.android.tradefed.log.LogUtil.CLog;
     24 import com.android.tradefed.util.UniqueMultiMap;
     25 
     26 /**
     27  * Implementation of {@link ICommandOptions}.
     28  */
     29 public class CommandOptions implements ICommandOptions {
     30 
     31     @Option(name = "help", description =
     32         "display the help text for the most important/critical options.",
     33         importance = Importance.ALWAYS)
     34     private boolean mHelpMode = false;
     35 
     36     @Option(name = "help-all", description = "display the full help text for all options.",
     37             importance = Importance.ALWAYS)
     38     private boolean mFullHelpMode = false;
     39 
     40     @Option(name = "json-help", description = "display the full help in json format.")
     41     private boolean mJsonHelpMode = false;
     42 
     43     public static final String DRY_RUN_OPTION = "dry-run";
     44 
     45     @Option(
     46         name = DRY_RUN_OPTION,
     47         description =
     48                 "build but don't actually run the command.  Intended as a quick check "
     49                         + "to ensure that a command is runnable.",
     50         importance = Importance.ALWAYS
     51     )
     52     private boolean mDryRunMode = false;
     53 
     54     @Option(name = "noisy-dry-run",
     55             description = "build but don't actually run the command.  This version prints the " +
     56                     "command to the console.  Intended for cmdfile debugging.",
     57             importance = Importance.ALWAYS)
     58     private boolean mNoisyDryRunMode = false;
     59 
     60     @Option(name = "min-loop-time", description =
     61             "the minimum invocation time in ms when in loop mode.")
     62     private Long mMinLoopTime = 10L * 60L * 1000L;
     63 
     64     @Option(name = "max-random-loop-time", description =
     65             "the maximum time to wait between invocation attempts when in loop mode. " +
     66             "when set, the actual value will be a random number between min-loop-time and this " +
     67             "number.",
     68             updateRule = OptionUpdateRule.LEAST)
     69     private Long mMaxRandomLoopTime = null;
     70 
     71     @Option(name = "test-tag", description = "Identifier for the invocation during reporting.")
     72     private String mTestTag = "stub";
     73 
     74     @Option(name = "test-tag-suffix", description = "suffix for test-tag. appended to test-tag to "
     75             + "represents some variants of one test.")
     76     private String mTestTagSuffix = null;
     77 
     78     @Option(name = "loop", description = "keep running continuously.",
     79             importance = Importance.ALWAYS)
     80     private boolean mLoopMode = false;
     81 
     82     @Option(name = "all-devices", description =
     83             "fork this command to run on all connected devices.")
     84     private boolean mAllDevices = false;
     85 
     86     @Option(name = "bugreport-on-invocation-ended", description =
     87             "take a bugreport when the test invocation has ended")
     88     private boolean mTakeBugreportOnInvocationEnded = false;
     89 
     90     @Option(name = "bugreportz-on-invocation-ended", description = "Attempt to take a bugreportz "
     91             + "instead of bugreport during the test invocation final bugreport.")
     92     private boolean mTakeBugreportzOnInvocationEnded = false;
     93 
     94     @Option(name = "invocation-timeout", description =
     95             "the maximum time to wait for an invocation to terminate before attempting to force"
     96             + "stop it.", isTimeVal = true)
     97     private long mInvocationTimeout = 0;
     98 
     99     @Option(name = "shard-count", description =
    100             "the number of total shards to run. Without --shard-index option, this will cause " +
    101             "the command to spawn multiple shards in the current TF instance. With --shard-index " +
    102             "option, it will cause the command to run a single shard of tests only.")
    103     private Integer mShardCount;
    104 
    105     @Option(name = "shard-index", description =
    106             "the index of shard to run. Only set if shard-count > 1 and the value is in range " +
    107             "[0, shard-count)")
    108     private Integer mShardIndex;
    109 
    110     @Option(
    111         name = "skip-pre-device-setup",
    112         description =
    113                 "allow TestInvocation to skip calling device.preInvocationSetup. This is for "
    114                         + "delaying device setup when the test runs with VersionedTfLauncher."
    115     )
    116     private boolean mSkipPreDeviceSetup = false;
    117 
    118     @Option(
    119         name = "dynamic-sharding",
    120         description =
    121                 "Allow to dynamically move IRemoteTest from one shard to another. Only for local "
    122                         + "sharding."
    123     )
    124     private boolean mDynamicSharding = true;
    125 
    126     @Option(
    127         name = "invocation-data",
    128         description =
    129                 "A map of values that describe the invocation, these values will be added to the "
    130                         + "invocation context."
    131     )
    132     private UniqueMultiMap<String, String> mInvocationData = new UniqueMultiMap<>();
    133 
    134     @Option(
    135         name = "disable-strict-sharding",
    136         description = "Temporary option to disable the new sharding logic while being tested."
    137     )
    138     private boolean mUseTfSharding = false;
    139 
    140     public static final String USE_SANDBOX = "use-sandbox";
    141 
    142     @Option(
    143         name = USE_SANDBOX,
    144         description = "Set if the invocation should use a sandbox to run or not."
    145     )
    146     private boolean mUseSandbox = false;
    147 
    148 
    149     /**
    150      * Set the help mode for the config.
    151      * <p/>
    152      * Exposed for testing.
    153      */
    154     void setHelpMode(boolean helpMode) {
    155         mHelpMode = helpMode;
    156     }
    157 
    158     /**
    159      * {@inheritDoc}
    160      */
    161     @Override
    162     public boolean isHelpMode() {
    163         return mHelpMode;
    164     }
    165 
    166     /**
    167      * {@inheritDoc}
    168      */
    169     @Override
    170     public boolean isFullHelpMode() {
    171         return mFullHelpMode;
    172     }
    173 
    174     /**
    175      * Set the json help mode for the config.
    176      * <p/>
    177      * Exposed for testing.
    178      */
    179     void setJsonHelpMode(boolean jsonHelpMode) {
    180         mJsonHelpMode = jsonHelpMode;
    181     }
    182 
    183     /**
    184      * {@inheritDoc}
    185      */
    186     @Override
    187     public boolean isJsonHelpMode() {
    188         return mJsonHelpMode;
    189     }
    190 
    191     /**
    192      * Set the dry run mode for the config.
    193      * <p/>
    194      * Exposed for testing.
    195      */
    196     void setDryRunMode(boolean dryRunMode) {
    197         mDryRunMode = dryRunMode;
    198     }
    199 
    200     /**
    201      * {@inheritDoc}
    202      */
    203     @Override
    204     public boolean isDryRunMode() {
    205         return mDryRunMode || mNoisyDryRunMode;
    206     }
    207 
    208     /**
    209      * {@inheritDoc}
    210      */
    211     @Override
    212     public boolean isNoisyDryRunMode() {
    213         return mNoisyDryRunMode;
    214     }
    215 
    216     /**
    217      * Set the loop mode for the config.
    218      */
    219     @Override
    220     public void setLoopMode(boolean loopMode) {
    221         mLoopMode = loopMode;
    222     }
    223 
    224     /**
    225      * {@inheritDoc}
    226      */
    227     @Override
    228     public boolean isLoopMode() {
    229         return mLoopMode;
    230     }
    231 
    232     /**
    233      * Set the min loop time for the config.
    234      * <p/>
    235      * Exposed for testing.
    236      */
    237     void setMinLoopTime(long loopTime) {
    238         mMinLoopTime = loopTime;
    239     }
    240 
    241     /**
    242      * {@inheritDoc}
    243      * @deprecated use {@link #getLoopTime()} instead
    244      */
    245     @Deprecated
    246     @Override
    247     public long getMinLoopTime() {
    248         return mMinLoopTime;
    249     }
    250 
    251     /**
    252      * {@inheritDoc}
    253      */
    254     @Override
    255     public long getLoopTime() {
    256         if (mMaxRandomLoopTime != null) {
    257             long randomizedValue = mMaxRandomLoopTime - mMinLoopTime;
    258             if (randomizedValue > 0) {
    259                 return mMinLoopTime + Math.round(randomizedValue * Math.random());
    260             } else {
    261                 CLog.e("max loop time %d is less than min loop time %d", mMaxRandomLoopTime,
    262                         mMinLoopTime);
    263             }
    264         }
    265         return mMinLoopTime;
    266     }
    267 
    268 
    269     @Override
    270     public ICommandOptions clone() {
    271         CommandOptions clone = new CommandOptions();
    272         try {
    273             OptionCopier.copyOptions(this, clone);
    274         } catch (ConfigurationException e) {
    275             CLog.e("failed to clone command options: %s", e.getMessage());
    276         }
    277         return clone;
    278     }
    279 
    280     /**
    281      * {@inheritDoc}
    282      */
    283     @Override
    284     public boolean runOnAllDevices() {
    285         return mAllDevices;
    286     }
    287 
    288     /**
    289      * {@inheritDoc}
    290      */
    291     @Override
    292     public boolean takeBugreportOnInvocationEnded() {
    293         return mTakeBugreportOnInvocationEnded;
    294     }
    295 
    296     /**
    297      * {@inheritDoc}
    298      */
    299     @Override
    300     public boolean takeBugreportzOnInvocationEnded() {
    301         return mTakeBugreportzOnInvocationEnded;
    302     }
    303 
    304     /**
    305      * {@inheritDoc}
    306      */
    307     @Override
    308     public long getInvocationTimeout() {
    309         return mInvocationTimeout;
    310     }
    311 
    312     /**
    313      * {@inheritDoc}
    314      */
    315     @Override
    316     public void setInvocationTimeout(Long invocationTimeout) {
    317         mInvocationTimeout = invocationTimeout;
    318     }
    319 
    320     /**
    321      * {@inheritDoc}
    322      */
    323     @Override
    324     public Integer getShardCount() {
    325         return mShardCount;
    326     }
    327 
    328     /**
    329      * {@inheritDoc}
    330      */
    331     @Override
    332     public void setShardCount(Integer shardCount) {
    333         mShardCount = shardCount;
    334     }
    335 
    336     /**
    337      * {@inheritDoc}
    338      */
    339     @Override
    340     public Integer getShardIndex() {
    341         return mShardIndex;
    342     }
    343 
    344     /**
    345      * {@inheritDoc}
    346      */
    347     @Override
    348     public void setShardIndex(Integer shardIndex) {
    349         mShardIndex = shardIndex;
    350     }
    351 
    352     /**
    353      * {@inheritDoc}
    354      */
    355     @Override
    356     public void setTestTag(String testTag) {
    357        mTestTag = testTag;
    358     }
    359 
    360     /**
    361      * {@inheritDoc}
    362      */
    363     @Override
    364     public String getTestTag() {
    365         return mTestTag;
    366     }
    367 
    368     /**
    369      * {@inheritDoc}
    370      */
    371     @Override
    372     public String getTestTagSuffix() {
    373         return mTestTagSuffix;
    374     }
    375 
    376     /** {@inheritDoc} */
    377     @Override
    378 
    379     public boolean shouldSkipPreDeviceSetup() {
    380         return mSkipPreDeviceSetup;
    381     }
    382 
    383     /** {@inheritDoc} */
    384     @Override
    385     public boolean shouldUseDynamicSharding() {
    386         return mDynamicSharding;
    387     }
    388 
    389     /** {@inheritDoc} */
    390     @Override
    391     public UniqueMultiMap<String, String> getInvocationData() {
    392         return mInvocationData;
    393     }
    394 
    395     /** {@inheritDoc} */
    396     @Override
    397     public boolean shouldUseTfSharding() {
    398         return mUseTfSharding;
    399     }
    400 
    401     /** {@inheritDoc} */
    402     @Override
    403     public boolean shouldUseSandboxing() {
    404         return mUseSandbox;
    405     }
    406 
    407     /** {@inheritDoc} */
    408     @Override
    409     public void setShouldUseSandboxing(boolean use) {
    410         mUseSandbox = use;
    411     }
    412 }
    413