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     /**
    141      * Set the help mode for the config.
    142      * <p/>
    143      * Exposed for testing.
    144      */
    145     void setHelpMode(boolean helpMode) {
    146         mHelpMode = helpMode;
    147     }
    148 
    149     /**
    150      * {@inheritDoc}
    151      */
    152     @Override
    153     public boolean isHelpMode() {
    154         return mHelpMode;
    155     }
    156 
    157     /**
    158      * {@inheritDoc}
    159      */
    160     @Override
    161     public boolean isFullHelpMode() {
    162         return mFullHelpMode;
    163     }
    164 
    165     /**
    166      * Set the json help mode for the config.
    167      * <p/>
    168      * Exposed for testing.
    169      */
    170     void setJsonHelpMode(boolean jsonHelpMode) {
    171         mJsonHelpMode = jsonHelpMode;
    172     }
    173 
    174     /**
    175      * {@inheritDoc}
    176      */
    177     @Override
    178     public boolean isJsonHelpMode() {
    179         return mJsonHelpMode;
    180     }
    181 
    182     /**
    183      * Set the dry run mode for the config.
    184      * <p/>
    185      * Exposed for testing.
    186      */
    187     void setDryRunMode(boolean dryRunMode) {
    188         mDryRunMode = dryRunMode;
    189     }
    190 
    191     /**
    192      * {@inheritDoc}
    193      */
    194     @Override
    195     public boolean isDryRunMode() {
    196         return mDryRunMode || mNoisyDryRunMode;
    197     }
    198 
    199     /**
    200      * {@inheritDoc}
    201      */
    202     @Override
    203     public boolean isNoisyDryRunMode() {
    204         return mNoisyDryRunMode;
    205     }
    206 
    207     /**
    208      * Set the loop mode for the config.
    209      */
    210     @Override
    211     public void setLoopMode(boolean loopMode) {
    212         mLoopMode = loopMode;
    213     }
    214 
    215     /**
    216      * {@inheritDoc}
    217      */
    218     @Override
    219     public boolean isLoopMode() {
    220         return mLoopMode;
    221     }
    222 
    223     /**
    224      * Set the min loop time for the config.
    225      * <p/>
    226      * Exposed for testing.
    227      */
    228     void setMinLoopTime(long loopTime) {
    229         mMinLoopTime = loopTime;
    230     }
    231 
    232     /**
    233      * {@inheritDoc}
    234      * @deprecated use {@link #getLoopTime()} instead
    235      */
    236     @Deprecated
    237     @Override
    238     public long getMinLoopTime() {
    239         return mMinLoopTime;
    240     }
    241 
    242     /**
    243      * {@inheritDoc}
    244      */
    245     @Override
    246     public long getLoopTime() {
    247         if (mMaxRandomLoopTime != null) {
    248             long randomizedValue = mMaxRandomLoopTime - mMinLoopTime;
    249             if (randomizedValue > 0) {
    250                 return mMinLoopTime + Math.round(randomizedValue * Math.random());
    251             } else {
    252                 CLog.e("max loop time %d is less than min loop time %d", mMaxRandomLoopTime,
    253                         mMinLoopTime);
    254             }
    255         }
    256         return mMinLoopTime;
    257     }
    258 
    259 
    260     @Override
    261     public ICommandOptions clone() {
    262         CommandOptions clone = new CommandOptions();
    263         try {
    264             OptionCopier.copyOptions(this, clone);
    265         } catch (ConfigurationException e) {
    266             CLog.e("failed to clone command options: %s", e.getMessage());
    267         }
    268         return clone;
    269     }
    270 
    271     /**
    272      * {@inheritDoc}
    273      */
    274     @Override
    275     public boolean runOnAllDevices() {
    276         return mAllDevices;
    277     }
    278 
    279     /**
    280      * {@inheritDoc}
    281      */
    282     @Override
    283     public boolean takeBugreportOnInvocationEnded() {
    284         return mTakeBugreportOnInvocationEnded;
    285     }
    286 
    287     /**
    288      * {@inheritDoc}
    289      */
    290     @Override
    291     public boolean takeBugreportzOnInvocationEnded() {
    292         return mTakeBugreportzOnInvocationEnded;
    293     }
    294 
    295     /**
    296      * {@inheritDoc}
    297      */
    298     @Override
    299     public long getInvocationTimeout() {
    300         return mInvocationTimeout;
    301     }
    302 
    303     /**
    304      * {@inheritDoc}
    305      */
    306     @Override
    307     public void setInvocationTimeout(Long invocationTimeout) {
    308         mInvocationTimeout = invocationTimeout;
    309     }
    310 
    311     /**
    312      * {@inheritDoc}
    313      */
    314     @Override
    315     public Integer getShardCount() {
    316         return mShardCount;
    317     }
    318 
    319     /**
    320      * {@inheritDoc}
    321      */
    322     @Override
    323     public void setShardCount(Integer shardCount) {
    324         mShardCount = shardCount;
    325     }
    326 
    327     /**
    328      * {@inheritDoc}
    329      */
    330     @Override
    331     public Integer getShardIndex() {
    332         return mShardIndex;
    333     }
    334 
    335     /**
    336      * {@inheritDoc}
    337      */
    338     @Override
    339     public void setShardIndex(Integer shardIndex) {
    340         mShardIndex = shardIndex;
    341     }
    342 
    343     /**
    344      * {@inheritDoc}
    345      */
    346     @Override
    347     public void setTestTag(String testTag) {
    348        mTestTag = testTag;
    349     }
    350 
    351     /**
    352      * {@inheritDoc}
    353      */
    354     @Override
    355     public String getTestTag() {
    356         return mTestTag;
    357     }
    358 
    359     /**
    360      * {@inheritDoc}
    361      */
    362     @Override
    363     public String getTestTagSuffix() {
    364         return mTestTagSuffix;
    365     }
    366 
    367     /** {@inheritDoc} */
    368     @Override
    369 
    370     public boolean shouldSkipPreDeviceSetup() {
    371         return mSkipPreDeviceSetup;
    372     }
    373 
    374     /** {@inheritDoc} */
    375     @Override
    376     public boolean shouldUseDynamicSharding() {
    377         return mDynamicSharding;
    378     }
    379 
    380     /** {@inheritDoc} */
    381     @Override
    382     public UniqueMultiMap<String, String> getInvocationData() {
    383         return mInvocationData;
    384     }
    385 
    386     /** {@inheritDoc} */
    387     @Override
    388     public boolean shouldUseTfSharding() {
    389         return mUseTfSharding;
    390     }
    391 }
    392