3
# Copyright (c) 2009 Google Inc. All rights reserved.
4
# Use of this source code is governed by a BSD-style license that can be
5
# found in the LICENSE file.
8
gyptest.py -- test runner for GYP tests.
18
Executor class for commands, including "commands" implemented by
24
def __init__(self, dictionary={}):
25
self.subst_dictionary(dictionary)
27
def subst_dictionary(self, dictionary):
28
self._subst_dictionary = dictionary
30
def subst(self, string, dictionary=None):
32
Substitutes (via the format operator) the values in the specified
33
dictionary into the specified command.
35
The command can be an (action, string) tuple. In all cases, we
36
perform substitution on strings and don't worry if something isn't
37
a string. (It's probably a Python function to be executed.)
39
if dictionary is None:
40
dictionary = self._subst_dictionary
43
string = string % dictionary
48
def display(self, command, stdout=None, stderr=None):
51
if type(command) == type(()):
54
s = '%s(%s)' % (func.__name__, ', '.join(map(repr, args)))
55
if type(command) == type([]):
56
# TODO: quote arguments containing spaces
57
# TODO: handle meta characters?
60
s = self.subst(command)
61
if not s.endswith('\n'):
66
def execute(self, command, stdout=None, stderr=None):
68
Executes a single command.
72
if type(command) == type(''):
73
command = self.subst(command)
74
cmdargs = shlex.split(command)
75
if cmdargs[0] == 'cd':
76
command = (os.chdir,) + tuple(cmdargs[1:])
77
if type(command) == type(()):
82
if stdout is sys.stdout:
83
# Same as passing sys.stdout, except python2.4 doesn't fail on it.
86
# Open pipe for anything else so Popen works on python2.4.
87
subout = subprocess.PIPE
88
if stderr is sys.stderr:
89
# Same as passing sys.stderr, except python2.4 doesn't fail on it.
92
# Merge with stdout if stderr isn't specified.
93
suberr = subprocess.STDOUT
95
# Open pipe for anything else so Popen works on python2.4.
96
suberr = subprocess.PIPE
97
p = subprocess.Popen(command,
98
shell=(sys.platform == 'win32'),
103
self.stdout = p.stdout.read()
104
elif stdout is not sys.stdout:
105
stdout.write(p.stdout.read())
106
if stderr not in (None, sys.stderr):
107
stderr.write(p.stderr.read())
110
def run(self, command, display=None, stdout=None, stderr=None):
112
Runs a single command, displaying it first.
116
self.display(display)
117
return self.execute(command, stdout, stderr)
121
def __init__(self, fp):
123
def write(self, arg):
126
def __getattr__(self, attr):
127
return getattr(self.fp, attr)
129
sys.stdout = Unbuffered(sys.stdout)
130
sys.stderr = Unbuffered(sys.stderr)
133
def find_all_gyptest_files(directory):
135
for root, dirs, files in os.walk(directory):
138
result.extend([ os.path.join(root, f) for f in files
139
if f.startswith('gyptest') and f.endswith('.py') ])
148
usage = "gyptest.py [-ahlnq] [-f formats] [test ...]"
149
parser = optparse.OptionParser(usage=usage)
150
parser.add_option("-a", "--all", action="store_true",
151
help="run all tests")
152
parser.add_option("-C", "--chdir", action="store", default=None,
153
help="chdir to the specified directory")
154
parser.add_option("-f", "--format", action="store", default='',
155
help="run tests with the specified formats")
156
parser.add_option("-l", "--list", action="store_true",
157
help="list available tests and exit")
158
parser.add_option("-n", "--no-exec", action="store_true",
159
help="no execute, just print the command line")
160
parser.add_option("--passed", action="store_true",
161
help="report passed tests")
162
parser.add_option("--path", action="append", default=[],
163
help="additional $PATH directory")
164
parser.add_option("-q", "--quiet", action="store_true",
165
help="quiet, don't print test command lines")
166
opts, args = parser.parse_args(argv[1:])
172
os.environ['PATH'] += ':' + ':'.join(opts.path)
176
sys.stderr.write('Specify -a to get all tests.\n')
182
if os.path.isdir(arg):
183
tests.extend(find_all_gyptest_files(os.path.normpath(arg)))
192
CommandRunner.verbose = not opts.quiet
193
CommandRunner.active = not opts.no_exec
196
os.environ['PYTHONPATH'] = os.path.abspath('test/lib')
198
sys.stdout.write('PYTHONPATH=%s\n' % os.environ['PYTHONPATH'])
205
format_list = opts.format.split(',')
207
# TODO: not duplicate this mapping from pylib/gyp/__init__.py
217
for format in format_list:
218
os.environ['TESTGYP_FORMAT'] = format
220
sys.stdout.write('TESTGYP_FORMAT=%s\n' % format)
223
status = cr.run([sys.executable, test],
227
no_result.append(test)
234
def report(description, tests):
237
sys.stdout.write("\n%s the following test:\n" % description)
239
fmt = "\n%s the following %d tests:\n"
240
sys.stdout.write(fmt % (description, len(tests)))
241
sys.stdout.write("\t" + "\n\t".join(tests) + "\n")
244
report("Passed", passed)
245
report("Failed", failed)
246
report("No result from", no_result)
254
if __name__ == "__main__":