FileFilter.java revision 2e5982a55ac031110ed39515a76f7a5ec9ff2c14
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 java.io.BufferedReader;
22import java.io.File;
23import java.io.FileNotFoundException;
24import java.io.FileReader;
25import java.io.IOException;
26import java.util.ArrayList;
27import java.util.Arrays;
28import java.util.HashSet;
29import java.util.List;
30import java.util.Set;
31
32/**
33 * A utility to filter out some files/directories from the views and tests that run.
34 */
35public class FileFilter {
36    private static final String LOG_TAG = "FileFilter";
37
38    private static final String TEST_EXPECTATIONS_TXT_PATH =
39            "platform/android/test_expectations.txt";
40
41    private static final String TOKEN_SKIP = "SKIP";
42    private static final String TOKEN_IGNORE_RESULT = "IGNORE_RESULT";
43    private static final String TOKEN_SLOW = "SLOW";
44
45    private final Set<String> mSkipList = new HashSet<String>();
46    private final Set<String> mIgnoreResultList = new HashSet<String>();
47    private final Set<String> mSlowList = new HashSet<String>();
48
49    private final String mRootDirPath;
50
51    public FileFilter(String rootDirPath) {
52        /** It may or may not contain a trailing slash */
53        this.mRootDirPath = rootDirPath;
54
55        reloadConfiguration();
56    }
57
58    private static final String trimTrailingSlashIfPresent(String path) {
59        File file = new File(path);
60        return file.getPath();
61    }
62
63    public void reloadConfiguration() {
64        File txt_exp = new File(mRootDirPath, TEST_EXPECTATIONS_TXT_PATH);
65
66        BufferedReader bufferedReader;
67        try {
68            bufferedReader =
69                    new BufferedReader(new FileReader(txt_exp));
70
71            String line;
72            String entry;
73            String[] parts;
74            String path;
75            Set<String> tokens;
76            Boolean skipped;
77            while (true) {
78                line = bufferedReader.readLine();
79                if (line == null) {
80                    break;
81                }
82
83                /** Remove the comment and trim */
84                entry = line.split("//", 2)[0].trim();
85
86                /** Omit empty lines, advance to next line */
87                if (entry.isEmpty()) {
88                    continue;
89                }
90
91                /** Split on whitespace into path part and the rest */
92                parts = entry.split("\\s", 2);
93
94                /** At this point parts.length >= 1 */
95                if (parts.length == 1) {
96                    Log.w(LOG_TAG + "::reloadConfiguration",
97                            "There are no options specified for the test!");
98                    continue;
99                }
100
101                path = trimTrailingSlashIfPresent(parts[0]);
102
103                /** Split on whitespace */
104                tokens = new HashSet<String>(Arrays.asList(parts[1].split("\\s", 0)));
105
106                /** Chose the right collections to add to */
107                skipped = false;
108                if (tokens.contains(TOKEN_SKIP)) {
109                    mSkipList.add(path);
110                    skipped = true;
111                }
112
113                /** If test is on skip list we ignore any further options */
114                if (skipped) {
115                    continue;
116                }
117
118                if (tokens.contains(TOKEN_IGNORE_RESULT)) {
119                    mIgnoreResultList.add(path);
120                }
121
122                if (tokens.contains(TOKEN_SLOW)) {
123                    mSlowList.add(path);
124                }
125            }
126        } catch (FileNotFoundException e) {
127            Log.w(LOG_TAG, "mRootDirPath=" + mRootDirPath + ": File not found: " +
128                    txt_exp.getPath(), e);
129        } catch (IOException e) {
130            Log.e(LOG_TAG, "mRootDirPath=" + mRootDirPath, e);
131        }
132    }
133
134    /**
135     * Checks if test is supposed to be skipped.
136     *
137     * <p>
138     * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
139     *
140     * @param testPath
141     *            - a relative path within LayoutTests folder
142     * @return if the test is supposed to be skipped
143     */
144    public boolean isSkip(String testPath) {
145        for (String prefix : getPrefixes(testPath)) {
146            if (mSkipList.contains(prefix)) {
147                return true;
148            }
149        }
150
151        return false;
152    }
153
154    /**
155     * Checks if test result is supposed to be ignored.
156     *
157     * <p>
158     * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
159     *
160     * @param testPath
161     *            - a relative path within LayoutTests folder
162     * @return if the test result is supposed to be ignored
163     */
164    public boolean isIgnoreRes(String testPath) {
165        for (String prefix : getPrefixes(testPath)) {
166            if (mIgnoreResultList.contains(prefix)) {
167                return true;
168            }
169        }
170
171        return false;
172    }
173
174    /**
175     * Checks if test is slow and should have timeout increased.
176     *
177     * <p>
178     * Path given should relative within LayoutTests folder, e.g. fast/dom/foo.html
179     *
180     * @param testPath
181     *            - a relative path within LayoutTests folder
182     * @return if the test is slow and should have timeout increased.
183     */
184    public boolean isSlow(String testPath) {
185        for (String prefix : getPrefixes(testPath)) {
186            if (mSlowList.contains(prefix)) {
187                return true;
188            }
189        }
190
191        return false;
192    }
193
194    /**
195     * Returns the list of all path prefixes of the given path.
196     *
197     * <p>
198     * e.g. this/is/a/path returns the list: this this/is this/is/a this/is/a/path
199     *
200     * @param path
201     * @return the list of all path prefixes of the given path.
202     */
203    private static List<String> getPrefixes(String path) {
204        File file = new File(path);
205        List<String> prefixes = new ArrayList<String>(8);
206
207        do {
208            prefixes.add(file.getPath());
209            file = file.getParentFile();
210        } while (file != null);
211
212        return prefixes;
213    }
214
215    /**
216     * Checks if the directory may contain tests or contains just helper files.
217     *
218     * @param dirName
219     * @return
220     *      if the directory may contain tests
221     */
222    public static boolean isTestDir(String dirName) {
223        return (!dirName.equals("script-tests")
224                && !dirName.equals("resources") && !dirName.startsWith("."));
225    }
226
227    /**
228     * Checks if the file is a test.
229     * Currently we run .html and .xhtml tests.
230     *
231     * @param testName
232     * @return
233     *      if the file is a test
234     */
235    public static boolean isTestFile(String testName) {
236        return testName.endsWith(".html") || testName.endsWith(".xhtml");
237    }
238
239    /**
240     * Return the path to the file relative to the tests root dir
241     *
242     * @param filePath
243     * @return
244     *      the path relative to the tests root dir
245     */
246    public String getRelativePath(String filePath) {
247        File rootDir = new File(mRootDirPath);
248        return filePath.replaceFirst(rootDir.getPath() + File.separator, "");
249    }
250
251    /**
252     * Return the path to the file relative to the tests root dir
253     *
254     * @param filePath
255     * @return
256     *      the path relative to the tests root dir
257     */
258    public String getRelativePath(File file) {
259        return getRelativePath(file.getAbsolutePath());
260    }
261
262    public File getAbsoluteFile(String relativePath) {
263        return new File(mRootDirPath, relativePath);
264    }
265
266    public String getAboslutePath(String relativePath) {
267        return getAbsoluteFile(relativePath).getAbsolutePath();
268    }
269
270    /**
271     * If the path contains extension (e.g .foo at the end of the file) then it changes
272     * this (.foo) into newEnding (so it has to contain the dot if we want to preserve it).
273     *
274     * <p>If the path doesn't contain an extension, it adds the ending to the path.
275     *
276     * @param relativePath
277     * @param newEnding
278     * @return
279     *      a new path, containing the newExtension
280     */
281    public static String setPathEnding(String relativePath, String newEnding) {
282        int dotPos = relativePath.lastIndexOf('.');
283        if (dotPos == -1) {
284            return relativePath + newEnding;
285        }
286
287        return relativePath.substring(0, dotPos) + newEnding;
288    }
289}