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") 205808f684SSatish Balay parser.add_option("-f", "--failfast", 215808f684SSatish Balay action="store_true", dest="failfast", default=False, 225808f684SSatish Balay help="Stop on first failure") 235808f684SSatish Balay parser.add_option("--no-builddir", 245808f684SSatish Balay action="store_false", dest="builddir", default=True, 255808f684SSatish Balay help="disable testing from build directory") 265808f684SSatish Balay parser.add_option("--path", type="string", 275808f684SSatish Balay action="append", dest="path", default=[], 285808f684SSatish Balay help="prepend PATH to sys.path", metavar="PATH") 295808f684SSatish Balay parser.add_option("--refleaks", type="int", 305808f684SSatish Balay action="store", dest="repeats", default=3, 315808f684SSatish Balay help="run tests REPEAT times in a loop to catch leaks", 325808f684SSatish Balay metavar="REPEAT") 335808f684SSatish Balay parser.add_option("--arch", type="string", 345808f684SSatish Balay action="store", dest="arch", default=None, 355808f684SSatish Balay help="use PETSC_ARCH", 365808f684SSatish Balay metavar="PETSC_ARCH") 375808f684SSatish Balay parser.add_option("-s","--summary", 385808f684SSatish Balay action="store_true", dest="summary", default=0, 395808f684SSatish Balay help="print PETSc log summary") 405808f684SSatish Balay return parser 415808f684SSatish Balay 425808f684SSatish Balaydef getbuilddir(): 435808f684SSatish Balay from distutils.util import get_platform 445808f684SSatish Balay s = os.path.join("build", "lib.%s-%.3s" % (get_platform(), sys.version)) 455808f684SSatish Balay if hasattr(sys, 'gettotalrefcount'): s += '-pydebug' 465808f684SSatish Balay return s 475808f684SSatish Balay 485808f684SSatish Balaydef setup_python(options): 495808f684SSatish Balay rootdir = os.path.dirname(os.path.dirname(__file__)) 505808f684SSatish Balay builddir = os.path.join(rootdir, getbuilddir()) 515808f684SSatish Balay if options.builddir and os.path.exists(builddir): 525808f684SSatish Balay sys.path.insert(0, builddir) 535808f684SSatish Balay if options.path: 545808f684SSatish Balay path = options.path[:] 555808f684SSatish Balay path.reverse() 565808f684SSatish Balay for p in path: 575808f684SSatish Balay sys.path.insert(0, p) 585808f684SSatish Balay 595808f684SSatish Balaydef setup_unittest(options): 605808f684SSatish Balay from unittest import TestSuite 615808f684SSatish Balay try: 625808f684SSatish Balay from unittest.runner import _WritelnDecorator 635808f684SSatish Balay except ImportError: 645808f684SSatish Balay from unittest import _WritelnDecorator 655808f684SSatish Balay # 665808f684SSatish Balay writeln_orig = _WritelnDecorator.writeln 675808f684SSatish Balay def writeln(self, message=''): 685808f684SSatish Balay try: self.stream.flush() 695808f684SSatish Balay except: pass 705808f684SSatish Balay writeln_orig(self, message) 715808f684SSatish Balay try: self.stream.flush() 725808f684SSatish Balay except: pass 735808f684SSatish Balay _WritelnDecorator.writeln = writeln 745808f684SSatish Balay 755808f684SSatish Balaydef import_package(options, pkgname): 765808f684SSatish Balay args = [ 775808f684SSatish Balay sys.argv[0], 785808f684SSatish Balay '-malloc', 795808f684SSatish Balay '-malloc_debug', 805808f684SSatish Balay '-malloc_dump', 815808f684SSatish Balay ] 825808f684SSatish Balay if options.summary: 835808f684SSatish Balay args.append('-log_view') 845808f684SSatish Balay package = __import__(pkgname) 855808f684SSatish Balay package.init(args, arch=options.arch) 865808f684SSatish Balay return package 875808f684SSatish Balay 885808f684SSatish Balaydef getprocessorinfo(): 89*45ab8edeSSatish Balay try: 90*45ab8edeSSatish Balay name = os.uname()[1] 91*45ab8edeSSatish Balay except: 92*45ab8edeSSatish Balay import platform 93*45ab8edeSSatish Balay name = platform.uname()[1] 945808f684SSatish Balay from petsc4py.PETSc import COMM_WORLD 955808f684SSatish Balay rank = COMM_WORLD.getRank() 965808f684SSatish Balay return (rank, name) 975808f684SSatish Balay 985808f684SSatish Balaydef getlibraryinfo(): 995808f684SSatish Balay from petsc4py import PETSc 1005808f684SSatish Balay (major, minor, micro) = PETSc.Sys.getVersion() 1015808f684SSatish Balay r = PETSc.Sys.getVersionInfo()['release'] 1025808f684SSatish Balay if r: release = 'release' 1035808f684SSatish Balay else: release = 'development' 1045808f684SSatish Balay arch = PETSc.__arch__ 1055808f684SSatish Balay return ("PETSc %d.%d.%d %s (conf: '%s')" 1065808f684SSatish Balay % (major, minor, micro, release, arch) ) 1075808f684SSatish Balay 1085808f684SSatish Balaydef getpythoninfo(): 1095808f684SSatish Balay x, y = sys.version_info[:2] 1105808f684SSatish Balay return ("Python %d.%d (%s)" % (x, y, sys.executable)) 1115808f684SSatish Balay 1125808f684SSatish Balaydef getpackageinfo(pkg): 1135808f684SSatish Balay return ("%s %s (%s)" % (pkg.__name__, 1145808f684SSatish Balay pkg.__version__, 1155808f684SSatish Balay pkg.__path__[0])) 1165808f684SSatish Balay 1175808f684SSatish Balaydef writeln(message='', endl='\n'): 1185808f684SSatish Balay from petsc4py.PETSc import Sys 1195808f684SSatish Balay Sys.syncPrint(message, endl=endl, flush=True) 1205808f684SSatish Balay 1215808f684SSatish Balaydef print_banner(options, package): 1225808f684SSatish Balay r, n = getprocessorinfo() 1235808f684SSatish Balay fmt = "[%d@%s] %s" 1245808f684SSatish Balay if options.verbose: 1255808f684SSatish Balay writeln(fmt % (r, n, getpythoninfo())) 1265808f684SSatish Balay writeln(fmt % (r, n, getlibraryinfo())) 1275808f684SSatish Balay writeln(fmt % (r, n, getpackageinfo(package))) 1285808f684SSatish Balay 1295808f684SSatish Balaydef load_tests(options, args): 1305808f684SSatish Balay from glob import glob 1315808f684SSatish Balay import re 1325808f684SSatish Balay testsuitedir = os.path.dirname(__file__) 1335808f684SSatish Balay sys.path.insert(0, testsuitedir) 1345808f684SSatish Balay pattern = 'test_*.py' 1355808f684SSatish Balay wildcard = os.path.join(testsuitedir, pattern) 1365808f684SSatish Balay testfiles = glob(wildcard) 1375808f684SSatish Balay testfiles.sort() 1385808f684SSatish Balay testsuite = unittest.TestSuite() 1395808f684SSatish Balay testloader = unittest.TestLoader() 1405808f684SSatish Balay include = exclude = None 1415808f684SSatish Balay if options.include: 1425808f684SSatish Balay include = re.compile('|'.join(options.include)).search 1435808f684SSatish Balay if options.exclude: 1445808f684SSatish Balay exclude = re.compile('|'.join(options.exclude)).search 1455808f684SSatish Balay for testfile in testfiles: 1465808f684SSatish Balay filename = os.path.basename(testfile) 1475808f684SSatish Balay testname = os.path.splitext(filename)[0] 1485808f684SSatish Balay if ((exclude and exclude(testname)) or 1495808f684SSatish Balay (include and not include(testname))): 1505808f684SSatish Balay continue 1515808f684SSatish Balay module = __import__(testname) 1525808f684SSatish Balay for arg in args: 1535808f684SSatish Balay try: 1545808f684SSatish Balay cases = testloader.loadTestsFromNames((arg,), module) 1555808f684SSatish Balay testsuite.addTests(cases) 1565808f684SSatish Balay except AttributeError: 1575808f684SSatish Balay pass 1585808f684SSatish Balay if not args: 1595808f684SSatish Balay cases = testloader.loadTestsFromModule(module) 1605808f684SSatish Balay testsuite.addTests(cases) 1615808f684SSatish Balay return testsuite 1625808f684SSatish Balay 1635808f684SSatish Balaydef run_tests(options, testsuite, runner=None): 1645808f684SSatish Balay if runner is None: 1655808f684SSatish Balay runner = unittest.TextTestRunner(verbosity=options.verbose) 1665808f684SSatish Balay runner.failfast = options.failfast 1675808f684SSatish Balay result = runner.run(testsuite) 1685808f684SSatish Balay return result.wasSuccessful() 1695808f684SSatish Balay 1705808f684SSatish Balaydef test_refleaks(options, args): 1715808f684SSatish Balay from sys import gettotalrefcount 1725808f684SSatish Balay from gc import collect 1735808f684SSatish Balay from copy import deepcopy 1745808f684SSatish Balay testsuite = load_tests(options, args) 1755808f684SSatish Balay class EmptyIO(object): 1765808f684SSatish Balay def write(self, *args): 1775808f684SSatish Balay pass 1785808f684SSatish Balay runner = unittest.TextTestRunner(stream=EmptyIO(), verbosity=0) 1795808f684SSatish Balay rank, name = getprocessorinfo() 1805808f684SSatish Balay r1 = r2 = 0 1815808f684SSatish Balay repeats = options.repeats 1825808f684SSatish Balay while repeats: 1835808f684SSatish Balay collect() 1845808f684SSatish Balay r1 = gettotalrefcount() 1855808f684SSatish Balay run_tests(options, deepcopy(testsuite), runner) 1865808f684SSatish Balay collect() 1875808f684SSatish Balay r2 = gettotalrefcount() 1885808f684SSatish Balay leaks = r2-r1 1895808f684SSatish Balay if leaks and repeats < options.repeats: 1905808f684SSatish Balay writeln('[%d@%s] refleaks: (%d - %d) --> %d' 1915808f684SSatish Balay % (rank, name, r2, r1, leaks)) 1925808f684SSatish Balay repeats -= 1 1935808f684SSatish Balay 1945808f684SSatish Balaydef abort(code=1): 1955808f684SSatish Balay os.abort() 1965808f684SSatish Balay 1975808f684SSatish Balaydef shutdown(success): 1985808f684SSatish Balay pass 1995808f684SSatish Balay 2005808f684SSatish Balaydef main(args=None): 2015808f684SSatish Balay pkgname = 'petsc4py' 2025808f684SSatish Balay parser = getoptionparser() 2035808f684SSatish Balay (options, args) = parser.parse_args(args) 2045808f684SSatish Balay setup_python(options) 2055808f684SSatish Balay setup_unittest(options) 2065808f684SSatish Balay package = import_package(options, pkgname) 2075808f684SSatish Balay print_banner(options, package) 2085808f684SSatish Balay testsuite = load_tests(options, args) 2095808f684SSatish Balay success = run_tests(options, testsuite) 2105808f684SSatish Balay if not success and options.failfast: abort() 2115808f684SSatish Balay if success and hasattr(sys, 'gettotalrefcount'): 2125808f684SSatish Balay test_refleaks(options, args) 2135808f684SSatish Balay shutdown(success) 2145808f684SSatish Balay return not success 2155808f684SSatish Balay 2165808f684SSatish Balayif __name__ == '__main__': 2175808f684SSatish Balay import sys 2185808f684SSatish Balay sys.dont_write_bytecode = True 2195808f684SSatish Balay sys.exit(main()) 220