Imported Upstream version 1.7.6
[platform/upstream/harfbuzz.git] / test / subset / run-tests.py
1 #!/usr/bin/env python
2
3 # Runs a subsetting test suite. Compares the results of subsetting via harfbuz
4 # to subsetting via fonttools.
5
6 from __future__ import print_function
7
8 import io
9 from difflib import unified_diff
10 import os
11 import re
12 import subprocess
13 import sys
14 import tempfile
15
16 from subset_test_suite import SubsetTestSuite
17
18
19 def cmd(command):
20         p = subprocess.Popen (
21                 command, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
22         p.wait ()
23         print (p.stderr.read (), end="") # file=sys.stderr
24         return p.stdout.read (), p.returncode
25
26 def read_binary(file_path):
27         with open(file_path, 'rb') as f:
28                 return f.read()
29
30 def fail_test(test, cli_args, message):
31         print ('ERROR: %s' % message)
32         print ('Test State:')
33         print ('  test.font_path    %s' % os.path.abspath(test.font_path))
34         print ('  test.profile_path %s' % os.path.abspath(test.profile_path))
35         print ('  test.unicodes     %s' % test.unicodes())
36         expected_file = os.path.join(test_suite.get_output_directory(),
37                                      test.get_font_name())
38         print ('  expected_file     %s' % os.path.abspath(expected_file))
39         return 1
40
41 def run_test(test, should_check_ots):
42         out_file = os.path.join(tempfile.mkdtemp(), test.get_font_name() + '-subset.ttf')
43         cli_args = [hb_subset,
44                     "--font-file=" + test.font_path,
45                     "--output-file=" + out_file,
46                     "--unicodes=%s" % test.unicodes()]
47         cli_args.extend (test.get_profile_flags())
48         print (' '.join(cli_args))
49         _, return_code = cmd(cli_args)
50
51         if return_code:
52                 return fail_test(test, cli_args, "%s returned %d" % (' '.join(cli_args), return_code))
53
54         expected_ttx, return_code = run_ttx(os.path.join(test_suite.get_output_directory(),
55                                             test.get_font_name()))
56         if return_code:
57                 return fail_test(test, cli_args, "ttx (expected) returned %d" % (return_code))
58
59         actual_ttx, return_code = run_ttx(out_file)
60         if return_code:
61                 return fail_test(test, cli_args, "ttx (actual) returned %d" % (return_code))
62
63         expected_ttx = strip_check_sum (expected_ttx)
64         actual_ttx = strip_check_sum (actual_ttx)
65
66         if not actual_ttx == expected_ttx:
67                 for line in unified_diff(expected_ttx.splitlines(1), actual_ttx.splitlines(1)):
68                         sys.stdout.write(line)
69                 sys.stdout.flush()
70                 return fail_test(test, cli_args, 'ttx for expected and actual does not match.')
71
72         if should_check_ots:
73                 print ("Checking output with ots-sanitize.")
74                 if not check_ots(out_file):
75                         return fail_test(test, cli_args, 'ots for subsetted file fails.')
76
77         return 0
78
79 def run_ttx(file):
80         cli_args = ["ttx",
81                     "-o-",
82                     file]
83         return cmd(cli_args)
84
85 def strip_check_sum (ttx_string):
86         return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
87                        'checkSumAdjustment value="0x00000000"',
88                        ttx_string, count=1)
89
90 def has_ots():
91         _, returncode = cmd(["which", "ots-sanitize"])
92         if returncode:
93                 print("OTS is not present, skipping all ots checks.")
94                 return False
95         return True
96
97 def check_ots (path):
98         ots_report, returncode = cmd(["ots-sanitize", path])
99         if returncode:
100                 print("OTS Failure: %s" % ots_report);
101                 return False
102         return True
103
104 args = sys.argv[1:]
105 if not args or sys.argv[1].find('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
106         print ("First argument does not seem to point to usable hb-subset.")
107         sys.exit (1)
108 hb_subset, args = args[0], args[1:]
109
110 if not len(args):
111         print ("No tests supplied.")
112         sys.exit (1)
113
114 _, returncode = cmd(["which", "ttx"])
115 if returncode:
116         print("TTX is not present, skipping test.")
117         sys.exit (77)
118
119 has_ots = has_ots()
120
121 fails = 0
122 for path in args:
123         with io.open(path, mode="r", encoding="utf-8") as f:
124                 print ("Running tests in " + path)
125                 test_suite = SubsetTestSuite(path, f.read())
126                 for test in test_suite.tests():
127                         fails += run_test(test, has_ots)
128
129 if fails != 0:
130         print (str (fails) + " test(s) failed.")
131         sys.exit(1)
132 else:
133         print ("All tests passed.")