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

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

Issue 1430623006: One test runner to rule them all. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Created 5 years, 1 month 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 function to call GenerateAndTest() and redirect output to stdout."" "
Lei Zhang 2015/10/29 17:35:01 80 chars / column, ditto below
dsinclair 2015/11/02 15:22:52 Done.
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
47 class TestRunner:
48 def __init__(self, dirname):
49 self.test_dir = dirname
50
51 def GenerateAndTest(self, input_filename, source_dir, redirect_output=False):
Lei Zhang 2015/10/29 17:35:01 Should this be split into Generate(), TestPixel()
dsinclair 2015/10/29 17:36:46 If we want good code and not just me randomly slap
dsinclair 2015/11/02 15:22:52 Done.
52 original_path = os.path.join(source_dir, input_filename)
53
54 input_root, _ = os.path.splitext(input_filename)
55 input_path = os.path.join(source_dir, input_root + '.in')
56 pdf_path = os.path.join(self.working_dir, input_root + '.pdf')
57 txt_path = os.path.join(self.working_dir, input_root + '.txt')
58 expected_txt_path = os.path.join(source_dir, input_root + '_expected.txt')
59
60 # Remove any existing generated images from previous runs.
61 actual_images = self.image_differ.GetActualFiles(
62 input_filename, source_dir, self.working_dir)
63 for image in actual_images:
64 if os.path.exists(image):
65 os.remove(image)
66
67 if os.path.exists(original_path) and not os.path.exists(input_path):
68 shutil.copyfile(original_path, pdf_path)
69
70 sys.stdout.flush()
71
72 raised_exception = None
73 if os.path.exists(input_path):
74 raised_exception = common.RunCommand(
75 [sys.executable, self.fixup_path,
76 '--output-dir=' + self.working_dir, input_path],
77 redirect_output)
78
79 if os.path.exists(expected_txt_path):
80 with open(txt_path, 'w') as outfile:
81 subprocess.check_call([self.pdfium_test_path, pdf_path], stdout=outfile)
82 raised_exception = common.RunCommand(
83 [sys.executable, self.text_diff_path, expected_txt_path, txt_path],
84 redirect_output)
85 else:
86 raised_exception = common.RunCommand(
87 [self.pdfium_test_path, '--png', pdf_path], redirect_output)
88
89 if raised_exception != None:
90 print "FAILURE: " + input_filename + "; " + str(raised_exception)
91 return False
92
93 if len(actual_images):
94 if self.image_differ.HasDifferences(input_filename, source_dir, self.worki ng_dir):
95 return False
96
97 return True
98
99 def HandleResult(self, input_filename, input_path, result):
100 if self.test_suppressor.IsSuppressed(input_filename):
101 if result:
102 self.surprises.append(input_path)
103 else:
104 if not result:
105 self.failures.append(input_path)
106
107 def Run(self):
108 parser = optparse.OptionParser()
109 parser.add_option('--build-dir', default=os.path.join('out', 'Debug'),
110 help='relative path from the base source directory')
111 parser.add_option('-j', default=multiprocessing.cpu_count(),
112 dest='num_workers', type='int',
113 help='run NUM_WORKERS jobs in parallel')
114 options, args = parser.parse_args()
115
116 finder = common.DirectoryFinder(options.build_dir)
117 self.fixup_path = finder.ScriptPath('fixup_pdf_template.py')
118 self.text_diff_path = finder.ScriptPath('text_diff.py')
119
120 self.source_dir = finder.TestingDir()
121
122 if self.test_dir != 'corpus':
123 test_dir = finder.TestingDir(os.path.join('resources', self.test_dir))
124 else:
125 test_dir = finder.TestingDir(self.test_dir)
126
127 self.pdfium_test_path = finder.ExecutablePath('pdfium_test')
128 if not os.path.exists(self.pdfium_test_path):
129 print "FAILURE: Can't find test executable '%s'" % self.pdfium_test_path
130 print "Use --build-dir to specify its location."
131 return 1
132
133 self.working_dir = finder.WorkingDir(os.path.join('testing', self.test_dir))
134 if not os.path.exists(self.working_dir):
135 os.makedirs(self.working_dir)
136
137 self.test_suppressor = suppressor.Suppressor(finder)
138 self.image_differ = pngdiffer.PNGDiffer(finder)
139
140 walk_from_dir = finder.TestingDir(test_dir);
141
142 test_cases = []
143 input_file_re = re.compile('^[a-zA-Z0-9_.]+[.](in|pdf)$')
144
145 if len(args):
146 for file_name in args:
147 file_name.replace(".pdf", ".in")
148 input_path = os.path.join(walk_from_dir, file_name)
149 if not os.path.isfile(input_path):
150 print "Can't find test file '%s'" % file_name
151 return 1
152
153 test_cases.append((os.path.basename(input_path),
154 os.path.dirname(input_path)))
155 else:
156 for file_dir, _, filename_list in os.walk(walk_from_dir):
157 for input_filename in filename_list:
158 if input_file_re.match(input_filename):
159 input_path = os.path.join(file_dir, input_filename)
160 if os.path.isfile(input_path):
161 test_cases.append((input_filename, file_dir))
162
163 self.failures = []
164 self.surprises = []
165
166 if options.num_workers > 1:
167 try:
168 pool = multiprocessing.Pool(options.num_workers)
169 worker_func = functools.partial(TestOneFileParallel, self)
170
171 worker_results = pool.imap(worker_func, test_cases)
172 for worker_result in worker_results:
173 result, output, input_filename, source_dir = worker_result
174 input_path = os.path.join(source_dir, input_filename)
175 sys.stdout.write(output)
176
177 self.HandleResult(input_filename, input_path, result)
178 except KeyboardInterrupt:
179 pool.terminate()
180 finally:
181 pool.close()
182 pool.join()
183 else:
184 for test_case in test_cases:
185 input_filename, input_file_dir = test_case
186 result = self.GenerateAndTest(input_filename, input_file_dir)
187 self.HandleResult(input_filename,
188 os.path.join(input_file_dir, input_filename), result)
189
190 if self.surprises:
191 self.surprises.sort()
192 print '\n\nUnexpected Successes:'
193 for surprise in self.surprises:
194 print surprise;
195
196 if self.failures:
197 self.failures.sort()
198 print '\n\nSummary of Failures:'
199 for failure in self.failures:
200 print failure
201 return 1
202
203 return 0
204
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