1#!/usr/bin/env python 2# Copyright (C) 2010 Google Inc. All rights reserved. 3# 4# Redistribution and use in source and binary forms, with or without 5# modification, are permitted provided that the following conditions are 6# met: 7# 8# * Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# * Redistributions in binary form must reproduce the above 11# copyright notice, this list of conditions and the following disclaimer 12# in the documentation and/or other materials provided with the 13# distribution. 14# * Neither the name of Google Inc. nor the names of its 15# contributors may be used to endorse or promote products derived from 16# this software without specific prior written permission. 17# 18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 30"""This module is used to find all of the layout test files used by 31run-webkit-tests. It exposes one public function - find() - 32which takes an optional list of paths. If a list is passed in, the returned 33list of test files is constrained to those found under the paths passed in, 34i.e. calling find(["LayoutTests/fast"]) will only return files 35under that directory.""" 36 37import time 38 39from webkitpy.common.system import logutils 40 41 42_log = logutils.get_logger(__file__) 43 44 45# When collecting test cases, we include any file with these extensions. 46_supported_file_extensions = set(['.html', '.shtml', '.xml', '.xhtml', '.xhtmlmp', '.pl', 47 '.php', '.svg']) 48# When collecting test cases, skip these directories 49_skipped_directories = set(['.svn', '_svn', 'resources', 'script-tests']) 50 51 52def find(port, paths=None): 53 """Finds the set of tests under a given list of sub-paths. 54 55 Args: 56 paths: a list of path expressions relative to port.layout_tests_dir() 57 to search. Glob patterns are ok, as are path expressions with 58 forward slashes on Windows. If paths is empty, we look at 59 everything under the layout_tests_dir(). 60 """ 61 paths = paths or ['*'] 62 filesystem = port._filesystem 63 return normalized_find(filesystem, normalize(filesystem, port.layout_tests_dir(), paths)) 64 65 66def normalize(filesystem, base_dir, paths): 67 return [filesystem.normpath(filesystem.join(base_dir, path)) for path in paths] 68 69 70def normalized_find(filesystem, paths): 71 """Finds the set of tests under the list of paths. 72 73 Args: 74 paths: a list of absolute path expressions to search. 75 Glob patterns are ok. 76 """ 77 gather_start_time = time.time() 78 paths_to_walk = set() 79 80 for path in paths: 81 # If there's an * in the name, assume it's a glob pattern. 82 if path.find('*') > -1: 83 filenames = filesystem.glob(path) 84 paths_to_walk.update(filenames) 85 else: 86 paths_to_walk.add(path) 87 88 # FIXME: I'm not sure there's much point in this being a set. A list would 89 # probably be faster. 90 test_files = set() 91 for path in paths_to_walk: 92 files = filesystem.files_under(path, _skipped_directories, _is_test_file) 93 test_files.update(set(files)) 94 95 gather_time = time.time() - gather_start_time 96 _log.debug("Test gathering took %f seconds" % gather_time) 97 98 return test_files 99 100 101def _has_supported_extension(filesystem, filename): 102 """Return true if filename is one of the file extensions we want to run a 103 test on.""" 104 extension = filesystem.splitext(filename)[1] 105 return extension in _supported_file_extensions 106 107 108def is_reference_html_file(filename): 109 """Return true if the filename points to a reference HTML file.""" 110 if (filename.endswith('-expected.html') or 111 filename.endswith('-expected-mismatch.html')): 112 return True 113 return False 114 115 116def _is_test_file(filesystem, dirname, filename): 117 """Return true if the filename points to a test file.""" 118 return (_has_supported_extension(filesystem, filename) and 119 not is_reference_html_file(filename)) 120