1 /* 2 * Copyright (C) 2016 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.config; 17 18 import com.android.tradefed.build.BuildSerializedVersion; 19 import com.android.tradefed.config.proto.ConfigurationDescription; 20 import com.android.tradefed.config.proto.ConfigurationDescription.Descriptor; 21 import com.android.tradefed.config.proto.ConfigurationDescription.Metadata; 22 import com.android.tradefed.testtype.Abi; 23 import com.android.tradefed.testtype.IAbi; 24 import com.android.tradefed.util.MultiMap; 25 26 import com.google.common.annotations.VisibleForTesting; 27 28 import java.io.Serializable; 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /** 33 * Configuration Object that describes some aspect of the configuration itself. Like a membership 34 * test-suite-tag. This class cannot receive option values via command line. Only directly in the 35 * xml. 36 */ 37 @OptionClass(alias = "config-descriptor") 38 public class ConfigurationDescriptor implements Serializable, Cloneable { 39 40 /** Enum used to indicate local test runner. */ 41 public enum LocalTestRunner { 42 NONE, 43 ATEST; 44 } 45 46 private static final long serialVersionUID = BuildSerializedVersion.VERSION; 47 48 /** Metadata key for a config to specify that it was sharded. */ 49 public static final String LOCAL_SHARDED_KEY = "sharded"; 50 /** Metadata key for a config parameterization, optional. */ 51 public static final String ACTIVE_PARAMETER_KEY = "active-parameter"; 52 53 @Option(name = "test-suite-tag", description = "A membership tag to suite. Can be repeated.") 54 private List<String> mSuiteTags = new ArrayList<>(); 55 56 @Option(name = "metadata", description = "Metadata associated with this configuration, can be " 57 + "free formed key value pairs, and a key may be associated with multiple values.") 58 private MultiMap<String, String> mMetaData = new MultiMap<>(); 59 60 @Option( 61 name = "not-shardable", 62 description = 63 "A metadata that allows a suite configuration to specify that it cannot be " 64 + "sharded. Not because it doesn't support it but because it doesn't make " 65 + "sense." 66 ) 67 private boolean mNotShardable = false; 68 69 @Option( 70 name = "not-strict-shardable", 71 description = 72 "A metadata to allows a suite configuration to specify that it cannot be " 73 + "sharded in a strict context (independent shards). If a config is already " 74 + "not-shardable, it will be not-strict-shardable." 75 ) 76 private boolean mNotStrictShardable = false; 77 78 @Option( 79 name = "use-sandboxing", 80 description = "Option used to notify an invocation that it is running in a sandbox." 81 ) 82 private boolean mUseSandboxing = false; 83 84 /** Optional Abi information the configuration will be run against. */ 85 private IAbi mAbi = null; 86 /** Optional for a module configuration, the original name of the module. */ 87 private String mModuleName = null; 88 89 /** a list of options applicable to rerun the test */ 90 private final List<OptionDef> mRerunOptions = new ArrayList<>(); 91 92 /** Returns the list of suite tags the test is part of. */ getSuiteTags()93 public List<String> getSuiteTags() { 94 return mSuiteTags; 95 } 96 97 /** Sets the list of suite tags the test is part of. */ setSuiteTags(List<String> suiteTags)98 public void setSuiteTags(List<String> suiteTags) { 99 mSuiteTags = suiteTags; 100 } 101 102 /** Retrieves all configured metadata and return a copy of the map. */ getAllMetaData()103 public MultiMap<String, String> getAllMetaData() { 104 MultiMap<String, String> copy = new MultiMap<>(); 105 copy.putAll(mMetaData); 106 return copy; 107 } 108 109 /** Get the named metadata entries */ getMetaData(String name)110 public List<String> getMetaData(String name) { 111 List<String> entry = mMetaData.get(name); 112 if (entry == null) { 113 return null; 114 } 115 return new ArrayList<>(entry); 116 } 117 118 @VisibleForTesting setMetaData(MultiMap<String, String> metadata)119 public void setMetaData(MultiMap<String, String> metadata) { 120 mMetaData = metadata; 121 } 122 123 /** 124 * Add a value for a given key to the metadata entries. 125 * 126 * @param key {@link String} of the key to add values to. 127 * @param value A{@link String} of the additional value. 128 */ addMetadata(String key, String value)129 public void addMetadata(String key, String value) { 130 mMetaData.put(key, value); 131 } 132 133 /** 134 * Add more values of a given key to the metadata entries. 135 * 136 * @param key {@link String} of the key to add values to. 137 * @param values a list of {@link String} of the additional values. 138 */ addMetadata(String key, List<String> values)139 public void addMetadata(String key, List<String> values) { 140 for (String source : values) { 141 mMetaData.put(key, source); 142 } 143 } 144 145 /** Returns if the configuration is shardable or not as part of a suite */ isNotShardable()146 public boolean isNotShardable() { 147 return mNotShardable; 148 } 149 150 /** Returns if the configuration is strict shardable or not as part of a suite */ isNotStrictShardable()151 public boolean isNotStrictShardable() { 152 return mNotStrictShardable; 153 } 154 155 /** Sets the abi the configuration is going to run against. */ setAbi(IAbi abi)156 public void setAbi(IAbi abi) { 157 mAbi = abi; 158 } 159 160 /** Returns the abi the configuration is running against if known, null otherwise. */ getAbi()161 public IAbi getAbi() { 162 return mAbi; 163 } 164 165 /** If this configuration represents a module, we can set the module name associated with it. */ setModuleName(String name)166 public void setModuleName(String name) { 167 mModuleName = name; 168 } 169 170 /** Returns the module name of the module configuration. */ getModuleName()171 public String getModuleName() { 172 return mModuleName; 173 } 174 175 /** Returns true if the invocation should run in sandboxed mode. False otherwise. */ shouldUseSandbox()176 public boolean shouldUseSandbox() { 177 return mUseSandboxing; 178 } 179 180 /** Sets whether or not a config will run in sandboxed mode or not. */ setSandboxed(boolean useSandboxed)181 public void setSandboxed(boolean useSandboxed) { 182 mUseSandboxing = useSandboxed; 183 } 184 185 /** 186 * Add the option to a list of options that can be used to rerun the test. 187 * 188 * @param optionDef a {@link OptionDef} object of the test option. 189 */ addRerunOption(OptionDef optionDef)190 public void addRerunOption(OptionDef optionDef) { 191 mRerunOptions.add(optionDef); 192 } 193 194 /** Get the list of {@link OptionDef} that can be used for rerun. */ getRerunOptions()195 public List<OptionDef> getRerunOptions() { 196 return mRerunOptions; 197 } 198 199 /** Convert the current instance of the descriptor into its proto format. */ toProto()200 public ConfigurationDescription.Descriptor toProto() { 201 Descriptor.Builder descriptorBuilder = Descriptor.newBuilder(); 202 // Test Suite Tags 203 descriptorBuilder.addAllTestSuiteTag(mSuiteTags); 204 // Metadata 205 List<Metadata> metadatas = new ArrayList<>(); 206 for (String key : mMetaData.keySet()) { 207 Metadata value = 208 Metadata.newBuilder().setKey(key).addAllValue(mMetaData.get(key)).build(); 209 metadatas.add(value); 210 } 211 descriptorBuilder.addAllMetadata(metadatas); 212 // Shardable 213 descriptorBuilder.setShardable(!mNotShardable); 214 // Strict Shardable 215 descriptorBuilder.setStrictShardable(!mNotStrictShardable); 216 // Use sandboxing 217 descriptorBuilder.setUseSandboxing(mUseSandboxing); 218 // Module name 219 if (mModuleName != null) { 220 descriptorBuilder.setModuleName(mModuleName); 221 } 222 // Abi 223 if (mAbi != null) { 224 descriptorBuilder.setAbi(mAbi.toProto()); 225 } 226 return descriptorBuilder.build(); 227 } 228 229 /** Inverse operation from {@link #toProto()} to get the object back. */ fromProto( ConfigurationDescription.Descriptor protoDescriptor)230 public static ConfigurationDescriptor fromProto( 231 ConfigurationDescription.Descriptor protoDescriptor) { 232 ConfigurationDescriptor configDescriptor = new ConfigurationDescriptor(); 233 // Test Suite Tags 234 configDescriptor.mSuiteTags.addAll(protoDescriptor.getTestSuiteTagList()); 235 // Metadata 236 for (Metadata meta : protoDescriptor.getMetadataList()) { 237 for (String value : meta.getValueList()) { 238 configDescriptor.mMetaData.put(meta.getKey(), value); 239 } 240 } 241 // Shardable 242 configDescriptor.mNotShardable = !protoDescriptor.getShardable(); 243 // Strict Shardable 244 configDescriptor.mNotStrictShardable = !protoDescriptor.getStrictShardable(); 245 // Use sandboxing 246 configDescriptor.mUseSandboxing = protoDescriptor.getUseSandboxing(); 247 // Module Name 248 if (!protoDescriptor.getModuleName().isEmpty()) { 249 configDescriptor.mModuleName = protoDescriptor.getModuleName(); 250 } 251 // Abi 252 if (protoDescriptor.hasAbi()) { 253 configDescriptor.mAbi = Abi.fromProto(protoDescriptor.getAbi()); 254 } 255 return configDescriptor; 256 } 257 258 /** Return a deep-copy of the {@link ConfigurationDescriptor} object. */ 259 @Override clone()260 public ConfigurationDescriptor clone() { 261 return fromProto(this.toProto()); 262 } 263 } 264