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.config.filter; 17 18 import com.android.annotations.VisibleForTesting; 19 import com.android.ddmlib.Log.LogLevel; 20 import com.android.tradefed.config.ConfigurationException; 21 import com.android.tradefed.config.IConfiguration; 22 import com.android.tradefed.invoker.TestInvocation; 23 import com.android.tradefed.log.LogUtil.CLog; 24 import com.android.tradefed.service.TradefedFeatureClient; 25 26 import com.google.common.base.Joiner; 27 import com.google.common.base.Strings; 28 import com.google.common.collect.ImmutableSet; 29 import com.proto.tradefed.feature.FeatureResponse; 30 import com.proto.tradefed.feature.PartResponse; 31 32 import java.util.HashMap; 33 import java.util.Map; 34 import java.util.Set; 35 36 /** 37 * Helper to get the test options from the parent process. 38 */ 39 public class OptionFetcher implements AutoCloseable { 40 41 /** Set of options that should align with the parent process. */ 42 private static final Set<String> OPTION_TO_FETCH = 43 ImmutableSet.of( 44 "retry-isolation-grade", 45 "avd-in-parent", 46 "enable-tracing", 47 "auto-collect", 48 "skip-retry-in-presubmit", 49 "skip-retrying-list", 50 "remote-dynamic-sharding", 51 "remote-cache-instance-name", 52 "upload-cached-module-results", 53 "report-cache-results", 54 "report-cache-results-presubmit"); 55 56 private TradefedFeatureClient mClient; 57 OptionFetcher()58 public OptionFetcher() { 59 this(new TradefedFeatureClient()); 60 } 61 62 @VisibleForTesting OptionFetcher(TradefedFeatureClient client)63 OptionFetcher(TradefedFeatureClient client) { 64 mClient = client; 65 } 66 67 /** 68 * Fill some options from the child if it's a subprocess by matching the parent values. 69 */ fetchParentOptions(IConfiguration config)70 public void fetchParentOptions(IConfiguration config) { 71 // Skip if this is not a subprocess 72 if (!TestInvocation.isSubprocess(config)) { 73 return; 74 } 75 try { 76 Map<String, String> args = new HashMap<>(); 77 args.put(CommandOptionsGetter.OPTION_NAME, Joiner.on(",").join(OPTION_TO_FETCH)); 78 FeatureResponse rep = mClient 79 .triggerFeature(CommandOptionsGetter.COMMAND_OPTIONS_GETTER, args); 80 if (rep.hasErrorInfo()) { 81 CLog.e("%s", rep.getErrorInfo()); 82 return; 83 } 84 if (rep.hasMultiPartResponse()) { 85 for (PartResponse part : rep.getMultiPartResponse().getResponsePartList()) { 86 CLog.logAndDisplay( 87 LogLevel.DEBUG, "Fetched: %s=%s from parent.", 88 part.getKey(), part.getValue()); 89 try { 90 config.injectOptionValue(part.getKey(), part.getValue()); 91 } catch (ConfigurationException e) { 92 CLog.e(e); 93 } 94 } 95 } else if(!Strings.isNullOrEmpty(rep.getResponse())) { 96 // When we have a single option, we fallback here 97 try { 98 config.injectOptionValue("retry-isolation-grade", rep.getResponse().trim()); 99 } catch (ConfigurationException e) { 100 CLog.e(e); 101 } 102 } 103 } catch (RuntimeException e) { 104 CLog.e(e); 105 } 106 } 107 108 @Override close()109 public void close() throws Exception { 110 if (mClient != null) { 111 mClient.close(); 112 } 113 } 114 } 115