import os
import sys
import re
+import gc
import codecs
import shutil
import unittest
import doctest
import operator
+import tempfile
try:
from StringIO import StringIO
except ImportError:
# Lists external modules, and a matcher matching tests
# which should be excluded if the module is not present.
EXT_DEP_MODULES = {
- 'numpy' : re.compile('.*\.numpy_.*').match
+ 'numpy' : re.compile('.*\.numpy_.*').match,
+ 'pstats' : re.compile('.*\.pstats_.*').match
}
def get_numpy_include_dirs():
class TestBuilder(object):
def __init__(self, rootdir, workdir, selectors, exclude_selectors, annotate,
cleanup_workdir, cleanup_sharedlibs, with_pyregr, cython_only,
- languages, test_bugs):
+ languages, test_bugs, fork):
self.rootdir = rootdir
self.workdir = workdir
self.selectors = selectors
self.cython_only = cython_only
self.languages = languages
self.test_bugs = test_bugs
+ self.fork = fork
def build_suite(self):
suite = unittest.TestSuite()
annotate=self.annotate,
cleanup_workdir=self.cleanup_workdir,
cleanup_sharedlibs=self.cleanup_sharedlibs,
- cython_only=self.cython_only)
+ cython_only=self.cython_only,
+ fork=self.fork)
class CythonCompileTestCase(unittest.TestCase):
def __init__(self, directory, workdir, module, language='c',
expect_errors=False, annotate=False, cleanup_workdir=True,
- cleanup_sharedlibs=True, cython_only=False):
+ cleanup_sharedlibs=True, cython_only=False, fork=True):
self.directory = directory
self.workdir = workdir
self.module = module
self.cleanup_workdir = cleanup_workdir
self.cleanup_sharedlibs = cleanup_sharedlibs
self.cython_only = cython_only
+ self.fork = fork
unittest.TestCase.__init__(self)
def shortDescription(self):
pass
def run_doctests(self, module_name, result):
- if sys.version_info[0] >= 3 or not hasattr(os, 'fork'):
+ if sys.version_info[0] >= 3 or not hasattr(os, 'fork') or not self.fork:
doctest.DocTestSuite(module_name).run(result)
+ gc.collect()
return
# fork to make sure we do not keep the tested module loaded
- input, output = os.pipe()
+ result_handle, result_file = tempfile.mkstemp()
+ os.close(result_handle)
child_id = os.fork()
if not child_id:
result_code = 0
try:
- output = os.fdopen(output, 'wb')
- tests = None
try:
- partial_result = PartialTestResult(result)
- tests = doctest.DocTestSuite(module_name)
- tests.run(partial_result)
- except Exception:
- if tests is None:
- # importing failed, try to fake a test class
- tests = _FakeClass(
- failureException=None,
- **{module_name: None})
- partial_result.addError(tests, sys.exc_info())
- result_code = 1
- pickle.dump(partial_result.data(), output)
+ tests = None
+ try:
+ partial_result = PartialTestResult(result)
+ tests = doctest.DocTestSuite(module_name)
+ tests.run(partial_result)
+ gc.collect()
+ except Exception:
+ if tests is None:
+ # importing failed, try to fake a test class
+ tests = _FakeClass(
+ failureException=None,
+ shortDescription = self.shortDescription,
+ **{module_name: None})
+ partial_result.addError(tests, sys.exc_info())
+ result_code = 1
+ output = open(result_file, 'wb')
+ pickle.dump(partial_result.data(), output)
+ except:
+ import traceback
+ traceback.print_exc()
finally:
try: output.close()
except: pass
os._exit(result_code)
- input = os.fdopen(input, 'rb')
- PartialTestResult.join_results(result, pickle.load(input))
- cid, result_code = os.waitpid(child_id, 0)
- if result_code:
- raise Exception("Tests in module '%s' exited with status %d" %
- (module_name, result_code >> 8))
+ try:
+ cid, result_code = os.waitpid(child_id, 0)
+ if result_code in (0,1):
+ input = open(result_file, 'rb')
+ try:
+ PartialTestResult.join_results(result, pickle.load(input))
+ finally:
+ input.close()
+ if result_code:
+ raise Exception("Tests in module '%s' exited with status %d" %
+ (module_name, result_code >> 8))
+ finally:
+ try: os.unlink(result_file)
+ except: pass
is_private_field = re.compile('^_[^_]').match
class _FakeClass(object):
def __init__(self, **kwargs):
- self.shortDescription = lambda x: kwargs.get('module_name')
+ self._shortDescription = kwargs.get('module_name')
self.__dict__.update(kwargs)
+ def shortDescription(self):
+ return self._shortDescription
try: # Py2.7+ and Py3.2+
from unittest.runner import _TextTestResult
parser.add_option("--no-refnanny", dest="with_refnanny",
action="store_false", default=True,
help="do not regression test reference counting")
+ parser.add_option("--no-fork", dest="fork",
+ action="store_false", default=True,
+ help="do not fork to run tests")
parser.add_option("--sys-pyregr", dest="system_pyregr",
action="store_true", default=False,
help="run the regression tests of the CPython installation")
''')
sys.path.insert(0, cy3_dir)
elif sys.version_info[0] >= 3:
- # make sure we do not import (or run) Cython itself
- options.with_cython = False
+ # make sure we do not import (or run) Cython itself (unless
+ # 2to3 was already run)
+ cy3_dir = os.path.join(WORKDIR, 'Cy3')
+ if os.path.isdir(cy3_dir):
+ sys.path.insert(0, cy3_dir)
+ else:
+ options.with_cython = False
options.doctests = False
options.unittests = False
options.pyregr = False
if not test_bugs:
exclude_selectors += [ FileListExcluder("tests/bugs.txt") ]
+
+ if sys.platform in ['win32', 'cygwin'] and sys.version_info < (2,6):
+ exclude_selectors += [ lambda x: x == "run.specialfloat" ]
languages = []
if options.use_c:
filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors,
options.annotate_source, options.cleanup_workdir,
options.cleanup_sharedlibs, options.pyregr,
- options.cython_only, languages, test_bugs)
+ options.cython_only, languages, test_bugs,
+ options.fork)
test_suite.addTest(filetests.build_suite())
if options.system_pyregr and languages:
filetests = TestBuilder(ROOTDIR, WORKDIR, selectors, exclude_selectors,
options.annotate_source, options.cleanup_workdir,
options.cleanup_sharedlibs, True,
- options.cython_only, languages, test_bugs)
+ options.cython_only, languages, test_bugs,
+ options.fork)
test_suite.addTest(
filetests.handle_directory(
os.path.join(sys.prefix, 'lib', 'python'+sys.version[:3], 'test'),
'pyregr'))
- unittest.TextTestRunner(verbosity=options.verbosity).run(test_suite)
+ result = unittest.TextTestRunner(verbosity=options.verbosity).run(test_suite)
if options.coverage:
coverage.stop()
if options.with_refnanny:
import refnanny
sys.stderr.write("\n".join([repr(x) for x in refnanny.reflog]))
+
+ sys.exit(not result.wasSuccessful())