summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorGregory P. Smith <greg@krypto.org>2014-06-16 00:51:04 (GMT)
committerGregory P. Smith <greg@krypto.org>2014-06-16 00:51:04 (GMT)
commit634aa68c2b2b3e7d93561aba670f9ac233b9c5b2 (patch)
treebe487b00b6e1bce284ff6a2806a430cf904e6450 /Lib
parent92a405534383927c48c8de2fc6bf06127ef2be78 (diff)
downloadcpython-634aa68c2b2b3e7d93561aba670f9ac233b9c5b2.zip
cpython-634aa68c2b2b3e7d93561aba670f9ac233b9c5b2.tar.gz
cpython-634aa68c2b2b3e7d93561aba670f9ac233b9c5b2.tar.bz2
Isolate the subprocess test_close_fds_when_max_fd_is_lowered test so
that the rlimit calls happens in a child process rather than the TestCase process to attempt to fix the gentoo buildbot's "Too many open files" error.
Diffstat (limited to 'Lib')
-rw-r--r--Lib/test/test_subprocess.py38
1 files changed, 30 insertions, 8 deletions
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 720025a..0c05358 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -1934,6 +1934,20 @@ class POSIXProcessTestCase(BaseTestCase):
"""Confirm that issue21618 is fixed (may fail under valgrind)."""
fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
+ # This launches the meat of the test in a child process to
+ # avoid messing with the larger unittest processes maximum
+ # number of file descriptors.
+ # This process launches:
+ # +--> Process that lowers its RLIMIT_NOFILE aftr setting up
+ # a bunch of high open fds above the new lower rlimit.
+ # Those are reported via stdout before launching a new
+ # process with close_fds=False to run the actual test:
+ # +--> The TEST: This one launches a fd_status.py
+ # subprocess with close_fds=True so we can find out if
+ # any of the fds above the lowered rlimit are still open.
+ p = subprocess.Popen([sys.executable, '-c', textwrap.dedent(
+ '''
+ import os, resource, subprocess, sys, textwrap
open_fds = set()
# Add a bunch more fds to pass down.
for _ in range(40):
@@ -1949,12 +1963,15 @@ class POSIXProcessTestCase(BaseTestCase):
open_fds.remove(fd)
for fd in open_fds:
- self.addCleanup(os.close, fd)
+ #self.addCleanup(os.close, fd)
os.set_inheritable(fd, True)
max_fd_open = max(open_fds)
- import resource
+ # Communicate the open_fds to the parent unittest.TestCase process.
+ print(','.join(map(str, sorted(open_fds))))
+ sys.stdout.flush()
+
rlim_cur, rlim_max = resource.getrlimit(resource.RLIMIT_NOFILE)
try:
# 29 is lower than the highest fds we are leaving open.
@@ -1965,22 +1982,27 @@ class POSIXProcessTestCase(BaseTestCase):
# An explicit list of fds to check is passed to fd_status.py as
# letting fd_status rely on its default logic would miss the
# fds above rlim_cur as it normally only checks up to that limit.
- p = subprocess.Popen(
+ subprocess.Popen(
[sys.executable, '-c',
textwrap.dedent("""
import subprocess, sys
- subprocess.Popen([sys.executable, {fd_status!r}] +
+ subprocess.Popen([sys.executable, %r] +
[str(x) for x in range({max_fd})],
close_fds=True).wait()
- """.format(fd_status=fd_status, max_fd=max_fd_open+1))],
- stdout=subprocess.PIPE, close_fds=False)
+ """.format(max_fd=max_fd_open+1))],
+ close_fds=False).wait()
finally:
resource.setrlimit(resource.RLIMIT_NOFILE, (rlim_cur, rlim_max))
+ ''' % fd_status)], stdout=subprocess.PIPE)
output, unused_stderr = p.communicate()
- remaining_fds = set(map(int, output.strip().split(b',')))
+ output_lines = output.splitlines()
+ self.assertEqual(len(output_lines), 2,
+ msg="expected exactly two lines of output:\n%s" % output)
+ opened_fds = set(map(int, output_lines[0].strip().split(b',')))
+ remaining_fds = set(map(int, output_lines[1].strip().split(b',')))
- self.assertFalse(remaining_fds & open_fds,
+ self.assertFalse(remaining_fds & opened_fds,
msg="Some fds were left open.")