1# Copyright 2009 Baptiste Lepilleur and The JsonCpp Authors 2# Distributed under MIT license, or public domain if desired and 3# recognized in your jurisdiction. 4# See file LICENSE for detail or copy at http://jsoncpp.sourceforge.net/LICENSE 5 6from __future__ import print_function 7from __future__ import unicode_literals 8from io import open 9from glob import glob 10import sys 11import os 12import os.path 13import subprocess 14import optparse 15 16VALGRIND_CMD = 'valgrind --tool=memcheck --leak-check=yes --undef-value-errors=yes' 17 18class TestProxy(object): 19 def __init__(self, test_exe_path, use_valgrind=False): 20 self.test_exe_path = os.path.normpath(os.path.abspath(test_exe_path)) 21 self.use_valgrind = use_valgrind 22 23 def run(self, options): 24 if self.use_valgrind: 25 cmd = VALGRIND_CMD.split() 26 else: 27 cmd = [] 28 cmd.extend([self.test_exe_path, '--test-auto'] + options) 29 try: 30 process = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 31 except: 32 print(cmd) 33 raise 34 stdout = process.communicate()[0] 35 if process.returncode: 36 return False, stdout 37 return True, stdout 38 39def runAllTests(exe_path, use_valgrind=False): 40 test_proxy = TestProxy(exe_path, use_valgrind=use_valgrind) 41 status, test_names = test_proxy.run(['--list-tests']) 42 if not status: 43 print("Failed to obtain unit tests list:\n" + test_names, file=sys.stderr) 44 return 1 45 test_names = [name.strip() for name in test_names.decode('utf-8').strip().split('\n')] 46 failures = [] 47 for name in test_names: 48 print('TESTING %s:' % name, end=' ') 49 succeed, result = test_proxy.run(['--test', name]) 50 if succeed: 51 print('OK') 52 else: 53 failures.append((name, result)) 54 print('FAILED') 55 failed_count = len(failures) 56 pass_count = len(test_names) - failed_count 57 if failed_count: 58 print() 59 for name, result in failures: 60 print(result) 61 print('%d/%d tests passed (%d failure(s))' % ( pass_count, len(test_names), failed_count)) 62 return 1 63 else: 64 print('All %d tests passed' % len(test_names)) 65 return 0 66 67def main(): 68 from optparse import OptionParser 69 parser = OptionParser(usage="%prog [options] <path to test_lib_json.exe>") 70 parser.add_option("--valgrind", 71 action="store_true", dest="valgrind", default=False, 72 help="run all the tests using valgrind to detect memory leaks") 73 parser.enable_interspersed_args() 74 options, args = parser.parse_args() 75 76 if len(args) != 1: 77 parser.error('Must provides at least path to test_lib_json executable.') 78 sys.exit(1) 79 80 exit_code = runAllTests(args[0], use_valgrind=options.valgrind) 81 sys.exit(exit_code) 82 83if __name__ == '__main__': 84 main() 85