1 /*
2  * Copyright (C) 2020 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.invoker.shard;
17 
18 import com.android.ddmlib.Log.LogLevel;
19 import com.android.tradefed.build.StubBuildProvider;
20 import com.android.tradefed.config.Configuration;
21 import com.android.tradefed.config.ConfigurationException;
22 import com.android.tradefed.config.IConfiguration;
23 import com.android.tradefed.config.IDeviceConfiguration;
24 import com.android.tradefed.log.LogUtil.CLog;
25 import com.android.tradefed.util.keystore.IKeyStoreClient;
26 
27 import java.util.ArrayList;
28 import java.util.HashSet;
29 import java.util.List;
30 import java.util.Set;
31 
32 /** Replicate a setup for one device to all other devices that will be part of sharding. */
33 public class ParentShardReplicate {
34 
35     /**
36      * Clone the setup for one devices to as many devices as sharding will target.
37      *
38      * @param config The config that will carry the replicate.
39      * @param client The keystore client.
40      */
replicatedSetup(IConfiguration config, IKeyStoreClient client)41     public static void replicatedSetup(IConfiguration config, IKeyStoreClient client) {
42         if (!config.getCommandOptions().shouldUseReplicateSetup()) {
43             return;
44         }
45         if (config.getDeviceConfig().size() != 1) {
46             return;
47         }
48 
49         // TODO: Support local sharding for multi-device tests.
50         Integer shardCount = config.getCommandOptions().getShardCount();
51         Integer shardIndex = config.getCommandOptions().getShardIndex();
52         Integer deviceCount = shardCount;
53         if (shardCount == null || shardIndex != null) {
54             // TODO: Remove the dependency on multiDeviceCount.
55             deviceCount = config.getCommandOptions().getMultiDeviceCount();
56             if (deviceCount == null || deviceCount < 2) {
57                 return;
58             }
59         }
60         CLog.logAndDisplay(LogLevel.DEBUG, "Using replicated setup.");
61         try {
62             List<IDeviceConfiguration> currentConfigs = config.getDeviceConfig();
63             Set<String> objectToReplicate =
64                     new HashSet<>(Configuration.getMultiDeviceSupportedTag());
65             objectToReplicate.remove(Configuration.BUILD_PROVIDER_TYPE_NAME);
66             for (int i = 0; i < deviceCount - 1; i++) {
67                 IConfiguration deepCopy =
68                         config.partialDeepClone(new ArrayList<>(objectToReplicate), client);
69                 String newName = String.format("expanded-%s", i);
70                 IDeviceConfiguration newDeviceConfig =
71                         deepCopy.getDeviceConfig().get(0).clone(newName);
72                 // Stub the build provider since it should never be called
73                 newDeviceConfig.addSpecificConfig(new StubBuildProvider());
74                 currentConfigs.add(newDeviceConfig);
75             }
76             config.setDeviceConfigList(currentConfigs);
77         } catch (ConfigurationException e) {
78             CLog.e("Failed replicated setup configuration:");
79             CLog.e(e);
80         }
81     }
82 }
83