Commit a1317103 authored by Erik M. Bray's avatar Erik M. Bray

Test cleanup on Cygwin should avoid deleting any DLLs until the end of the test run.

This issue is particular to Cygwin since on Cygwin distutils.spawn uses os.fork(). Deleting DLLs can lead to Cygwin's fork() breaking, due to trying to load a DLL that no longer exists.  This means that the test run will use a little more disk space on Cygwin, but still allows full (or partial) cleanup at the end.
parent 4ef6edb0
#!/usr/bin/env python #!/usr/bin/env python
import atexit
import os import os
import sys import sys
import re import re
...@@ -70,6 +71,24 @@ CY3_DIR = None ...@@ -70,6 +71,24 @@ CY3_DIR = None
from distutils.command.build_ext import build_ext as _build_ext from distutils.command.build_ext import build_ext as _build_ext
from distutils import sysconfig from distutils import sysconfig
_to_clean = []
@atexit.register
def _cleanup_files():
"""
This is only used on Cygwin to clean up shared libraries that are unsafe
to delete while the test suite is running.
"""
for filename in _to_clean:
if os.path.isdir(filename):
shutil.rmtree(filename, ignore_errors=True)
else:
try:
os.remove(filename)
except OSError:
pass
def get_distutils_distro(_cache=[]): def get_distutils_distro(_cache=[]):
if _cache: if _cache:
...@@ -673,8 +692,10 @@ class CythonCompileTestCase(unittest.TestCase): ...@@ -673,8 +692,10 @@ class CythonCompileTestCase(unittest.TestCase):
cleanup = self.cleanup_failures or self.success cleanup = self.cleanup_failures or self.success
cleanup_c_files = WITH_CYTHON and self.cleanup_workdir and cleanup cleanup_c_files = WITH_CYTHON and self.cleanup_workdir and cleanup
cleanup_lib_files = self.cleanup_sharedlibs and cleanup cleanup_lib_files = self.cleanup_sharedlibs and cleanup
is_cygwin = sys.platform == 'cygwin'
if os.path.exists(self.workdir): if os.path.exists(self.workdir):
if cleanup_c_files and cleanup_lib_files: if cleanup_c_files and cleanup_lib_files and not is_cygwin:
shutil.rmtree(self.workdir, ignore_errors=True) shutil.rmtree(self.workdir, ignore_errors=True)
else: else:
for rmfile in os.listdir(self.workdir): for rmfile in os.listdir(self.workdir):
...@@ -683,17 +704,28 @@ class CythonCompileTestCase(unittest.TestCase): ...@@ -683,17 +704,28 @@ class CythonCompileTestCase(unittest.TestCase):
rmfile[-4:] == ".cpp" or rmfile[-4:] == ".cpp" or
rmfile.endswith(".html") and rmfile.startswith(self.module)): rmfile.endswith(".html") and rmfile.startswith(self.module)):
continue continue
if not cleanup_lib_files and (rmfile.endswith(".so") or rmfile.endswith(".dll")):
is_shared_obj = rmfile.endswith(".so") or rmfile.endswith(".dll")
if not cleanup_lib_files and is_shared_obj:
continue continue
try: try:
rmfile = os.path.join(self.workdir, rmfile) rmfile = os.path.join(self.workdir, rmfile)
if os.path.isdir(rmfile): if os.path.isdir(rmfile):
shutil.rmtree(rmfile, ignore_errors=True) shutil.rmtree(rmfile, ignore_errors=True)
elif is_cygwin and is_shared_obj:
# Delete later
_to_clean.append(rmfile)
else: else:
os.remove(rmfile) os.remove(rmfile)
except IOError: except IOError:
pass pass
if cleanup_c_files and cleanup_lib_files and is_cygwin:
# Finally, remove the work dir itself
_to_clean.append(self.workdir)
def runTest(self): def runTest(self):
self.success = False self.success = False
self.runCompileTest() self.runCompileTest()
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment