blob: 4c9f29bdb8d51716e91e2c54a48a30fb02531f72 [file] [log] [blame]
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001import unittest
Chris Jerdonekec3ea942012-09-30 00:10:28 -07002from test import script_helper
Benjamin Petersonee8712c2008-05-20 21:35:26 +00003from test import support
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00004import subprocess
5import sys
6import signal
Gregory P. Smith112bb3a2011-03-15 14:55:17 -04007import io
Andrew Svetlov82860712012-08-19 22:13:41 +03008import locale
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00009import os
Gregory P. Smitha59c59f2010-03-01 00:17:40 +000010import errno
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000011import tempfile
12import time
Tim Peters3761e8d2004-10-13 04:07:12 +000013import re
Ezio Melotti184bdfb2010-02-18 09:37:05 +000014import sysconfig
Gregory P. Smithd23047b2010-12-04 09:10:44 +000015import warnings
Gregory P. Smith51ee2702010-12-13 07:59:39 +000016import select
Gregory P. Smith81ce6852011-03-15 02:04:11 -040017import shutil
Benjamin Petersonb870aa12011-12-10 12:44:25 -050018import gc
Andrew Svetlov47ec25d2012-08-19 16:25:37 +030019import textwrap
Benjamin Peterson964561b2011-12-10 12:31:42 -050020
21try:
22 import resource
23except ImportError:
24 resource = None
Antoine Pitroua8392712013-08-30 23:38:13 +020025try:
26 import threading
27except ImportError:
28 threading = None
Benjamin Peterson964561b2011-12-10 12:31:42 -050029
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000030mswindows = (sys.platform == "win32")
31
32#
33# Depends on the following external programs: Python
34#
35
36if mswindows:
Tim Peters3b01a702004-10-12 22:19:32 +000037 SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
38 'os.O_BINARY);')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000039else:
40 SETBINARY = ''
41
Florent Xiclunab1e94e82010-02-27 22:12:37 +000042
43try:
44 mkstemp = tempfile.mkstemp
45except AttributeError:
46 # tempfile.mkstemp is not available
47 def mkstemp():
48 """Replacement for mkstemp, calling mktemp."""
49 fname = tempfile.mktemp()
50 return os.open(fname, os.O_RDWR|os.O_CREAT), fname
51
Tim Peters3761e8d2004-10-13 04:07:12 +000052
Florent Xiclunac049d872010-03-27 22:47:23 +000053class BaseTestCase(unittest.TestCase):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000054 def setUp(self):
55 # Try to minimize the number of children we have so this test
56 # doesn't crash on some buildbots (Alphas in particular).
Florent Xiclunab1e94e82010-02-27 22:12:37 +000057 support.reap_children()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058
Florent Xiclunaf0cbd822010-03-04 21:50:56 +000059 def tearDown(self):
60 for inst in subprocess._active:
61 inst.wait()
62 subprocess._cleanup()
63 self.assertFalse(subprocess._active, "subprocess._active not empty")
64
Florent Xiclunab1e94e82010-02-27 22:12:37 +000065 def assertStderrEqual(self, stderr, expected, msg=None):
66 # In a debug build, stuff like "[6580 refs]" is printed to stderr at
67 # shutdown time. That frustrates tests trying to check stderr produced
68 # from a spawned Python process.
Antoine Pitrou62f68ed2010-08-04 11:48:56 +000069 actual = support.strip_python_stderr(stderr)
Reid Kleckner31aa7dd2011-03-14 12:02:10 -040070 # strip_python_stderr also strips whitespace, so we do too.
71 expected = expected.strip()
Florent Xiclunab1e94e82010-02-27 22:12:37 +000072 self.assertEqual(actual, expected, msg)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000073
Florent Xiclunac049d872010-03-27 22:47:23 +000074
Gregory P. Smith3d8e7762012-11-10 22:32:22 -080075class PopenTestException(Exception):
76 pass
77
78
79class PopenExecuteChildRaises(subprocess.Popen):
80 """Popen subclass for testing cleanup of subprocess.PIPE filehandles when
81 _execute_child fails.
82 """
83 def _execute_child(self, *args, **kwargs):
84 raise PopenTestException("Forced Exception for Test")
85
86
Florent Xiclunac049d872010-03-27 22:47:23 +000087class ProcessTestCase(BaseTestCase):
88
Gregory P. Smitha1ed5392013-03-23 11:44:25 -070089 def test_io_buffered_by_default(self):
90 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
91 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
92 stderr=subprocess.PIPE)
93 try:
94 self.assertIsInstance(p.stdin, io.BufferedIOBase)
95 self.assertIsInstance(p.stdout, io.BufferedIOBase)
96 self.assertIsInstance(p.stderr, io.BufferedIOBase)
97 finally:
Gregory P. Smitha1b9ed32013-03-23 11:54:22 -070098 p.stdin.close()
99 p.stdout.close()
100 p.stderr.close()
Gregory P. Smitha1ed5392013-03-23 11:44:25 -0700101 p.wait()
102
103 def test_io_unbuffered_works(self):
104 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
105 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
106 stderr=subprocess.PIPE, bufsize=0)
107 try:
108 self.assertIsInstance(p.stdin, io.RawIOBase)
109 self.assertIsInstance(p.stdout, io.RawIOBase)
110 self.assertIsInstance(p.stderr, io.RawIOBase)
111 finally:
Gregory P. Smitha1b9ed32013-03-23 11:54:22 -0700112 p.stdin.close()
113 p.stdout.close()
114 p.stderr.close()
Gregory P. Smitha1ed5392013-03-23 11:44:25 -0700115 p.wait()
116
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000117 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000118 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +0000119 rc = subprocess.call([sys.executable, "-c",
120 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000121 self.assertEqual(rc, 47)
122
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400123 def test_call_timeout(self):
124 # call() function with timeout argument; we want to test that the child
125 # process gets killed when the timeout expires. If the child isn't
126 # killed, this call will deadlock since subprocess.call waits for the
127 # child.
128 self.assertRaises(subprocess.TimeoutExpired, subprocess.call,
129 [sys.executable, "-c", "while True: pass"],
130 timeout=0.1)
131
Peter Astrand454f7672005-01-01 09:36:35 +0000132 def test_check_call_zero(self):
133 # check_call() function with zero return code
134 rc = subprocess.check_call([sys.executable, "-c",
135 "import sys; sys.exit(0)"])
136 self.assertEqual(rc, 0)
137
138 def test_check_call_nonzero(self):
139 # check_call() function with non-zero return code
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000140 with self.assertRaises(subprocess.CalledProcessError) as c:
Peter Astrand454f7672005-01-01 09:36:35 +0000141 subprocess.check_call([sys.executable, "-c",
142 "import sys; sys.exit(47)"])
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000143 self.assertEqual(c.exception.returncode, 47)
Peter Astrand454f7672005-01-01 09:36:35 +0000144
Georg Brandlf9734072008-12-07 15:30:06 +0000145 def test_check_output(self):
146 # check_output() function with zero return code
147 output = subprocess.check_output(
148 [sys.executable, "-c", "print('BDFL')"])
Benjamin Peterson577473f2010-01-19 00:09:57 +0000149 self.assertIn(b'BDFL', output)
Georg Brandlf9734072008-12-07 15:30:06 +0000150
151 def test_check_output_nonzero(self):
152 # check_call() function with non-zero return code
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000153 with self.assertRaises(subprocess.CalledProcessError) as c:
Georg Brandlf9734072008-12-07 15:30:06 +0000154 subprocess.check_output(
155 [sys.executable, "-c", "import sys; sys.exit(5)"])
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000156 self.assertEqual(c.exception.returncode, 5)
Georg Brandlf9734072008-12-07 15:30:06 +0000157
158 def test_check_output_stderr(self):
159 # check_output() function stderr redirected to stdout
160 output = subprocess.check_output(
161 [sys.executable, "-c", "import sys; sys.stderr.write('BDFL')"],
162 stderr=subprocess.STDOUT)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000163 self.assertIn(b'BDFL', output)
Georg Brandlf9734072008-12-07 15:30:06 +0000164
165 def test_check_output_stdout_arg(self):
166 # check_output() function stderr redirected to stdout
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000167 with self.assertRaises(ValueError) as c:
Georg Brandlf9734072008-12-07 15:30:06 +0000168 output = subprocess.check_output(
169 [sys.executable, "-c", "print('will not be run')"],
170 stdout=sys.stdout)
Georg Brandlf9734072008-12-07 15:30:06 +0000171 self.fail("Expected ValueError when stdout arg supplied.")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000172 self.assertIn('stdout', c.exception.args[0])
Georg Brandlf9734072008-12-07 15:30:06 +0000173
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400174 def test_check_output_timeout(self):
175 # check_output() function with timeout arg
176 with self.assertRaises(subprocess.TimeoutExpired) as c:
177 output = subprocess.check_output(
178 [sys.executable, "-c",
Victor Stinner149b1c72011-06-06 23:43:02 +0200179 "import sys, time\n"
180 "sys.stdout.write('BDFL')\n"
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400181 "sys.stdout.flush()\n"
Victor Stinner149b1c72011-06-06 23:43:02 +0200182 "time.sleep(3600)"],
Reid Klecknerda9ac722011-03-16 17:08:21 -0400183 # Some heavily loaded buildbots (sparc Debian 3.x) require
184 # this much time to start and print.
185 timeout=3)
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400186 self.fail("Expected TimeoutExpired.")
187 self.assertEqual(c.exception.output, b'BDFL')
188
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000189 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000190 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000191 newenv = os.environ.copy()
192 newenv["FRUIT"] = "banana"
193 rc = subprocess.call([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000194 'import sys, os;'
195 'sys.exit(os.getenv("FRUIT")=="banana")'],
196 env=newenv)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000197 self.assertEqual(rc, 1)
198
Victor Stinner87b9bc32011-06-01 00:57:47 +0200199 def test_invalid_args(self):
200 # Popen() called with invalid arguments should raise TypeError
201 # but Popen.__del__ should not complain (issue #12085)
202 with support.captured_stderr() as s:
203 self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1)
204 argcount = subprocess.Popen.__init__.__code__.co_argcount
205 too_many_args = [0] * (argcount + 1)
206 self.assertRaises(TypeError, subprocess.Popen, *too_many_args)
207 self.assertEqual(s.getvalue(), '')
208
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000209 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000210 # .stdin is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000211 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000212 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000213 self.addCleanup(p.stdout.close)
214 self.addCleanup(p.stderr.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000215 p.wait()
216 self.assertEqual(p.stdin, None)
217
218 def test_stdout_none(self):
Ezio Melotti42a541b2013-03-11 05:53:34 +0200219 # .stdout is None when not redirected, and the child's stdout will
220 # be inherited from the parent. In order to test this we run a
221 # subprocess in a subprocess:
222 # this_test
223 # \-- subprocess created by this test (parent)
224 # \-- subprocess created by the parent subprocess (child)
225 # The parent doesn't specify stdout, so the child will use the
226 # parent's stdout. This test checks that the message printed by the
227 # child goes to the parent stdout. The parent also checks that the
228 # child's stdout is None. See #11963.
229 code = ('import sys; from subprocess import Popen, PIPE;'
230 'p = Popen([sys.executable, "-c", "print(\'test_stdout_none\')"],'
231 ' stdin=PIPE, stderr=PIPE);'
232 'p.wait(); assert p.stdout is None;')
233 p = subprocess.Popen([sys.executable, "-c", code],
234 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
235 self.addCleanup(p.stdout.close)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000236 self.addCleanup(p.stderr.close)
Ezio Melotti42a541b2013-03-11 05:53:34 +0200237 out, err = p.communicate()
238 self.assertEqual(p.returncode, 0, err)
239 self.assertEqual(out.rstrip(), b'test_stdout_none')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000240
241 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000242 # .stderr is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000243 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000244 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000245 self.addCleanup(p.stdout.close)
246 self.addCleanup(p.stdin.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000247 p.wait()
248 self.assertEqual(p.stderr, None)
249
Chris Jerdonek776cb192012-10-08 15:56:43 -0700250 def _assert_python(self, pre_args, **kwargs):
251 # We include sys.exit() to prevent the test runner from hanging
252 # whenever python is found.
253 args = pre_args + ["import sys; sys.exit(47)"]
254 p = subprocess.Popen(args, **kwargs)
255 p.wait()
256 self.assertEqual(47, p.returncode)
257
258 def test_executable(self):
259 # Check that the executable argument works.
Chris Jerdonek86b0fb22012-10-09 13:17:49 -0700260 #
261 # On Unix (non-Mac and non-Windows), Python looks at args[0] to
262 # determine where its standard library is, so we need the directory
263 # of args[0] to be valid for the Popen() call to Python to succeed.
264 # See also issue #16170 and issue #7774.
265 doesnotexist = os.path.join(os.path.dirname(sys.executable),
266 "doesnotexist")
267 self._assert_python([doesnotexist, "-c"], executable=sys.executable)
Chris Jerdonek776cb192012-10-08 15:56:43 -0700268
269 def test_executable_takes_precedence(self):
270 # Check that the executable argument takes precedence over args[0].
271 #
272 # Verify first that the call succeeds without the executable arg.
273 pre_args = [sys.executable, "-c"]
274 self._assert_python(pre_args)
275 self.assertRaises(FileNotFoundError, self._assert_python, pre_args,
276 executable="doesnotexist")
277
278 @unittest.skipIf(mswindows, "executable argument replaces shell")
279 def test_executable_replaces_shell(self):
280 # Check that the executable argument replaces the default shell
281 # when shell=True.
282 self._assert_python([], executable=sys.executable, shell=True)
283
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700284 # For use in the test_cwd* tests below.
285 def _normalize_cwd(self, cwd):
286 # Normalize an expected cwd (for Tru64 support).
287 # We can't use os.path.realpath since it doesn't expand Tru64 {memb}
288 # strings. See bug #1063571.
289 original_cwd = os.getcwd()
290 os.chdir(cwd)
291 cwd = os.getcwd()
292 os.chdir(original_cwd)
293 return cwd
294
295 # For use in the test_cwd* tests below.
296 def _split_python_path(self):
297 # Return normalized (python_dir, python_base).
298 python_path = os.path.realpath(sys.executable)
299 return os.path.split(python_path)
300
301 # For use in the test_cwd* tests below.
302 def _assert_cwd(self, expected_cwd, python_arg, **kwargs):
303 # Invoke Python via Popen, and assert that (1) the call succeeds,
304 # and that (2) the current working directory of the child process
305 # matches *expected_cwd*.
306 p = subprocess.Popen([python_arg, "-c",
307 "import os, sys; "
308 "sys.stdout.write(os.getcwd()); "
309 "sys.exit(47)"],
310 stdout=subprocess.PIPE,
311 **kwargs)
312 self.addCleanup(p.stdout.close)
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000313 p.wait()
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700314 self.assertEqual(47, p.returncode)
315 normcase = os.path.normcase
316 self.assertEqual(normcase(expected_cwd),
317 normcase(p.stdout.read().decode("utf-8")))
318
319 def test_cwd(self):
320 # Check that cwd changes the cwd for the child process.
321 temp_dir = tempfile.gettempdir()
322 temp_dir = self._normalize_cwd(temp_dir)
323 self._assert_cwd(temp_dir, sys.executable, cwd=temp_dir)
324
Chris Jerdonekc2cd6262012-09-30 09:45:00 -0700325 @unittest.skipIf(mswindows, "pending resolution of issue #15533")
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700326 def test_cwd_with_relative_arg(self):
327 # Check that Popen looks for args[0] relative to cwd if args[0]
328 # is relative.
329 python_dir, python_base = self._split_python_path()
330 rel_python = os.path.join(os.curdir, python_base)
331 with support.temp_cwd() as wrong_dir:
332 # Before calling with the correct cwd, confirm that the call fails
333 # without cwd and with the wrong cwd.
Chris Jerdonek28714c82012-09-30 02:15:37 -0700334 self.assertRaises(FileNotFoundError, subprocess.Popen,
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700335 [rel_python])
Chris Jerdonek28714c82012-09-30 02:15:37 -0700336 self.assertRaises(FileNotFoundError, subprocess.Popen,
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700337 [rel_python], cwd=wrong_dir)
338 python_dir = self._normalize_cwd(python_dir)
339 self._assert_cwd(python_dir, rel_python, cwd=python_dir)
340
Chris Jerdonekc2cd6262012-09-30 09:45:00 -0700341 @unittest.skipIf(mswindows, "pending resolution of issue #15533")
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700342 def test_cwd_with_relative_executable(self):
343 # Check that Popen looks for executable relative to cwd if executable
344 # is relative (and that executable takes precedence over args[0]).
345 python_dir, python_base = self._split_python_path()
346 rel_python = os.path.join(os.curdir, python_base)
347 doesntexist = "somethingyoudonthave"
348 with support.temp_cwd() as wrong_dir:
349 # Before calling with the correct cwd, confirm that the call fails
350 # without cwd and with the wrong cwd.
Chris Jerdonek28714c82012-09-30 02:15:37 -0700351 self.assertRaises(FileNotFoundError, subprocess.Popen,
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700352 [doesntexist], executable=rel_python)
Chris Jerdonek28714c82012-09-30 02:15:37 -0700353 self.assertRaises(FileNotFoundError, subprocess.Popen,
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700354 [doesntexist], executable=rel_python,
355 cwd=wrong_dir)
356 python_dir = self._normalize_cwd(python_dir)
357 self._assert_cwd(python_dir, doesntexist, executable=rel_python,
358 cwd=python_dir)
359
360 def test_cwd_with_absolute_arg(self):
361 # Check that Popen can find the executable when the cwd is wrong
362 # if args[0] is an absolute path.
363 python_dir, python_base = self._split_python_path()
364 abs_python = os.path.join(python_dir, python_base)
365 rel_python = os.path.join(os.curdir, python_base)
366 with script_helper.temp_dir() as wrong_dir:
367 # Before calling with an absolute path, confirm that using a
368 # relative path fails.
Chris Jerdonek28714c82012-09-30 02:15:37 -0700369 self.assertRaises(FileNotFoundError, subprocess.Popen,
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700370 [rel_python], cwd=wrong_dir)
371 wrong_dir = self._normalize_cwd(wrong_dir)
372 self._assert_cwd(wrong_dir, abs_python, cwd=wrong_dir)
373
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100374 @unittest.skipIf(sys.base_prefix != sys.prefix,
375 'Test is not venv-compatible')
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000376 def test_executable_with_cwd(self):
Chris Jerdonekec3ea942012-09-30 00:10:28 -0700377 python_dir, python_base = self._split_python_path()
378 python_dir = self._normalize_cwd(python_dir)
379 self._assert_cwd(python_dir, "somethingyoudonthave",
380 executable=sys.executable, cwd=python_dir)
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000381
Vinay Sajip7ded1f02012-05-26 03:45:29 +0100382 @unittest.skipIf(sys.base_prefix != sys.prefix,
383 'Test is not venv-compatible')
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000384 @unittest.skipIf(sysconfig.is_python_build(),
385 "need an installed Python. See #7774")
386 def test_executable_without_cwd(self):
387 # For a normal installation, it should work without 'cwd'
388 # argument. For test runs in the build directory, see #7774.
Ned Deilye92dfbf2013-08-02 18:02:21 -0700389 self._assert_cwd(os.getcwd(), "somethingyoudonthave",
390 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000391
392 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000393 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000394 p = subprocess.Popen([sys.executable, "-c",
395 'import sys; sys.exit(sys.stdin.read() == "pear")'],
396 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000397 p.stdin.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000398 p.stdin.close()
399 p.wait()
400 self.assertEqual(p.returncode, 1)
401
402 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000403 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000404 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000405 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000406 d = tf.fileno()
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000407 os.write(d, b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000408 os.lseek(d, 0, 0)
409 p = subprocess.Popen([sys.executable, "-c",
410 'import sys; sys.exit(sys.stdin.read() == "pear")'],
411 stdin=d)
412 p.wait()
413 self.assertEqual(p.returncode, 1)
414
415 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000416 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000417 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000418 self.addCleanup(tf.close)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000419 tf.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000420 tf.seek(0)
421 p = subprocess.Popen([sys.executable, "-c",
422 'import sys; sys.exit(sys.stdin.read() == "pear")'],
423 stdin=tf)
424 p.wait()
425 self.assertEqual(p.returncode, 1)
426
427 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000428 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000429 p = subprocess.Popen([sys.executable, "-c",
430 'import sys; sys.stdout.write("orange")'],
431 stdout=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000432 self.addCleanup(p.stdout.close)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000433 self.assertEqual(p.stdout.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000434
435 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000436 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000437 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000438 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000439 d = tf.fileno()
440 p = subprocess.Popen([sys.executable, "-c",
441 'import sys; sys.stdout.write("orange")'],
442 stdout=d)
443 p.wait()
444 os.lseek(d, 0, 0)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000445 self.assertEqual(os.read(d, 1024), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000446
447 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000448 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000449 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000450 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000451 p = subprocess.Popen([sys.executable, "-c",
452 'import sys; sys.stdout.write("orange")'],
453 stdout=tf)
454 p.wait()
455 tf.seek(0)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000456 self.assertEqual(tf.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000457
458 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000459 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000460 p = subprocess.Popen([sys.executable, "-c",
461 'import sys; sys.stderr.write("strawberry")'],
462 stderr=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000463 self.addCleanup(p.stderr.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000464 self.assertStderrEqual(p.stderr.read(), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000465
466 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000467 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000468 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000469 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000470 d = tf.fileno()
471 p = subprocess.Popen([sys.executable, "-c",
472 'import sys; sys.stderr.write("strawberry")'],
473 stderr=d)
474 p.wait()
475 os.lseek(d, 0, 0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000476 self.assertStderrEqual(os.read(d, 1024), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000477
478 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000479 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000480 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000481 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000482 p = subprocess.Popen([sys.executable, "-c",
483 'import sys; sys.stderr.write("strawberry")'],
484 stderr=tf)
485 p.wait()
486 tf.seek(0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000487 self.assertStderrEqual(tf.read(), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000488
489 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000490 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000491 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000492 'import sys;'
493 'sys.stdout.write("apple");'
494 'sys.stdout.flush();'
495 'sys.stderr.write("orange")'],
496 stdout=subprocess.PIPE,
497 stderr=subprocess.STDOUT)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000498 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000499 self.assertStderrEqual(p.stdout.read(), b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000500
501 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000502 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000503 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000504 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000505 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000506 'import sys;'
507 'sys.stdout.write("apple");'
508 'sys.stdout.flush();'
509 'sys.stderr.write("orange")'],
510 stdout=tf,
511 stderr=tf)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000512 p.wait()
513 tf.seek(0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000514 self.assertStderrEqual(tf.read(), b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000515
Thomas Wouters89f507f2006-12-13 04:49:30 +0000516 def test_stdout_filedes_of_stdout(self):
517 # stdout is set to 1 (#1531862).
Ezio Melotti42a541b2013-03-11 05:53:34 +0200518 # To avoid printing the text on stdout, we do something similar to
519 # test_stdout_none (see above). The parent subprocess calls the child
520 # subprocess passing stdout=1, and this test uses stdout=PIPE in
521 # order to capture and check the output of the parent. See #11963.
522 code = ('import sys, subprocess; '
523 'rc = subprocess.call([sys.executable, "-c", '
524 ' "import os, sys; sys.exit(os.write(sys.stdout.fileno(), '
525 'b\'test with stdout=1\'))"], stdout=1); '
526 'assert rc == 18')
527 p = subprocess.Popen([sys.executable, "-c", code],
528 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
529 self.addCleanup(p.stdout.close)
530 self.addCleanup(p.stderr.close)
531 out, err = p.communicate()
532 self.assertEqual(p.returncode, 0, err)
533 self.assertEqual(out.rstrip(), b'test with stdout=1')
Thomas Wouters89f507f2006-12-13 04:49:30 +0000534
Ross Lagerwallba102ec2011-03-16 18:40:25 +0200535 def test_stdout_devnull(self):
536 p = subprocess.Popen([sys.executable, "-c",
537 'for i in range(10240):'
538 'print("x" * 1024)'],
539 stdout=subprocess.DEVNULL)
540 p.wait()
541 self.assertEqual(p.stdout, None)
542
543 def test_stderr_devnull(self):
544 p = subprocess.Popen([sys.executable, "-c",
545 'import sys\n'
546 'for i in range(10240):'
547 'sys.stderr.write("x" * 1024)'],
548 stderr=subprocess.DEVNULL)
549 p.wait()
550 self.assertEqual(p.stderr, None)
551
552 def test_stdin_devnull(self):
553 p = subprocess.Popen([sys.executable, "-c",
554 'import sys;'
555 'sys.stdin.read(1)'],
556 stdin=subprocess.DEVNULL)
557 p.wait()
558 self.assertEqual(p.stdin, None)
559
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000560 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000561 newenv = os.environ.copy()
562 newenv["FRUIT"] = "orange"
Victor Stinnerf1512a22011-06-21 17:18:38 +0200563 with subprocess.Popen([sys.executable, "-c",
564 'import sys,os;'
565 'sys.stdout.write(os.getenv("FRUIT"))'],
566 stdout=subprocess.PIPE,
567 env=newenv) as p:
568 stdout, stderr = p.communicate()
569 self.assertEqual(stdout, b"orange")
570
Victor Stinner62d51182011-06-23 01:02:25 +0200571 # Windows requires at least the SYSTEMROOT environment variable to start
572 # Python
573 @unittest.skipIf(sys.platform == 'win32',
574 'cannot test an empty env on Windows')
Victor Stinner237e5cb2011-06-22 21:28:43 +0200575 @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') is not None,
Victor Stinner372309a2011-06-21 21:59:06 +0200576 'the python library cannot be loaded '
577 'with an empty environment')
Victor Stinnerf1512a22011-06-21 17:18:38 +0200578 def test_empty_env(self):
579 with subprocess.Popen([sys.executable, "-c",
580 'import os; '
Victor Stinner372309a2011-06-21 21:59:06 +0200581 'print(list(os.environ.keys()))'],
Victor Stinnerf1512a22011-06-21 17:18:38 +0200582 stdout=subprocess.PIPE,
583 env={}) as p:
584 stdout, stderr = p.communicate()
Victor Stinner237e5cb2011-06-22 21:28:43 +0200585 self.assertIn(stdout.strip(),
586 (b"[]",
587 # Mac OS X adds __CF_USER_TEXT_ENCODING variable to an empty
588 # environment
589 b"['__CF_USER_TEXT_ENCODING']"))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000590
Peter Astrandcbac93c2005-03-03 20:24:28 +0000591 def test_communicate_stdin(self):
592 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000593 'import sys;'
594 'sys.exit(sys.stdin.read() == "pear")'],
Peter Astrandcbac93c2005-03-03 20:24:28 +0000595 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000596 p.communicate(b"pear")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000597 self.assertEqual(p.returncode, 1)
598
599 def test_communicate_stdout(self):
600 p = subprocess.Popen([sys.executable, "-c",
601 'import sys; sys.stdout.write("pineapple")'],
602 stdout=subprocess.PIPE)
603 (stdout, stderr) = p.communicate()
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000604 self.assertEqual(stdout, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000605 self.assertEqual(stderr, None)
606
607 def test_communicate_stderr(self):
608 p = subprocess.Popen([sys.executable, "-c",
609 'import sys; sys.stderr.write("pineapple")'],
610 stderr=subprocess.PIPE)
611 (stdout, stderr) = p.communicate()
612 self.assertEqual(stdout, None)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000613 self.assertStderrEqual(stderr, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000614
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000615 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000616 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000617 'import sys,os;'
618 'sys.stderr.write("pineapple");'
619 'sys.stdout.write(sys.stdin.read())'],
620 stdin=subprocess.PIPE,
621 stdout=subprocess.PIPE,
622 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +0000623 self.addCleanup(p.stdout.close)
624 self.addCleanup(p.stderr.close)
625 self.addCleanup(p.stdin.close)
Georg Brandl1abcbf82008-07-01 19:28:43 +0000626 (stdout, stderr) = p.communicate(b"banana")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000627 self.assertEqual(stdout, b"banana")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000628 self.assertStderrEqual(stderr, b"pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000629
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400630 def test_communicate_timeout(self):
631 p = subprocess.Popen([sys.executable, "-c",
632 'import sys,os,time;'
633 'sys.stderr.write("pineapple\\n");'
634 'time.sleep(1);'
635 'sys.stderr.write("pear\\n");'
636 'sys.stdout.write(sys.stdin.read())'],
637 universal_newlines=True,
638 stdin=subprocess.PIPE,
639 stdout=subprocess.PIPE,
640 stderr=subprocess.PIPE)
641 self.assertRaises(subprocess.TimeoutExpired, p.communicate, "banana",
642 timeout=0.3)
643 # Make sure we can keep waiting for it, and that we get the whole output
644 # after it completes.
645 (stdout, stderr) = p.communicate()
646 self.assertEqual(stdout, "banana")
647 self.assertStderrEqual(stderr.encode(), b"pineapple\npear\n")
648
649 def test_communicate_timeout_large_ouput(self):
Ross Lagerwall003c7a32012-02-12 09:02:01 +0200650 # Test an expiring timeout while the child is outputting lots of data.
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400651 p = subprocess.Popen([sys.executable, "-c",
652 'import sys,os,time;'
653 'sys.stdout.write("a" * (64 * 1024));'
654 'time.sleep(0.2);'
655 'sys.stdout.write("a" * (64 * 1024));'
656 'time.sleep(0.2);'
657 'sys.stdout.write("a" * (64 * 1024));'
658 'time.sleep(0.2);'
659 'sys.stdout.write("a" * (64 * 1024));'],
660 stdout=subprocess.PIPE)
661 self.assertRaises(subprocess.TimeoutExpired, p.communicate, timeout=0.4)
662 (stdout, _) = p.communicate()
663 self.assertEqual(len(stdout), 4 * 64 * 1024)
664
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000665 # Test for the fd leak reported in http://bugs.python.org/issue2791.
666 def test_communicate_pipe_fd_leak(self):
Victor Stinner667d4b52010-12-25 22:40:32 +0000667 for stdin_pipe in (False, True):
668 for stdout_pipe in (False, True):
669 for stderr_pipe in (False, True):
670 options = {}
671 if stdin_pipe:
672 options['stdin'] = subprocess.PIPE
673 if stdout_pipe:
674 options['stdout'] = subprocess.PIPE
675 if stderr_pipe:
676 options['stderr'] = subprocess.PIPE
677 if not options:
678 continue
679 p = subprocess.Popen((sys.executable, "-c", "pass"), **options)
680 p.communicate()
681 if p.stdin is not None:
682 self.assertTrue(p.stdin.closed)
683 if p.stdout is not None:
684 self.assertTrue(p.stdout.closed)
685 if p.stderr is not None:
686 self.assertTrue(p.stderr.closed)
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000687
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000688 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000689 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000690 p = subprocess.Popen([sys.executable, "-c",
691 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000692 (stdout, stderr) = p.communicate()
693 self.assertEqual(stdout, None)
694 self.assertEqual(stderr, None)
695
696 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000697 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000698 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000699 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000700 x, y = os.pipe()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000701 os.close(x)
702 os.close(y)
703 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000704 'import sys,os;'
705 'sys.stdout.write(sys.stdin.read(47));'
Charles-François Natali2d517212011-05-29 16:36:44 +0200706 'sys.stderr.write("x" * %d);'
707 'sys.stdout.write(sys.stdin.read())' %
708 support.PIPE_MAX_SIZE],
Guido van Rossum98297ee2007-11-06 21:34:58 +0000709 stdin=subprocess.PIPE,
710 stdout=subprocess.PIPE,
711 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +0000712 self.addCleanup(p.stdout.close)
713 self.addCleanup(p.stderr.close)
714 self.addCleanup(p.stdin.close)
Charles-François Natali2d517212011-05-29 16:36:44 +0200715 string_to_write = b"a" * support.PIPE_MAX_SIZE
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000716 (stdout, stderr) = p.communicate(string_to_write)
717 self.assertEqual(stdout, string_to_write)
718
719 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000720 # stdin.write before communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000721 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000722 'import sys,os;'
723 'sys.stdout.write(sys.stdin.read())'],
724 stdin=subprocess.PIPE,
725 stdout=subprocess.PIPE,
726 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +0000727 self.addCleanup(p.stdout.close)
728 self.addCleanup(p.stderr.close)
729 self.addCleanup(p.stdin.close)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000730 p.stdin.write(b"banana")
731 (stdout, stderr) = p.communicate(b"split")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000732 self.assertEqual(stdout, b"bananasplit")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000733 self.assertStderrEqual(stderr, b"")
Tim Peterse718f612004-10-12 21:51:32 +0000734
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000735 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000736 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000737 'import sys,os;' + SETBINARY +
Antoine Pitrouec2d2692012-08-05 00:23:40 +0200738 'buf = sys.stdout.buffer;'
739 'buf.write(sys.stdin.readline().encode());'
740 'buf.flush();'
741 'buf.write(b"line2\\n");'
742 'buf.flush();'
743 'buf.write(sys.stdin.read().encode());'
744 'buf.flush();'
745 'buf.write(b"line4\\n");'
746 'buf.flush();'
747 'buf.write(b"line5\\r\\n");'
748 'buf.flush();'
749 'buf.write(b"line6\\r");'
750 'buf.flush();'
751 'buf.write(b"\\nline7");'
752 'buf.flush();'
753 'buf.write(b"\\nline8");'],
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200754 stdin=subprocess.PIPE,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000755 stdout=subprocess.PIPE,
756 universal_newlines=1)
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200757 p.stdin.write("line1\n")
758 self.assertEqual(p.stdout.readline(), "line1\n")
759 p.stdin.write("line3\n")
760 p.stdin.close()
Brian Curtin3c6a9512010-11-05 03:58:52 +0000761 self.addCleanup(p.stdout.close)
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200762 self.assertEqual(p.stdout.readline(),
763 "line2\n")
764 self.assertEqual(p.stdout.read(6),
765 "line3\n")
766 self.assertEqual(p.stdout.read(),
767 "line4\nline5\nline6\nline7\nline8")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000768
769 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000770 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000771 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000772 'import sys,os;' + SETBINARY +
Antoine Pitrouec2d2692012-08-05 00:23:40 +0200773 'buf = sys.stdout.buffer;'
774 'buf.write(b"line2\\n");'
775 'buf.flush();'
776 'buf.write(b"line4\\n");'
777 'buf.flush();'
778 'buf.write(b"line5\\r\\n");'
779 'buf.flush();'
780 'buf.write(b"line6\\r");'
781 'buf.flush();'
782 'buf.write(b"\\nline7");'
783 'buf.flush();'
784 'buf.write(b"\\nline8");'],
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200785 stderr=subprocess.PIPE,
786 stdout=subprocess.PIPE,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000787 universal_newlines=1)
Brian Curtin19a53792010-11-05 17:09:05 +0000788 self.addCleanup(p.stdout.close)
789 self.addCleanup(p.stderr.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000790 (stdout, stderr) = p.communicate()
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200791 self.assertEqual(stdout,
792 "line2\nline4\nline5\nline6\nline7\nline8")
793
794 def test_universal_newlines_communicate_stdin(self):
795 # universal newlines through communicate(), with only stdin
796 p = subprocess.Popen([sys.executable, "-c",
Andrew Svetlov47ec25d2012-08-19 16:25:37 +0300797 'import sys,os;' + SETBINARY + textwrap.dedent('''
798 s = sys.stdin.readline()
799 assert s == "line1\\n", repr(s)
800 s = sys.stdin.read()
801 assert s == "line3\\n", repr(s)
802 ''')],
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200803 stdin=subprocess.PIPE,
804 universal_newlines=1)
805 (stdout, stderr) = p.communicate("line1\nline3\n")
806 self.assertEqual(p.returncode, 0)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000807
Andrew Svetlovf3765072012-08-14 18:35:17 +0300808 def test_universal_newlines_communicate_input_none(self):
809 # Test communicate(input=None) with universal newlines.
810 #
811 # We set stdout to PIPE because, as of this writing, a different
812 # code path is tested when the number of pipes is zero or one.
813 p = subprocess.Popen([sys.executable, "-c", "pass"],
814 stdin=subprocess.PIPE,
815 stdout=subprocess.PIPE,
816 universal_newlines=True)
817 p.communicate()
818 self.assertEqual(p.returncode, 0)
819
Andrew Svetlov5395d2f2012-08-15 22:46:43 +0300820 def test_universal_newlines_communicate_stdin_stdout_stderr(self):
Andrew Svetlov47ec25d2012-08-19 16:25:37 +0300821 # universal newlines through communicate(), with stdin, stdout, stderr
Andrew Svetlov5395d2f2012-08-15 22:46:43 +0300822 p = subprocess.Popen([sys.executable, "-c",
Andrew Svetlov47ec25d2012-08-19 16:25:37 +0300823 'import sys,os;' + SETBINARY + textwrap.dedent('''
824 s = sys.stdin.buffer.readline()
825 sys.stdout.buffer.write(s)
826 sys.stdout.buffer.write(b"line2\\r")
827 sys.stderr.buffer.write(b"eline2\\n")
828 s = sys.stdin.buffer.read()
829 sys.stdout.buffer.write(s)
830 sys.stdout.buffer.write(b"line4\\n")
831 sys.stdout.buffer.write(b"line5\\r\\n")
832 sys.stderr.buffer.write(b"eline6\\r")
833 sys.stderr.buffer.write(b"eline7\\r\\nz")
834 ''')],
Andrew Svetlov5395d2f2012-08-15 22:46:43 +0300835 stdin=subprocess.PIPE,
836 stderr=subprocess.PIPE,
837 stdout=subprocess.PIPE,
Andrew Svetlov47ec25d2012-08-19 16:25:37 +0300838 universal_newlines=True)
Andrew Svetlov5395d2f2012-08-15 22:46:43 +0300839 self.addCleanup(p.stdout.close)
840 self.addCleanup(p.stderr.close)
841 (stdout, stderr) = p.communicate("line1\nline3\n")
842 self.assertEqual(p.returncode, 0)
Andrew Svetlov943c5b32012-08-16 20:17:47 +0300843 self.assertEqual("line1\nline2\nline3\nline4\nline5\n", stdout)
Andrew Svetlov5395d2f2012-08-15 22:46:43 +0300844 # Python debug build push something like "[42442 refs]\n"
845 # to stderr at exit of subprocess.
Andrew Svetlov943c5b32012-08-16 20:17:47 +0300846 # Don't use assertStderrEqual because it strips CR and LF from output.
847 self.assertTrue(stderr.startswith("eline2\neline6\neline7\n"))
Andrew Svetlov5395d2f2012-08-15 22:46:43 +0300848
Andrew Svetlov82860712012-08-19 22:13:41 +0300849 def test_universal_newlines_communicate_encodings(self):
850 # Check that universal newlines mode works for various encodings,
851 # in particular for encodings in the UTF-16 and UTF-32 families.
852 # See issue #15595.
853 #
854 # UTF-16 and UTF-32-BE are sufficient to check both with BOM and
855 # without, and UTF-16 and UTF-32.
856 for encoding in ['utf-16', 'utf-32-be']:
857 old_getpreferredencoding = locale.getpreferredencoding
858 # Indirectly via io.TextIOWrapper, Popen() defaults to
859 # locale.getpreferredencoding(False) and earlier in Python 3.2 to
860 # locale.getpreferredencoding().
861 def getpreferredencoding(do_setlocale=True):
862 return encoding
863 code = ("import sys; "
864 r"sys.stdout.buffer.write('1\r\n2\r3\n4'.encode('%s'))" %
865 encoding)
866 args = [sys.executable, '-c', code]
867 try:
868 locale.getpreferredencoding = getpreferredencoding
869 # We set stdin to be non-None because, as of this writing,
870 # a different code path is used when the number of pipes is
871 # zero or one.
872 popen = subprocess.Popen(args, universal_newlines=True,
873 stdin=subprocess.PIPE,
874 stdout=subprocess.PIPE)
875 stdout, stderr = popen.communicate(input='')
876 finally:
877 locale.getpreferredencoding = old_getpreferredencoding
Andrew Svetlov82860712012-08-19 22:13:41 +0300878 self.assertEqual(stdout, '1\n2\n3\n4')
879
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000880 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000881 # Make sure we leak no resources
Antoine Pitrou8db30272010-09-18 22:38:48 +0000882 if not mswindows:
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000883 max_handles = 1026 # too much for most UNIX systems
884 else:
Antoine Pitrou8db30272010-09-18 22:38:48 +0000885 max_handles = 2050 # too much for (at least some) Windows setups
886 handles = []
Gregory P. Smith81ce6852011-03-15 02:04:11 -0400887 tmpdir = tempfile.mkdtemp()
Antoine Pitrou8db30272010-09-18 22:38:48 +0000888 try:
889 for i in range(max_handles):
890 try:
Gregory P. Smith81ce6852011-03-15 02:04:11 -0400891 tmpfile = os.path.join(tmpdir, support.TESTFN)
892 handles.append(os.open(tmpfile, os.O_WRONLY|os.O_CREAT))
Antoine Pitrou8db30272010-09-18 22:38:48 +0000893 except OSError as e:
894 if e.errno != errno.EMFILE:
895 raise
896 break
897 else:
898 self.skipTest("failed to reach the file descriptor limit "
899 "(tried %d)" % max_handles)
900 # Close a couple of them (should be enough for a subprocess)
901 for i in range(10):
902 os.close(handles.pop())
903 # Loop creating some subprocesses. If one of them leaks some fds,
904 # the next loop iteration will fail by reaching the max fd limit.
905 for i in range(15):
906 p = subprocess.Popen([sys.executable, "-c",
907 "import sys;"
908 "sys.stdout.write(sys.stdin.read())"],
909 stdin=subprocess.PIPE,
910 stdout=subprocess.PIPE,
911 stderr=subprocess.PIPE)
912 data = p.communicate(b"lime")[0]
913 self.assertEqual(data, b"lime")
914 finally:
915 for h in handles:
916 os.close(h)
Gregory P. Smith81ce6852011-03-15 02:04:11 -0400917 shutil.rmtree(tmpdir)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000918
919 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000920 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
921 '"a b c" d e')
922 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
923 'ab\\"c \\ d')
Christian Heimesfdab48e2008-01-20 09:06:41 +0000924 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
925 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000926 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
927 'a\\\\\\b "de fg" h')
928 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
929 'a\\\\\\"b c d')
930 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
931 '"a\\\\b c" d e')
932 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
933 '"a\\\\b\\ c" d e')
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000934 self.assertEqual(subprocess.list2cmdline(['ab', '']),
935 'ab ""')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000936
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000937 def test_poll(self):
Ross Lagerwallab66d2a2012-02-12 09:01:30 +0200938 p = subprocess.Popen([sys.executable, "-c",
Ross Lagerwalle7ad4192012-02-22 06:02:07 +0200939 "import os; os.read(0, 1)"],
940 stdin=subprocess.PIPE)
Ross Lagerwallab66d2a2012-02-12 09:01:30 +0200941 self.addCleanup(p.stdin.close)
942 self.assertIsNone(p.poll())
943 os.write(p.stdin.fileno(), b'A')
944 p.wait()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000945 # Subsequent invocations should just return the returncode
946 self.assertEqual(p.poll(), 0)
947
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000948 def test_wait(self):
Ross Lagerwallab66d2a2012-02-12 09:01:30 +0200949 p = subprocess.Popen([sys.executable, "-c", "pass"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000950 self.assertEqual(p.wait(), 0)
951 # Subsequent invocations should just return the returncode
952 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000953
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400954 def test_wait_timeout(self):
955 p = subprocess.Popen([sys.executable,
Antoine Pitroudc49b2b2013-05-19 15:55:40 +0200956 "-c", "import time; time.sleep(0.3)"])
Reid Kleckner2b228f02011-03-16 16:57:54 -0400957 with self.assertRaises(subprocess.TimeoutExpired) as c:
Antoine Pitroudc49b2b2013-05-19 15:55:40 +0200958 p.wait(timeout=0.0001)
959 self.assertIn("0.0001", str(c.exception)) # For coverage of __str__.
Reid Klecknerda9ac722011-03-16 17:08:21 -0400960 # Some heavily loaded buildbots (sparc Debian 3.x) require this much
961 # time to start.
962 self.assertEqual(p.wait(timeout=3), 0)
Reid Kleckner31aa7dd2011-03-14 12:02:10 -0400963
Peter Astrand738131d2004-11-30 21:04:45 +0000964 def test_invalid_bufsize(self):
965 # an invalid type of the bufsize argument should raise
966 # TypeError.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000967 with self.assertRaises(TypeError):
Peter Astrand738131d2004-11-30 21:04:45 +0000968 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
Peter Astrand738131d2004-11-30 21:04:45 +0000969
Guido van Rossum46a05a72007-06-07 21:56:45 +0000970 def test_bufsize_is_none(self):
971 # bufsize=None should be the same as bufsize=0.
972 p = subprocess.Popen([sys.executable, "-c", "pass"], None)
973 self.assertEqual(p.wait(), 0)
974 # Again with keyword arg
975 p = subprocess.Popen([sys.executable, "-c", "pass"], bufsize=None)
976 self.assertEqual(p.wait(), 0)
977
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000978 def test_leaking_fds_on_error(self):
979 # see bug #5179: Popen leaks file descriptors to PIPEs if
980 # the child fails to execute; this will eventually exhaust
981 # the maximum number of open fds. 1024 seems a very common
982 # value for that limit, but Windows has 2048, so we loop
983 # 1024 times (each call leaked two fds).
984 for i in range(1024):
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000985 # Windows raises IOError. Others raise OSError.
986 with self.assertRaises(EnvironmentError) as c:
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000987 subprocess.Popen(['nonexisting_i_hope'],
988 stdout=subprocess.PIPE,
989 stderr=subprocess.PIPE)
R David Murray384069c2011-03-13 22:26:53 -0400990 # ignore errors that indicate the command was not found
R David Murray6924bd72011-03-13 22:48:55 -0400991 if c.exception.errno not in (errno.ENOENT, errno.EACCES):
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000992 raise c.exception
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000993
Antoine Pitroua8392712013-08-30 23:38:13 +0200994 @unittest.skipIf(threading is None, "threading required")
995 def test_double_close_on_error(self):
996 # Issue #18851
997 fds = []
998 def open_fds():
999 for i in range(20):
1000 fds.extend(os.pipe())
1001 time.sleep(0.001)
1002 t = threading.Thread(target=open_fds)
1003 t.start()
1004 try:
1005 with self.assertRaises(EnvironmentError):
1006 subprocess.Popen(['nonexisting_i_hope'],
1007 stdin=subprocess.PIPE,
1008 stdout=subprocess.PIPE,
1009 stderr=subprocess.PIPE)
1010 finally:
1011 t.join()
1012 exc = None
1013 for fd in fds:
1014 # If a double close occurred, some of those fds will
1015 # already have been closed by mistake, and os.close()
1016 # here will raise.
1017 try:
1018 os.close(fd)
1019 except OSError as e:
1020 exc = e
1021 if exc is not None:
1022 raise exc
1023
Victor Stinnerb3693582010-05-21 20:13:12 +00001024 def test_issue8780(self):
1025 # Ensure that stdout is inherited from the parent
1026 # if stdout=PIPE is not used
1027 code = ';'.join((
1028 'import subprocess, sys',
1029 'retcode = subprocess.call('
1030 "[sys.executable, '-c', 'print(\"Hello World!\")'])",
1031 'assert retcode == 0'))
1032 output = subprocess.check_output([sys.executable, '-c', code])
Ezio Melottib3aedd42010-11-20 19:04:17 +00001033 self.assertTrue(output.startswith(b'Hello World!'), ascii(output))
Victor Stinnerb3693582010-05-21 20:13:12 +00001034
Tim Goldenaf5ac392010-08-06 13:03:56 +00001035 def test_handles_closed_on_exception(self):
1036 # If CreateProcess exits with an error, ensure the
1037 # duplicate output handles are released
1038 ifhandle, ifname = mkstemp()
1039 ofhandle, ofname = mkstemp()
1040 efhandle, efname = mkstemp()
1041 try:
1042 subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle,
1043 stderr=efhandle)
1044 except OSError:
1045 os.close(ifhandle)
1046 os.remove(ifname)
1047 os.close(ofhandle)
1048 os.remove(ofname)
1049 os.close(efhandle)
1050 os.remove(efname)
1051 self.assertFalse(os.path.exists(ifname))
1052 self.assertFalse(os.path.exists(ofname))
1053 self.assertFalse(os.path.exists(efname))
1054
Ross Lagerwall4f61b022011-04-05 15:34:00 +02001055 def test_communicate_epipe(self):
1056 # Issue 10963: communicate() should hide EPIPE
1057 p = subprocess.Popen([sys.executable, "-c", 'pass'],
1058 stdin=subprocess.PIPE,
1059 stdout=subprocess.PIPE,
1060 stderr=subprocess.PIPE)
1061 self.addCleanup(p.stdout.close)
1062 self.addCleanup(p.stderr.close)
1063 self.addCleanup(p.stdin.close)
1064 p.communicate(b"x" * 2**20)
1065
1066 def test_communicate_epipe_only_stdin(self):
1067 # Issue 10963: communicate() should hide EPIPE
1068 p = subprocess.Popen([sys.executable, "-c", 'pass'],
1069 stdin=subprocess.PIPE)
1070 self.addCleanup(p.stdin.close)
Ross Lagerwallab66d2a2012-02-12 09:01:30 +02001071 p.wait()
Ross Lagerwall4f61b022011-04-05 15:34:00 +02001072 p.communicate(b"x" * 2**20)
1073
Ross Lagerwallab66d2a2012-02-12 09:01:30 +02001074 @unittest.skipUnless(hasattr(signal, 'SIGUSR1'),
1075 "Requires signal.SIGUSR1")
1076 @unittest.skipUnless(hasattr(os, 'kill'),
1077 "Requires os.kill")
1078 @unittest.skipUnless(hasattr(os, 'getppid'),
1079 "Requires os.getppid")
Victor Stinner2cfb6f32011-07-05 14:00:56 +02001080 def test_communicate_eintr(self):
1081 # Issue #12493: communicate() should handle EINTR
1082 def handler(signum, frame):
1083 pass
Ross Lagerwallab66d2a2012-02-12 09:01:30 +02001084 old_handler = signal.signal(signal.SIGUSR1, handler)
1085 self.addCleanup(signal.signal, signal.SIGUSR1, old_handler)
Victor Stinner2cfb6f32011-07-05 14:00:56 +02001086
Ross Lagerwallab66d2a2012-02-12 09:01:30 +02001087 args = [sys.executable, "-c",
1088 'import os, signal;'
1089 'os.kill(os.getppid(), signal.SIGUSR1)']
Victor Stinner2cfb6f32011-07-05 14:00:56 +02001090 for stream in ('stdout', 'stderr'):
1091 kw = {stream: subprocess.PIPE}
1092 with subprocess.Popen(args, **kw) as process:
Ross Lagerwallab66d2a2012-02-12 09:01:30 +02001093 # communicate() will be interrupted by SIGUSR1
Victor Stinner2cfb6f32011-07-05 14:00:56 +02001094 process.communicate()
1095
Tim Peterse718f612004-10-12 21:51:32 +00001096
Gregory P. Smith3d8e7762012-11-10 22:32:22 -08001097 # This test is Linux-ish specific for simplicity to at least have
1098 # some coverage. It is not a platform specific bug.
1099 @unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()),
1100 "Linux specific")
1101 def test_failed_child_execute_fd_leak(self):
1102 """Test for the fork() failure fd leak reported in issue16327."""
1103 fd_directory = '/proc/%d/fd' % os.getpid()
1104 fds_before_popen = os.listdir(fd_directory)
1105 with self.assertRaises(PopenTestException):
1106 PopenExecuteChildRaises(
1107 [sys.executable, '-c', 'pass'], stdin=subprocess.PIPE,
1108 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1109
1110 # NOTE: This test doesn't verify that the real _execute_child
1111 # does not close the file descriptors itself on the way out
1112 # during an exception. Code inspection has confirmed that.
1113
1114 fds_after_exception = os.listdir(fd_directory)
1115 self.assertEqual(fds_before_popen, fds_after_exception)
1116
1117
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001118# context manager
1119class _SuppressCoreFiles(object):
1120 """Try to prevent core files from being created."""
1121 old_limit = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001122
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001123 def __enter__(self):
1124 """Try to save previous ulimit, then set it to (0, 0)."""
Benjamin Peterson964561b2011-12-10 12:31:42 -05001125 if resource is not None:
1126 try:
1127 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
1128 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
1129 except (ValueError, resource.error):
1130 pass
Thomas Wouters0e3f5912006-08-11 14:57:12 +00001131
Ronald Oussoren102d11a2010-07-23 09:50:05 +00001132 if sys.platform == 'darwin':
1133 # Check if the 'Crash Reporter' on OSX was configured
1134 # in 'Developer' mode and warn that it will get triggered
1135 # when it is.
1136 #
1137 # This assumes that this context manager is used in tests
1138 # that might trigger the next manager.
1139 value = subprocess.Popen(['/usr/bin/defaults', 'read',
1140 'com.apple.CrashReporter', 'DialogType'],
1141 stdout=subprocess.PIPE).communicate()[0]
1142 if value.strip() == b'developer':
1143 print("this tests triggers the Crash Reporter, "
1144 "that is intentional", end='')
1145 sys.stdout.flush()
1146
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001147 def __exit__(self, *args):
1148 """Return core file behavior to default."""
1149 if self.old_limit is None:
1150 return
Benjamin Peterson964561b2011-12-10 12:31:42 -05001151 if resource is not None:
1152 try:
1153 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
1154 except (ValueError, resource.error):
1155 pass
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001156
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001157
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001158@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunac049d872010-03-27 22:47:23 +00001159class POSIXProcessTestCase(BaseTestCase):
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001160
Gregory P. Smith5591b022012-10-10 03:34:47 -07001161 def setUp(self):
1162 super().setUp()
1163 self._nonexistent_dir = "/_this/pa.th/does/not/exist"
1164
1165 def _get_chdir_exception(self):
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001166 try:
Gregory P. Smith5591b022012-10-10 03:34:47 -07001167 os.chdir(self._nonexistent_dir)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001168 except OSError as e:
1169 # This avoids hard coding the errno value or the OS perror()
1170 # string and instead capture the exception that we want to see
1171 # below for comparison.
1172 desired_exception = e
Gregory P. Smith5591b022012-10-10 03:34:47 -07001173 desired_exception.strerror += ': ' + repr(self._nonexistent_dir)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001174 else:
1175 self.fail("chdir to nonexistant directory %s succeeded." %
Gregory P. Smith5591b022012-10-10 03:34:47 -07001176 self._nonexistent_dir)
1177 return desired_exception
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001178
Gregory P. Smith5591b022012-10-10 03:34:47 -07001179 def test_exception_cwd(self):
1180 """Test error in the child raised in the parent for a bad cwd."""
1181 desired_exception = self._get_chdir_exception()
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001182 try:
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001183 p = subprocess.Popen([sys.executable, "-c", ""],
Gregory P. Smith5591b022012-10-10 03:34:47 -07001184 cwd=self._nonexistent_dir)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001185 except OSError as e:
1186 # Test that the child process chdir failure actually makes
1187 # it up to the parent process as the correct exception.
1188 self.assertEqual(desired_exception.errno, e.errno)
1189 self.assertEqual(desired_exception.strerror, e.strerror)
1190 else:
1191 self.fail("Expected OSError: %s" % desired_exception)
1192
Gregory P. Smith5591b022012-10-10 03:34:47 -07001193 def test_exception_bad_executable(self):
1194 """Test error in the child raised in the parent for a bad executable."""
1195 desired_exception = self._get_chdir_exception()
1196 try:
1197 p = subprocess.Popen([sys.executable, "-c", ""],
1198 executable=self._nonexistent_dir)
1199 except OSError as e:
1200 # Test that the child process exec failure actually makes
1201 # it up to the parent process as the correct exception.
1202 self.assertEqual(desired_exception.errno, e.errno)
1203 self.assertEqual(desired_exception.strerror, e.strerror)
1204 else:
1205 self.fail("Expected OSError: %s" % desired_exception)
1206
1207 def test_exception_bad_args_0(self):
1208 """Test error in the child raised in the parent for a bad args[0]."""
1209 desired_exception = self._get_chdir_exception()
1210 try:
1211 p = subprocess.Popen([self._nonexistent_dir, "-c", ""])
1212 except OSError as e:
1213 # Test that the child process exec failure actually makes
1214 # it up to the parent process as the correct exception.
1215 self.assertEqual(desired_exception.errno, e.errno)
1216 self.assertEqual(desired_exception.strerror, e.strerror)
1217 else:
1218 self.fail("Expected OSError: %s" % desired_exception)
1219
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001220 def test_restore_signals(self):
1221 # Code coverage for both values of restore_signals to make sure it
1222 # at least does not blow up.
1223 # A test for behavior would be complex. Contributions welcome.
1224 subprocess.call([sys.executable, "-c", ""], restore_signals=True)
1225 subprocess.call([sys.executable, "-c", ""], restore_signals=False)
1226
1227 def test_start_new_session(self):
1228 # For code coverage of calling setsid(). We don't care if we get an
1229 # EPERM error from it depending on the test execution environment, that
1230 # still indicates that it was called.
1231 try:
1232 output = subprocess.check_output(
1233 [sys.executable, "-c",
1234 "import os; print(os.getpgid(os.getpid()))"],
1235 start_new_session=True)
1236 except OSError as e:
1237 if e.errno != errno.EPERM:
1238 raise
1239 else:
1240 parent_pgid = os.getpgid(os.getpid())
1241 child_pgid = int(output)
1242 self.assertNotEqual(parent_pgid, child_pgid)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001243
1244 def test_run_abort(self):
1245 # returncode handles signal termination
1246 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001247 p = subprocess.Popen([sys.executable, "-c",
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001248 'import os; os.abort()'])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001249 p.wait()
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001250 self.assertEqual(-p.returncode, signal.SIGABRT)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001251
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001252 def test_preexec(self):
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001253 # DISCLAIMER: Setting environment variables is *not* a good use
1254 # of a preexec_fn. This is merely a test.
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001255 p = subprocess.Popen([sys.executable, "-c",
1256 'import sys,os;'
1257 'sys.stdout.write(os.getenv("FRUIT"))'],
1258 stdout=subprocess.PIPE,
1259 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
Brian Curtin3c6a9512010-11-05 03:58:52 +00001260 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001261 self.assertEqual(p.stdout.read(), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001262
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001263 def test_preexec_exception(self):
1264 def raise_it():
1265 raise ValueError("What if two swallows carried a coconut?")
1266 try:
1267 p = subprocess.Popen([sys.executable, "-c", ""],
1268 preexec_fn=raise_it)
1269 except RuntimeError as e:
1270 self.assertTrue(
1271 subprocess._posixsubprocess,
1272 "Expected a ValueError from the preexec_fn")
1273 except ValueError as e:
1274 self.assertIn("coconut", e.args[0])
1275 else:
1276 self.fail("Exception raised by preexec_fn did not make it "
1277 "to the parent process.")
1278
Gregory P. Smithe27faac2012-11-11 09:59:27 -08001279 class _TestExecuteChildPopen(subprocess.Popen):
1280 """Used to test behavior at the end of _execute_child."""
1281 def __init__(self, testcase, *args, **kwargs):
1282 self._testcase = testcase
1283 subprocess.Popen.__init__(self, *args, **kwargs)
Gregory P. Smith12489d92012-11-11 01:37:02 -08001284
Gregory P. Smithe27faac2012-11-11 09:59:27 -08001285 def _execute_child(self, *args, **kwargs):
Gregory P. Smith12489d92012-11-11 01:37:02 -08001286 try:
Gregory P. Smithe27faac2012-11-11 09:59:27 -08001287 subprocess.Popen._execute_child(self, *args, **kwargs)
Gregory P. Smith12489d92012-11-11 01:37:02 -08001288 finally:
1289 # Open a bunch of file descriptors and verify that
1290 # none of them are the same as the ones the Popen
1291 # instance is using for stdin/stdout/stderr.
1292 devzero_fds = [os.open("/dev/zero", os.O_RDONLY)
1293 for _ in range(8)]
1294 try:
1295 for fd in devzero_fds:
Gregory P. Smithe27faac2012-11-11 09:59:27 -08001296 self._testcase.assertNotIn(
1297 fd, (self.stdin.fileno(), self.stdout.fileno(),
1298 self.stderr.fileno()),
Gregory P. Smith12489d92012-11-11 01:37:02 -08001299 msg="At least one fd was closed early.")
1300 finally:
Richard Oudkerk0e547b62013-06-10 16:29:19 +01001301 for fd in devzero_fds:
1302 os.close(fd)
Gregory P. Smith12489d92012-11-11 01:37:02 -08001303
Gregory P. Smithe27faac2012-11-11 09:59:27 -08001304 @unittest.skipIf(not os.path.exists("/dev/zero"), "/dev/zero required.")
1305 def test_preexec_errpipe_does_not_double_close_pipes(self):
1306 """Issue16140: Don't double close pipes on preexec error."""
1307
1308 def raise_it():
1309 raise RuntimeError("force the _execute_child() errpipe_data path.")
Gregory P. Smith12489d92012-11-11 01:37:02 -08001310
1311 with self.assertRaises(RuntimeError):
Gregory P. Smithe27faac2012-11-11 09:59:27 -08001312 self._TestExecuteChildPopen(
1313 self, [sys.executable, "-c", "pass"],
Gregory P. Smith12489d92012-11-11 01:37:02 -08001314 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1315 stderr=subprocess.PIPE, preexec_fn=raise_it)
1316
Gregory P. Smith32ec9da2010-03-19 16:53:08 +00001317 def test_preexec_gc_module_failure(self):
1318 # This tests the code that disables garbage collection if the child
1319 # process will execute any Python.
1320 def raise_runtime_error():
1321 raise RuntimeError("this shouldn't escape")
1322 enabled = gc.isenabled()
1323 orig_gc_disable = gc.disable
1324 orig_gc_isenabled = gc.isenabled
1325 try:
1326 gc.disable()
1327 self.assertFalse(gc.isenabled())
1328 subprocess.call([sys.executable, '-c', ''],
1329 preexec_fn=lambda: None)
1330 self.assertFalse(gc.isenabled(),
1331 "Popen enabled gc when it shouldn't.")
1332
1333 gc.enable()
1334 self.assertTrue(gc.isenabled())
1335 subprocess.call([sys.executable, '-c', ''],
1336 preexec_fn=lambda: None)
1337 self.assertTrue(gc.isenabled(), "Popen left gc disabled.")
1338
1339 gc.disable = raise_runtime_error
1340 self.assertRaises(RuntimeError, subprocess.Popen,
1341 [sys.executable, '-c', ''],
1342 preexec_fn=lambda: None)
1343
1344 del gc.isenabled # force an AttributeError
1345 self.assertRaises(AttributeError, subprocess.Popen,
1346 [sys.executable, '-c', ''],
1347 preexec_fn=lambda: None)
1348 finally:
1349 gc.disable = orig_gc_disable
1350 gc.isenabled = orig_gc_isenabled
1351 if not enabled:
1352 gc.disable()
1353
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001354 def test_args_string(self):
1355 # args is a string
1356 fd, fname = mkstemp()
1357 # reopen in text mode
Victor Stinnerf6782ac2010-10-16 23:46:43 +00001358 with open(fd, "w", errors="surrogateescape") as fobj:
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001359 fobj.write("#!/bin/sh\n")
1360 fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" %
1361 sys.executable)
1362 os.chmod(fname, 0o700)
1363 p = subprocess.Popen(fname)
1364 p.wait()
1365 os.remove(fname)
1366 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001367
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001368 def test_invalid_args(self):
1369 # invalid arguments should raise ValueError
1370 self.assertRaises(ValueError, subprocess.call,
1371 [sys.executable, "-c",
1372 "import sys; sys.exit(47)"],
1373 startupinfo=47)
1374 self.assertRaises(ValueError, subprocess.call,
1375 [sys.executable, "-c",
1376 "import sys; sys.exit(47)"],
1377 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001378
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001379 def test_shell_sequence(self):
1380 # Run command through the shell (sequence)
1381 newenv = os.environ.copy()
1382 newenv["FRUIT"] = "apple"
1383 p = subprocess.Popen(["echo $FRUIT"], shell=1,
1384 stdout=subprocess.PIPE,
1385 env=newenv)
Brian Curtin3c6a9512010-11-05 03:58:52 +00001386 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001387 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001388
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001389 def test_shell_string(self):
1390 # Run command through the shell (string)
1391 newenv = os.environ.copy()
1392 newenv["FRUIT"] = "apple"
1393 p = subprocess.Popen("echo $FRUIT", shell=1,
1394 stdout=subprocess.PIPE,
1395 env=newenv)
Brian Curtin3c6a9512010-11-05 03:58:52 +00001396 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001397 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Christian Heimesa342c012008-04-20 21:01:16 +00001398
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001399 def test_call_string(self):
1400 # call() function with string argument on UNIX
1401 fd, fname = mkstemp()
1402 # reopen in text mode
Victor Stinnerf6782ac2010-10-16 23:46:43 +00001403 with open(fd, "w", errors="surrogateescape") as fobj:
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001404 fobj.write("#!/bin/sh\n")
1405 fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" %
1406 sys.executable)
1407 os.chmod(fname, 0o700)
1408 rc = subprocess.call(fname)
1409 os.remove(fname)
1410 self.assertEqual(rc, 47)
Christian Heimesa342c012008-04-20 21:01:16 +00001411
Stefan Krah9542cc62010-07-19 14:20:53 +00001412 def test_specific_shell(self):
1413 # Issue #9265: Incorrect name passed as arg[0].
1414 shells = []
1415 for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']:
1416 for name in ['bash', 'ksh']:
1417 sh = os.path.join(prefix, name)
1418 if os.path.isfile(sh):
1419 shells.append(sh)
1420 if not shells: # Will probably work for any shell but csh.
1421 self.skipTest("bash or ksh required for this test")
1422 sh = '/bin/sh'
1423 if os.path.isfile(sh) and not os.path.islink(sh):
1424 # Test will fail if /bin/sh is a symlink to csh.
1425 shells.append(sh)
1426 for sh in shells:
1427 p = subprocess.Popen("echo $0", executable=sh, shell=True,
1428 stdout=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +00001429 self.addCleanup(p.stdout.close)
Stefan Krah9542cc62010-07-19 14:20:53 +00001430 self.assertEqual(p.stdout.read().strip(), bytes(sh, 'ascii'))
1431
Florent Xicluna4886d242010-03-08 13:27:26 +00001432 def _kill_process(self, method, *args):
Florent Xicluna1d8ee3a2010-03-05 20:26:54 +00001433 # Do not inherit file handles from the parent.
1434 # It should fix failures on some platforms.
Gregory P. Smithdee04342013-08-29 13:35:27 -07001435 # Also set the SIGINT handler to the default to make sure it's not
1436 # being ignored (some tests rely on that.)
1437 old_handler = signal.signal(signal.SIGINT, signal.default_int_handler)
1438 try:
1439 p = subprocess.Popen([sys.executable, "-c", """if 1:
1440 import sys, time
1441 sys.stdout.write('x\\n')
1442 sys.stdout.flush()
1443 time.sleep(30)
1444 """],
1445 close_fds=True,
1446 stdin=subprocess.PIPE,
1447 stdout=subprocess.PIPE,
1448 stderr=subprocess.PIPE)
1449 finally:
1450 signal.signal(signal.SIGINT, old_handler)
Antoine Pitrou3d8580f2010-09-20 01:33:21 +00001451 # Wait for the interpreter to be completely initialized before
1452 # sending any signal.
1453 p.stdout.read(1)
1454 getattr(p, method)(*args)
Florent Xicluna4886d242010-03-08 13:27:26 +00001455 return p
1456
Charles-François Natali53221e32013-01-12 16:52:20 +01001457 @unittest.skipIf(sys.platform.startswith(('netbsd', 'openbsd')),
1458 "Due to known OS bug (issue #16762)")
Antoine Pitrou1f9a8352012-03-11 19:29:12 +01001459 def _kill_dead_process(self, method, *args):
1460 # Do not inherit file handles from the parent.
1461 # It should fix failures on some platforms.
1462 p = subprocess.Popen([sys.executable, "-c", """if 1:
1463 import sys, time
1464 sys.stdout.write('x\\n')
1465 sys.stdout.flush()
1466 """],
1467 close_fds=True,
1468 stdin=subprocess.PIPE,
1469 stdout=subprocess.PIPE,
1470 stderr=subprocess.PIPE)
1471 # Wait for the interpreter to be completely initialized before
1472 # sending any signal.
1473 p.stdout.read(1)
1474 # The process should end after this
1475 time.sleep(1)
1476 # This shouldn't raise even though the child is now dead
1477 getattr(p, method)(*args)
1478 p.communicate()
1479
Florent Xicluna4886d242010-03-08 13:27:26 +00001480 def test_send_signal(self):
1481 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunac049d872010-03-27 22:47:23 +00001482 _, stderr = p.communicate()
1483 self.assertIn(b'KeyboardInterrupt', stderr)
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001484 self.assertNotEqual(p.wait(), 0)
Christian Heimesa342c012008-04-20 21:01:16 +00001485
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001486 def test_kill(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00001487 p = self._kill_process('kill')
Florent Xiclunac049d872010-03-27 22:47:23 +00001488 _, stderr = p.communicate()
1489 self.assertStderrEqual(stderr, b'')
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001490 self.assertEqual(p.wait(), -signal.SIGKILL)
Tim Peterse718f612004-10-12 21:51:32 +00001491
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001492 def test_terminate(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00001493 p = self._kill_process('terminate')
Florent Xiclunac049d872010-03-27 22:47:23 +00001494 _, stderr = p.communicate()
1495 self.assertStderrEqual(stderr, b'')
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001496 self.assertEqual(p.wait(), -signal.SIGTERM)
1497
Antoine Pitrou1f9a8352012-03-11 19:29:12 +01001498 def test_send_signal_dead(self):
1499 # Sending a signal to a dead process
1500 self._kill_dead_process('send_signal', signal.SIGINT)
1501
1502 def test_kill_dead(self):
1503 # Killing a dead process
1504 self._kill_dead_process('kill')
1505
1506 def test_terminate_dead(self):
1507 # Terminating a dead process
1508 self._kill_dead_process('terminate')
1509
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +00001510 def check_close_std_fds(self, fds):
1511 # Issue #9905: test that subprocess pipes still work properly with
1512 # some standard fds closed
1513 stdin = 0
1514 newfds = []
1515 for a in fds:
1516 b = os.dup(a)
1517 newfds.append(b)
1518 if a == 0:
1519 stdin = b
1520 try:
1521 for fd in fds:
1522 os.close(fd)
1523 out, err = subprocess.Popen([sys.executable, "-c",
1524 'import sys;'
1525 'sys.stdout.write("apple");'
1526 'sys.stdout.flush();'
1527 'sys.stderr.write("orange")'],
1528 stdin=stdin,
1529 stdout=subprocess.PIPE,
1530 stderr=subprocess.PIPE).communicate()
1531 err = support.strip_python_stderr(err)
1532 self.assertEqual((out, err), (b'apple', b'orange'))
1533 finally:
1534 for b, a in zip(newfds, fds):
1535 os.dup2(b, a)
1536 for b in newfds:
1537 os.close(b)
1538
1539 def test_close_fd_0(self):
1540 self.check_close_std_fds([0])
1541
1542 def test_close_fd_1(self):
1543 self.check_close_std_fds([1])
1544
1545 def test_close_fd_2(self):
1546 self.check_close_std_fds([2])
1547
1548 def test_close_fds_0_1(self):
1549 self.check_close_std_fds([0, 1])
1550
1551 def test_close_fds_0_2(self):
1552 self.check_close_std_fds([0, 2])
1553
1554 def test_close_fds_1_2(self):
1555 self.check_close_std_fds([1, 2])
1556
1557 def test_close_fds_0_1_2(self):
1558 # Issue #10806: test that subprocess pipes still work properly with
1559 # all standard fds closed.
1560 self.check_close_std_fds([0, 1, 2])
1561
Antoine Pitrou95aaeee2011-01-03 21:15:48 +00001562 def test_remapping_std_fds(self):
1563 # open up some temporary files
1564 temps = [mkstemp() for i in range(3)]
1565 try:
1566 temp_fds = [fd for fd, fname in temps]
1567
1568 # unlink the files -- we won't need to reopen them
1569 for fd, fname in temps:
1570 os.unlink(fname)
1571
1572 # write some data to what will become stdin, and rewind
1573 os.write(temp_fds[1], b"STDIN")
1574 os.lseek(temp_fds[1], 0, 0)
1575
1576 # move the standard file descriptors out of the way
1577 saved_fds = [os.dup(fd) for fd in range(3)]
1578 try:
1579 # duplicate the file objects over the standard fd's
1580 for fd, temp_fd in enumerate(temp_fds):
1581 os.dup2(temp_fd, fd)
1582
1583 # now use those files in the "wrong" order, so that subprocess
1584 # has to rearrange them in the child
1585 p = subprocess.Popen([sys.executable, "-c",
1586 'import sys; got = sys.stdin.read();'
1587 'sys.stdout.write("got %s"%got); sys.stderr.write("err")'],
1588 stdin=temp_fds[1],
1589 stdout=temp_fds[2],
1590 stderr=temp_fds[0])
1591 p.wait()
1592 finally:
1593 # restore the original fd's underneath sys.stdin, etc.
1594 for std, saved in enumerate(saved_fds):
1595 os.dup2(saved, std)
1596 os.close(saved)
1597
1598 for fd in temp_fds:
1599 os.lseek(fd, 0, 0)
1600
1601 out = os.read(temp_fds[2], 1024)
1602 err = support.strip_python_stderr(os.read(temp_fds[0], 1024))
1603 self.assertEqual(out, b"got STDIN")
1604 self.assertEqual(err, b"err")
1605
1606 finally:
1607 for fd in temp_fds:
1608 os.close(fd)
1609
Ross Lagerwalld98646e2011-07-27 07:16:31 +02001610 def check_swap_fds(self, stdin_no, stdout_no, stderr_no):
1611 # open up some temporary files
1612 temps = [mkstemp() for i in range(3)]
1613 temp_fds = [fd for fd, fname in temps]
1614 try:
1615 # unlink the files -- we won't need to reopen them
1616 for fd, fname in temps:
1617 os.unlink(fname)
1618
1619 # save a copy of the standard file descriptors
1620 saved_fds = [os.dup(fd) for fd in range(3)]
1621 try:
1622 # duplicate the temp files over the standard fd's 0, 1, 2
1623 for fd, temp_fd in enumerate(temp_fds):
1624 os.dup2(temp_fd, fd)
1625
1626 # write some data to what will become stdin, and rewind
1627 os.write(stdin_no, b"STDIN")
1628 os.lseek(stdin_no, 0, 0)
1629
1630 # now use those files in the given order, so that subprocess
1631 # has to rearrange them in the child
1632 p = subprocess.Popen([sys.executable, "-c",
1633 'import sys; got = sys.stdin.read();'
1634 'sys.stdout.write("got %s"%got); sys.stderr.write("err")'],
1635 stdin=stdin_no,
1636 stdout=stdout_no,
1637 stderr=stderr_no)
1638 p.wait()
1639
1640 for fd in temp_fds:
1641 os.lseek(fd, 0, 0)
1642
1643 out = os.read(stdout_no, 1024)
1644 err = support.strip_python_stderr(os.read(stderr_no, 1024))
1645 finally:
1646 for std, saved in enumerate(saved_fds):
1647 os.dup2(saved, std)
1648 os.close(saved)
1649
1650 self.assertEqual(out, b"got STDIN")
1651 self.assertEqual(err, b"err")
1652
1653 finally:
1654 for fd in temp_fds:
1655 os.close(fd)
1656
1657 # When duping fds, if there arises a situation where one of the fds is
1658 # either 0, 1 or 2, it is possible that it is overwritten (#12607).
1659 # This tests all combinations of this.
1660 def test_swap_fds(self):
1661 self.check_swap_fds(0, 1, 2)
1662 self.check_swap_fds(0, 2, 1)
1663 self.check_swap_fds(1, 0, 2)
1664 self.check_swap_fds(1, 2, 0)
1665 self.check_swap_fds(2, 0, 1)
1666 self.check_swap_fds(2, 1, 0)
1667
Victor Stinner13bb71c2010-04-23 21:41:56 +00001668 def test_surrogates_error_message(self):
Victor Stinner4d078042010-04-23 19:28:32 +00001669 def prepare():
1670 raise ValueError("surrogate:\uDCff")
1671
1672 try:
1673 subprocess.call(
1674 [sys.executable, "-c", "pass"],
1675 preexec_fn=prepare)
1676 except ValueError as err:
1677 # Pure Python implementations keeps the message
1678 self.assertIsNone(subprocess._posixsubprocess)
1679 self.assertEqual(str(err), "surrogate:\uDCff")
1680 except RuntimeError as err:
1681 # _posixsubprocess uses a default message
1682 self.assertIsNotNone(subprocess._posixsubprocess)
1683 self.assertEqual(str(err), "Exception occurred in preexec_fn.")
1684 else:
1685 self.fail("Expected ValueError or RuntimeError")
1686
Victor Stinner13bb71c2010-04-23 21:41:56 +00001687 def test_undecodable_env(self):
1688 for key, value in (('test', 'abc\uDCFF'), ('test\uDCFF', '42')):
Victor Stinner13bb71c2010-04-23 21:41:56 +00001689 # test str with surrogates
Antoine Pitroufb8db8f2010-09-19 22:46:05 +00001690 script = "import os; print(ascii(os.getenv(%s)))" % repr(key)
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001691 env = os.environ.copy()
1692 env[key] = value
Victor Stinner89f3ad12010-10-14 10:43:31 +00001693 # Use C locale to get ascii for the locale encoding to force
1694 # surrogate-escaping of \xFF in the child process; otherwise it can
1695 # be decoded as-is if the default locale is latin-1.
Victor Stinnerebc78d22010-10-14 10:38:17 +00001696 env['LC_ALL'] = 'C'
Victor Stinner13bb71c2010-04-23 21:41:56 +00001697 stdout = subprocess.check_output(
1698 [sys.executable, "-c", script],
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001699 env=env)
Victor Stinner13bb71c2010-04-23 21:41:56 +00001700 stdout = stdout.rstrip(b'\n\r')
Ezio Melottib3aedd42010-11-20 19:04:17 +00001701 self.assertEqual(stdout.decode('ascii'), ascii(value))
Victor Stinner13bb71c2010-04-23 21:41:56 +00001702
1703 # test bytes
1704 key = key.encode("ascii", "surrogateescape")
1705 value = value.encode("ascii", "surrogateescape")
Antoine Pitroufb8db8f2010-09-19 22:46:05 +00001706 script = "import os; print(ascii(os.getenvb(%s)))" % repr(key)
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001707 env = os.environ.copy()
1708 env[key] = value
Victor Stinner13bb71c2010-04-23 21:41:56 +00001709 stdout = subprocess.check_output(
1710 [sys.executable, "-c", script],
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001711 env=env)
Victor Stinner13bb71c2010-04-23 21:41:56 +00001712 stdout = stdout.rstrip(b'\n\r')
Ezio Melottib3aedd42010-11-20 19:04:17 +00001713 self.assertEqual(stdout.decode('ascii'), ascii(value))
Victor Stinner13bb71c2010-04-23 21:41:56 +00001714
Victor Stinnerb745a742010-05-18 17:17:23 +00001715 def test_bytes_program(self):
1716 abs_program = os.fsencode(sys.executable)
1717 path, program = os.path.split(sys.executable)
1718 program = os.fsencode(program)
1719
1720 # absolute bytes path
1721 exitcode = subprocess.call([abs_program, "-c", "pass"])
Ezio Melottib3aedd42010-11-20 19:04:17 +00001722 self.assertEqual(exitcode, 0)
Victor Stinnerb745a742010-05-18 17:17:23 +00001723
Victor Stinner7b3b20a2011-03-03 12:54:05 +00001724 # absolute bytes path as a string
1725 cmd = b"'" + abs_program + b"' -c pass"
1726 exitcode = subprocess.call(cmd, shell=True)
1727 self.assertEqual(exitcode, 0)
1728
Victor Stinnerb745a742010-05-18 17:17:23 +00001729 # bytes program, unicode PATH
1730 env = os.environ.copy()
1731 env["PATH"] = path
1732 exitcode = subprocess.call([program, "-c", "pass"], env=env)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001733 self.assertEqual(exitcode, 0)
Victor Stinnerb745a742010-05-18 17:17:23 +00001734
1735 # bytes program, bytes PATH
1736 envb = os.environb.copy()
1737 envb[b"PATH"] = os.fsencode(path)
1738 exitcode = subprocess.call([program, "-c", "pass"], env=envb)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001739 self.assertEqual(exitcode, 0)
Victor Stinnerb745a742010-05-18 17:17:23 +00001740
Gregory P. Smith51ee2702010-12-13 07:59:39 +00001741 def test_pipe_cloexec(self):
1742 sleeper = support.findfile("input_reader.py", subdir="subprocessdata")
1743 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1744
1745 p1 = subprocess.Popen([sys.executable, sleeper],
1746 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1747 stderr=subprocess.PIPE, close_fds=False)
1748
1749 self.addCleanup(p1.communicate, b'')
1750
1751 p2 = subprocess.Popen([sys.executable, fd_status],
1752 stdout=subprocess.PIPE, close_fds=False)
1753
1754 output, error = p2.communicate()
1755 result_fds = set(map(int, output.split(b',')))
1756 unwanted_fds = set([p1.stdin.fileno(), p1.stdout.fileno(),
1757 p1.stderr.fileno()])
1758
1759 self.assertFalse(result_fds & unwanted_fds,
1760 "Expected no fds from %r to be open in child, "
1761 "found %r" %
1762 (unwanted_fds, result_fds & unwanted_fds))
1763
1764 def test_pipe_cloexec_real_tools(self):
1765 qcat = support.findfile("qcat.py", subdir="subprocessdata")
1766 qgrep = support.findfile("qgrep.py", subdir="subprocessdata")
1767
1768 subdata = b'zxcvbn'
1769 data = subdata * 4 + b'\n'
1770
1771 p1 = subprocess.Popen([sys.executable, qcat],
1772 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1773 close_fds=False)
1774
1775 p2 = subprocess.Popen([sys.executable, qgrep, subdata],
1776 stdin=p1.stdout, stdout=subprocess.PIPE,
1777 close_fds=False)
1778
1779 self.addCleanup(p1.wait)
1780 self.addCleanup(p2.wait)
Gregory P. Smith886455c2012-01-21 22:05:10 -08001781 def kill_p1():
1782 try:
1783 p1.terminate()
1784 except ProcessLookupError:
1785 pass
1786 def kill_p2():
1787 try:
1788 p2.terminate()
1789 except ProcessLookupError:
1790 pass
1791 self.addCleanup(kill_p1)
1792 self.addCleanup(kill_p2)
Gregory P. Smith51ee2702010-12-13 07:59:39 +00001793
1794 p1.stdin.write(data)
1795 p1.stdin.close()
1796
1797 readfiles, ignored1, ignored2 = select.select([p2.stdout], [], [], 10)
1798
1799 self.assertTrue(readfiles, "The child hung")
1800 self.assertEqual(p2.stdout.read(), data)
1801
Victor Stinnerfaa8c132011-01-03 16:36:00 +00001802 p1.stdout.close()
1803 p2.stdout.close()
1804
Gregory P. Smith51ee2702010-12-13 07:59:39 +00001805 def test_close_fds(self):
1806 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1807
1808 fds = os.pipe()
1809 self.addCleanup(os.close, fds[0])
1810 self.addCleanup(os.close, fds[1])
1811
1812 open_fds = set(fds)
Gregory P. Smith8facece2012-01-21 14:01:08 -08001813 # add a bunch more fds
1814 for _ in range(9):
1815 fd = os.open("/dev/null", os.O_RDONLY)
1816 self.addCleanup(os.close, fd)
1817 open_fds.add(fd)
Gregory P. Smith51ee2702010-12-13 07:59:39 +00001818
1819 p = subprocess.Popen([sys.executable, fd_status],
1820 stdout=subprocess.PIPE, close_fds=False)
1821 output, ignored = p.communicate()
1822 remaining_fds = set(map(int, output.split(b',')))
1823
1824 self.assertEqual(remaining_fds & open_fds, open_fds,
1825 "Some fds were closed")
1826
1827 p = subprocess.Popen([sys.executable, fd_status],
1828 stdout=subprocess.PIPE, close_fds=True)
1829 output, ignored = p.communicate()
1830 remaining_fds = set(map(int, output.split(b',')))
1831
1832 self.assertFalse(remaining_fds & open_fds,
1833 "Some fds were left open")
1834 self.assertIn(1, remaining_fds, "Subprocess failed")
1835
Gregory P. Smith8facece2012-01-21 14:01:08 -08001836 # Keep some of the fd's we opened open in the subprocess.
1837 # This tests _posixsubprocess.c's proper handling of fds_to_keep.
1838 fds_to_keep = set(open_fds.pop() for _ in range(8))
1839 p = subprocess.Popen([sys.executable, fd_status],
1840 stdout=subprocess.PIPE, close_fds=True,
1841 pass_fds=())
1842 output, ignored = p.communicate()
1843 remaining_fds = set(map(int, output.split(b',')))
1844
1845 self.assertFalse(remaining_fds & fds_to_keep & open_fds,
1846 "Some fds not in pass_fds were left open")
1847 self.assertIn(1, remaining_fds, "Subprocess failed")
1848
Victor Stinner88701e22011-06-01 13:13:04 +02001849 # Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file
1850 # descriptor of a pipe closed in the parent process is valid in the
1851 # child process according to fstat(), but the mode of the file
1852 # descriptor is invalid, and read or write raise an error.
1853 @support.requires_mac_ver(10, 5)
Gregory P. Smith8edd99d2010-12-14 13:43:30 +00001854 def test_pass_fds(self):
1855 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1856
1857 open_fds = set()
1858
1859 for x in range(5):
1860 fds = os.pipe()
1861 self.addCleanup(os.close, fds[0])
1862 self.addCleanup(os.close, fds[1])
1863 open_fds.update(fds)
1864
1865 for fd in open_fds:
1866 p = subprocess.Popen([sys.executable, fd_status],
1867 stdout=subprocess.PIPE, close_fds=True,
1868 pass_fds=(fd, ))
1869 output, ignored = p.communicate()
1870
1871 remaining_fds = set(map(int, output.split(b',')))
1872 to_be_closed = open_fds - {fd}
1873
1874 self.assertIn(fd, remaining_fds, "fd to be passed not passed")
1875 self.assertFalse(remaining_fds & to_be_closed,
1876 "fd to be closed passed")
1877
1878 # pass_fds overrides close_fds with a warning.
1879 with self.assertWarns(RuntimeWarning) as context:
1880 self.assertFalse(subprocess.call(
1881 [sys.executable, "-c", "import sys; sys.exit(0)"],
1882 close_fds=False, pass_fds=(fd, )))
1883 self.assertIn('overriding close_fds', str(context.warning))
1884
Gregory P. Smith112bb3a2011-03-15 14:55:17 -04001885 def test_stdout_stdin_are_single_inout_fd(self):
1886 with io.open(os.devnull, "r+") as inout:
1887 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
1888 stdout=inout, stdin=inout)
1889 p.wait()
1890
1891 def test_stdout_stderr_are_single_inout_fd(self):
1892 with io.open(os.devnull, "r+") as inout:
1893 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
1894 stdout=inout, stderr=inout)
1895 p.wait()
1896
1897 def test_stderr_stdin_are_single_inout_fd(self):
1898 with io.open(os.devnull, "r+") as inout:
1899 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
1900 stderr=inout, stdin=inout)
1901 p.wait()
1902
Gregory P. Smithe85db2b2010-12-14 14:38:00 +00001903 def test_wait_when_sigchild_ignored(self):
1904 # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
1905 sigchild_ignore = support.findfile("sigchild_ignore.py",
1906 subdir="subprocessdata")
1907 p = subprocess.Popen([sys.executable, sigchild_ignore],
1908 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1909 stdout, stderr = p.communicate()
1910 self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
Gregory P. Smitha80f4fb2010-12-14 15:23:02 +00001911 " non-zero with this error:\n%s" %
Marc-André Lemburg8f36af72011-02-25 15:42:01 +00001912 stderr.decode('utf-8'))
Gregory P. Smithe85db2b2010-12-14 14:38:00 +00001913
Antoine Pitrou7b98d022011-03-19 17:04:13 +01001914 def test_select_unbuffered(self):
1915 # Issue #11459: bufsize=0 should really set the pipes as
1916 # unbuffered (and therefore let select() work properly).
1917 select = support.import_module("select")
1918 p = subprocess.Popen([sys.executable, "-c",
1919 'import sys;'
1920 'sys.stdout.write("apple")'],
1921 stdout=subprocess.PIPE,
1922 bufsize=0)
1923 f = p.stdout
Ross Lagerwall17ace7a2011-03-26 21:21:46 +02001924 self.addCleanup(f.close)
Antoine Pitrou7b98d022011-03-19 17:04:13 +01001925 try:
1926 self.assertEqual(f.read(4), b"appl")
1927 self.assertIn(f, select.select([f], [], [], 0.0)[0])
1928 finally:
1929 p.wait()
1930
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001931 def test_zombie_fast_process_del(self):
1932 # Issue #12650: on Unix, if Popen.__del__() was called before the
1933 # process exited, it wouldn't be added to subprocess._active, and would
1934 # remain a zombie.
1935 # spawn a Popen, and delete its reference before it exits
1936 p = subprocess.Popen([sys.executable, "-c",
1937 'import sys, time;'
1938 'time.sleep(0.2)'],
1939 stdout=subprocess.PIPE,
1940 stderr=subprocess.PIPE)
Nadeem Vawda0d7cda32011-08-19 05:12:01 +02001941 self.addCleanup(p.stdout.close)
1942 self.addCleanup(p.stderr.close)
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001943 ident = id(p)
1944 pid = p.pid
1945 del p
1946 # check that p is in the active processes list
1947 self.assertIn(ident, [id(o) for o in subprocess._active])
1948
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001949 def test_leak_fast_process_del_killed(self):
1950 # Issue #12650: on Unix, if Popen.__del__() was called before the
1951 # process exited, and the process got killed by a signal, it would never
1952 # be removed from subprocess._active, which triggered a FD and memory
1953 # leak.
1954 # spawn a Popen, delete its reference and kill it
1955 p = subprocess.Popen([sys.executable, "-c",
1956 'import time;'
1957 'time.sleep(3)'],
1958 stdout=subprocess.PIPE,
1959 stderr=subprocess.PIPE)
Nadeem Vawda0d7cda32011-08-19 05:12:01 +02001960 self.addCleanup(p.stdout.close)
1961 self.addCleanup(p.stderr.close)
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001962 ident = id(p)
1963 pid = p.pid
1964 del p
1965 os.kill(pid, signal.SIGKILL)
1966 # check that p is in the active processes list
1967 self.assertIn(ident, [id(o) for o in subprocess._active])
1968
1969 # let some time for the process to exit, and create a new Popen: this
1970 # should trigger the wait() of p
1971 time.sleep(0.2)
1972 with self.assertRaises(EnvironmentError) as c:
1973 with subprocess.Popen(['nonexisting_i_hope'],
1974 stdout=subprocess.PIPE,
1975 stderr=subprocess.PIPE) as proc:
1976 pass
1977 # p should have been wait()ed on, and removed from the _active list
1978 self.assertRaises(OSError, os.waitpid, pid, 0)
1979 self.assertNotIn(ident, [id(o) for o in subprocess._active])
1980
Charles-François Natali249cdc32013-08-25 18:24:45 +02001981 def test_close_fds_after_preexec(self):
1982 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1983
1984 # this FD is used as dup2() target by preexec_fn, and should be closed
1985 # in the child process
1986 fd = os.dup(1)
1987 self.addCleanup(os.close, fd)
1988
1989 p = subprocess.Popen([sys.executable, fd_status],
1990 stdout=subprocess.PIPE, close_fds=True,
1991 preexec_fn=lambda: os.dup2(1, fd))
1992 output, ignored = p.communicate()
1993
1994 remaining_fds = set(map(int, output.split(b',')))
1995
1996 self.assertNotIn(fd, remaining_fds)
1997
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001998
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001999@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunac049d872010-03-27 22:47:23 +00002000class Win32ProcessTestCase(BaseTestCase):
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00002001
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002002 def test_startupinfo(self):
2003 # startupinfo argument
2004 # We uses hardcoded constants, because we do not want to
2005 # depend on win32all.
2006 STARTF_USESHOWWINDOW = 1
2007 SW_MAXIMIZE = 3
2008 startupinfo = subprocess.STARTUPINFO()
2009 startupinfo.dwFlags = STARTF_USESHOWWINDOW
2010 startupinfo.wShowWindow = SW_MAXIMIZE
2011 # Since Python is a console process, it won't be affected
2012 # by wShowWindow, but the argument should be silently
2013 # ignored
2014 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002015 startupinfo=startupinfo)
2016
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002017 def test_creationflags(self):
2018 # creationflags argument
2019 CREATE_NEW_CONSOLE = 16
2020 sys.stderr.write(" a DOS box should flash briefly ...\n")
2021 subprocess.call(sys.executable +
2022 ' -c "import time; time.sleep(0.25)"',
2023 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002024
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002025 def test_invalid_args(self):
2026 # invalid arguments should raise ValueError
2027 self.assertRaises(ValueError, subprocess.call,
2028 [sys.executable, "-c",
2029 "import sys; sys.exit(47)"],
2030 preexec_fn=lambda: 1)
2031 self.assertRaises(ValueError, subprocess.call,
2032 [sys.executable, "-c",
2033 "import sys; sys.exit(47)"],
2034 stdout=subprocess.PIPE,
2035 close_fds=True)
2036
2037 def test_close_fds(self):
2038 # close file descriptors
2039 rc = subprocess.call([sys.executable, "-c",
2040 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002041 close_fds=True)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002042 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002043
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002044 def test_shell_sequence(self):
2045 # Run command through the shell (sequence)
2046 newenv = os.environ.copy()
2047 newenv["FRUIT"] = "physalis"
2048 p = subprocess.Popen(["set"], shell=1,
2049 stdout=subprocess.PIPE,
2050 env=newenv)
Brian Curtin19a53792010-11-05 17:09:05 +00002051 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002052 self.assertIn(b"physalis", p.stdout.read())
Guido van Rossume7ba4952007-06-06 23:52:48 +00002053
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002054 def test_shell_string(self):
2055 # Run command through the shell (string)
2056 newenv = os.environ.copy()
2057 newenv["FRUIT"] = "physalis"
2058 p = subprocess.Popen("set", shell=1,
2059 stdout=subprocess.PIPE,
2060 env=newenv)
Brian Curtin19a53792010-11-05 17:09:05 +00002061 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002062 self.assertIn(b"physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002063
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002064 def test_call_string(self):
2065 # call() function with string argument on Windows
2066 rc = subprocess.call(sys.executable +
2067 ' -c "import sys; sys.exit(47)"')
2068 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002069
Florent Xicluna4886d242010-03-08 13:27:26 +00002070 def _kill_process(self, method, *args):
2071 # Some win32 buildbot raises EOFError if stdin is inherited
Antoine Pitroua4024e22010-09-24 18:57:01 +00002072 p = subprocess.Popen([sys.executable, "-c", """if 1:
2073 import sys, time
2074 sys.stdout.write('x\\n')
2075 sys.stdout.flush()
2076 time.sleep(30)
2077 """],
2078 stdin=subprocess.PIPE,
2079 stdout=subprocess.PIPE,
2080 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +00002081 self.addCleanup(p.stdout.close)
2082 self.addCleanup(p.stderr.close)
2083 self.addCleanup(p.stdin.close)
Antoine Pitroua4024e22010-09-24 18:57:01 +00002084 # Wait for the interpreter to be completely initialized before
2085 # sending any signal.
2086 p.stdout.read(1)
2087 getattr(p, method)(*args)
Florent Xiclunac049d872010-03-27 22:47:23 +00002088 _, stderr = p.communicate()
2089 self.assertStderrEqual(stderr, b'')
Antoine Pitroua4024e22010-09-24 18:57:01 +00002090 returncode = p.wait()
Florent Xicluna4886d242010-03-08 13:27:26 +00002091 self.assertNotEqual(returncode, 0)
2092
Antoine Pitrou1f9a8352012-03-11 19:29:12 +01002093 def _kill_dead_process(self, method, *args):
2094 p = subprocess.Popen([sys.executable, "-c", """if 1:
2095 import sys, time
2096 sys.stdout.write('x\\n')
2097 sys.stdout.flush()
2098 sys.exit(42)
2099 """],
2100 stdin=subprocess.PIPE,
2101 stdout=subprocess.PIPE,
2102 stderr=subprocess.PIPE)
2103 self.addCleanup(p.stdout.close)
2104 self.addCleanup(p.stderr.close)
2105 self.addCleanup(p.stdin.close)
2106 # Wait for the interpreter to be completely initialized before
2107 # sending any signal.
2108 p.stdout.read(1)
2109 # The process should end after this
2110 time.sleep(1)
2111 # This shouldn't raise even though the child is now dead
2112 getattr(p, method)(*args)
2113 _, stderr = p.communicate()
2114 self.assertStderrEqual(stderr, b'')
2115 rc = p.wait()
2116 self.assertEqual(rc, 42)
2117
Florent Xicluna4886d242010-03-08 13:27:26 +00002118 def test_send_signal(self):
2119 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimesa342c012008-04-20 21:01:16 +00002120
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002121 def test_kill(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00002122 self._kill_process('kill')
Christian Heimesa342c012008-04-20 21:01:16 +00002123
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002124 def test_terminate(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00002125 self._kill_process('terminate')
Christian Heimesa342c012008-04-20 21:01:16 +00002126
Antoine Pitrou1f9a8352012-03-11 19:29:12 +01002127 def test_send_signal_dead(self):
2128 self._kill_dead_process('send_signal', signal.SIGTERM)
2129
2130 def test_kill_dead(self):
2131 self._kill_dead_process('kill')
2132
2133 def test_terminate_dead(self):
2134 self._kill_dead_process('terminate')
2135
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002136
Brett Cannona23810f2008-05-26 19:04:21 +00002137# The module says:
2138# "NB This only works (and is only relevant) for UNIX."
2139#
2140# Actually, getoutput should work on any platform with an os.popen, but
2141# I'll take the comment as given, and skip this suite.
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00002142@unittest.skipUnless(os.name == 'posix', "only relevant for UNIX")
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002143class CommandTests(unittest.TestCase):
2144 def test_getoutput(self):
2145 self.assertEqual(subprocess.getoutput('echo xyzzy'), 'xyzzy')
2146 self.assertEqual(subprocess.getstatusoutput('echo xyzzy'),
2147 (0, 'xyzzy'))
Brett Cannona23810f2008-05-26 19:04:21 +00002148
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002149 # we use mkdtemp in the next line to create an empty directory
2150 # under our exclusive control; from that, we can invent a pathname
2151 # that we _know_ won't exist. This is guaranteed to fail.
2152 dir = None
2153 try:
2154 dir = tempfile.mkdtemp()
2155 name = os.path.join(dir, "foo")
Brett Cannona23810f2008-05-26 19:04:21 +00002156
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002157 status, output = subprocess.getstatusoutput('cat ' + name)
2158 self.assertNotEqual(status, 0)
2159 finally:
2160 if dir is not None:
2161 os.rmdir(dir)
Brett Cannona23810f2008-05-26 19:04:21 +00002162
Gregory P. Smithd06fa472009-07-04 02:46:54 +00002163
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002164@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
2165 "poll system call not supported")
2166class ProcessTestCaseNoPoll(ProcessTestCase):
2167 def setUp(self):
2168 subprocess._has_poll = False
2169 ProcessTestCase.setUp(self)
Gregory P. Smithd06fa472009-07-04 02:46:54 +00002170
Florent Xiclunab1e94e82010-02-27 22:12:37 +00002171 def tearDown(self):
2172 subprocess._has_poll = True
2173 ProcessTestCase.tearDown(self)
Gregory P. Smithd06fa472009-07-04 02:46:54 +00002174
2175
Gregory P. Smitha59c59f2010-03-01 00:17:40 +00002176class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithaf6d3b82010-03-01 02:56:44 +00002177 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smitha59c59f2010-03-01 00:17:40 +00002178 def test_eintr_retry_call(self):
2179 record_calls = []
2180 def fake_os_func(*args):
2181 record_calls.append(args)
2182 if len(record_calls) == 2:
2183 raise OSError(errno.EINTR, "fake interrupted system call")
2184 return tuple(reversed(args))
2185
2186 self.assertEqual((999, 256),
2187 subprocess._eintr_retry_call(fake_os_func, 256, 999))
2188 self.assertEqual([(256, 999)], record_calls)
2189 # This time there will be an EINTR so it will loop once.
2190 self.assertEqual((666,),
2191 subprocess._eintr_retry_call(fake_os_func, 666))
2192 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
2193
2194
Tim Golden126c2962010-08-11 14:20:40 +00002195@unittest.skipUnless(mswindows, "Windows-specific tests")
2196class CommandsWithSpaces (BaseTestCase):
2197
2198 def setUp(self):
2199 super().setUp()
2200 f, fname = mkstemp(".py", "te st")
2201 self.fname = fname.lower ()
2202 os.write(f, b"import sys;"
2203 b"sys.stdout.write('%d %s' % (len(sys.argv), [a.lower () for a in sys.argv]))"
2204 )
2205 os.close(f)
2206
2207 def tearDown(self):
2208 os.remove(self.fname)
2209 super().tearDown()
2210
2211 def with_spaces(self, *args, **kwargs):
2212 kwargs['stdout'] = subprocess.PIPE
2213 p = subprocess.Popen(*args, **kwargs)
Brian Curtin19a53792010-11-05 17:09:05 +00002214 self.addCleanup(p.stdout.close)
Tim Golden126c2962010-08-11 14:20:40 +00002215 self.assertEqual(
2216 p.stdout.read ().decode("mbcs"),
2217 "2 [%r, 'ab cd']" % self.fname
2218 )
2219
2220 def test_shell_string_with_spaces(self):
2221 # call() function with string argument with spaces on Windows
Brian Curtind835cf12010-08-13 20:42:57 +00002222 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
2223 "ab cd"), shell=1)
Tim Golden126c2962010-08-11 14:20:40 +00002224
2225 def test_shell_sequence_with_spaces(self):
2226 # call() function with sequence argument with spaces on Windows
Brian Curtind835cf12010-08-13 20:42:57 +00002227 self.with_spaces([sys.executable, self.fname, "ab cd"], shell=1)
Tim Golden126c2962010-08-11 14:20:40 +00002228
2229 def test_noshell_string_with_spaces(self):
2230 # call() function with string argument with spaces on Windows
2231 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
2232 "ab cd"))
2233
2234 def test_noshell_sequence_with_spaces(self):
2235 # call() function with sequence argument with spaces on Windows
2236 self.with_spaces([sys.executable, self.fname, "ab cd"])
2237
Brian Curtin79cdb662010-12-03 02:46:02 +00002238
Georg Brandla86b2622012-02-20 21:34:57 +01002239class ContextManagerTests(BaseTestCase):
Brian Curtin79cdb662010-12-03 02:46:02 +00002240
2241 def test_pipe(self):
2242 with subprocess.Popen([sys.executable, "-c",
2243 "import sys;"
2244 "sys.stdout.write('stdout');"
2245 "sys.stderr.write('stderr');"],
2246 stdout=subprocess.PIPE,
2247 stderr=subprocess.PIPE) as proc:
2248 self.assertEqual(proc.stdout.read(), b"stdout")
2249 self.assertStderrEqual(proc.stderr.read(), b"stderr")
2250
2251 self.assertTrue(proc.stdout.closed)
2252 self.assertTrue(proc.stderr.closed)
2253
2254 def test_returncode(self):
2255 with subprocess.Popen([sys.executable, "-c",
2256 "import sys; sys.exit(100)"]) as proc:
Gregory P. Smith6b657452011-05-11 21:42:08 -07002257 pass
2258 # __exit__ calls wait(), so the returncode should be set
Brian Curtin79cdb662010-12-03 02:46:02 +00002259 self.assertEqual(proc.returncode, 100)
2260
2261 def test_communicate_stdin(self):
2262 with subprocess.Popen([sys.executable, "-c",
2263 "import sys;"
2264 "sys.exit(sys.stdin.read() == 'context')"],
2265 stdin=subprocess.PIPE) as proc:
2266 proc.communicate(b"context")
2267 self.assertEqual(proc.returncode, 1)
2268
2269 def test_invalid_args(self):
Andrew Svetlovb1726972012-12-26 23:34:54 +02002270 with self.assertRaises(FileNotFoundError) as c:
Brian Curtin79cdb662010-12-03 02:46:02 +00002271 with subprocess.Popen(['nonexisting_i_hope'],
2272 stdout=subprocess.PIPE,
2273 stderr=subprocess.PIPE) as proc:
2274 pass
2275
Brian Curtin79cdb662010-12-03 02:46:02 +00002276
Gregory P. Smith3b4652e2011-03-15 15:43:39 -04002277def test_main():
2278 unit_tests = (ProcessTestCase,
2279 POSIXProcessTestCase,
2280 Win32ProcessTestCase,
Gregory P. Smith3b4652e2011-03-15 15:43:39 -04002281 CommandTests,
2282 ProcessTestCaseNoPoll,
2283 HelperFunctionTests,
2284 CommandsWithSpaces,
Antoine Pitrouab85ff32011-07-23 22:03:45 +02002285 ContextManagerTests,
2286 )
Gregory P. Smith3b4652e2011-03-15 15:43:39 -04002287
2288 support.run_unittest(*unit_tests)
2289 support.reap_children()
2290
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00002291if __name__ == "__main__":
Gregory P. Smith112bb3a2011-03-15 14:55:17 -04002292 unittest.main()