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.tradefed.config.IConfiguration; 19 import com.android.tradefed.log.LogUtil.CLog; 20 import com.android.tradefed.service.TradefedFeatureClient; 21 import com.android.tradefed.testtype.suite.SuiteTestFilter; 22 23 import com.google.common.base.Strings; 24 import com.proto.tradefed.feature.FeatureResponse; 25 26 import java.util.ArrayList; 27 import java.util.HashMap; 28 import java.util.LinkedHashSet; 29 import java.util.List; 30 import java.util.Map; 31 import java.util.Set; 32 33 /** 34 * Helper to get the previous passed test filters. 35 */ 36 public class GetPreviousPassedHelper { 37 GetPreviousPassedHelper()38 public GetPreviousPassedHelper() {} 39 40 /** 41 * Fetch previous passed tests if applicable from previous attempt. 42 * 43 * @param config The configuration to apply filter to 44 * @return The list of tests that previously passed. 45 */ getPreviousPassedFilters(IConfiguration config)46 public Set<String> getPreviousPassedFilters(IConfiguration config) { 47 Set<String> filters = new LinkedHashSet<>(); 48 List<SuiteTestFilter> previousPassedFilters = new ArrayList<>(); 49 if (config == null) { 50 return filters; 51 } 52 if (!config.getCommandOptions().filterPreviousPassedTests()) { 53 return filters; 54 } 55 // Build the query of previous passed test 56 Map<String, String> args = new HashMap<>(); 57 Map<String, String> invocationData = config 58 .getCommandOptions() 59 .getInvocationData() 60 .getUniqueMap(); 61 String invocationId = invocationData.get("invocation_id"); 62 if (!Strings.isNullOrEmpty(invocationId)) { 63 args.put("invocation_id", invocationId); 64 } 65 if (args.isEmpty()) { 66 return filters; 67 } 68 String attempt = invocationData.get("attempt_index"); 69 if ("0".equals(attempt)) { 70 return filters; 71 } 72 // Include the shard_index in query to filter server side. 73 if (config.getCommandOptions().getShardIndex() != null) { 74 args.put("shard_index", Integer.toString(config.getCommandOptions().getShardIndex())); 75 } 76 try (TradefedFeatureClient client = new TradefedFeatureClient()) { 77 FeatureResponse previousPassed = client.triggerFeature("getPreviousPassed", args); 78 convertResponseToFilter(previousPassed, previousPassedFilters); 79 boolean filterShards = 80 previousPassedFilters.removeIf( 81 f -> 82 f.getShardIndex() != null 83 && !f.getShardIndex() 84 .equals( 85 config 86 .getCommandOptions() 87 .getShardIndex())); 88 if (filterShards) { 89 CLog.d("Remaining filter for the shard: %s", previousPassedFilters); 90 } 91 previousPassedFilters.stream().forEach(f->filters.add(f.toString())); 92 } catch (RuntimeException e) { 93 CLog.e(e); 94 } 95 return filters; 96 } 97 convertResponseToFilter( FeatureResponse previousPassed, List<SuiteTestFilter> previousPassedFilters)98 private void convertResponseToFilter( 99 FeatureResponse previousPassed, List<SuiteTestFilter> previousPassedFilters) { 100 if (previousPassed.hasErrorInfo()) { 101 return; 102 } 103 if (Strings.isNullOrEmpty(previousPassed.getResponse())) { 104 return; 105 } 106 for (String line : previousPassed.getResponse().split("\n")) { 107 if (line.isEmpty()) { 108 continue; 109 } 110 previousPassedFilters.add(SuiteTestFilter.createFrom(line)); 111 } 112 } 113 } 114