FileFilter.java revision 5f21f5a4a9f240e1c35ab86b2f3a332f0d541cf0
1/* 2 * Copyright (C) 2010 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 17package com.android.dumprendertree2; 18 19import android.util.Log; 20 21import com.android.dumprendertree2.forwarder.ForwarderManager; 22 23import java.io.BufferedReader; 24import java.io.File; 25import java.io.FileNotFoundException; 26import java.io.IOException; 27import java.io.InputStream; 28import java.io.InputStreamReader; 29import java.io.StringReader; 30import java.net.MalformedURLException; 31import java.net.URL; 32import java.net.URLConnection; 33import java.util.ArrayList; 34import java.util.Arrays; 35import java.util.HashSet; 36import java.util.List; 37import java.util.Set; 38 39/** 40 * A utility to filter out some files/directories from the views and tests that run. 41 */ 42public class FileFilter { 43 private static final String LOG_TAG = "FileFilter"; 44 45 private static final String TEST_EXPECTATIONS_TXT_PATH = 46 "platform/android/test_expectations.txt"; 47 48 private static final String HTTP_TESTS_PATH = "http/tests/"; 49 private static final String SSL_PATH = "ssl/"; 50 51 private static final String TOKEN_CRASH = "CRASH"; 52 private static final String TOKEN_FAIL = "FAIL"; 53 private static final String TOKEN_SLOW = "SLOW"; 54 55 private final Set<String> mCrashList = new HashSet<String>(); 56 private final Set<String> mFailList = new HashSet<String>(); 57 private final Set<String> mSlowList = new HashSet<String>(); 58 59 private final String mRootDirPath; 60 61 public FileFilter(String rootDirPath) { 62 /** It may or may not contain a trailing slash */ 63 this.mRootDirPath = rootDirPath; 64 65 loadTestExpectations(); 66 } 67 68 private static final String trimTrailingSlashIfPresent(String path) { 69 File file = new File(path); 70 return file.getPath(); 71 } 72 73 public void loadTestExpectations() { 74 URL url = null; 75 try { 76 url = new URL(ForwarderManager.getHostSchemePort(false) + "LayoutTests/" + 77 TEST_EXPECTATIONS_TXT_PATH); 78 } catch (MalformedURLException e) { 79 assert false; 80 } 81 82 try { 83 InputStream inputStream = null; 84 BufferedReader bufferedReader = null; 85 try { 86 bufferedReader = new BufferedReader(new StringReader(new String( 87 FsUtils.readDataFromUrl(url)))); 88 89 String line; 90 String entry; 91 String[] parts; 92 String path; 93 Set<String> tokens; 94 while (true) { 95 line = bufferedReader.readLine(); 96 if (line == null) { 97 break; 98 } 99 100 /** Remove the comment and trim */ 101 entry = line.split("//", 2)[0].trim(); 102 103 /** Omit empty lines, advance to next line */ 104 if (entry.isEmpty()) { 105 continue; 106 } 107 108 /** Split on whitespace into path part and the rest */ 109 parts = entry.split("\\s", 2); 110 111 /** At this point parts.length >= 1 */ 112 if (parts.length == 1) { 113 Log.w(LOG_TAG + "::reloadConfiguration", 114 "There are no options specified for the test!"); 115 continue; 116 } 117 118 path = trimTrailingSlashIfPresent(parts[0]); 119 120 /** Split on whitespace */ 121 tokens = new HashSet<String>(Arrays.asList(parts[1].split("\\s", 0))); 122 123 /** Chose the right collections to add to */ 124 if (tokens.contains(TOKEN_CRASH)) { 125 mCrashList.add(path); 126 127 /** If test is on skip list we ignore any further options */ 128 continue; 129 } 130 131 if (tokens.contains(TOKEN_FAIL)) { 132 mFailList.add(path); 133 } 134 if (tokens.contains(TOKEN_SLOW)) { 135 mSlowList.add(path); 136 } 137 } 138 } finally { 139 if (inputStream != null) { 140 inputStream.close(); 141 } 142 if (bufferedReader != null) { 143 bufferedReader.close(); 144 } 145 } 146 } catch (FileNotFoundException e) { 147 Log.w(LOG_TAG, "reloadConfiguration(): File not found: " + e.getMessage()); 148 } catch (IOException e) { 149 Log.e(LOG_TAG, "url=" + url, e); 150 } 151 } 152 153 /** 154 * Checks if test is expected to crash. 155 * 156 * <p> 157 * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html 158 * 159 * @param testPath 160 * - a relative path within LayoutTests folder 161 * @return if the test is supposed to be skipped 162 */ 163 public boolean isCrash(String testPath) { 164 for (String prefix : getPrefixes(testPath)) { 165 if (mCrashList.contains(prefix)) { 166 return true; 167 } 168 } 169 170 return false; 171 } 172 173 /** 174 * Checks if test result is supposed to be "failed". 175 * 176 * <p> 177 * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html 178 * 179 * @param testPath 180 * - a relative path within LayoutTests folder 181 * @return if the test result is supposed to be "failed" 182 */ 183 public boolean isFail(String testPath) { 184 for (String prefix : getPrefixes(testPath)) { 185 if (mFailList.contains(prefix)) { 186 return true; 187 } 188 } 189 190 return false; 191 } 192 193 /** 194 * Checks if test is slow and should have timeout increased. 195 * 196 * <p> 197 * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html 198 * 199 * @param testPath 200 * - a relative path within LayoutTests folder 201 * @return if the test is slow and should have timeout increased. 202 */ 203 public boolean isSlow(String testPath) { 204 for (String prefix : getPrefixes(testPath)) { 205 if (mSlowList.contains(prefix)) { 206 return true; 207 } 208 } 209 210 return false; 211 } 212 213 /** 214 * Returns the list of all path prefixes of the given path. 215 * 216 * <p> 217 * e.g. this/is/a/path returns the list: this this/is this/is/a this/is/a/path 218 * 219 * @param path 220 * @return the list of all path prefixes of the given path. 221 */ 222 private static List<String> getPrefixes(String path) { 223 File file = new File(path); 224 List<String> prefixes = new ArrayList<String>(8); 225 226 do { 227 prefixes.add(file.getPath()); 228 file = file.getParentFile(); 229 } while (file != null); 230 231 return prefixes; 232 } 233 234 /** 235 * Checks if the directory may contain tests or contains just helper files. 236 * 237 * @param dirName 238 * @return 239 * if the directory may contain tests 240 */ 241 public static boolean isTestDir(String dirName) { 242 return (!dirName.equals("script-tests") 243 && !dirName.equals("resources") && !dirName.startsWith(".")); 244 } 245 246 /** 247 * Checks if the file is a test. 248 * Currently we run .html and .xhtml tests. 249 * 250 * @param testName 251 * @return 252 * if the file is a test 253 */ 254 public static boolean isTestFile(String testName) { 255 return testName.endsWith(".html") || testName.endsWith(".xhtml"); 256 } 257 258 /** 259 * Return a URL of the test on the server. 260 * 261 * @param relativePath 262 * @return a URL of the test on the server 263 */ 264 public static URL getUrl(String relativePath) { 265 String urlBase = ForwarderManager.getHostSchemePort(false); 266 267 /** 268 * URL is formed differently for HTTP vs non-HTTP tests, because HTTP tests 269 * expect different document root. See run_apache2.py and .conf file for details 270 */ 271 if (relativePath.startsWith(HTTP_TESTS_PATH)) { 272 relativePath = relativePath.substring(HTTP_TESTS_PATH.length()); 273 if (relativePath.startsWith(SSL_PATH)) { 274 urlBase = ForwarderManager.getHostSchemePort(true); 275 } 276 } else { 277 relativePath = "LayoutTests/" + relativePath; 278 } 279 280 try { 281 return new URL(urlBase + relativePath); 282 } catch (MalformedURLException e) { 283 Log.e(LOG_TAG, "Malformed URL!", e); 284 } 285 286 return null; 287 } 288 289 /** 290 * Return the path to the file relative to the tests root dir 291 * 292 * @param filePath 293 * @return 294 * the path relative to the tests root dir 295 */ 296 public String getRelativePath(String filePath) { 297 File rootDir = new File(mRootDirPath); 298 return filePath.replaceFirst(rootDir.getPath() + File.separator, ""); 299 } 300 301 /** 302 * Return the path to the file relative to the tests root dir 303 * 304 * @param filePath 305 * @return 306 * the path relative to the tests root dir 307 */ 308 public String getRelativePath(File file) { 309 return getRelativePath(file.getAbsolutePath()); 310 } 311 312 public File getAbsoluteFile(String relativePath) { 313 return new File(mRootDirPath, relativePath); 314 } 315 316 public String getAboslutePath(String relativePath) { 317 return getAbsoluteFile(relativePath).getAbsolutePath(); 318 } 319 320 /** 321 * If the path contains extension (e.g .foo at the end of the file) then it changes 322 * this (.foo) into newEnding (so it has to contain the dot if we want to preserve it). 323 * 324 * <p>If the path doesn't contain an extension, it adds the ending to the path. 325 * 326 * @param relativePath 327 * @param newEnding 328 * @return 329 * a new path, containing the newExtension 330 */ 331 public static String setPathEnding(String relativePath, String newEnding) { 332 int dotPos = relativePath.lastIndexOf('.'); 333 if (dotPos == -1) { 334 return relativePath + newEnding; 335 } 336 337 return relativePath.substring(0, dotPos) + newEnding; 338 } 339}