1 /* 2 * Copyright (C) 2015 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.compatibility.common.tradefed.build; 17 18 import com.android.compatibility.common.util.DynamicConfigHostSide; 19 import com.android.tradefed.build.IBuildInfo; 20 import com.android.tradefed.build.IFolderBuildInfo; 21 22 import java.io.File; 23 import java.io.FileNotFoundException; 24 import java.text.SimpleDateFormat; 25 import java.util.Date; 26 import java.util.HashMap; 27 import java.util.Map; 28 29 /** 30 * A simple helper that stores and retrieves information from a {@link IBuildInfo}. 31 */ 32 public class CompatibilityBuildHelper { 33 34 public static final String MODULE_IDS = "MODULE_IDS"; 35 public static final String ROOT_DIR = "ROOT_DIR"; 36 public static final String SUITE_BUILD = "SUITE_BUILD"; 37 public static final String SUITE_NAME = "SUITE_NAME"; 38 public static final String SUITE_FULL_NAME = "SUITE_FULL_NAME"; 39 public static final String SUITE_VERSION = "SUITE_VERSION"; 40 public static final String SUITE_PLAN = "SUITE_PLAN"; 41 public static final String START_TIME_MS = "START_TIME_MS"; 42 public static final String COMMAND_LINE_ARGS = "command_line_args"; 43 44 private static final String ROOT_DIR2 = "ROOT_DIR2"; 45 private static final String DYNAMIC_CONFIG_OVERRIDE_URL = "DYNAMIC_CONFIG_OVERRIDE_URL"; 46 private static final String RETRY_COMMAND_LINE_ARGS = "retry_command_line_args"; 47 private final IBuildInfo mBuildInfo; 48 49 /** 50 * Creates a {@link CompatibilityBuildHelper} wrapping the given {@link IBuildInfo}. 51 */ CompatibilityBuildHelper(IBuildInfo buildInfo)52 public CompatibilityBuildHelper(IBuildInfo buildInfo) { 53 mBuildInfo = buildInfo; 54 } 55 getBuildInfo()56 public IBuildInfo getBuildInfo() { 57 return mBuildInfo; 58 } 59 setRetryCommandLineArgs(String commandLineArgs)60 public void setRetryCommandLineArgs(String commandLineArgs) { 61 mBuildInfo.addBuildAttribute(RETRY_COMMAND_LINE_ARGS, commandLineArgs); 62 } 63 getCommandLineArgs()64 public String getCommandLineArgs() { 65 if (mBuildInfo.getBuildAttributes().containsKey(RETRY_COMMAND_LINE_ARGS)) { 66 return mBuildInfo.getBuildAttributes().get(RETRY_COMMAND_LINE_ARGS); 67 } else { 68 // NOTE: this is a temporary workaround set in TestInvocation#invoke in tradefed. 69 // This will be moved to a separate method in a new invocation metadata class. 70 return mBuildInfo.getBuildAttributes().get(COMMAND_LINE_ARGS); 71 } 72 } 73 getRecentCommandLineArgs()74 public String getRecentCommandLineArgs() { 75 return mBuildInfo.getBuildAttributes().get(COMMAND_LINE_ARGS); 76 } 77 getSuiteBuild()78 public String getSuiteBuild() { 79 return mBuildInfo.getBuildAttributes().get(SUITE_BUILD); 80 } 81 getSuiteName()82 public String getSuiteName() { 83 return mBuildInfo.getBuildAttributes().get(SUITE_NAME); 84 } 85 getSuiteFullName()86 public String getSuiteFullName() { 87 return mBuildInfo.getBuildAttributes().get(SUITE_FULL_NAME); 88 } 89 getSuiteVersion()90 public String getSuiteVersion() { 91 return mBuildInfo.getBuildAttributes().get(SUITE_VERSION); 92 } 93 getSuitePlan()94 public String getSuitePlan() { 95 return mBuildInfo.getBuildAttributes().get(SUITE_PLAN); 96 } 97 getDynamicConfigUrl()98 public String getDynamicConfigUrl() { 99 return mBuildInfo.getBuildAttributes().get(DYNAMIC_CONFIG_OVERRIDE_URL); 100 } 101 getStartTime()102 public long getStartTime() { 103 return Long.parseLong(mBuildInfo.getBuildAttributes().get(START_TIME_MS)); 104 } 105 addDynamicConfigFile(String moduleName, File configFile)106 public void addDynamicConfigFile(String moduleName, File configFile) { 107 mBuildInfo.addBuildAttribute(DynamicConfigHostSide.CONFIG_PATH_PREFIX + moduleName, 108 configFile.getAbsolutePath()); 109 } 110 setModuleIds(String[] moduleIds)111 public void setModuleIds(String[] moduleIds) { 112 mBuildInfo.addBuildAttribute(MODULE_IDS, String.join(",", moduleIds)); 113 } 114 getDynamicConfigFiles()115 public Map<String, File> getDynamicConfigFiles() { 116 Map<String, File> configMap = new HashMap<>(); 117 for (String key : mBuildInfo.getBuildAttributes().keySet()) { 118 if (key.startsWith(DynamicConfigHostSide.CONFIG_PATH_PREFIX)) { 119 configMap.put(key.substring(DynamicConfigHostSide.CONFIG_PATH_PREFIX.length()), 120 new File(mBuildInfo.getBuildAttributes().get(key))); 121 } 122 } 123 return configMap; 124 } 125 126 /** 127 * @return a {@link File} representing the directory holding the Compatibility installation 128 * @throws FileNotFoundException if the directory does not exist 129 */ getRootDir()130 public File getRootDir() throws FileNotFoundException { 131 File dir = null; 132 if (mBuildInfo instanceof IFolderBuildInfo) { 133 dir = ((IFolderBuildInfo) mBuildInfo).getRootDir(); 134 } 135 if (dir == null || !dir.exists()) { 136 dir = new File(mBuildInfo.getBuildAttributes().get(ROOT_DIR)); 137 if (!dir.exists()) { 138 dir = new File(mBuildInfo.getBuildAttributes().get(ROOT_DIR2)); 139 } 140 } 141 if (!dir.exists()) { 142 throw new FileNotFoundException(String.format( 143 "Compatibility root directory %s does not exist", 144 dir.getAbsolutePath())); 145 } 146 return dir; 147 } 148 149 /** 150 * @return a {@link File} representing the "android-<suite>" folder of the Compatibility 151 * installation 152 * @throws FileNotFoundException if the directory does not exist 153 */ getDir()154 public File getDir() throws FileNotFoundException { 155 File dir = new File(getRootDir(), String.format("android-%s", getSuiteName().toLowerCase())); 156 if (!dir.exists()) { 157 throw new FileNotFoundException(String.format( 158 "Compatibility install folder %s does not exist", 159 dir.getAbsolutePath())); 160 } 161 return dir; 162 } 163 164 /** 165 * @return a {@link File} representing the results directory. 166 * @throws FileNotFoundException if the directory structure is not valid. 167 */ getResultsDir()168 public File getResultsDir() throws FileNotFoundException { 169 return new File(getDir(), "results"); 170 } 171 172 /** 173 * @return a {@link File} representing the result directory of the current invocation. 174 * @throws FileNotFoundException if the directory structure is not valid. 175 */ getResultDir()176 public File getResultDir() throws FileNotFoundException { 177 return new File(getResultsDir(), 178 getDirSuffix(Long.parseLong(mBuildInfo.getBuildAttributes().get(START_TIME_MS)))); 179 } 180 181 /** 182 * @return a {@link File} representing the directory to store result logs. 183 * @throws FileNotFoundException if the directory structure is not valid. 184 */ getLogsDir()185 public File getLogsDir() throws FileNotFoundException { 186 return new File(getDir(), "logs"); 187 } 188 189 /** 190 * @return a {@link File} representing the directory to store derivedplan files. 191 * @throws FileNotFoundException if the directory structure is not valid. 192 */ getSubPlansDir()193 public File getSubPlansDir() throws FileNotFoundException { 194 File subPlansDir = new File(getDir(), "subplans"); 195 if (!subPlansDir.exists()) { 196 subPlansDir.mkdirs(); 197 } 198 return subPlansDir; 199 } 200 201 /** 202 * @return a {@link File} representing the test modules directory. 203 * @throws FileNotFoundException if the directory structure is not valid. 204 */ getTestsDir()205 public File getTestsDir() throws FileNotFoundException { 206 File testsDir = new File(getDir(), "testcases"); 207 if (!testsDir.exists()) { 208 throw new FileNotFoundException(String.format( 209 "Compatibility tests folder %s does not exist", 210 testsDir.getAbsolutePath())); 211 } 212 return testsDir; 213 } 214 215 /** 216 * @return a {@link File} representing the test file in the test modules directory. 217 * @throws FileNotFoundException if the test file cannot be found 218 */ getTestFile(String filename)219 public File getTestFile(String filename) throws FileNotFoundException { 220 File testFile = new File(getTestsDir(), filename); 221 if (!testFile.exists()) { 222 throw new FileNotFoundException(String.format( 223 "Compatibility test file %s does not exist", filename)); 224 } 225 return testFile; 226 } 227 228 /** 229 * @return a {@link File} in the resultDir for logging invocation failures 230 */ getInvocationFailureFile()231 public File getInvocationFailureFile() throws FileNotFoundException { 232 return new File(getResultDir(), "invocation_failure.txt"); 233 } 234 235 /** 236 * @return a {@link File} in the resultDir for counting expected test runs 237 */ getTestRunsFile()238 public File getTestRunsFile() throws FileNotFoundException { 239 return new File(getResultDir(), "test_runs.txt"); 240 } 241 242 /** 243 * @return a {@link String} to use for directory suffixes created from the given time. 244 */ getDirSuffix(long millis)245 public static String getDirSuffix(long millis) { 246 return new SimpleDateFormat("yyyy.MM.dd_HH.mm.ss").format(new Date(millis)); 247 } 248 } 249