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

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

Issue 1398793003: Parallelize run_corpus_tests.py. (Closed) Base URL: https://pdfium.googlesource.com/pdfium@master
Patch Set: address comments Created 5 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
« no previous file with comments | « testing/tools/pngdiffer.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
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2015 The PDFium Authors. All rights reserved. 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 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import cStringIO
7 import functools
8 import multiprocessing
6 import optparse 9 import optparse
7 import os 10 import os
8 import re 11 import re
9 import shutil 12 import shutil
10 import subprocess 13 import subprocess
11 import sys 14 import sys
12 15
13 import common 16 import common
14 import pngdiffer 17 import pngdiffer
15 import suppressor 18 import suppressor
16 19
17 # Nomenclature: 20 # Nomenclature:
18 # x_root - "x" 21 # x_root - "x"
19 # x_filename - "x.ext" 22 # x_filename - "x.ext"
20 # x_path - "path/to/a/b/c/x.ext" 23 # x_path - "path/to/a/b/c/x.ext"
21 # c_dir - "path/to/a/b/c" 24 # c_dir - "path/to/a/b/c"
22 25
23 def test_one_file(input_filename, source_dir, working_dir, 26 def test_one_file(input_filename, source_dir, working_dir,
24 pdfium_test_path, image_differ): 27 pdfium_test_path, image_differ, redirect_output=False):
25 input_path = os.path.join(source_dir, input_filename) 28 input_path = os.path.join(source_dir, input_filename)
26 pdf_path = os.path.join(working_dir, input_filename) 29 pdf_path = os.path.join(working_dir, input_filename)
27 30
28 # Remove any existing generated images from previous runs. 31 # Remove any existing generated images from previous runs.
29 actual_images = image_differ.GetActualFiles( 32 actual_images = image_differ.GetActualFiles(
30 input_filename, source_dir, working_dir) 33 input_filename, source_dir, working_dir)
31 for image in actual_images: 34 for image in actual_images:
32 if os.path.exists(image): 35 if os.path.exists(image):
33 os.remove(image) 36 os.remove(image)
34 37
35 try: 38 shutil.copyfile(input_path, pdf_path)
36 shutil.copyfile(input_path, pdf_path) 39 sys.stdout.flush()
37 sys.stdout.flush() 40 error = common.RunCommand([pdfium_test_path, '--png', pdf_path],
38 subprocess.check_call([pdfium_test_path, '--png', pdf_path]) 41 redirect_output)
39 except subprocess.CalledProcessError as e: 42 if error:
40 print "FAILURE: " + input_filename + "; " + str(e) 43 print "FAILURE: " + input_filename + "; " + str(error)
41 return False 44 return False
42 if image_differ.HasDifferences(input_filename, source_dir, working_dir): 45 return not image_differ.HasDifferences(input_filename, source_dir,
43 return False 46 working_dir, redirect_output)
44 return True 47
48
49 def test_one_file_parallel(working_dir, pdfium_test_path, image_differ,
50 test_case):
51 """Wrapper function to call test_one_file() and redirect output to stdout."""
52 old_stdout = sys.stdout
53 old_stderr = sys.stderr
54 sys.stdout = cStringIO.StringIO()
55 sys.stderr = sys.stdout
56 input_filename, source_dir = test_case
57 result = test_one_file(input_filename, source_dir, working_dir,
58 pdfium_test_path, image_differ, True);
59 output = sys.stdout
60 sys.stdout = old_stdout
61 sys.stderr = old_stderr
62 return (result, output.getvalue(), input_filename, source_dir)
63
64
65 def handle_result(test_suppressor, input_filename, input_path, result,
66 surprises, failures):
67 if test_suppressor.IsSuppressed(input_filename):
68 if result:
69 surprises.append(input_path)
70 else:
71 if not result:
72 failures.append(input_path)
45 73
46 74
47 def main(): 75 def main():
48 parser = optparse.OptionParser() 76 parser = optparse.OptionParser()
49 parser.add_option('--build-dir', default=os.path.join('out', 'Debug'), 77 parser.add_option('--build-dir', default=os.path.join('out', 'Debug'),
50 help='relative path from the base source directory') 78 help='relative path from the base source directory')
79 parser.add_option('-j', default=multiprocessing.cpu_count(),
80 dest='num_workers', type='int',
81 help='run NUM_WORKERS jobs in parallel')
51 options, args = parser.parse_args() 82 options, args = parser.parse_args()
52 finder = common.DirectoryFinder(options.build_dir) 83 finder = common.DirectoryFinder(options.build_dir)
53 pdfium_test_path = finder.ExecutablePath('pdfium_test') 84 pdfium_test_path = finder.ExecutablePath('pdfium_test')
54 if not os.path.exists(pdfium_test_path): 85 if not os.path.exists(pdfium_test_path):
55 print "FAILURE: Can't find test executable '%s'" % pdfium_test_path 86 print "FAILURE: Can't find test executable '%s'" % pdfium_test_path
56 print "Use --build-dir to specify its location." 87 print "Use --build-dir to specify its location."
57 return 1 88 return 1
58 working_dir = finder.WorkingDir(os.path.join('testing', 'corpus')) 89 working_dir = finder.WorkingDir(os.path.join('testing', 'corpus'))
59 if not os.path.exists(working_dir): 90 if not os.path.exists(working_dir):
60 os.makedirs(working_dir) 91 os.makedirs(working_dir)
61 92
62 test_suppressor = suppressor.Suppressor(finder) 93 test_suppressor = suppressor.Suppressor(finder)
63 image_differ = pngdiffer.PNGDiffer(finder) 94 image_differ = pngdiffer.PNGDiffer(finder)
64 95
65 # test files are under .../pdfium/testing/corpus. 96 # test files are under .../pdfium/testing/corpus.
66 failures = [] 97 failures = []
67 surprises = [] 98 surprises = []
68 walk_from_dir = finder.TestingDir('corpus'); 99 walk_from_dir = finder.TestingDir('corpus');
69 input_file_re = re.compile('^[a-zA-Z0-9_.]+[.]pdf$') 100 input_file_re = re.compile('^[a-zA-Z0-9_.]+[.]pdf$')
101 test_cases = []
70 for source_dir, _, filename_list in os.walk(walk_from_dir): 102 for source_dir, _, filename_list in os.walk(walk_from_dir):
71 for input_filename in filename_list: 103 for input_filename in filename_list:
72 if input_file_re.match(input_filename): 104 if input_file_re.match(input_filename):
73 input_path = os.path.join(source_dir, input_filename) 105 input_path = os.path.join(source_dir, input_filename)
74 if os.path.isfile(input_path): 106 if os.path.isfile(input_path):
75 result = test_one_file(input_filename, source_dir, working_dir, 107 test_cases.append((input_filename, source_dir))
76 pdfium_test_path, image_differ) 108
77 if test_suppressor.IsSuppressed(input_filename): 109 if options.num_workers > 1:
78 if result: 110 pool = multiprocessing.Pool(options.num_workers)
79 surprises.append(input_path) 111 worker_func = functools.partial(test_one_file_parallel, working_dir,
80 else: 112 pdfium_test_path, image_differ)
81 if not result: 113 worker_results = pool.imap(worker_func, test_cases)
82 failures.append(input_path) 114 for worker_result in worker_results:
115 result, output, input_filename, source_dir = worker_result
116 input_path = os.path.join(source_dir, input_filename)
117 sys.stdout.write(output)
118 handle_result(test_suppressor, input_filename, input_path, result,
119 surprises, failures)
120 else:
121 for test_case in test_cases:
122 input_filename, source_dir = test_case
123 result = test_one_file(input_filename, source_dir, working_dir,
124 pdfium_test_path, image_differ)
125 handle_result(test_suppressor, input_filename, input_path, result,
126 surprises, failures)
83 127
84 if surprises: 128 if surprises:
85 surprises.sort() 129 surprises.sort()
86 print '\n\nUnexpected Successes:' 130 print '\n\nUnexpected Successes:'
87 for surprise in surprises: 131 for surprise in surprises:
88 print surprise; 132 print surprise;
89 133
90 if failures: 134 if failures:
91 failures.sort() 135 failures.sort()
92 print '\n\nSummary of Failures:' 136 print '\n\nSummary of Failures:'
93 for failure in failures: 137 for failure in failures:
94 print failure 138 print failure
95 return 1 139 return 1
96 140
97 return 0 141 return 0
98 142
99 143
100 if __name__ == '__main__': 144 if __name__ == '__main__':
101 sys.exit(main()) 145 sys.exit(main())
OLDNEW
« no previous file with comments | « testing/tools/pngdiffer.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698