1# Author: Lisandro Dalcin 2# Contact: dalcinl@gmail.com 3import os 4import sys 5import optparse 6import unittest 7 8__unittest = True 9 10 11def getoptionparser(): 12 parser = optparse.OptionParser() 13 14 parser.add_option("-q", "--quiet", 15 action="store_const", const=0, dest="verbose", default=1, 16 help="do not print status messages to stdout") 17 parser.add_option("-v", "--verbose", 18 action="store_const", const=2, dest="verbose", default=1, 19 help="print status messages to stdout") 20 parser.add_option("-i", "--include", type="string", 21 action="append", dest="include", default=[], 22 help="include tests matching PATTERN", metavar="PATTERN") 23 parser.add_option("-e", "--exclude", type="string", 24 action="append", dest="exclude", default=[], 25 help="exclude tests matching PATTERN", metavar="PATTERN") 26 parser.add_option("-k", "--pattern", type="string", 27 action="append", dest="patterns", default=[], 28 help="only run tests which match the given substring") 29 parser.add_option("-f", "--failfast", 30 action="store_true", dest="failfast", default=False, 31 help="Stop on first failure") 32 parser.add_option("--no-builddir", 33 action="store_false", dest="builddir", default=True, 34 help="disable testing from build directory") 35 parser.add_option("--path", type="string", 36 action="append", dest="path", default=[], 37 help="prepend PATH to sys.path", metavar="PATH") 38 parser.add_option("--arch", type="string", 39 action="store", dest="arch", default=None, 40 help="use PETSC_ARCH", 41 metavar="PETSC_ARCH") 42 parser.add_option("-s","--summary", 43 action="store_true", dest="summary", default=0, 44 help="print PETSc log summary") 45 parser.add_option("--no-memdebug", 46 action="store_false", dest="memdebug", default=True, 47 help="Do not use PETSc memory debugging") 48 return parser 49 50 51def getbuilddir(): 52 try: 53 try: 54 from setuptools.dist import Distribution 55 except ImportError: 56 from distutils.dist import Distribution 57 try: 58 from setuptools.command.build import build 59 except ImportError: 60 from distutils.command.build import build 61 cmd_obj = build(Distribution()) 62 cmd_obj.finalize_options() 63 return cmd_obj.build_platlib 64 except Exception: 65 return None 66 67 68def getprocessorinfo(): 69 try: 70 name = os.uname()[1] 71 except: 72 import platform 73 name = platform.uname()[1] 74 from petsc4py.PETSc import COMM_WORLD 75 rank = COMM_WORLD.getRank() 76 return (rank, name) 77 78 79def getlibraryinfo(): 80 from petsc4py import PETSc 81 (major, minor, micro) = PETSc.Sys.getVersion() 82 r = PETSc.Sys.getVersionInfo()['release'] 83 if r: release = 'release' 84 else: release = 'development' 85 arch = PETSc.__arch__ 86 return ("PETSc %d.%d.%d %s (conf: '%s')" 87 % (major, minor, micro, release, arch) ) 88 89 90def getpythoninfo(): 91 x, y, z = sys.version_info[:3] 92 return ("Python %d.%d.%d (%s)" % (x, y, z, sys.executable)) 93 94 95def getpackageinfo(pkg): 96 try: 97 pkg = __import__(pkg) 98 except ImportError: 99 return None 100 name = pkg.__name__ 101 version = pkg.__version__ 102 path = pkg.__path__[0] 103 return ("%s %s (%s)" % (name, version, path)) 104 105 106def setup_python(options): 107 rootdir = os.path.dirname(os.path.dirname(__file__)) 108 builddir = os.path.join(rootdir, getbuilddir()) 109 if options.builddir and os.path.exists(builddir): 110 sys.path.insert(0, builddir) 111 if options.path: 112 path = options.path[:] 113 path.reverse() 114 for p in path: 115 sys.path.insert(0, p) 116 117 118def setup_unittest(options): 119 from unittest import TestSuite 120 try: 121 from unittest.runner import _WritelnDecorator 122 except ImportError: 123 from unittest import _WritelnDecorator 124 # 125 writeln_orig = _WritelnDecorator.writeln 126 def writeln(self, message=''): 127 try: self.stream.flush() 128 except: pass 129 writeln_orig(self, message) 130 try: self.stream.flush() 131 except: pass 132 _WritelnDecorator.writeln = writeln 133 134 135def import_package(options, pkgname): 136 args = [ sys.argv[0] ] 137 if options.memdebug: 138 args.append('-malloc') 139 args.append('-malloc_debug') 140 args.append('-malloc_dump') 141 if options.summary: 142 args.append('-log_view') 143 package = __import__(pkgname) 144 package.init(args, arch=options.arch) 145 146 147def print_banner(options): 148 r, n = getprocessorinfo() 149 prefix = "[%d@%s]" % (r, n) 150 151 def writeln(message='', endl='\n'): 152 if message is None: 153 return 154 from petsc4py.PETSc import Sys 155 message = "%s %s" % (prefix, message) 156 Sys.syncPrint(message, endl=endl, flush=True) 157 158 if options.verbose: 159 writeln(getpythoninfo()) 160 writeln(getpackageinfo('numpy')) 161 writeln(getlibraryinfo()) 162 writeln(getpackageinfo('petsc4py')) 163 164 165def load_tests(options, args): 166 from glob import glob 167 import re 168 testsuitedir = os.path.dirname(__file__) 169 sys.path.insert(0, testsuitedir) 170 pattern = 'test_*.py' 171 wildcard = os.path.join(testsuitedir, pattern) 172 testfiles = glob(wildcard) 173 testfiles.sort() 174 testsuite = unittest.TestSuite() 175 testloader = unittest.TestLoader() 176 if options.patterns: 177 testloader.testNamePatterns = [ 178 ('*%s*' % p) if ('*' not in p) else p 179 for p in options.patterns] 180 include = exclude = None 181 if options.include: 182 include = re.compile('|'.join(options.include)).search 183 if options.exclude: 184 exclude = re.compile('|'.join(options.exclude)).search 185 for testfile in testfiles: 186 filename = os.path.basename(testfile) 187 testname = os.path.splitext(filename)[0] 188 if ((exclude and exclude(testname)) or 189 (include and not include(testname))): 190 continue 191 module = __import__(testname) 192 for arg in args: 193 try: 194 cases = testloader.loadTestsFromNames((arg,), module) 195 testsuite.addTests(cases) 196 except AttributeError: 197 pass 198 if not args: 199 cases = testloader.loadTestsFromModule(module) 200 testsuite.addTests(cases) 201 return testsuite 202 203 204def run_tests(options, testsuite, runner=None): 205 if runner is None: 206 runner = unittest.TextTestRunner(verbosity=options.verbose) 207 runner.failfast = options.failfast 208 result = runner.run(testsuite) 209 return result.wasSuccessful() 210 211 212 213def abort(code=1): 214 os.abort() 215 216 217def shutdown(success): 218 pass 219 220 221def main(args=None): 222 pkgname = 'petsc4py' 223 parser = getoptionparser() 224 (options, args) = parser.parse_args(args) 225 setup_python(options) 226 setup_unittest(options) 227 import_package(options, pkgname) 228 print_banner(options) 229 testsuite = load_tests(options, args) 230 success = run_tests(options, testsuite) 231 if not success and options.failfast: abort() 232 shutdown(success) 233 return not success 234 235 236if __name__ == '__main__': 237 import sys 238 sys.dont_write_bytecode = True 239 sys.exit(main()) 240