1fb83dddaSLisandro Dalcin# Author: Lisandro Dalcin 2fb83dddaSLisandro Dalcin# Contact: dalcinl@gmail.com 3fb83dddaSLisandro Dalcinimport os 4fb83dddaSLisandro Dalcinimport sys 55808f684SSatish Balayimport optparse 65808f684SSatish Balayimport unittest 75808f684SSatish Balay 8fb83dddaSLisandro Dalcin__unittest = True 9fb83dddaSLisandro Dalcin 10f46a955bSLisandro Dalcincomponents = [ 11f46a955bSLisandro Dalcin 'PETSc', 12f46a955bSLisandro Dalcin] 13f46a955bSLisandro Dalcin 14fb83dddaSLisandro Dalcin 155808f684SSatish Balaydef getoptionparser(): 165808f684SSatish Balay parser = optparse.OptionParser() 175808f684SSatish Balay 186f336411SStefano Zampini parser.add_option( 196f336411SStefano Zampini '-q', 206f336411SStefano Zampini '--quiet', 216f336411SStefano Zampini action='store_const', 226f336411SStefano Zampini const=0, 236f336411SStefano Zampini dest='verbose', 246f336411SStefano Zampini default=1, 256f336411SStefano Zampini help='do not print status messages to stdout', 266f336411SStefano Zampini ) 276f336411SStefano Zampini parser.add_option( 286f336411SStefano Zampini '-v', 296f336411SStefano Zampini '--verbose', 306f336411SStefano Zampini action='store_const', 316f336411SStefano Zampini const=2, 326f336411SStefano Zampini dest='verbose', 336f336411SStefano Zampini default=1, 346f336411SStefano Zampini help='print status messages to stdout', 356f336411SStefano Zampini ) 366f336411SStefano Zampini parser.add_option( 376f336411SStefano Zampini '-i', 386f336411SStefano Zampini '--include', 396f336411SStefano Zampini type='string', 406f336411SStefano Zampini action='append', 416f336411SStefano Zampini dest='include', 426f336411SStefano Zampini default=[], 436f336411SStefano Zampini help='include tests matching PATTERN', 446f336411SStefano Zampini metavar='PATTERN', 456f336411SStefano Zampini ) 466f336411SStefano Zampini parser.add_option( 476f336411SStefano Zampini '-e', 486f336411SStefano Zampini '--exclude', 496f336411SStefano Zampini type='string', 506f336411SStefano Zampini action='append', 516f336411SStefano Zampini dest='exclude', 526f336411SStefano Zampini default=[], 536f336411SStefano Zampini help='exclude tests matching PATTERN', 546f336411SStefano Zampini metavar='PATTERN', 556f336411SStefano Zampini ) 566f336411SStefano Zampini parser.add_option( 576f336411SStefano Zampini '-k', 586f336411SStefano Zampini '--pattern', 596f336411SStefano Zampini type='string', 606f336411SStefano Zampini action='append', 616f336411SStefano Zampini dest='patterns', 626f336411SStefano Zampini default=[], 636f336411SStefano Zampini help='only run tests which match the given substring', 646f336411SStefano Zampini ) 656f336411SStefano Zampini parser.add_option( 666f336411SStefano Zampini '-f', 676f336411SStefano Zampini '--failfast', 686f336411SStefano Zampini action='store_true', 696f336411SStefano Zampini dest='failfast', 706f336411SStefano Zampini default=False, 716f336411SStefano Zampini help='Stop on first failure', 726f336411SStefano Zampini ) 736f336411SStefano Zampini parser.add_option( 746f336411SStefano Zampini '--no-builddir', 756f336411SStefano Zampini action='store_false', 766f336411SStefano Zampini dest='builddir', 776f336411SStefano Zampini default=True, 786f336411SStefano Zampini help='disable testing from build directory', 796f336411SStefano Zampini ) 806f336411SStefano Zampini parser.add_option( 816f336411SStefano Zampini '--path', 826f336411SStefano Zampini type='string', 836f336411SStefano Zampini action='append', 846f336411SStefano Zampini dest='path', 856f336411SStefano Zampini default=[], 866f336411SStefano Zampini help='prepend PATH to sys.path', 876f336411SStefano Zampini metavar='PATH', 886f336411SStefano Zampini ) 896f336411SStefano Zampini parser.add_option( 906f336411SStefano Zampini '--arch', 916f336411SStefano Zampini type='string', 926f336411SStefano Zampini action='store', 936f336411SStefano Zampini dest='arch', 946f336411SStefano Zampini default=None, 956f336411SStefano Zampini help='use PETSC_ARCH', 966f336411SStefano Zampini metavar='PETSC_ARCH', 976f336411SStefano Zampini ) 986f336411SStefano Zampini parser.add_option( 996f336411SStefano Zampini '-s', 1006f336411SStefano Zampini '--summary', 1016f336411SStefano Zampini action='store_true', 1026f336411SStefano Zampini dest='summary', 1036f336411SStefano Zampini default=0, 1046f336411SStefano Zampini help='print PETSc log summary', 1056f336411SStefano Zampini ) 1066f336411SStefano Zampini parser.add_option( 1076f336411SStefano Zampini '--no-memdebug', 1086f336411SStefano Zampini action='store_false', 1096f336411SStefano Zampini dest='memdebug', 1106f336411SStefano Zampini default=True, 1116f336411SStefano Zampini help='Do not use PETSc memory debugging', 1126f336411SStefano Zampini ) 1135808f684SSatish Balay return parser 1145808f684SSatish Balay 115fb83dddaSLisandro Dalcin 1165808f684SSatish Balaydef getbuilddir(): 117fb83dddaSLisandro Dalcin try: 118fb83dddaSLisandro Dalcin try: 119fb83dddaSLisandro Dalcin from setuptools.dist import Distribution 120fb83dddaSLisandro Dalcin except ImportError: 121fb83dddaSLisandro Dalcin from distutils.dist import Distribution 122fb83dddaSLisandro Dalcin try: 123fb83dddaSLisandro Dalcin from setuptools.command.build import build 124fb83dddaSLisandro Dalcin except ImportError: 125fb83dddaSLisandro Dalcin from distutils.command.build import build 126fb83dddaSLisandro Dalcin cmd_obj = build(Distribution()) 127fb83dddaSLisandro Dalcin cmd_obj.finalize_options() 128fb83dddaSLisandro Dalcin return cmd_obj.build_platlib 129fb83dddaSLisandro Dalcin except Exception: 130fb83dddaSLisandro Dalcin return None 131fb83dddaSLisandro Dalcin 132fb83dddaSLisandro Dalcin 133fb83dddaSLisandro Dalcindef getprocessorinfo(): 134fb83dddaSLisandro Dalcin try: 135fb83dddaSLisandro Dalcin name = os.uname()[1] 1366f336411SStefano Zampini except Exception: 137fb83dddaSLisandro Dalcin import platform 1386f336411SStefano Zampini 139fb83dddaSLisandro Dalcin name = platform.uname()[1] 140fb83dddaSLisandro Dalcin from petsc4py.PETSc import COMM_WORLD 1416f336411SStefano Zampini 142fb83dddaSLisandro Dalcin rank = COMM_WORLD.getRank() 143fb83dddaSLisandro Dalcin return (rank, name) 144fb83dddaSLisandro Dalcin 145fb83dddaSLisandro Dalcin 146f46a955bSLisandro Dalcindef getlibraryinfo(name): 1476f336411SStefano Zampini modname = f'{name.lower()}4py.{name}' 148f46a955bSLisandro Dalcin module = __import__(modname, fromlist=[name]) 149f46a955bSLisandro Dalcin (major, minor, micro), devel = module.Sys.getVersion(devel=True) 150f46a955bSLisandro Dalcin r = not devel 1516f336411SStefano Zampini if r: 1526f336411SStefano Zampini release = 'release' 1536f336411SStefano Zampini else: 1546f336411SStefano Zampini release = 'development' 155f46a955bSLisandro Dalcin arch = module.__arch__ 1566f336411SStefano Zampini return "%s %d.%d.%d %s (conf: '%s')" % (name, major, minor, micro, release, arch) 157fb83dddaSLisandro Dalcin 158fb83dddaSLisandro Dalcin 159fb83dddaSLisandro Dalcindef getpythoninfo(): 160fb83dddaSLisandro Dalcin x, y, z = sys.version_info[:3] 1616f336411SStefano Zampini return 'Python %d.%d.%d (%s)' % (x, y, z, sys.executable) 162fb83dddaSLisandro Dalcin 163fb83dddaSLisandro Dalcin 164fb83dddaSLisandro Dalcindef getpackageinfo(pkg): 165fb83dddaSLisandro Dalcin try: 166fb83dddaSLisandro Dalcin pkg = __import__(pkg) 167fb83dddaSLisandro Dalcin except ImportError: 168fb83dddaSLisandro Dalcin return None 169fb83dddaSLisandro Dalcin name = pkg.__name__ 170fb83dddaSLisandro Dalcin version = pkg.__version__ 171fb83dddaSLisandro Dalcin path = pkg.__path__[0] 1726f336411SStefano Zampini return f'{name} {version} ({path})' 173fb83dddaSLisandro Dalcin 1745808f684SSatish Balay 1755808f684SSatish Balaydef setup_python(options): 1765808f684SSatish Balay rootdir = os.path.dirname(os.path.dirname(__file__)) 177*051d6827SStefano Zampini builddir = getbuilddir() 178*051d6827SStefano Zampini if builddir is not None: 179*051d6827SStefano Zampini builddir = os.path.join(rootdir, builddir) 180*051d6827SStefano Zampini if options.builddir and builddir is not None and os.path.exists(builddir): 1815808f684SSatish Balay sys.path.insert(0, builddir) 1825808f684SSatish Balay if options.path: 1835808f684SSatish Balay path = options.path[:] 1845808f684SSatish Balay path.reverse() 1855808f684SSatish Balay for p in path: 1865808f684SSatish Balay sys.path.insert(0, p) 1875808f684SSatish Balay 188fb83dddaSLisandro Dalcin 1895808f684SSatish Balaydef setup_unittest(options): 1905808f684SSatish Balay try: 1915808f684SSatish Balay from unittest.runner import _WritelnDecorator 1925808f684SSatish Balay except ImportError: 1935808f684SSatish Balay from unittest import _WritelnDecorator 1945808f684SSatish Balay # 1955808f684SSatish Balay writeln_orig = _WritelnDecorator.writeln 1966f336411SStefano Zampini 1975808f684SSatish Balay def writeln(self, message=''): 1986f336411SStefano Zampini try: 1996f336411SStefano Zampini self.stream.flush() 2006f336411SStefano Zampini except Exception: 2016f336411SStefano Zampini pass 2025808f684SSatish Balay writeln_orig(self, message) 2036f336411SStefano Zampini try: 2046f336411SStefano Zampini self.stream.flush() 2056f336411SStefano Zampini except Exception: 2066f336411SStefano Zampini pass 2076f336411SStefano Zampini 2085808f684SSatish Balay _WritelnDecorator.writeln = writeln 2095808f684SSatish Balay 210fb83dddaSLisandro Dalcin 2115808f684SSatish Balaydef import_package(options, pkgname): 212b254a87dSStefano Zampini args = [sys.argv[0]] 213b254a87dSStefano Zampini if options.memdebug: 214b254a87dSStefano Zampini args.append('-malloc_debug') 215b254a87dSStefano Zampini args.append('-malloc_dump') 2165808f684SSatish Balay if options.summary: 2175808f684SSatish Balay args.append('-log_view') 2185808f684SSatish Balay package = __import__(pkgname) 2195808f684SSatish Balay package.init(args, arch=options.arch) 2205808f684SSatish Balay 2215808f684SSatish Balay 222fb83dddaSLisandro Dalcindef print_banner(options): 223fb83dddaSLisandro Dalcin r, n = getprocessorinfo() 2246f336411SStefano Zampini prefix = '[%d@%s]' % (r, n) 2255808f684SSatish Balay 2265808f684SSatish Balay def writeln(message='', endl='\n'): 227fb83dddaSLisandro Dalcin if message is None: 228fb83dddaSLisandro Dalcin return 2295808f684SSatish Balay from petsc4py.PETSc import Sys 2306f336411SStefano Zampini 2316f336411SStefano Zampini message = f'{prefix} {message}' 2325808f684SSatish Balay Sys.syncPrint(message, endl=endl, flush=True) 2335808f684SSatish Balay 2345808f684SSatish Balay if options.verbose: 235fb83dddaSLisandro Dalcin writeln(getpythoninfo()) 236fb83dddaSLisandro Dalcin writeln(getpackageinfo('numpy')) 237f46a955bSLisandro Dalcin for entry in components: 238f46a955bSLisandro Dalcin writeln(getlibraryinfo(entry)) 239e405789aSLisandro Dalcin writeln(getpackageinfo('%s4py' % entry.lower())) 240fb83dddaSLisandro Dalcin 2415808f684SSatish Balay 2425808f684SSatish Balaydef load_tests(options, args): 2435808f684SSatish Balay from glob import glob 2445808f684SSatish Balay import re 2456f336411SStefano Zampini 2465808f684SSatish Balay testsuitedir = os.path.dirname(__file__) 2475808f684SSatish Balay sys.path.insert(0, testsuitedir) 2485808f684SSatish Balay pattern = 'test_*.py' 2495808f684SSatish Balay wildcard = os.path.join(testsuitedir, pattern) 2505808f684SSatish Balay testfiles = glob(wildcard) 2515808f684SSatish Balay testfiles.sort() 2525808f684SSatish Balay testsuite = unittest.TestSuite() 2535808f684SSatish Balay testloader = unittest.TestLoader() 2541e51fb16SStefano Zampini if options.patterns: 255f5636c68SSatish Balay testloader.testNamePatterns = [ # novermin 2566f336411SStefano Zampini ('*%s*' % p) if ('*' not in p) else p for p in options.patterns 257f46a955bSLisandro Dalcin ] 2585808f684SSatish Balay include = exclude = None 2595808f684SSatish Balay if options.include: 2605808f684SSatish Balay include = re.compile('|'.join(options.include)).search 2615808f684SSatish Balay if options.exclude: 2625808f684SSatish Balay exclude = re.compile('|'.join(options.exclude)).search 2635808f684SSatish Balay for testfile in testfiles: 2645808f684SSatish Balay filename = os.path.basename(testfile) 2655808f684SSatish Balay testname = os.path.splitext(filename)[0] 2666f336411SStefano Zampini if (exclude and exclude(testname)) or (include and not include(testname)): 2675808f684SSatish Balay continue 2685808f684SSatish Balay module = __import__(testname) 2695808f684SSatish Balay for arg in args: 2705808f684SSatish Balay try: 2715808f684SSatish Balay cases = testloader.loadTestsFromNames((arg,), module) 2725808f684SSatish Balay testsuite.addTests(cases) 2735808f684SSatish Balay except AttributeError: 2745808f684SSatish Balay pass 2755808f684SSatish Balay if not args: 2765808f684SSatish Balay cases = testloader.loadTestsFromModule(module) 2775808f684SSatish Balay testsuite.addTests(cases) 2785808f684SSatish Balay return testsuite 2795808f684SSatish Balay 280fb83dddaSLisandro Dalcin 2815808f684SSatish Balaydef run_tests(options, testsuite, runner=None): 2825808f684SSatish Balay if runner is None: 2835808f684SSatish Balay runner = unittest.TextTestRunner(verbosity=options.verbose) 2845808f684SSatish Balay runner.failfast = options.failfast 2855808f684SSatish Balay result = runner.run(testsuite) 2865808f684SSatish Balay return result.wasSuccessful() 2875808f684SSatish Balay 288fb83dddaSLisandro Dalcin 2895808f684SSatish Balaydef abort(code=1): 2905808f684SSatish Balay os.abort() 2915808f684SSatish Balay 292fb83dddaSLisandro Dalcin 2935808f684SSatish Balaydef shutdown(success): 2945808f684SSatish Balay pass 2955808f684SSatish Balay 296fb83dddaSLisandro Dalcin 2975808f684SSatish Balaydef main(args=None): 298f46a955bSLisandro Dalcin pkgname = '%s4py' % components[-1].lower() 2995808f684SSatish Balay parser = getoptionparser() 3005808f684SSatish Balay (options, args) = parser.parse_args(args) 3015808f684SSatish Balay setup_python(options) 3025808f684SSatish Balay setup_unittest(options) 303fb83dddaSLisandro Dalcin import_package(options, pkgname) 304fb83dddaSLisandro Dalcin print_banner(options) 3055808f684SSatish Balay testsuite = load_tests(options, args) 3065808f684SSatish Balay success = run_tests(options, testsuite) 3076f336411SStefano Zampini if not success and options.failfast: 3086f336411SStefano Zampini abort() 3095808f684SSatish Balay shutdown(success) 3105808f684SSatish Balay return not success 3115808f684SSatish Balay 312fb83dddaSLisandro Dalcin 3135808f684SSatish Balayif __name__ == '__main__': 3145808f684SSatish Balay import sys 3156f336411SStefano Zampini 3165808f684SSatish Balay sys.dont_write_bytecode = True 3175808f684SSatish Balay sys.exit(main()) 318