1#!/usr/bin/env python 2 3from __future__ import print_function 4 5import ctypes 6import random 7import gmpapi 8import wrappers 9import glob 10import sys 11import os 12from optparse import OptionParser 13from gmpapi import void 14from gmpapi import ilong 15from gmpapi import ulong 16from gmpapi import mpz_t 17from gmpapi import voidp 18from gmpapi import size_t 19from gmpapi import size_tp 20from gmpapi import iint 21from gmpapi import charp 22from gmpapi import mpq_t 23 24 25def print_failure(line, test): 26 print("FAIL: {}@{}".format(line, test)) 27 28 29def run_tests(test_file, options): 30 passes = 0 31 failures = 0 32 fail_lines = [] 33 for (line, test) in enumerate(open(test_file), start=1): 34 if test.startswith("#"): 35 continue 36 if options.skip > 0 and line < options.skip: 37 continue 38 name, args = test.split("|") 39 if options.verbose or (options.progress > 0 and line % options.progress == 0): 40 print("TEST: {}@{}".format(line, test), end="") 41 api = gmpapi.get_api(name) 42 wrapper = wrappers.get_wrapper(name) 43 input_args = args.split(",") 44 if len(api.params) != len(input_args): 45 raise RuntimeError( 46 "Mismatch in args length: {} != {}".format( 47 len(api.params), len(input_args) 48 ) 49 ) 50 51 call_args = [] 52 for i in range(len(api.params)): 53 param = api.params[i] 54 if param == mpz_t: 55 call_args.append(bytes(input_args[i]).encode("utf-8")) 56 elif param == mpq_t: 57 call_args.append(bytes(input_args[i]).encode("utf-8")) 58 elif param == ulong: 59 call_args.append(ctypes.c_ulong(int(input_args[i]))) 60 elif param == ilong: 61 call_args.append(ctypes.c_long(int(input_args[i]))) 62 elif param == voidp or param == size_tp: 63 call_args.append(ctypes.c_void_p(None)) 64 elif param == size_t: 65 call_args.append(ctypes.c_size_t(int(input_args[i]))) 66 elif param == iint: 67 call_args.append(ctypes.c_int(int(input_args[i]))) 68 # pass null for charp 69 elif param == charp: 70 if input_args[i] == "NULL": 71 call_args.append(ctypes.c_void_p(None)) 72 else: 73 call_args.append(bytes(input_args[i]).encode("utf-8")) 74 else: 75 raise RuntimeError("Unknown param type: {}".format(param)) 76 77 res = wrappers.run_test( 78 wrapper, line, name, gmp_test_so, imath_test_so, *call_args 79 ) 80 if not res: 81 failures += 1 82 print_failure(line, test) 83 fail_lines.append((line, test)) 84 else: 85 passes += 1 86 return (passes, failures, fail_lines) 87 88 89def parse_args(): 90 parser = OptionParser() 91 parser.add_option( 92 "-f", 93 "--fork", 94 help="fork() before each operation", 95 action="store_true", 96 default=False, 97 ) 98 parser.add_option( 99 "-v", 100 "--verbose", 101 help="print PASS and FAIL tests", 102 action="store_true", 103 default=False, 104 ) 105 parser.add_option( 106 "-p", 107 "--progress", 108 help="print progress every N tests ", 109 metavar="N", 110 type="int", 111 default=0, 112 ) 113 parser.add_option( 114 "-s", "--skip", help="skip to test N", metavar="N", type="int", default=0 115 ) 116 return parser.parse_args() 117 118 119if __name__ == "__main__": 120 (options, tests) = parse_args() 121 gmp_test_so = ctypes.cdll.LoadLibrary("gmp_test.so") 122 imath_test_so = ctypes.cdll.LoadLibrary("imath_test.so") 123 124 wrappers.verbose = options.verbose 125 wrappers.fork = options.fork 126 127 total_pass = 0 128 total_fail = 0 129 all_fail_lines = [] 130 for test_file in tests: 131 print("Running tests in {}".format(test_file)) 132 (passes, failures, fail_lines) = run_tests(test_file, options) 133 print( 134 " Tests: {}. Passes: {}. Failures: {}.".format( 135 passes + failures, passes, failures 136 ) 137 ) 138 total_pass += passes 139 total_fail += failures 140 all_fail_lines += fail_lines 141 142 print("=" * 70) 143 print("Total") 144 print( 145 " Tests: {}. Passes: {}. Failures: {}.".format( 146 total_pass + total_fail, total_pass, total_fail 147 ) 148 ) 149 if len(all_fail_lines) > 0: 150 print("Failing Tests:") 151 for (line, test) in all_fail_lines: 152 print(test.rstrip()) 153