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

Side by Side Diff: testing/tools/test_runner.py

Issue 1850273003: Combined test runner. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « testing/tools/run_pixel_tests.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright 2015 The PDFium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import cStringIO
7 import functools
8 import multiprocessing
9 import optparse
10 import os
11 import re
12 import shutil
13 import subprocess
14 import sys
15
16 import common
17 import pngdiffer
18 import suppressor
19
20 class KeyboardInterruptError(Exception): pass
21
22 # Nomenclature:
23 # x_root - "x"
24 # x_filename - "x.ext"
25 # x_path - "path/to/a/b/c/x.ext"
26 # c_dir - "path/to/a/b/c"
27
28 def TestOneFileParallel(this, test_case):
29 """Wrapper to call GenerateAndTest() and redirect output to stdout."""
30 try:
31 old_stdout = sys.stdout
32 old_stderr = sys.stderr
33 sys.stdout = cStringIO.StringIO()
34 sys.stderr = sys.stdout
35
36 input_filename, source_dir = test_case
37 result = this.GenerateAndTest(input_filename, source_dir, True);
38
39 output = sys.stdout
40 sys.stdout = old_stdout
41 sys.stderr = old_stderr
42 return (result, output.getvalue(), input_filename, source_dir)
43 except KeyboardInterrupt:
44 raise KeyboardInterruptError()
45
46 class TestRunner:
47 def __init__(self, dirname):
48 self.test_dir = dirname
49
50 def GenerateAndTest(self, input_filename, source_dir, redirect_output=False):
51 input_root, _ = os.path.splitext(input_filename)
52 expected_txt_path = os.path.join(source_dir, input_root + '_expected.txt')
53
54 pdf_path = os.path.join(self.working_dir, input_root + '.pdf')
55
56 # Remove any existing generated images from previous runs.
57 actual_images = self.image_differ.GetActualFiles(input_filename, source_dir,
58 self.working_dir)
59 for image in actual_images:
60 if os.path.exists(image):
61 os.remove(image)
62
63 sys.stdout.flush()
64
65 raised_exception = self.Generate(source_dir, input_filename, input_root,
66 pdf_path, redirect_output)
67
68 if raised_exception != None:
69 print "FAILURE: " + input_filename + "; " + str(raised_exception)
70 return False
71
72 if os.path.exists(expected_txt_path):
73 raised_exception = self.TestText(input_root, expected_txt_path, pdf_path,
74 redirect_output)
75 else:
76 raised_exception = self.TestPixel(pdf_path, redirect_output)
77
78 if raised_exception != None:
79 print "FAILURE: " + input_filename + "; " + str(raised_exception)
80 return False
81
82 if len(actual_images):
83 if self.image_differ.HasDifferences(input_filename, source_dir,
84 self.working_dir, redirect_output):
85 return False
86
87 return True
88
89
90 def Generate(self, source_dir, input_filename, input_root, pdf_path,
91 redirect_output):
92 original_path = os.path.join(source_dir, input_filename)
93 input_path = os.path.join(source_dir, input_root + '.in')
94
95 if os.path.exists(original_path) and not os.path.exists(input_path):
Lei Zhang 2016/04/05 23:33:24 Can we combine this with line 98? if not os.path.
dsinclair 2016/04/06 13:39:33 Done.
96 shutil.copyfile(original_path, pdf_path)
97
98 if not os.path.exists(input_path):
99 return None
100
101 # Add Dr. Memory wrapper if exists, remove .pdf suffix
102 cmd = common.DrMemoryWrapper(self.drmem_wrapper,
103 os.path.splitext(input_root))
Lei Zhang 2016/04/05 23:33:24 - Funny indentation. - Do you need to call splitex
dsinclair 2016/04/06 13:39:33 Done.
104 cmd.extend([sys.executable, self.fixup_path,
105 '--output-dir=' + self.working_dir, input_path])
Lei Zhang 2016/04/05 23:33:24 Funny indentation.
dsinclair 2016/04/06 13:39:33 Done.
106 return common.RunCommand(cmd, redirect_output)
107
108
109 def TestText(self, input_root, expected_txt_path, pdf_path, redirect_output):
110 txt_path = os.path.join(self.working_dir, input_root + '.txt')
111 with open(txt_path, 'w') as outfile:
112 subprocess.check_call([self.pdfium_test_path, pdf_path], stdout=outfile)
113
114 cmd = [sys.executable, self.text_diff_path, expected_txt_path, txt_path]
115 return common.RunCommand(cmd, redirect_output)
116
117
118 def TestPixel(self, pdf_path, redirect_output):
119 return common.RunCommand(
120 [self.pdfium_test_path, '--png', pdf_path], redirect_output)
121
122
123 def HandleResult(self, input_filename, input_path, result):
124 if self.test_suppressor.IsSuppressed(input_filename):
125 if result:
126 self.surprises.append(input_path)
127 else:
128 if not result:
129 self.failures.append(input_path)
130
131
132 def Run(self):
133 parser = optparse.OptionParser()
134 parser.add_option('--build-dir', default=os.path.join('out', 'Debug'),
135 help='relative path from the base source directory')
136 parser.add_option('-j', default=multiprocessing.cpu_count(),
137 dest='num_workers', type='int',
138 help='run NUM_WORKERS jobs in parallel')
139 parser.add_option('--wrapper', default='', dest="wrapper",
140 help='wrapper for running test under Dr. Memory')
141 options, args = parser.parse_args()
142
143 finder = common.DirectoryFinder(options.build_dir)
144 self.fixup_path = finder.ScriptPath('fixup_pdf_template.py')
145 self.text_diff_path = finder.ScriptPath('text_diff.py')
146
147 self.drmem_wrapper = options.wrapper
148
149 self.source_dir = finder.TestingDir()
150
151 if self.test_dir != 'corpus':
152 test_dir = finder.TestingDir(os.path.join('resources', self.test_dir))
153 else:
154 test_dir = finder.TestingDir(self.test_dir)
155
156 self.pdfium_test_path = finder.ExecutablePath('pdfium_test')
157 if not os.path.exists(self.pdfium_test_path):
158 print "FAILURE: Can't find test executable '%s'" % self.pdfium_test_path
159 print "Use --build-dir to specify its location."
160 return 1
161
162 self.working_dir = finder.WorkingDir(os.path.join('testing', self.test_dir))
163 if not os.path.exists(self.working_dir):
164 os.makedirs(self.working_dir)
165
166 self.feature_string = subprocess.check_output([self.pdfium_test_path,
167 '--show-config'])
168 self.test_suppressor = suppressor.Suppressor(finder, self.feature_string)
169 self.image_differ = pngdiffer.PNGDiffer(finder)
170
171 walk_from_dir = finder.TestingDir(test_dir);
172
173 test_cases = []
174 input_file_re = re.compile('^[a-zA-Z0-9_.]+[.](in|pdf)$')
175
176 if len(args):
177 for file_name in args:
178 file_name.replace(".pdf", ".in")
179 input_path = os.path.join(walk_from_dir, file_name)
180 if not os.path.isfile(input_path):
181 print "Can't find test file '%s'" % file_name
182 return 1
183
184 test_cases.append((os.path.basename(input_path),
185 os.path.dirname(input_path)))
186 else:
187 for file_dir, _, filename_list in os.walk(walk_from_dir):
188 for input_filename in filename_list:
189 if input_file_re.match(input_filename):
190 input_path = os.path.join(file_dir, input_filename)
191 if os.path.isfile(input_path):
192 test_cases.append((input_filename, file_dir))
193
194 self.failures = []
195 self.surprises = []
196
197 if options.num_workers > 1 and not len(args):
198 try:
199 pool = multiprocessing.Pool(options.num_workers)
200 worker_func = functools.partial(TestOneFileParallel, self)
201
202 worker_results = pool.imap(worker_func, test_cases)
203 for worker_result in worker_results:
204 result, output, input_filename, source_dir = worker_result
205 input_path = os.path.join(source_dir, input_filename)
206 sys.stdout.write(output)
207
208 self.HandleResult(input_filename, input_path, result)
209 except KeyboardInterrupt:
210 pool.terminate()
211 finally:
212 pool.close()
213 pool.join()
214 else:
215 for test_case in test_cases:
216 input_filename, input_file_dir = test_case
217 result = self.GenerateAndTest(input_filename, input_file_dir)
218 self.HandleResult(input_filename,
219 os.path.join(input_file_dir, input_filename), result)
220
221 if self.surprises:
222 self.surprises.sort()
223 print '\n\nUnexpected Successes:'
224 for surprise in self.surprises:
225 print surprise;
226
227 if self.failures:
228 self.failures.sort()
229 print '\n\nSummary of Failures:'
230 for failure in self.failures:
231 print failure
232 return 1
233
234 return 0
235
236
237
OLDNEW
« no previous file with comments | « testing/tools/run_pixel_tests.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698