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