Imported Upstream version 3.4.0
[platform/upstream/harfbuzz.git] / test / fuzzing / run-subset-fuzzer-tests.py
index 0136288..da7d1e5 100755 (executable)
@@ -1,53 +1,72 @@
-#!/usr/bin/env python
+#!/usr/bin/env python3
 
-from __future__ import print_function, division, absolute_import
+import sys, os, subprocess, tempfile, shutil
 
-import sys, os, subprocess
 
-srcdir = os.environ.get ("srcdir", ".")
-EXEEXT = os.environ.get ("EXEEXT", "")
-top_builddir = os.environ.get ("top_builddir", ".")
+def cmd (command):
+       # https://stackoverflow.com/a/4408409 as we might have huge output sometimes
+       with tempfile.TemporaryFile () as tempf:
+               p = subprocess.Popen (command, stderr=tempf)
+
+               try:
+                       p.wait ()
+                       tempf.seek (0)
+                       text = tempf.read ()
+
+                       #TODO: Detect debug mode with a better way
+                       is_debug_mode = b"SANITIZE" in text
+
+                       return ("" if is_debug_mode else text.decode ("utf-8").strip ()), p.returncode
+               except subprocess.TimeoutExpired:
+                       return 'error: timeout, ' + ' '.join (command), 1
+
+
+srcdir = os.getenv ("srcdir", ".")
+EXEEXT = os.getenv ("EXEEXT", "")
+top_builddir = os.getenv ("top_builddir", ".")
 hb_subset_fuzzer = os.path.join (top_builddir, "hb-subset-fuzzer" + EXEEXT)
-hb_subset_get_codepoints_fuzzer = os.path.join (top_builddir, "hb-subset-get-codepoints-fuzzer" + EXEEXT)
 
 if not os.path.exists (hb_subset_fuzzer):
         if len (sys.argv) < 2 or not os.path.exists (sys.argv[1]):
-                print ("""Failed to find hb-subset-fuzzer binary automatically,
+                sys.exit ("""Failed to find hb-subset-fuzzer binary automatically,
 please provide it as the first argument to the tool""")
-                sys.exit (1)
 
         hb_subset_fuzzer = sys.argv[1]
 
-if not os.path.exists (hb_subset_get_codepoints_fuzzer):
-        if len (sys.argv) < 3 or not os.path.exists (sys.argv[2]):
-                print ("""Failed to find hb-subset-get-codepoints-fuzzer binary automatically,
-please provide it as the second argument to the tool""")
-                sys.exit (1)
-
-        hb_subset_get_codepoints_fuzzer = sys.argv[2]
-
 print ('hb_subset_fuzzer:', hb_subset_fuzzer)
 fails = 0
 
-parent_path = os.path.join (srcdir, "..", "subset", "data", "fonts")
-print ("running subset fuzzer against fonts in %s" % parent_path)
-for file in os.listdir (parent_path):
-        path = os.path.join(parent_path, file)
+valgrind = None
+if os.getenv ('RUN_VALGRIND', ''):
+       valgrind = shutil.which ('valgrind')
+       if valgrind is None:
+               sys.exit ("""Valgrind requested but not found.""")
+
+def run_dir (parent_path):
+       global fails
+       for file in os.listdir (parent_path):
+               path = os.path.join(parent_path, file)
+               # TODO: Run on all the fonts not just subset related ones
+               if "subset" not in path: continue
+
+               print ("running subset fuzzer against %s" % path)
+               if valgrind:
+                       text, returncode = cmd ([valgrind, '--leak-check=full', '--error-exitcode=1', hb_subset_fuzzer, path])
+               else:
+                       text, returncode = cmd ([hb_subset_fuzzer, path])
+                       if 'error' in text:
+                               returncode = 1
 
-        print ("running subset fuzzer against %s" % path)
-        p = subprocess.Popen ([hb_subset_fuzzer, path])
+               if (not valgrind or returncode) and text.strip ():
+                       print (text)
 
-        if p.wait () != 0:
-                print ("failed for %s" % path)
-                fails = fails + 1
+               if returncode != 0:
+                       print ("failed for %s" % path)
+                       fails = fails + 1
 
-        print ("running subset get codepoints fuzzer against %s" % path)
-        p = subprocess.Popen ([hb_subset_get_codepoints_fuzzer, path])
 
-        if p.wait () != 0:
-                print ("failed for %s" % path)
-                fails = fails + 1
+run_dir (os.path.join (srcdir, "..", "subset", "data", "fonts"))
+run_dir (os.path.join (srcdir, "fonts"))
 
 if fails:
-        print ("%i subset fuzzer related tests failed." % fails)
-        sys.exit (1)
+       sys.exit ("%d subset fuzzer related tests failed." % fails)