1 /*
2  * Copyright (C) 2021 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.testtype.suite;
17 
18 import com.android.tradefed.build.BuildRetrievalError;
19 import com.android.tradefed.config.DynamicRemoteFileResolver;
20 import com.android.tradefed.invoker.TestInformation;
21 import com.android.tradefed.log.LogUtil.CLog;
22 import com.android.tradefed.service.IRemoteFeature;
23 import com.android.tradefed.testtype.ITestInformationReceiver;
24 import com.android.tradefed.util.StreamUtil;
25 
26 import com.proto.tradefed.feature.ErrorInfo;
27 import com.proto.tradefed.feature.FeatureRequest;
28 import com.proto.tradefed.feature.FeatureResponse;
29 
30 import java.io.File;
31 import java.util.Arrays;
32 import java.util.HashMap;
33 import java.util.HashSet;
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37 
38 /** Resolve a partial download request. */
39 public class ResolvePartialDownload implements IRemoteFeature, ITestInformationReceiver {
40 
41     public static final String RESOLVE_PARTIAL_DOWNLOAD_FEATURE_NAME = "resolvePartialDownload";
42     public static final String INCLUDE_FILTERS = "include_filters";
43     public static final String EXCLUDE_FILTERS = "exclude_filters";
44     public static final String DESTINATION_DIR = "destination_dir";
45     public static final String REMOTE_PATHS = "remote_paths";
46 
47     private TestInformation mTestInformation;
48     private DynamicRemoteFileResolver mResolver;
49 
ResolvePartialDownload()50     public ResolvePartialDownload() {}
51 
ResolvePartialDownload(DynamicRemoteFileResolver resolver)52     protected ResolvePartialDownload(DynamicRemoteFileResolver resolver) {
53         this();
54         mResolver = resolver;
55     }
56 
57     @Override
setTestInformation(TestInformation testInformation)58     public void setTestInformation(TestInformation testInformation) {
59         mTestInformation = testInformation;
60     }
61 
62     @Override
getTestInformation()63     public TestInformation getTestInformation() {
64         return mTestInformation;
65     }
66 
67     @Override
getName()68     public String getName() {
69         return RESOLVE_PARTIAL_DOWNLOAD_FEATURE_NAME;
70     }
71 
72     @Override
execute(FeatureRequest request)73     public FeatureResponse execute(FeatureRequest request) {
74         FeatureResponse.Builder responseBuilder = FeatureResponse.newBuilder();
75         try {
76             DynamicRemoteFileResolver dynamicResolver = getResolver();
77             dynamicResolver.setDevice(mTestInformation.getDevice());
78 
79             Map<String, String> args = new HashMap<>(request.getArgsMap());
80             String destDir = args.remove(DESTINATION_DIR);
81             String includeFilter = args.remove(INCLUDE_FILTERS);
82             List<String> includeFilterList = null;
83             if (includeFilter != null) {
84                 includeFilterList = Arrays.asList(includeFilter);
85             }
86             String excludeFilter = args.remove(EXCLUDE_FILTERS);
87             List<String> excludeFilterList = null;
88             if (excludeFilter != null) {
89                 excludeFilterList = Arrays.asList(excludeFilter);
90             }
91 
92             dynamicResolver.addExtraArgs(args);
93 
94             String remotePaths = args.remove(REMOTE_PATHS);
95             Set<String> allPaths = new HashSet<>();
96             List<String> remotePathList = null;
97             if (remotePaths != null) {
98                 remotePathList = Arrays.asList(remotePaths.split(";"));
99                 allPaths.addAll(remotePathList);
100             }
101             // TODO: Remove this when all clients pass explicitly the remote paths
102             for (File remotePath : mTestInformation.getBuildInfo().getRemoteFiles()) {
103                 allPaths.add(remotePath.toString());
104             }
105             // TODO: Report errors if no remote paths to be resolved ?
106             for (String path : allPaths) {
107                 dynamicResolver.resolvePartialDownloadZip(
108                         new File(destDir), path, includeFilterList, excludeFilterList);
109             }
110             if (allPaths.isEmpty()) {
111                 responseBuilder.setResponse("No remote paths specified. Nothing downloaded.");
112             }
113         } catch (RuntimeException | BuildRetrievalError e) {
114             responseBuilder.setErrorInfo(
115                     ErrorInfo.newBuilder().setErrorTrace(StreamUtil.getStackTrace(e)));
116             CLog.e(e);
117         }
118         return responseBuilder.build();
119     }
120 
getResolver()121     private DynamicRemoteFileResolver getResolver() {
122         if (mResolver == null) {
123             return new DynamicRemoteFileResolver();
124         }
125         return mResolver;
126     }
127 }
128