1e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#!/usr/bin/env python
2e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov# Copyright 2015 The PDFium Authors. All rights reserved.
3e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov# Use of this source code is governed by a BSD-style license that can be
4e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov# found in the LICENSE file.
5e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
6e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport optparse
7e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport os
8e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport re
9e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport subprocess
10e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport sys
11e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
12e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport common
13e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport pngdiffer
14e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovimport suppressor
15e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
16e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov# Nomenclature:
17e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#   x_root - "x"
18e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#   x_filename - "x.ext"
19e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#   x_path - "path/to/a/b/c/x.ext"
20e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov#   c_dir - "path/to/a/b/c"
21e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
22e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovdef generate_and_test(input_filename, source_dir, working_dir,
23ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      fixup_path, pdfium_test_path, image_differ,
24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                      drmem_wrapper):
25e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  input_root, _ = os.path.splitext(input_filename)
26e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  input_path = os.path.join(source_dir, input_root + '.in')
27e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  pdf_path = os.path.join(working_dir, input_root + '.pdf')
28ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
29ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  # Remove any existing generated images from previous runs.
30ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  actual_images = image_differ.GetActualFiles(
31ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      input_filename, source_dir, working_dir)
32ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for image in actual_images:
33ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    if os.path.exists(image):
34ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      os.remove(image)
35ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
36e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  try:
37e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    sys.stdout.flush()
38e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    subprocess.check_call(
39e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        [sys.executable, fixup_path, '--output-dir=' + working_dir, input_path])
40ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    # add Dr. Memory wrapper if exist
41ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    cmd_to_run = common.DrMemoryWrapper(drmem_wrapper, input_root)
42ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    cmd_to_run.extend([pdfium_test_path, '--png', pdf_path])
43ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    # run test
44ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    subprocess.check_call(cmd_to_run)
45e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  except subprocess.CalledProcessError as e:
46e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    print "FAILURE: " + input_filename + "; " + str(e)
47e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return False
48e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  if image_differ.HasDifferences(input_filename, source_dir, working_dir):
49e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    print "FAILURE: " + input_filename
50e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return False
51e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  return True
52e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
53ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
54e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovdef main():
55e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  parser = optparse.OptionParser()
56e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  parser.add_option('--build-dir', default=os.path.join('out', 'Debug'),
57e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov                    help='relative path from the base source directory')
58ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  parser.add_option('--wrapper', default='', dest="wrapper",
59ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                    help='Dr. Memory wrapper for running test under Dr. Memory')
60e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  options, args = parser.parse_args()
61e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  finder = common.DirectoryFinder(options.build_dir)
62e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  fixup_path = finder.ScriptPath('fixup_pdf_template.py')
63e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  source_dir = finder.TestingDir(os.path.join('resources', 'pixel'))
64e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  pdfium_test_path = finder.ExecutablePath('pdfium_test')
65e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  if not os.path.exists(pdfium_test_path):
66e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    print "FAILURE: Can't find test executable '%s'" % pdfium_test_path
67e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    print "Use --build-dir to specify its location."
68e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return 1
69e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  working_dir = finder.WorkingDir(os.path.join('testing', 'pixel'))
70e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  if not os.path.exists(working_dir):
71e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    os.makedirs(working_dir)
72e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
73e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  test_suppressor = suppressor.Suppressor(finder)
74e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  image_differ = pngdiffer.PNGDiffer(finder)
75e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
76ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  input_files = []
77ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  if len(args):
78ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    for file_name in args:
79ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann      input_files.append(file_name.replace(".pdf", ".in"))
80ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  else:
81ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    input_files = os.listdir(source_dir)
82ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
83e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  failures = []
84e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  input_file_re = re.compile('^[a-zA-Z0-9_.]+[.]in$')
85ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann  for input_filename in input_files:
86e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    if input_file_re.match(input_filename):
87e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      input_path = os.path.join(source_dir, input_filename)
88e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      if os.path.isfile(input_path):
89e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if test_suppressor.IsSuppressed(input_filename):
90e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov          continue
91e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov        if not generate_and_test(input_filename, source_dir, working_dir,
92ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                 fixup_path, pdfium_test_path, image_differ,
93ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann                                 options.wrapper):
94e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov          failures.append(input_path)
95e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
96e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  if failures:
97ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann    failures.sort()
98e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    print '\n\nSummary of Failures:'
99e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    for failure in failures:
100e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov      print failure
101e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov    return 1
102e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  return 0
103e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov
104ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann
105e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganovif __name__ == '__main__':
106e6986e1e8d4a57987f47c215490cb080a65ee29aSvet Ganov  sys.exit(main())
107