• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     /** Metadata key for a config to specify if it is prioritizing host config. */
54     public static final String PRIORITIZE_HOST_CONFIG_KEY = "prioritize-host-config";
55 
56     /** Metadata key for a config to specify the module dir path when it's a module config. */
57     public static final String MODULE_DIR_PATH_KEY = "module-dir-path";
58 
59     @Option(name = "test-suite-tag", description = "A membership tag to suite. Can be repeated.")
60     private List<String> mSuiteTags = new ArrayList<>();
61 
62     @Option(name = "metadata", description = "Metadata associated with this configuration, can be "
63             + "free formed key value pairs, and a key may be associated with multiple values.")
64     private MultiMap<String, String> mMetaData = new MultiMap<>();
65 
66     @Option(
67         name = "not-shardable",
68         description =
69                 "A metadata that allows a suite configuration to specify that it cannot be "
70                         + "sharded. Not because it doesn't support it but because it doesn't make "
71                         + "sense."
72     )
73     private boolean mNotShardable = false;
74 
75     @Option(
76             name = "not-strict-shardable",
77             description =
78                     "A metadata to allows a suite configuration to specify that it cannot be"
79                             + " sharded in a strict context (independent shards). If a config is"
80                             + " already not-shardable, it will be not-strict-shardable.")
81     private boolean mNotStrictShardable = false;
82 
83     @Option(
84             name = "not-iremotetest-shardable",
85             description =
86                     "A metadata to allows a suite configuration to specify that it cannot be"
87                             + " sharded in a strict context (independent shards). If a config is"
88                             + " already not-shardable, it will be not-strict-shardable.")
89     private boolean mNotIRemoteTestShardable = false;
90 
91     @Option(
92         name = "use-sandboxing",
93         description = "Option used to notify an invocation that it is running in a sandbox."
94     )
95     private boolean mUseSandboxing = false;
96 
97     /** Optional Abi information the configuration will be run against. */
98     private IAbi mAbi = null;
99     /** Optional for a module configuration, the original name of the module. */
100     private String mModuleName = null;
101     /** Optional: track the shard index of the invocation */
102     private Integer mShardIndex = null;
103 
104     private MultiMap<String, String> mInternalMetaData = new MultiMap<>();
105 
106     /** a list of options applicable to rerun the test */
107     private final List<OptionDef> mRerunOptions = new ArrayList<>();
108 
109     /** Returns the list of suite tags the test is part of. */
getSuiteTags()110     public List<String> getSuiteTags() {
111         return mSuiteTags;
112     }
113 
114     /** Sets the list of suite tags the test is part of. */
setSuiteTags(List<String> suiteTags)115     public void setSuiteTags(List<String> suiteTags) {
116         mSuiteTags = suiteTags;
117     }
118 
119     /** Retrieves all configured metadata and return a copy of the map. */
getAllMetaData()120     public MultiMap<String, String> getAllMetaData() {
121         MultiMap<String, String> copy = new MultiMap<>();
122         copy.putAll(mMetaData);
123         copy.putAll(mInternalMetaData);
124         return copy;
125     }
126 
127     /** Get the named metadata entries */
getMetaData(String name)128     public List<String> getMetaData(String name) {
129         MultiMap<String, String> copy = new MultiMap<>();
130         copy.putAll(mMetaData);
131         copy.putAll(mInternalMetaData);
132         List<String> entry = copy.get(name);
133         if (entry == null) {
134             return null;
135         }
136         return new ArrayList<>(entry);
137     }
138 
139     @VisibleForTesting
setMetaData(MultiMap<String, String> metadata)140     public void setMetaData(MultiMap<String, String> metadata) {
141         mMetaData = metadata;
142     }
143 
144     /**
145      * Add a value for a given key to the metadata entries.
146      *
147      * @param key {@link String} of the key to add values to.
148      * @param value A{@link String} of the additional value.
149      */
addMetadata(String key, String value)150     public void addMetadata(String key, String value) {
151         mInternalMetaData.put(key, value);
152     }
153 
154     /**
155      * Add more values of a given key to the metadata entries.
156      *
157      * @param key {@link String} of the key to add values to.
158      * @param values a list of {@link String} of the additional values.
159      */
addMetadata(String key, List<String> values)160     public void addMetadata(String key, List<String> values) {
161         for (String source : values) {
162             mInternalMetaData.put(key, source);
163         }
164     }
165 
166     /**
167      * Remove the tracking of the specified metadata key.
168      */
removeMetadata(String key)169     public List<String> removeMetadata(String key) {
170         return mInternalMetaData.remove(key);
171     }
172 
173     /** Returns if the configuration is shardable or not as part of a suite */
isNotShardable()174     public boolean isNotShardable() {
175         return mNotShardable;
176     }
177 
178     /** Returns if the configuration is strict shardable or not as part of a suite */
isNotStrictShardable()179     public boolean isNotStrictShardable() {
180         return mNotStrictShardable;
181     }
182 
183     /** Returns if the configuration should split the IRemoteTest into different modules. */
isNotIRemoteTestShardable()184     public boolean isNotIRemoteTestShardable() {
185         return mNotIRemoteTestShardable;
186     }
187 
setNotIRemoteTestShardable(boolean notIRemoteTestShardable)188     public void setNotIRemoteTestShardable(boolean notIRemoteTestShardable) {
189         mNotIRemoteTestShardable = notIRemoteTestShardable;
190     }
191 
192     /** Sets the abi the configuration is going to run against. */
setAbi(IAbi abi)193     public void setAbi(IAbi abi) {
194         mAbi = abi;
195     }
196 
197     /** Returns the abi the configuration is running against if known, null otherwise. */
getAbi()198     public IAbi getAbi() {
199         return mAbi;
200     }
201 
202     /** If this configuration represents a module, we can set the module name associated with it. */
setModuleName(String name)203     public void setModuleName(String name) {
204         mModuleName = name;
205     }
206 
207     /** Returns the module name of the module configuration. */
getModuleName()208     public String getModuleName() {
209         return mModuleName;
210     }
211 
212     /** Returns true if the invocation should run in sandboxed mode. False otherwise. */
shouldUseSandbox()213     public boolean shouldUseSandbox() {
214         return mUseSandboxing;
215     }
216 
217     /** Sets whether or not a config will run in sandboxed mode or not. */
setSandboxed(boolean useSandboxed)218     public void setSandboxed(boolean useSandboxed) {
219         mUseSandboxing = useSandboxed;
220     }
221 
222     /** Set the shard index for the invocation in local sharding. */
setShardIndex(int index)223     public void setShardIndex(int index) {
224         mShardIndex = index;
225     }
226 
227     /** Get the shard index of the invocation during local sharding. Returns null if no sharding. */
getShardIndex()228     public Integer getShardIndex() {
229         return mShardIndex;
230     }
231 
232     /**
233      * Add the option to a list of options that can be used to rerun the test.
234      *
235      * @param optionDef a {@link OptionDef} object of the test option.
236      */
addRerunOption(OptionDef optionDef)237     public void addRerunOption(OptionDef optionDef) {
238         mRerunOptions.add(optionDef);
239     }
240 
241     /** Get the list of {@link OptionDef} that can be used for rerun. */
getRerunOptions()242     public List<OptionDef> getRerunOptions() {
243         return mRerunOptions;
244     }
245 
246     /** Convert the current instance of the descriptor into its proto format. */
toProto()247     public ConfigurationDescription.Descriptor toProto() {
248         Descriptor.Builder descriptorBuilder = Descriptor.newBuilder();
249         // Test Suite Tags
250         descriptorBuilder.addAllTestSuiteTag(mSuiteTags);
251         // Metadata
252         List<Metadata> metadatas = new ArrayList<>();
253         MultiMap<String, String> local = getAllMetaData();
254         for (String key : local.keySet()) {
255             Metadata value = Metadata.newBuilder().setKey(key).addAllValue(local.get(key)).build();
256             metadatas.add(value);
257         }
258         descriptorBuilder.addAllMetadata(metadatas);
259         // Shardable
260         descriptorBuilder.setShardable(!mNotShardable);
261         // Strict Shardable
262         descriptorBuilder.setStrictShardable(!mNotStrictShardable);
263         // Use sandboxing
264         descriptorBuilder.setUseSandboxing(mUseSandboxing);
265         // Module name
266         if (mModuleName != null) {
267             descriptorBuilder.setModuleName(mModuleName);
268         }
269         // Abi
270         if (mAbi != null) {
271             descriptorBuilder.setAbi(mAbi.toProto());
272         }
273         return descriptorBuilder.build();
274     }
275 
276     /** Inverse operation from {@link #toProto()} to get the object back. */
fromProto( ConfigurationDescription.Descriptor protoDescriptor)277     public static ConfigurationDescriptor fromProto(
278             ConfigurationDescription.Descriptor protoDescriptor) {
279         ConfigurationDescriptor configDescriptor = new ConfigurationDescriptor();
280         // Test Suite Tags
281         configDescriptor.mSuiteTags.addAll(protoDescriptor.getTestSuiteTagList());
282         // Metadata
283         for (Metadata meta : protoDescriptor.getMetadataList()) {
284             for (String value : meta.getValueList()) {
285                 configDescriptor.mMetaData.put(meta.getKey(), value);
286             }
287         }
288         // Shardable
289         configDescriptor.mNotShardable = !protoDescriptor.getShardable();
290         // Strict Shardable
291         configDescriptor.mNotStrictShardable = !protoDescriptor.getStrictShardable();
292         // Use sandboxing
293         configDescriptor.mUseSandboxing = protoDescriptor.getUseSandboxing();
294         // Module Name
295         if (!protoDescriptor.getModuleName().isEmpty()) {
296             configDescriptor.mModuleName = protoDescriptor.getModuleName();
297         }
298         // Abi
299         if (protoDescriptor.hasAbi()) {
300             configDescriptor.mAbi = Abi.fromProto(protoDescriptor.getAbi());
301         }
302         return configDescriptor;
303     }
304 
305     /** Return a deep-copy of the {@link ConfigurationDescriptor} object. */
306     @Override
clone()307     public ConfigurationDescriptor clone() {
308         return fromProto(this.toProto());
309     }
310 }
311