diff options
author | Gregory P. Smith <greg@krypto.org> | 2014-06-16 00:51:04 (GMT) |
---|---|---|
committer | Gregory P. Smith <greg@krypto.org> | 2014-06-16 00:51:04 (GMT) |
commit | 634aa68c2b2b3e7d93561aba670f9ac233b9c5b2 (patch) | |
tree | be487b00b6e1bce284ff6a2806a430cf904e6450 /Lib | |
parent | 92a405534383927c48c8de2fc6bf06127ef2be78 (diff) | |
download | cpython-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.py | 38 |
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.") |