15808f684SSatish Balayimport sys, os 25808f684SSatish Balayimport optparse 35808f684SSatish Balayimport unittest 45808f684SSatish Balay 55808f684SSatish Balaydef getoptionparser(): 65808f684SSatish Balay parser = optparse.OptionParser() 75808f684SSatish Balay 85808f684SSatish Balay parser.add_option("-q", "--quiet", 95808f684SSatish Balay action="store_const", const=0, dest="verbose", default=1, 105808f684SSatish Balay help="do not print status messages to stdout") 115808f684SSatish Balay parser.add_option("-v", "--verbose", 125808f684SSatish Balay action="store_const", const=2, dest="verbose", default=1, 135808f684SSatish Balay help="print status messages to stdout") 145808f684SSatish Balay parser.add_option("-i", "--include", type="string", 155808f684SSatish Balay action="append", dest="include", default=[], 165808f684SSatish Balay help="include tests matching PATTERN", metavar="PATTERN") 175808f684SSatish Balay parser.add_option("-e", "--exclude", type="string", 185808f684SSatish Balay action="append", dest="exclude", default=[], 195808f684SSatish Balay help="exclude tests matching PATTERN", metavar="PATTERN") 201e51fb16SStefano Zampini parser.add_option("-k", "--pattern", type="string", 211e51fb16SStefano Zampini action="append", dest="patterns", default=[], 221e51fb16SStefano Zampini help="only run tests which match the given substring") 235808f684SSatish Balay parser.add_option("-f", "--failfast", 245808f684SSatish Balay action="store_true", dest="failfast", default=False, 255808f684SSatish Balay help="Stop on first failure") 265808f684SSatish Balay parser.add_option("--no-builddir", 275808f684SSatish Balay action="store_false", dest="builddir", default=True, 285808f684SSatish Balay help="disable testing from build directory") 295808f684SSatish Balay parser.add_option("--path", type="string", 305808f684SSatish Balay action="append", dest="path", default=[], 315808f684SSatish Balay help="prepend PATH to sys.path", metavar="PATH") 325808f684SSatish Balay parser.add_option("--refleaks", type="int", 335808f684SSatish Balay action="store", dest="repeats", default=3, 345808f684SSatish Balay help="run tests REPEAT times in a loop to catch leaks", 355808f684SSatish Balay metavar="REPEAT") 365808f684SSatish Balay parser.add_option("--arch", type="string", 375808f684SSatish Balay action="store", dest="arch", default=None, 385808f684SSatish Balay help="use PETSC_ARCH", 395808f684SSatish Balay metavar="PETSC_ARCH") 405808f684SSatish Balay parser.add_option("-s","--summary", 415808f684SSatish Balay action="store_true", dest="summary", default=0, 425808f684SSatish Balay help="print PETSc log summary") 43*b254a87dSStefano Zampini parser.add_option("--no-memdebug", 44*b254a87dSStefano Zampini action="store_false", dest="memdebug", default=True, 45*b254a87dSStefano Zampini help="Do not use PETSc memory debugging") 465808f684SSatish Balay return parser 475808f684SSatish Balay 485808f684SSatish Balaydef getbuilddir(): 495808f684SSatish Balay from distutils.util import get_platform 505808f684SSatish Balay s = os.path.join("build", "lib.%s-%.3s" % (get_platform(), sys.version)) 515808f684SSatish Balay if hasattr(sys, 'gettotalrefcount'): s += '-pydebug' 525808f684SSatish Balay return s 535808f684SSatish Balay 545808f684SSatish Balaydef setup_python(options): 555808f684SSatish Balay rootdir = os.path.dirname(os.path.dirname(__file__)) 565808f684SSatish Balay builddir = os.path.join(rootdir, getbuilddir()) 575808f684SSatish Balay if options.builddir and os.path.exists(builddir): 585808f684SSatish Balay sys.path.insert(0, builddir) 595808f684SSatish Balay if options.path: 605808f684SSatish Balay path = options.path[:] 615808f684SSatish Balay path.reverse() 625808f684SSatish Balay for p in path: 635808f684SSatish Balay sys.path.insert(0, p) 645808f684SSatish Balay 655808f684SSatish Balaydef setup_unittest(options): 665808f684SSatish Balay from unittest import TestSuite 675808f684SSatish Balay try: 685808f684SSatish Balay from unittest.runner import _WritelnDecorator 695808f684SSatish Balay except ImportError: 705808f684SSatish Balay from unittest import _WritelnDecorator 715808f684SSatish Balay # 725808f684SSatish Balay writeln_orig = _WritelnDecorator.writeln 735808f684SSatish Balay def writeln(self, message=''): 745808f684SSatish Balay try: self.stream.flush() 755808f684SSatish Balay except: pass 765808f684SSatish Balay writeln_orig(self, message) 775808f684SSatish Balay try: self.stream.flush() 785808f684SSatish Balay except: pass 795808f684SSatish Balay _WritelnDecorator.writeln = writeln 805808f684SSatish Balay 815808f684SSatish Balaydef import_package(options, pkgname): 82*b254a87dSStefano Zampini args = [ sys.argv[0] ] 83*b254a87dSStefano Zampini if options.memdebug: 84*b254a87dSStefano Zampini args.append('-malloc') 85*b254a87dSStefano Zampini args.append('-malloc_debug') 86*b254a87dSStefano Zampini args.append('-malloc_dump') 875808f684SSatish Balay if options.summary: 885808f684SSatish Balay args.append('-log_view') 895808f684SSatish Balay package = __import__(pkgname) 905808f684SSatish Balay package.init(args, arch=options.arch) 915808f684SSatish Balay return package 925808f684SSatish Balay 935808f684SSatish Balaydef getprocessorinfo(): 9445ab8edeSSatish Balay try: 9545ab8edeSSatish Balay name = os.uname()[1] 9645ab8edeSSatish Balay except: 9745ab8edeSSatish Balay import platform 9845ab8edeSSatish Balay name = platform.uname()[1] 995808f684SSatish Balay from petsc4py.PETSc import COMM_WORLD 1005808f684SSatish Balay rank = COMM_WORLD.getRank() 1015808f684SSatish Balay return (rank, name) 1025808f684SSatish Balay 1035808f684SSatish Balaydef getlibraryinfo(): 1045808f684SSatish Balay from petsc4py import PETSc 1055808f684SSatish Balay (major, minor, micro) = PETSc.Sys.getVersion() 1065808f684SSatish Balay r = PETSc.Sys.getVersionInfo()['release'] 1075808f684SSatish Balay if r: release = 'release' 1085808f684SSatish Balay else: release = 'development' 1095808f684SSatish Balay arch = PETSc.__arch__ 1105808f684SSatish Balay return ("PETSc %d.%d.%d %s (conf: '%s')" 1115808f684SSatish Balay % (major, minor, micro, release, arch) ) 1125808f684SSatish Balay 1135808f684SSatish Balaydef getpythoninfo(): 1145808f684SSatish Balay x, y = sys.version_info[:2] 1155808f684SSatish Balay return ("Python %d.%d (%s)" % (x, y, sys.executable)) 1165808f684SSatish Balay 1175808f684SSatish Balaydef getpackageinfo(pkg): 1185808f684SSatish Balay return ("%s %s (%s)" % (pkg.__name__, 1195808f684SSatish Balay pkg.__version__, 1205808f684SSatish Balay pkg.__path__[0])) 1215808f684SSatish Balay 1225808f684SSatish Balaydef writeln(message='', endl='\n'): 1235808f684SSatish Balay from petsc4py.PETSc import Sys 1245808f684SSatish Balay Sys.syncPrint(message, endl=endl, flush=True) 1255808f684SSatish Balay 1265808f684SSatish Balaydef print_banner(options, package): 1275808f684SSatish Balay r, n = getprocessorinfo() 1285808f684SSatish Balay fmt = "[%d@%s] %s" 1295808f684SSatish Balay if options.verbose: 1305808f684SSatish Balay writeln(fmt % (r, n, getpythoninfo())) 1315808f684SSatish Balay writeln(fmt % (r, n, getlibraryinfo())) 1325808f684SSatish Balay writeln(fmt % (r, n, getpackageinfo(package))) 1335808f684SSatish Balay 1345808f684SSatish Balaydef load_tests(options, args): 1355808f684SSatish Balay from glob import glob 1365808f684SSatish Balay import re 1375808f684SSatish Balay testsuitedir = os.path.dirname(__file__) 1385808f684SSatish Balay sys.path.insert(0, testsuitedir) 1395808f684SSatish Balay pattern = 'test_*.py' 1405808f684SSatish Balay wildcard = os.path.join(testsuitedir, pattern) 1415808f684SSatish Balay testfiles = glob(wildcard) 1425808f684SSatish Balay testfiles.sort() 1435808f684SSatish Balay testsuite = unittest.TestSuite() 1445808f684SSatish Balay testloader = unittest.TestLoader() 1451e51fb16SStefano Zampini if options.patterns: 1461e51fb16SStefano Zampini testloader.testNamePatterns = [ 1471e51fb16SStefano Zampini ('*%s*' % p) if ('*' not in p) else p 1481e51fb16SStefano Zampini for p in options.patterns] 1495808f684SSatish Balay include = exclude = None 1505808f684SSatish Balay if options.include: 1515808f684SSatish Balay include = re.compile('|'.join(options.include)).search 1525808f684SSatish Balay if options.exclude: 1535808f684SSatish Balay exclude = re.compile('|'.join(options.exclude)).search 1545808f684SSatish Balay for testfile in testfiles: 1555808f684SSatish Balay filename = os.path.basename(testfile) 1565808f684SSatish Balay testname = os.path.splitext(filename)[0] 1575808f684SSatish Balay if ((exclude and exclude(testname)) or 1585808f684SSatish Balay (include and not include(testname))): 1595808f684SSatish Balay continue 1605808f684SSatish Balay module = __import__(testname) 1615808f684SSatish Balay for arg in args: 1625808f684SSatish Balay try: 1635808f684SSatish Balay cases = testloader.loadTestsFromNames((arg,), module) 1645808f684SSatish Balay testsuite.addTests(cases) 1655808f684SSatish Balay except AttributeError: 1665808f684SSatish Balay pass 1675808f684SSatish Balay if not args: 1685808f684SSatish Balay cases = testloader.loadTestsFromModule(module) 1695808f684SSatish Balay testsuite.addTests(cases) 1705808f684SSatish Balay return testsuite 1715808f684SSatish Balay 1725808f684SSatish Balaydef run_tests(options, testsuite, runner=None): 1735808f684SSatish Balay if runner is None: 1745808f684SSatish Balay runner = unittest.TextTestRunner(verbosity=options.verbose) 1755808f684SSatish Balay runner.failfast = options.failfast 1765808f684SSatish Balay result = runner.run(testsuite) 1775808f684SSatish Balay return result.wasSuccessful() 1785808f684SSatish Balay 1795808f684SSatish Balaydef test_refleaks(options, args): 1805808f684SSatish Balay from sys import gettotalrefcount 1815808f684SSatish Balay from gc import collect 1825808f684SSatish Balay from copy import deepcopy 1835808f684SSatish Balay testsuite = load_tests(options, args) 1845808f684SSatish Balay class EmptyIO(object): 1855808f684SSatish Balay def write(self, *args): 1865808f684SSatish Balay pass 1875808f684SSatish Balay runner = unittest.TextTestRunner(stream=EmptyIO(), verbosity=0) 1885808f684SSatish Balay rank, name = getprocessorinfo() 1895808f684SSatish Balay r1 = r2 = 0 1905808f684SSatish Balay repeats = options.repeats 1915808f684SSatish Balay while repeats: 1925808f684SSatish Balay collect() 1935808f684SSatish Balay r1 = gettotalrefcount() 1945808f684SSatish Balay run_tests(options, deepcopy(testsuite), runner) 1955808f684SSatish Balay collect() 1965808f684SSatish Balay r2 = gettotalrefcount() 1975808f684SSatish Balay leaks = r2-r1 1985808f684SSatish Balay if leaks and repeats < options.repeats: 1995808f684SSatish Balay writeln('[%d@%s] refleaks: (%d - %d) --> %d' 2005808f684SSatish Balay % (rank, name, r2, r1, leaks)) 2015808f684SSatish Balay repeats -= 1 2025808f684SSatish Balay 2035808f684SSatish Balaydef abort(code=1): 2045808f684SSatish Balay os.abort() 2055808f684SSatish Balay 2065808f684SSatish Balaydef shutdown(success): 2075808f684SSatish Balay pass 2085808f684SSatish Balay 2095808f684SSatish Balaydef main(args=None): 2105808f684SSatish Balay pkgname = 'petsc4py' 2115808f684SSatish Balay parser = getoptionparser() 2125808f684SSatish Balay (options, args) = parser.parse_args(args) 2135808f684SSatish Balay setup_python(options) 2145808f684SSatish Balay setup_unittest(options) 2155808f684SSatish Balay package = import_package(options, pkgname) 2165808f684SSatish Balay print_banner(options, package) 2175808f684SSatish Balay testsuite = load_tests(options, args) 2185808f684SSatish Balay success = run_tests(options, testsuite) 2195808f684SSatish Balay if not success and options.failfast: abort() 2205808f684SSatish Balay if success and hasattr(sys, 'gettotalrefcount'): 2215808f684SSatish Balay test_refleaks(options, args) 2225808f684SSatish Balay shutdown(success) 2235808f684SSatish Balay return not success 2245808f684SSatish Balay 2255808f684SSatish Balayif __name__ == '__main__': 2265808f684SSatish Balay import sys 2275808f684SSatish Balay sys.dont_write_bytecode = True 2285808f684SSatish Balay sys.exit(main()) 229