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") 20*1e51fb16SStefano Zampini parser.add_option("-k", "--pattern", type="string", 21*1e51fb16SStefano Zampini action="append", dest="patterns", default=[], 22*1e51fb16SStefano 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") 435808f684SSatish Balay return parser 445808f684SSatish Balay 455808f684SSatish Balaydef getbuilddir(): 465808f684SSatish Balay from distutils.util import get_platform 475808f684SSatish Balay s = os.path.join("build", "lib.%s-%.3s" % (get_platform(), sys.version)) 485808f684SSatish Balay if hasattr(sys, 'gettotalrefcount'): s += '-pydebug' 495808f684SSatish Balay return s 505808f684SSatish Balay 515808f684SSatish Balaydef setup_python(options): 525808f684SSatish Balay rootdir = os.path.dirname(os.path.dirname(__file__)) 535808f684SSatish Balay builddir = os.path.join(rootdir, getbuilddir()) 545808f684SSatish Balay if options.builddir and os.path.exists(builddir): 555808f684SSatish Balay sys.path.insert(0, builddir) 565808f684SSatish Balay if options.path: 575808f684SSatish Balay path = options.path[:] 585808f684SSatish Balay path.reverse() 595808f684SSatish Balay for p in path: 605808f684SSatish Balay sys.path.insert(0, p) 615808f684SSatish Balay 625808f684SSatish Balaydef setup_unittest(options): 635808f684SSatish Balay from unittest import TestSuite 645808f684SSatish Balay try: 655808f684SSatish Balay from unittest.runner import _WritelnDecorator 665808f684SSatish Balay except ImportError: 675808f684SSatish Balay from unittest import _WritelnDecorator 685808f684SSatish Balay # 695808f684SSatish Balay writeln_orig = _WritelnDecorator.writeln 705808f684SSatish Balay def writeln(self, message=''): 715808f684SSatish Balay try: self.stream.flush() 725808f684SSatish Balay except: pass 735808f684SSatish Balay writeln_orig(self, message) 745808f684SSatish Balay try: self.stream.flush() 755808f684SSatish Balay except: pass 765808f684SSatish Balay _WritelnDecorator.writeln = writeln 775808f684SSatish Balay 785808f684SSatish Balaydef import_package(options, pkgname): 795808f684SSatish Balay args = [ 805808f684SSatish Balay sys.argv[0], 815808f684SSatish Balay '-malloc', 825808f684SSatish Balay '-malloc_debug', 835808f684SSatish Balay '-malloc_dump', 845808f684SSatish Balay ] 855808f684SSatish Balay if options.summary: 865808f684SSatish Balay args.append('-log_view') 875808f684SSatish Balay package = __import__(pkgname) 885808f684SSatish Balay package.init(args, arch=options.arch) 895808f684SSatish Balay return package 905808f684SSatish Balay 915808f684SSatish Balaydef getprocessorinfo(): 9245ab8edeSSatish Balay try: 9345ab8edeSSatish Balay name = os.uname()[1] 9445ab8edeSSatish Balay except: 9545ab8edeSSatish Balay import platform 9645ab8edeSSatish Balay name = platform.uname()[1] 975808f684SSatish Balay from petsc4py.PETSc import COMM_WORLD 985808f684SSatish Balay rank = COMM_WORLD.getRank() 995808f684SSatish Balay return (rank, name) 1005808f684SSatish Balay 1015808f684SSatish Balaydef getlibraryinfo(): 1025808f684SSatish Balay from petsc4py import PETSc 1035808f684SSatish Balay (major, minor, micro) = PETSc.Sys.getVersion() 1045808f684SSatish Balay r = PETSc.Sys.getVersionInfo()['release'] 1055808f684SSatish Balay if r: release = 'release' 1065808f684SSatish Balay else: release = 'development' 1075808f684SSatish Balay arch = PETSc.__arch__ 1085808f684SSatish Balay return ("PETSc %d.%d.%d %s (conf: '%s')" 1095808f684SSatish Balay % (major, minor, micro, release, arch) ) 1105808f684SSatish Balay 1115808f684SSatish Balaydef getpythoninfo(): 1125808f684SSatish Balay x, y = sys.version_info[:2] 1135808f684SSatish Balay return ("Python %d.%d (%s)" % (x, y, sys.executable)) 1145808f684SSatish Balay 1155808f684SSatish Balaydef getpackageinfo(pkg): 1165808f684SSatish Balay return ("%s %s (%s)" % (pkg.__name__, 1175808f684SSatish Balay pkg.__version__, 1185808f684SSatish Balay pkg.__path__[0])) 1195808f684SSatish Balay 1205808f684SSatish Balaydef writeln(message='', endl='\n'): 1215808f684SSatish Balay from petsc4py.PETSc import Sys 1225808f684SSatish Balay Sys.syncPrint(message, endl=endl, flush=True) 1235808f684SSatish Balay 1245808f684SSatish Balaydef print_banner(options, package): 1255808f684SSatish Balay r, n = getprocessorinfo() 1265808f684SSatish Balay fmt = "[%d@%s] %s" 1275808f684SSatish Balay if options.verbose: 1285808f684SSatish Balay writeln(fmt % (r, n, getpythoninfo())) 1295808f684SSatish Balay writeln(fmt % (r, n, getlibraryinfo())) 1305808f684SSatish Balay writeln(fmt % (r, n, getpackageinfo(package))) 1315808f684SSatish Balay 1325808f684SSatish Balaydef load_tests(options, args): 1335808f684SSatish Balay from glob import glob 1345808f684SSatish Balay import re 1355808f684SSatish Balay testsuitedir = os.path.dirname(__file__) 1365808f684SSatish Balay sys.path.insert(0, testsuitedir) 1375808f684SSatish Balay pattern = 'test_*.py' 1385808f684SSatish Balay wildcard = os.path.join(testsuitedir, pattern) 1395808f684SSatish Balay testfiles = glob(wildcard) 1405808f684SSatish Balay testfiles.sort() 1415808f684SSatish Balay testsuite = unittest.TestSuite() 1425808f684SSatish Balay testloader = unittest.TestLoader() 143*1e51fb16SStefano Zampini if options.patterns: 144*1e51fb16SStefano Zampini testloader.testNamePatterns = [ 145*1e51fb16SStefano Zampini ('*%s*' % p) if ('*' not in p) else p 146*1e51fb16SStefano Zampini for p in options.patterns] 1475808f684SSatish Balay include = exclude = None 1485808f684SSatish Balay if options.include: 1495808f684SSatish Balay include = re.compile('|'.join(options.include)).search 1505808f684SSatish Balay if options.exclude: 1515808f684SSatish Balay exclude = re.compile('|'.join(options.exclude)).search 1525808f684SSatish Balay for testfile in testfiles: 1535808f684SSatish Balay filename = os.path.basename(testfile) 1545808f684SSatish Balay testname = os.path.splitext(filename)[0] 1555808f684SSatish Balay if ((exclude and exclude(testname)) or 1565808f684SSatish Balay (include and not include(testname))): 1575808f684SSatish Balay continue 1585808f684SSatish Balay module = __import__(testname) 1595808f684SSatish Balay for arg in args: 1605808f684SSatish Balay try: 1615808f684SSatish Balay cases = testloader.loadTestsFromNames((arg,), module) 1625808f684SSatish Balay testsuite.addTests(cases) 1635808f684SSatish Balay except AttributeError: 1645808f684SSatish Balay pass 1655808f684SSatish Balay if not args: 1665808f684SSatish Balay cases = testloader.loadTestsFromModule(module) 1675808f684SSatish Balay testsuite.addTests(cases) 1685808f684SSatish Balay return testsuite 1695808f684SSatish Balay 1705808f684SSatish Balaydef run_tests(options, testsuite, runner=None): 1715808f684SSatish Balay if runner is None: 1725808f684SSatish Balay runner = unittest.TextTestRunner(verbosity=options.verbose) 1735808f684SSatish Balay runner.failfast = options.failfast 1745808f684SSatish Balay result = runner.run(testsuite) 1755808f684SSatish Balay return result.wasSuccessful() 1765808f684SSatish Balay 1775808f684SSatish Balaydef test_refleaks(options, args): 1785808f684SSatish Balay from sys import gettotalrefcount 1795808f684SSatish Balay from gc import collect 1805808f684SSatish Balay from copy import deepcopy 1815808f684SSatish Balay testsuite = load_tests(options, args) 1825808f684SSatish Balay class EmptyIO(object): 1835808f684SSatish Balay def write(self, *args): 1845808f684SSatish Balay pass 1855808f684SSatish Balay runner = unittest.TextTestRunner(stream=EmptyIO(), verbosity=0) 1865808f684SSatish Balay rank, name = getprocessorinfo() 1875808f684SSatish Balay r1 = r2 = 0 1885808f684SSatish Balay repeats = options.repeats 1895808f684SSatish Balay while repeats: 1905808f684SSatish Balay collect() 1915808f684SSatish Balay r1 = gettotalrefcount() 1925808f684SSatish Balay run_tests(options, deepcopy(testsuite), runner) 1935808f684SSatish Balay collect() 1945808f684SSatish Balay r2 = gettotalrefcount() 1955808f684SSatish Balay leaks = r2-r1 1965808f684SSatish Balay if leaks and repeats < options.repeats: 1975808f684SSatish Balay writeln('[%d@%s] refleaks: (%d - %d) --> %d' 1985808f684SSatish Balay % (rank, name, r2, r1, leaks)) 1995808f684SSatish Balay repeats -= 1 2005808f684SSatish Balay 2015808f684SSatish Balaydef abort(code=1): 2025808f684SSatish Balay os.abort() 2035808f684SSatish Balay 2045808f684SSatish Balaydef shutdown(success): 2055808f684SSatish Balay pass 2065808f684SSatish Balay 2075808f684SSatish Balaydef main(args=None): 2085808f684SSatish Balay pkgname = 'petsc4py' 2095808f684SSatish Balay parser = getoptionparser() 2105808f684SSatish Balay (options, args) = parser.parse_args(args) 2115808f684SSatish Balay setup_python(options) 2125808f684SSatish Balay setup_unittest(options) 2135808f684SSatish Balay package = import_package(options, pkgname) 2145808f684SSatish Balay print_banner(options, package) 2155808f684SSatish Balay testsuite = load_tests(options, args) 2165808f684SSatish Balay success = run_tests(options, testsuite) 2175808f684SSatish Balay if not success and options.failfast: abort() 2185808f684SSatish Balay if success and hasattr(sys, 'gettotalrefcount'): 2195808f684SSatish Balay test_refleaks(options, args) 2205808f684SSatish Balay shutdown(success) 2215808f684SSatish Balay return not success 2225808f684SSatish Balay 2235808f684SSatish Balayif __name__ == '__main__': 2245808f684SSatish Balay import sys 2255808f684SSatish Balay sys.dont_write_bytecode = True 2265808f684SSatish Balay sys.exit(main()) 227