1*2d1272b8SAndroid Build Coastguard Worker#!/usr/bin/env python3 2*2d1272b8SAndroid Build Coastguard Worker 3*2d1272b8SAndroid Build Coastguard Workerimport sys, os, subprocess, tempfile, shutil 4*2d1272b8SAndroid Build Coastguard Worker 5*2d1272b8SAndroid Build Coastguard Worker 6*2d1272b8SAndroid Build Coastguard Workerdef cmd (command): 7*2d1272b8SAndroid Build Coastguard Worker # https://stackoverflow.com/a/4408409 as we might have huge output sometimes 8*2d1272b8SAndroid Build Coastguard Worker with tempfile.TemporaryFile () as tempf: 9*2d1272b8SAndroid Build Coastguard Worker p = subprocess.Popen (command, stderr=tempf) 10*2d1272b8SAndroid Build Coastguard Worker 11*2d1272b8SAndroid Build Coastguard Worker try: 12*2d1272b8SAndroid Build Coastguard Worker p.wait () 13*2d1272b8SAndroid Build Coastguard Worker tempf.seek (0) 14*2d1272b8SAndroid Build Coastguard Worker text = tempf.read () 15*2d1272b8SAndroid Build Coastguard Worker 16*2d1272b8SAndroid Build Coastguard Worker #TODO: Detect debug mode with a better way 17*2d1272b8SAndroid Build Coastguard Worker is_debug_mode = b"SANITIZE" in text 18*2d1272b8SAndroid Build Coastguard Worker 19*2d1272b8SAndroid Build Coastguard Worker return ("" if is_debug_mode else text.decode ("utf-8").strip ()), p.returncode 20*2d1272b8SAndroid Build Coastguard Worker except subprocess.TimeoutExpired: 21*2d1272b8SAndroid Build Coastguard Worker return 'error: timeout, ' + ' '.join (command), 1 22*2d1272b8SAndroid Build Coastguard Worker 23*2d1272b8SAndroid Build Coastguard Worker 24*2d1272b8SAndroid Build Coastguard Workersrcdir = os.getenv ("srcdir", ".") 25*2d1272b8SAndroid Build Coastguard WorkerEXEEXT = os.getenv ("EXEEXT", "") 26*2d1272b8SAndroid Build Coastguard Workertop_builddir = os.getenv ("top_builddir", ".") 27*2d1272b8SAndroid Build Coastguard Workerhb_shape_fuzzer = os.path.join (top_builddir, "hb-shape-fuzzer" + EXEEXT) 28*2d1272b8SAndroid Build Coastguard Worker 29*2d1272b8SAndroid Build Coastguard Workerif not os.path.exists (hb_shape_fuzzer): 30*2d1272b8SAndroid Build Coastguard Worker if len (sys.argv) == 1 or not os.path.exists (sys.argv[1]): 31*2d1272b8SAndroid Build Coastguard Worker sys.exit ("""Failed to find hb-shape-fuzzer binary automatically, 32*2d1272b8SAndroid Build Coastguard Workerplease provide it as the first argument to the tool""") 33*2d1272b8SAndroid Build Coastguard Worker 34*2d1272b8SAndroid Build Coastguard Worker hb_shape_fuzzer = sys.argv[1] 35*2d1272b8SAndroid Build Coastguard Worker 36*2d1272b8SAndroid Build Coastguard Workerprint ('hb_shape_fuzzer:', hb_shape_fuzzer) 37*2d1272b8SAndroid Build Coastguard Workerfails = 0 38*2d1272b8SAndroid Build Coastguard Worker 39*2d1272b8SAndroid Build Coastguard Workervalgrind = None 40*2d1272b8SAndroid Build Coastguard Workerif os.getenv ('RUN_VALGRIND', ''): 41*2d1272b8SAndroid Build Coastguard Worker valgrind = shutil.which ('valgrind') 42*2d1272b8SAndroid Build Coastguard Worker if valgrind is None: 43*2d1272b8SAndroid Build Coastguard Worker sys.exit ("""Valgrind requested but not found.""") 44*2d1272b8SAndroid Build Coastguard Worker 45*2d1272b8SAndroid Build Coastguard Workerparent_path = os.path.join (srcdir, "fonts") 46*2d1272b8SAndroid Build Coastguard Workerfor file in os.listdir (parent_path): 47*2d1272b8SAndroid Build Coastguard Worker path = os.path.join (parent_path, file) 48*2d1272b8SAndroid Build Coastguard Worker 49*2d1272b8SAndroid Build Coastguard Worker if valgrind: 50*2d1272b8SAndroid Build Coastguard Worker text, returncode = cmd ([valgrind, '--leak-check=full', '--error-exitcode=1', hb_shape_fuzzer, path]) 51*2d1272b8SAndroid Build Coastguard Worker else: 52*2d1272b8SAndroid Build Coastguard Worker text, returncode = cmd ([hb_shape_fuzzer, path]) 53*2d1272b8SAndroid Build Coastguard Worker if 'error' in text: 54*2d1272b8SAndroid Build Coastguard Worker returncode = 1 55*2d1272b8SAndroid Build Coastguard Worker 56*2d1272b8SAndroid Build Coastguard Worker if (not valgrind or returncode) and text.strip (): 57*2d1272b8SAndroid Build Coastguard Worker print (text) 58*2d1272b8SAndroid Build Coastguard Worker 59*2d1272b8SAndroid Build Coastguard Worker if returncode != 0: 60*2d1272b8SAndroid Build Coastguard Worker print ('failure on %s' % file) 61*2d1272b8SAndroid Build Coastguard Worker fails = fails + 1 62*2d1272b8SAndroid Build Coastguard Worker 63*2d1272b8SAndroid Build Coastguard Worker 64*2d1272b8SAndroid Build Coastguard Workerif fails: 65*2d1272b8SAndroid Build Coastguard Worker sys.exit ("%d shape fuzzer related tests failed." % fails) 66