1 /* 2 * Copyright (C) 2017 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.StubBuildProvider; 19 import com.android.tradefed.config.Configuration; 20 import com.android.tradefed.config.IConfiguration; 21 import com.android.tradefed.config.IDeviceConfiguration; 22 import com.android.tradefed.device.metric.FilePullerLogCollector; 23 import com.android.tradefed.device.metric.IMetricCollector; 24 import com.android.tradefed.result.TextResultReporter; 25 import com.android.tradefed.targetprep.ITargetPreparer; 26 import com.android.tradefed.targetprep.multi.IMultiTargetPreparer; 27 import com.android.tradefed.testtype.suite.module.BaseModuleController; 28 29 import java.util.ArrayList; 30 import java.util.List; 31 32 /** 33 * This class will help validating that the {@link IConfiguration} loaded for the suite are meeting 34 * the expected requirements: - No Build providers - No Result reporters 35 */ 36 public class ValidateSuiteConfigHelper { 37 38 /** 39 * Special exemption list for some collectors. They would be overly cumbersome to be defined at 40 * the suite level. 41 */ 42 private static final List<String> ALLOWED_COLLECTOR_IN_MODULE = new ArrayList<>(); 43 44 static { 45 // This collector simply pull and log file from the device. it is useful at the module level 46 // so they can specify which 'key' is going to be watched to be pulled. FilePullerLogCollector.class.getCanonicalName()47 ALLOWED_COLLECTOR_IN_MODULE.add(FilePullerLogCollector.class.getCanonicalName()); 48 } 49 ValidateSuiteConfigHelper()50 private ValidateSuiteConfigHelper() {} 51 52 /** 53 * Check that a configuration is properly built to run in a suite. 54 * 55 * @param config a {@link IConfiguration} to be checked if valide for suite. 56 */ validateConfig(IConfiguration config)57 public static void validateConfig(IConfiguration config) { 58 if (config.getDeviceConfig().size() < 2) { 59 // Special handling for single device objects. 60 if (!config.getBuildProvider().getClass().isAssignableFrom(StubBuildProvider.class)) { 61 throwRuntime( 62 config, 63 String.format( 64 "%s objects are not allowed in module.", 65 Configuration.BUILD_PROVIDER_TYPE_NAME)); 66 } 67 checkTargetPrep(config, config.getTargetPreparers()); 68 } 69 // if a multi device config is presented, ensure none of the devices define a build_provider 70 for (IDeviceConfiguration deviceConfig : config.getDeviceConfig()) { 71 if (!deviceConfig 72 .getBuildProvider() 73 .getClass() 74 .isAssignableFrom(StubBuildProvider.class)) { 75 throwRuntime( 76 config, 77 String.format( 78 "%s objects are not allowed in module.", 79 Configuration.BUILD_PROVIDER_TYPE_NAME)); 80 } 81 checkTargetPrep(config, deviceConfig.getTargetPreparers()); 82 } 83 if (config.getTestInvocationListeners().size() != 1) { 84 throwRuntime( 85 config, 86 String.format( 87 "%s objects are not allowed in module.", 88 Configuration.RESULT_REPORTER_TYPE_NAME)); 89 } 90 if (!config.getTestInvocationListeners() 91 .get(0) 92 .getClass() 93 .isAssignableFrom(TextResultReporter.class)) { 94 throwRuntime( 95 config, 96 String.format( 97 "%s objects are not allowed in module.", 98 Configuration.RESULT_REPORTER_TYPE_NAME)); 99 } 100 // For now we do not allow pre-multi target preparers in modules. 101 if (config.getMultiPreTargetPreparers().size() > 0) { 102 throwRuntime( 103 config, 104 String.format( 105 "%s objects are not allowed in module.", 106 Configuration.MULTI_PRE_TARGET_PREPARER_TYPE_NAME)); 107 } 108 109 // Check multi target preparers 110 checkTargetPrep(config, config.getMultiTargetPreparers()); 111 112 // Check metric collectors 113 for (IMetricCollector collector : config.getMetricCollectors()) { 114 // Only some collectors are allowed in the module 115 if (!ALLOWED_COLLECTOR_IN_MODULE.contains(collector.getClass().getCanonicalName())) { 116 throwRuntime( 117 config, 118 String.format( 119 "%s objects are not allowed in module. Except for: %s", 120 Configuration.DEVICE_METRICS_COLLECTOR_TYPE_NAME, 121 ALLOWED_COLLECTOR_IN_MODULE)); 122 } 123 } 124 125 // Check that we validate the module_controller. 126 Object controller = config.getConfigurationObject(ModuleDefinition.MODULE_CONTROLLER); 127 if (controller != null) { 128 if (!(controller instanceof BaseModuleController)) { 129 throwRuntime( 130 config, 131 String.format( 132 "%s object should be of type %s", 133 ModuleDefinition.MODULE_CONTROLLER, BaseModuleController.class)); 134 } 135 } 136 } 137 138 /** 139 * Check target_preparer and multi_target_preparer to ensure they do not extends each other as 140 * it could lead to some issues. 141 */ checkTargetPrep(IConfiguration config, List<?> targetPrepList)142 private static boolean checkTargetPrep(IConfiguration config, List<?> targetPrepList) { 143 for (Object o : targetPrepList) { 144 if (o instanceof ITargetPreparer && o instanceof IMultiTargetPreparer) { 145 throwRuntime( 146 config, 147 String.format( 148 "%s is extending both %s and " + "%s", 149 o.getClass().getCanonicalName(), 150 Configuration.TARGET_PREPARER_TYPE_NAME, 151 Configuration.MULTI_PREPARER_TYPE_NAME)); 152 return false; 153 } 154 } 155 return true; 156 } 157 throwRuntime(IConfiguration config, String msg)158 private static void throwRuntime(IConfiguration config, String msg) { 159 throw new RuntimeException( 160 String.format( 161 "Configuration %s cannot be run in a suite: %s", config.getName(), msg)); 162 } 163 } 164