Imported Upstream version 1.8.1
[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, division, absolute_import
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         (stdoutdata, stderrdata) = p.communicate()
23         print (stderrdata, end="") # file=sys.stderr
24         return stdoutdata, 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         print ("stripping checksums.")
64         expected_ttx = strip_check_sum (expected_ttx)
65         actual_ttx = strip_check_sum (actual_ttx)
66
67         if not actual_ttx == expected_ttx:
68                 for line in unified_diff(expected_ttx.splitlines(1), actual_ttx.splitlines(1)):
69                         sys.stdout.write(line)
70                 sys.stdout.flush()
71                 return fail_test(test, cli_args, 'ttx for expected and actual does not match.')
72
73         if should_check_ots:
74                 print ("Checking output with ots-sanitize.")
75                 if not check_ots(out_file):
76                         return fail_test(test, cli_args, 'ots for subsetted file fails.')
77
78         return 0
79
80 def run_ttx(file):
81         print ("ttx %s" % file)
82         cli_args = ["ttx",
83                     "-q",
84                     "-o-",
85                     file]
86         return cmd(cli_args)
87
88 def strip_check_sum (ttx_string):
89         return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
90                        'checkSumAdjustment value="0x00000000"',
91                        ttx_string.decode (), count=1)
92
93 def has_ots ():
94         _, returncode = cmd(["which", "ots-sanitize"])
95         if returncode:
96                 print("OTS is not present, skipping all ots checks.")
97                 return False
98         return True
99
100 def check_ots (path):
101         ots_report, returncode = cmd(["ots-sanitize", path])
102         if returncode:
103                 print("OTS Failure: %s" % ots_report);
104                 return False
105         return True
106
107 args = sys.argv[1:]
108 if not args or sys.argv[1].find('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
109         print ("First argument does not seem to point to usable hb-subset.")
110         sys.exit (1)
111 hb_subset, args = args[0], args[1:]
112
113 if not len(args):
114         print ("No tests supplied.")
115         sys.exit (1)
116
117 _, returncode = cmd(["which", "ttx"])
118 if returncode:
119         print("TTX is not present, skipping test.")
120         sys.exit (77)
121
122 has_ots = has_ots()
123
124 fails = 0
125 for path in args:
126         with io.open(path, mode="r", encoding="utf-8") as f:
127                 print ("Running tests in " + path)
128                 test_suite = SubsetTestSuite(path, f.read())
129                 for test in test_suite.tests():
130                         fails += run_test(test, has_ots)
131
132 if fails != 0:
133         print (str (fails) + " test(s) failed.")
134         sys.exit(1)
135 else:
136         print ("All tests passed.")