Home | History | Annotate | Download | only in dumprendertree2
      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 
     17 package com.android.dumprendertree2;
     18 
     19 import android.util.Log;
     20 
     21 import com.android.dumprendertree2.forwarder.ForwarderManager;
     22 
     23 import java.io.BufferedReader;
     24 import java.io.File;
     25 import java.io.FileNotFoundException;
     26 import java.io.IOException;
     27 import java.io.InputStream;
     28 import java.io.InputStreamReader;
     29 import java.io.StringReader;
     30 import java.net.MalformedURLException;
     31 import java.net.URL;
     32 import java.net.URLConnection;
     33 import java.util.ArrayList;
     34 import java.util.Arrays;
     35 import java.util.HashSet;
     36 import java.util.List;
     37 import java.util.Set;
     38 
     39 /**
     40  * A utility to filter out some files/directories from the views and tests that run.
     41  */
     42 public 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     public FileFilter() {
     60         loadTestExpectations();
     61     }
     62 
     63     private static final String trimTrailingSlashIfPresent(String path) {
     64         File file = new File(path);
     65         return file.getPath();
     66     }
     67 
     68     public void loadTestExpectations() {
     69         URL url = null;
     70         try {
     71             url = new URL(ForwarderManager.getHostSchemePort(false) +
     72                     "LayoutTests/" + TEST_EXPECTATIONS_TXT_PATH);
     73         } catch (MalformedURLException e) {
     74             assert false;
     75         }
     76 
     77         try {
     78             InputStream inputStream = null;
     79             BufferedReader bufferedReader = null;
     80             try {
     81                 byte[] httpAnswer = FsUtils.readDataFromUrl(url);
     82                 if (httpAnswer == null) {
     83                     Log.w(LOG_TAG, "loadTestExpectations(): File not found: " +
     84                             TEST_EXPECTATIONS_TXT_PATH);
     85                     return;
     86                 }
     87                 bufferedReader = new BufferedReader(new StringReader(
     88                         new String(httpAnswer)));
     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(
    122                             parts[1].split("\\s", 0)));
    123 
    124                     /** Chose the right collections to add to */
    125                     if (tokens.contains(TOKEN_CRASH)) {
    126                         mCrashList.add(path);
    127 
    128                         /** If test is on skip list we ignore any further options */
    129                         continue;
    130                     }
    131 
    132                     if (tokens.contains(TOKEN_FAIL)) {
    133                         mFailList.add(path);
    134                     }
    135                     if (tokens.contains(TOKEN_SLOW)) {
    136                         mSlowList.add(path);
    137                     }
    138                 }
    139             } finally {
    140                 if (inputStream != null) {
    141                     inputStream.close();
    142                 }
    143                 if (bufferedReader != null) {
    144                     bufferedReader.close();
    145                 }
    146             }
    147         } catch (IOException e) {
    148             Log.e(LOG_TAG, "url=" + url, e);
    149         }
    150     }
    151 
    152     /**
    153      * Checks if test is expected to crash.
    154      *
    155      * <p>
    156      * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
    157      *
    158      * @param testPath
    159      *            - a relative path within LayoutTests folder
    160      * @return if the test is supposed to be skipped
    161      */
    162     public boolean isCrash(String testPath) {
    163         for (String prefix : getPrefixes(testPath)) {
    164             if (mCrashList.contains(prefix)) {
    165                 return true;
    166             }
    167         }
    168 
    169         return false;
    170     }
    171 
    172     /**
    173      * Checks if test result is supposed to be "failed".
    174      *
    175      * <p>
    176      * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
    177      *
    178      * @param testPath
    179      *            - a relative path within LayoutTests folder
    180      * @return if the test result is supposed to be "failed"
    181      */
    182     public boolean isFail(String testPath) {
    183         for (String prefix : getPrefixes(testPath)) {
    184             if (mFailList.contains(prefix)) {
    185                 return true;
    186             }
    187         }
    188 
    189         return false;
    190     }
    191 
    192     /**
    193      * Checks if test is slow and should have timeout increased.
    194      *
    195      * <p>
    196      * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
    197      *
    198      * @param testPath
    199      *            - a relative path within LayoutTests folder
    200      * @return if the test is slow and should have timeout increased.
    201      */
    202     public boolean isSlow(String testPath) {
    203         for (String prefix : getPrefixes(testPath)) {
    204             if (mSlowList.contains(prefix)) {
    205                 return true;
    206             }
    207         }
    208 
    209         return false;
    210     }
    211 
    212     /**
    213      * Returns the list of all path prefixes of the given path.
    214      *
    215      * <p>
    216      * e.g. this/is/a/path returns the list: this this/is this/is/a this/is/a/path
    217      *
    218      * @param path
    219      * @return the list of all path prefixes of the given path.
    220      */
    221     private static List<String> getPrefixes(String path) {
    222         File file = new File(path);
    223         List<String> prefixes = new ArrayList<String>(8);
    224 
    225         do {
    226             prefixes.add(file.getPath());
    227             file = file.getParentFile();
    228         } while (file != null);
    229 
    230         return prefixes;
    231     }
    232 
    233     /**
    234      * Checks if the directory may contain tests or contains just helper files.
    235      *
    236      * @param dirName
    237      * @return
    238      *      if the directory may contain tests
    239      */
    240     public static boolean isTestDir(String dirName) {
    241         return (!dirName.equals("script-tests")
    242                 && !dirName.equals("resources") && !dirName.startsWith("."));
    243     }
    244 
    245     /**
    246      * Checks if the file is a test.
    247      * Currently we run .html, .xhtml and .php tests.
    248      *
    249      * @warning You MUST also call isTestDir() on the parent directory before
    250      * assuming that a file is a test.
    251      *
    252      * @param testName
    253      * @return if the file is a test
    254      */
    255     public static boolean isTestFile(String testName) {
    256         return testName.endsWith(".html")
    257             || testName.endsWith(".xhtml")
    258             || testName.endsWith(".php");
    259     }
    260 
    261     /**
    262      * Return a URL of the test on the server.
    263      *
    264      * @param relativePath
    265      * @param allowHttps Whether to allow the use of HTTPS, even if the file is in the SSL
    266      *     directory.
    267      * @return a URL of the test on the server
    268      */
    269     public static URL getUrl(String relativePath, boolean allowHttps) {
    270         String urlBase = ForwarderManager.getHostSchemePort(false);
    271 
    272         /**
    273          * URL is formed differently for HTTP vs non-HTTP tests, because HTTP tests
    274          * expect different document root. See run_apache2.py and .conf file for details
    275          */
    276         if (relativePath.startsWith(HTTP_TESTS_PATH)) {
    277             relativePath = relativePath.substring(HTTP_TESTS_PATH.length());
    278             if (relativePath.startsWith(SSL_PATH) && allowHttps) {
    279                 urlBase = ForwarderManager.getHostSchemePort(true);
    280             }
    281         } else {
    282             relativePath = "LayoutTests/" + relativePath;
    283         }
    284 
    285         try {
    286             return new URL(urlBase + relativePath);
    287         } catch (MalformedURLException e) {
    288             Log.e(LOG_TAG, "Malformed URL!", e);
    289         }
    290 
    291         return null;
    292     }
    293 
    294     /**
    295      * If the path contains extension (e.g .foo at the end of the file) then it changes
    296      * this (.foo) into newEnding (so it has to contain the dot if we want to preserve it).
    297      *
    298      * <p>If the path doesn't contain an extension, it adds the ending to the path.
    299      *
    300      * @param relativePath
    301      * @param newEnding
    302      * @return
    303      *      a new path, containing the newExtension
    304      */
    305     public static String setPathEnding(String relativePath, String newEnding) {
    306         int dotPos = relativePath.lastIndexOf('.');
    307         if (dotPos == -1) {
    308             return relativePath + newEnding;
    309         }
    310 
    311         return relativePath.substring(0, dotPos) + newEnding;
    312     }
    313 }
    314