run-repack-tests.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #!/usr/bin/env python3
  2. # Runs a subsetting test suite. Compares the results of subsetting via harfbuzz
  3. # to subsetting via fonttools.
  4. from difflib import unified_diff
  5. import os
  6. import re
  7. import subprocess
  8. import sys
  9. import tempfile
  10. import shutil
  11. import io
  12. from repack_test import RepackTest
  13. try:
  14. from fontTools.ttLib import TTFont
  15. except ImportError:
  16. print ("fonttools is not present, skipping test.")
  17. sys.exit (77)
  18. ots_sanitize = shutil.which ("ots-sanitize")
  19. def subset_cmd (command):
  20. global hb_subset, process
  21. print (hb_subset + ' ' + " ".join(command))
  22. process.stdin.write ((';'.join (command) + '\n').encode ("utf-8"))
  23. process.stdin.flush ()
  24. return process.stdout.readline().decode ("utf-8").strip ()
  25. def cmd (command):
  26. p = subprocess.Popen (
  27. command, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
  28. universal_newlines=True)
  29. (stdoutdata, stderrdata) = p.communicate ()
  30. print (stderrdata, end="", file=sys.stderr)
  31. return stdoutdata, p.returncode
  32. def fail_test (test, cli_args, message):
  33. print ('ERROR: %s' % message)
  34. print ('Test State:')
  35. print (' test.font_name %s' % test.font_name)
  36. print (' test.test_path %s' % os.path.abspath (test.test_path))
  37. return 1
  38. def run_test (test, should_check_ots):
  39. out_file = os.path.join (tempfile.mkdtemp (), test.font_name + '-subset.ttf')
  40. cli_args = ["--font-file=" + test.font_path (),
  41. "--output-file=" + out_file,
  42. "--unicodes=%s" % test.codepoints_string (),
  43. "--drop-tables-=GPOS,GSUB,GDEF",]
  44. print (' '.join (cli_args))
  45. ret = subset_cmd (cli_args)
  46. if ret != "success":
  47. return fail_test (test, cli_args, "%s failed" % ' '.join (cli_args))
  48. try:
  49. with TTFont (out_file) as font:
  50. pass
  51. except Exception as e:
  52. print (e)
  53. return fail_test (test, cli_args, "ttx failed to parse the result")
  54. if should_check_ots:
  55. print ("Checking output with ots-sanitize.")
  56. if not check_ots (out_file):
  57. return fail_test (test, cli_args, 'ots for subsetted file fails.')
  58. return 0
  59. def has_ots ():
  60. if not ots_sanitize:
  61. print ("OTS is not present, skipping all ots checks.")
  62. return False
  63. return True
  64. def check_ots (path):
  65. ots_report, returncode = cmd ([ots_sanitize, path])
  66. if returncode:
  67. print ("OTS Failure: %s" % ots_report)
  68. return False
  69. return True
  70. args = sys.argv[1:]
  71. if not args or sys.argv[1].find ('hb-subset') == -1 or not os.path.exists (sys.argv[1]):
  72. sys.exit ("First argument does not seem to point to usable hb-subset.")
  73. hb_subset, args = args[0], args[1:]
  74. if len (args) != 1:
  75. sys.exit ("No tests supplied.")
  76. has_ots = has_ots()
  77. process = subprocess.Popen ([hb_subset, '--batch'],
  78. stdin=subprocess.PIPE,
  79. stdout=subprocess.PIPE,
  80. stderr=sys.stdout)
  81. fails = 0
  82. path = args[0]
  83. if not path.endswith(".tests"):
  84. sys.exit ("Not a valid test case path.")
  85. with open (path, mode="r", encoding="utf-8") as f:
  86. # TODO(garretrieger): re-enable OTS checking.
  87. fails += run_test (RepackTest (path, f.read ()), False)
  88. if fails != 0:
  89. sys.exit ("%d test(s) failed." % fails)
  90. else:
  91. print ("All tests passed.")