Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: Tools/Scripts/webkitpy/test/finder.py

Issue 654063002: Switch webkitpy to use the typ test framework (delete webkitpy.test). (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: fix typo for bot_test_expectations Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Tools/Scripts/webkitpy/test/__init__.py ('k') | Tools/Scripts/webkitpy/test/finder_unittest.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 # Copyright (C) 2012 Google, Inc.
2 # Copyright (C) 2010 Chris Jerdonek (cjerdonek@webkit.org)
3 #
4 # Redistribution and use in source and binary forms, with or without
5 # modification, are permitted provided that the following conditions
6 # are met:
7 # 1. Redistributions of source code must retain the above copyright
8 # notice, this list of conditions and the following disclaimer.
9 # 2. Redistributions in binary form must reproduce the above copyright
10 # notice, this list of conditions and the following disclaimer in the
11 # documentation and/or other materials provided with the distribution.
12 #
13 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND
14 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
15 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
16 # DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR
17 # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
19 # SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
20 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
21 # OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
22 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
24 """this module is responsible for finding python tests."""
25
26 import logging
27 import re
28
29
30 _log = logging.getLogger(__name__)
31
32
33 class _DirectoryTree(object):
34 def __init__(self, filesystem, top_directory, starting_subdirectory):
35 self.filesystem = filesystem
36 self.top_directory = filesystem.realpath(top_directory)
37 self.search_directory = self.top_directory
38 self.top_package = ''
39 if starting_subdirectory:
40 self.top_package = starting_subdirectory.replace(filesystem.sep, '.' ) + '.'
41 self.search_directory = filesystem.join(self.top_directory, starting _subdirectory)
42
43 def find_modules(self, suffixes, sub_directory=None):
44 if sub_directory:
45 search_directory = self.filesystem.join(self.top_directory, sub_dire ctory)
46 else:
47 search_directory = self.search_directory
48
49 def file_filter(filesystem, dirname, basename):
50 return any(basename.endswith(suffix) for suffix in suffixes)
51
52 filenames = self.filesystem.files_under(search_directory, file_filter=fi le_filter)
53 return [self.to_module(filename) for filename in filenames]
54
55 def to_module(self, path):
56 return path.replace(self.top_directory + self.filesystem.sep, '').replac e(self.filesystem.sep, '.')[:-3]
57
58 def subpath(self, path):
59 """Returns the relative path from the top of the tree to the path, or No ne if the path is not under the top of the tree."""
60 realpath = self.filesystem.realpath(self.filesystem.join(self.top_direct ory, path))
61 if realpath.startswith(self.top_directory + self.filesystem.sep):
62 return realpath.replace(self.top_directory + self.filesystem.sep, '' )
63 return None
64
65 def clean(self):
66 """Delete all .pyc files in the tree that have no matching .py file."""
67 _log.debug("Cleaning orphaned *.pyc files from: %s" % self.search_direct ory)
68 filenames = self.filesystem.files_under(self.search_directory)
69 for filename in filenames:
70 if filename.endswith(".pyc") and filename[:-1] not in filenames:
71 _log.info("Deleting orphan *.pyc file: %s" % filename)
72 self.filesystem.remove(filename)
73
74
75 class Finder(object):
76 def __init__(self, filesystem):
77 self.filesystem = filesystem
78 self.trees = []
79 self._names_to_skip = []
80
81 def add_tree(self, top_directory, starting_subdirectory=None):
82 self.trees.append(_DirectoryTree(self.filesystem, top_directory, startin g_subdirectory))
83
84 def skip(self, names, reason, bugid):
85 self._names_to_skip.append(tuple([names, reason, bugid]))
86
87 def additional_paths(self, paths):
88 return [tree.top_directory for tree in self.trees if tree.top_directory not in paths]
89
90 def clean_trees(self):
91 for tree in self.trees:
92 tree.clean()
93
94 def is_module(self, name):
95 relpath = name.replace('.', self.filesystem.sep) + '.py'
96 return any(self.filesystem.exists(self.filesystem.join(tree.top_director y, relpath)) for tree in self.trees)
97
98 def is_dotted_name(self, name):
99 return re.match(r'[a-zA-Z.][a-zA-Z0-9_.]*', name)
100
101 def to_module(self, path):
102 for tree in self.trees:
103 if path.startswith(tree.top_directory):
104 return tree.to_module(path)
105 return None
106
107 def find_names(self, args, find_all):
108 suffixes = ['_unittest.py', '_integrationtest.py']
109 if args:
110 names = []
111 for arg in args:
112 names.extend(self._find_names_for_arg(arg, suffixes))
113 return names
114
115 return self._default_names(suffixes, find_all)
116
117 def _find_names_for_arg(self, arg, suffixes):
118 realpath = self.filesystem.realpath(arg)
119 if self.filesystem.exists(realpath):
120 names = self._find_in_trees(realpath, suffixes)
121 if not names:
122 _log.error("%s is not in one of the test trees." % arg)
123 return names
124
125 # See if it's a python package in a tree (or a relative path from the to p of a tree).
126 names = self._find_in_trees(arg.replace('.', self.filesystem.sep), suffi xes)
127 if names:
128 return names
129
130 if self.is_dotted_name(arg):
131 # The name may not exist, but that's okay; we'll find out later.
132 return [arg]
133
134 _log.error("%s is not a python name or an existing file or directory." % arg)
135 return []
136
137 def _find_in_trees(self, path, suffixes):
138 for tree in self.trees:
139 relpath = tree.subpath(path)
140 if not relpath:
141 continue
142 if self.filesystem.isfile(path):
143 return [tree.to_module(path)]
144 else:
145 return tree.find_modules(suffixes, path)
146 return []
147
148 def _default_names(self, suffixes, find_all):
149 modules = []
150 for tree in self.trees:
151 modules.extend(tree.find_modules(suffixes))
152 modules.sort()
153
154 for module in modules:
155 _log.debug("Found: %s" % module)
156
157 if not find_all:
158 for (names, reason, bugid) in self._names_to_skip:
159 self._exclude(modules, names, reason, bugid)
160
161 return modules
162
163 def _exclude(self, modules, module_prefixes, reason, bugid):
164 _log.info('Skipping tests in the following modules or packages because t hey %s:' % reason)
165 for prefix in module_prefixes:
166 _log.info(' %s' % prefix)
167 modules_to_exclude = filter(lambda m: m.startswith(prefix), modules)
168 for m in modules_to_exclude:
169 if len(modules_to_exclude) > 1:
170 _log.debug(' %s' % m)
171 modules.remove(m)
172 _log.info(' (https://bugs.webkit.org/show_bug.cgi?id=%d; use --all to include)' % bugid)
173 _log.info('')
OLDNEW
« no previous file with comments | « Tools/Scripts/webkitpy/test/__init__.py ('k') | Tools/Scripts/webkitpy/test/finder_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698