blob: c3eae9a908a821ca2ee572210a9ef3933e67fd8b [file] [log] [blame]
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00003import subprocess
4import sys
5import signal
Gregory P. Smithe14e9c22011-03-15 14:55:17 -04006import io
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00007import os
Gregory P. Smitha59c59f2010-03-01 00:17:40 +00008import errno
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00009import tempfile
10import time
Tim Peters3761e8d2004-10-13 04:07:12 +000011import re
Ezio Melotti184bdfb2010-02-18 09:37:05 +000012import sysconfig
Gregory P. Smithd23047b2010-12-04 09:10:44 +000013import warnings
Gregory P. Smith51ee2702010-12-13 07:59:39 +000014import select
Gregory P. Smith81ce6852011-03-15 02:04:11 -040015import shutil
Gregory P. Smith32ec9da2010-03-19 16:53:08 +000016try:
17 import gc
18except ImportError:
19 gc = None
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000020
Benjamin Peterson964561b2011-12-10 12:31:42 -050021
22try:
23 import resource
24except ImportError:
25 resource = None
26
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000027mswindows = (sys.platform == "win32")
28
29#
30# Depends on the following external programs: Python
31#
32
33if mswindows:
Tim Peters3b01a702004-10-12 22:19:32 +000034 SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
35 'os.O_BINARY);')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000036else:
37 SETBINARY = ''
38
Florent Xiclunab1e94e82010-02-27 22:12:37 +000039
40try:
41 mkstemp = tempfile.mkstemp
42except AttributeError:
43 # tempfile.mkstemp is not available
44 def mkstemp():
45 """Replacement for mkstemp, calling mktemp."""
46 fname = tempfile.mktemp()
47 return os.open(fname, os.O_RDWR|os.O_CREAT), fname
48
Tim Peters3761e8d2004-10-13 04:07:12 +000049
Florent Xiclunac049d872010-03-27 22:47:23 +000050class BaseTestCase(unittest.TestCase):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000051 def setUp(self):
52 # Try to minimize the number of children we have so this test
53 # doesn't crash on some buildbots (Alphas in particular).
Florent Xiclunab1e94e82010-02-27 22:12:37 +000054 support.reap_children()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000055
Florent Xiclunaf0cbd822010-03-04 21:50:56 +000056 def tearDown(self):
57 for inst in subprocess._active:
58 inst.wait()
59 subprocess._cleanup()
60 self.assertFalse(subprocess._active, "subprocess._active not empty")
61
Florent Xiclunab1e94e82010-02-27 22:12:37 +000062 def assertStderrEqual(self, stderr, expected, msg=None):
63 # In a debug build, stuff like "[6580 refs]" is printed to stderr at
64 # shutdown time. That frustrates tests trying to check stderr produced
65 # from a spawned Python process.
Antoine Pitrou62f68ed2010-08-04 11:48:56 +000066 actual = support.strip_python_stderr(stderr)
Florent Xiclunab1e94e82010-02-27 22:12:37 +000067 self.assertEqual(actual, expected, msg)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000068
Florent Xiclunac049d872010-03-27 22:47:23 +000069
70class ProcessTestCase(BaseTestCase):
71
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000072 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +000073 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +000074 rc = subprocess.call([sys.executable, "-c",
75 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000076 self.assertEqual(rc, 47)
77
Peter Astrand454f7672005-01-01 09:36:35 +000078 def test_check_call_zero(self):
79 # check_call() function with zero return code
80 rc = subprocess.check_call([sys.executable, "-c",
81 "import sys; sys.exit(0)"])
82 self.assertEqual(rc, 0)
83
84 def test_check_call_nonzero(self):
85 # check_call() function with non-zero return code
Florent Xiclunab1e94e82010-02-27 22:12:37 +000086 with self.assertRaises(subprocess.CalledProcessError) as c:
Peter Astrand454f7672005-01-01 09:36:35 +000087 subprocess.check_call([sys.executable, "-c",
88 "import sys; sys.exit(47)"])
Florent Xiclunab1e94e82010-02-27 22:12:37 +000089 self.assertEqual(c.exception.returncode, 47)
Peter Astrand454f7672005-01-01 09:36:35 +000090
Georg Brandlf9734072008-12-07 15:30:06 +000091 def test_check_output(self):
92 # check_output() function with zero return code
93 output = subprocess.check_output(
94 [sys.executable, "-c", "print('BDFL')"])
Benjamin Peterson577473f2010-01-19 00:09:57 +000095 self.assertIn(b'BDFL', output)
Georg Brandlf9734072008-12-07 15:30:06 +000096
97 def test_check_output_nonzero(self):
98 # check_call() function with non-zero return code
Florent Xiclunab1e94e82010-02-27 22:12:37 +000099 with self.assertRaises(subprocess.CalledProcessError) as c:
Georg Brandlf9734072008-12-07 15:30:06 +0000100 subprocess.check_output(
101 [sys.executable, "-c", "import sys; sys.exit(5)"])
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000102 self.assertEqual(c.exception.returncode, 5)
Georg Brandlf9734072008-12-07 15:30:06 +0000103
104 def test_check_output_stderr(self):
105 # check_output() function stderr redirected to stdout
106 output = subprocess.check_output(
107 [sys.executable, "-c", "import sys; sys.stderr.write('BDFL')"],
108 stderr=subprocess.STDOUT)
Benjamin Peterson577473f2010-01-19 00:09:57 +0000109 self.assertIn(b'BDFL', output)
Georg Brandlf9734072008-12-07 15:30:06 +0000110
111 def test_check_output_stdout_arg(self):
112 # check_output() function stderr redirected to stdout
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000113 with self.assertRaises(ValueError) as c:
Georg Brandlf9734072008-12-07 15:30:06 +0000114 output = subprocess.check_output(
115 [sys.executable, "-c", "print('will not be run')"],
116 stdout=sys.stdout)
Georg Brandlf9734072008-12-07 15:30:06 +0000117 self.fail("Expected ValueError when stdout arg supplied.")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000118 self.assertIn('stdout', c.exception.args[0])
Georg Brandlf9734072008-12-07 15:30:06 +0000119
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000120 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000121 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000122 newenv = os.environ.copy()
123 newenv["FRUIT"] = "banana"
124 rc = subprocess.call([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000125 'import sys, os;'
126 'sys.exit(os.getenv("FRUIT")=="banana")'],
127 env=newenv)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000128 self.assertEqual(rc, 1)
129
Victor Stinner87b9bc32011-06-01 00:57:47 +0200130 def test_invalid_args(self):
131 # Popen() called with invalid arguments should raise TypeError
132 # but Popen.__del__ should not complain (issue #12085)
133 with support.captured_stderr() as s:
134 self.assertRaises(TypeError, subprocess.Popen, invalid_arg_name=1)
135 argcount = subprocess.Popen.__init__.__code__.co_argcount
136 too_many_args = [0] * (argcount + 1)
137 self.assertRaises(TypeError, subprocess.Popen, *too_many_args)
138 self.assertEqual(s.getvalue(), '')
139
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000140 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000141 # .stdin is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000142 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000143 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000144 self.addCleanup(p.stdout.close)
145 self.addCleanup(p.stderr.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000146 p.wait()
147 self.assertEqual(p.stdin, None)
148
149 def test_stdout_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000150 # .stdout is None when not redirected
Tim Peters29b6b4f2004-10-13 03:43:40 +0000151 p = subprocess.Popen([sys.executable, "-c",
Georg Brandl88fc6642007-02-09 21:28:07 +0000152 'print(" this bit of output is from a '
Tim Peters4052fe52004-10-13 03:29:54 +0000153 'test of stdout in a different '
Georg Brandl88fc6642007-02-09 21:28:07 +0000154 'process ...")'],
Tim Peters4052fe52004-10-13 03:29:54 +0000155 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000156 self.addCleanup(p.stdin.close)
157 self.addCleanup(p.stderr.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000158 p.wait()
159 self.assertEqual(p.stdout, None)
160
161 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000162 # .stderr is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000163 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000164 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000165 self.addCleanup(p.stdout.close)
166 self.addCleanup(p.stdin.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000167 p.wait()
168 self.assertEqual(p.stderr, None)
169
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000170 def test_executable_with_cwd(self):
Florent Xicluna1d1ab972010-03-11 01:53:10 +0000171 python_dir = os.path.dirname(os.path.realpath(sys.executable))
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000172 p = subprocess.Popen(["somethingyoudonthave", "-c",
173 "import sys; sys.exit(47)"],
174 executable=sys.executable, cwd=python_dir)
175 p.wait()
176 self.assertEqual(p.returncode, 47)
177
178 @unittest.skipIf(sysconfig.is_python_build(),
179 "need an installed Python. See #7774")
180 def test_executable_without_cwd(self):
181 # For a normal installation, it should work without 'cwd'
182 # argument. For test runs in the build directory, see #7774.
183 p = subprocess.Popen(["somethingyoudonthave", "-c",
184 "import sys; sys.exit(47)"],
Tim Peters3b01a702004-10-12 22:19:32 +0000185 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000186 p.wait()
187 self.assertEqual(p.returncode, 47)
188
189 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000190 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000191 p = subprocess.Popen([sys.executable, "-c",
192 'import sys; sys.exit(sys.stdin.read() == "pear")'],
193 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000194 p.stdin.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000195 p.stdin.close()
196 p.wait()
197 self.assertEqual(p.returncode, 1)
198
199 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000200 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000201 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000202 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000203 d = tf.fileno()
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000204 os.write(d, b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000205 os.lseek(d, 0, 0)
206 p = subprocess.Popen([sys.executable, "-c",
207 'import sys; sys.exit(sys.stdin.read() == "pear")'],
208 stdin=d)
209 p.wait()
210 self.assertEqual(p.returncode, 1)
211
212 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000213 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000214 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000215 self.addCleanup(tf.close)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000216 tf.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000217 tf.seek(0)
218 p = subprocess.Popen([sys.executable, "-c",
219 'import sys; sys.exit(sys.stdin.read() == "pear")'],
220 stdin=tf)
221 p.wait()
222 self.assertEqual(p.returncode, 1)
223
224 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000225 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000226 p = subprocess.Popen([sys.executable, "-c",
227 'import sys; sys.stdout.write("orange")'],
228 stdout=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000229 self.addCleanup(p.stdout.close)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000230 self.assertEqual(p.stdout.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000231
232 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000233 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000234 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000235 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000236 d = tf.fileno()
237 p = subprocess.Popen([sys.executable, "-c",
238 'import sys; sys.stdout.write("orange")'],
239 stdout=d)
240 p.wait()
241 os.lseek(d, 0, 0)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000242 self.assertEqual(os.read(d, 1024), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000243
244 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000245 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000246 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000247 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000248 p = subprocess.Popen([sys.executable, "-c",
249 'import sys; sys.stdout.write("orange")'],
250 stdout=tf)
251 p.wait()
252 tf.seek(0)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000253 self.assertEqual(tf.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000254
255 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000256 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000257 p = subprocess.Popen([sys.executable, "-c",
258 'import sys; sys.stderr.write("strawberry")'],
259 stderr=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000260 self.addCleanup(p.stderr.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000261 self.assertStderrEqual(p.stderr.read(), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000262
263 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000264 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000265 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000266 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000267 d = tf.fileno()
268 p = subprocess.Popen([sys.executable, "-c",
269 'import sys; sys.stderr.write("strawberry")'],
270 stderr=d)
271 p.wait()
272 os.lseek(d, 0, 0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000273 self.assertStderrEqual(os.read(d, 1024), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000274
275 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000276 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000277 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000278 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000279 p = subprocess.Popen([sys.executable, "-c",
280 'import sys; sys.stderr.write("strawberry")'],
281 stderr=tf)
282 p.wait()
283 tf.seek(0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000284 self.assertStderrEqual(tf.read(), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000285
286 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000287 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000288 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000289 'import sys;'
290 'sys.stdout.write("apple");'
291 'sys.stdout.flush();'
292 'sys.stderr.write("orange")'],
293 stdout=subprocess.PIPE,
294 stderr=subprocess.STDOUT)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000295 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000296 self.assertStderrEqual(p.stdout.read(), b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000297
298 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000299 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000300 tf = tempfile.TemporaryFile()
Benjamin Petersoncc221b22010-10-31 02:06:21 +0000301 self.addCleanup(tf.close)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000302 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000303 'import sys;'
304 'sys.stdout.write("apple");'
305 'sys.stdout.flush();'
306 'sys.stderr.write("orange")'],
307 stdout=tf,
308 stderr=tf)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000309 p.wait()
310 tf.seek(0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000311 self.assertStderrEqual(tf.read(), b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000312
Thomas Wouters89f507f2006-12-13 04:49:30 +0000313 def test_stdout_filedes_of_stdout(self):
314 # stdout is set to 1 (#1531862).
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000315 cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), b'.\n'))"
Thomas Wouters89f507f2006-12-13 04:49:30 +0000316 rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000317 self.assertEqual(rc, 2)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000318
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000319 def test_cwd(self):
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000320 tmpdir = tempfile.gettempdir()
Peter Astrand195404f2004-11-12 15:51:48 +0000321 # We cannot use os.path.realpath to canonicalize the path,
322 # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
323 cwd = os.getcwd()
324 os.chdir(tmpdir)
325 tmpdir = os.getcwd()
326 os.chdir(cwd)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000327 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000328 'import sys,os;'
329 'sys.stdout.write(os.getcwd())'],
330 stdout=subprocess.PIPE,
331 cwd=tmpdir)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000332 self.addCleanup(p.stdout.close)
Fredrik Lundh59c05592004-10-13 06:55:40 +0000333 normcase = os.path.normcase
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000334 self.assertEqual(normcase(p.stdout.read().decode("utf-8")),
335 normcase(tmpdir))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000336
337 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000338 newenv = os.environ.copy()
339 newenv["FRUIT"] = "orange"
Victor Stinnerf1512a22011-06-21 17:18:38 +0200340 with subprocess.Popen([sys.executable, "-c",
341 'import sys,os;'
342 'sys.stdout.write(os.getenv("FRUIT"))'],
343 stdout=subprocess.PIPE,
344 env=newenv) as p:
345 stdout, stderr = p.communicate()
346 self.assertEqual(stdout, b"orange")
347
Victor Stinner62d51182011-06-23 01:02:25 +0200348 # Windows requires at least the SYSTEMROOT environment variable to start
349 # Python
350 @unittest.skipIf(sys.platform == 'win32',
351 'cannot test an empty env on Windows')
Victor Stinner237e5cb2011-06-22 21:28:43 +0200352 @unittest.skipIf(sysconfig.get_config_var('Py_ENABLE_SHARED') is not None,
Victor Stinner372309a2011-06-21 21:59:06 +0200353 'the python library cannot be loaded '
354 'with an empty environment')
Victor Stinnerf1512a22011-06-21 17:18:38 +0200355 def test_empty_env(self):
356 with subprocess.Popen([sys.executable, "-c",
357 'import os; '
Victor Stinner372309a2011-06-21 21:59:06 +0200358 'print(list(os.environ.keys()))'],
Victor Stinnerf1512a22011-06-21 17:18:38 +0200359 stdout=subprocess.PIPE,
360 env={}) as p:
361 stdout, stderr = p.communicate()
Victor Stinner237e5cb2011-06-22 21:28:43 +0200362 self.assertIn(stdout.strip(),
363 (b"[]",
364 # Mac OS X adds __CF_USER_TEXT_ENCODING variable to an empty
365 # environment
366 b"['__CF_USER_TEXT_ENCODING']"))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000367
Peter Astrandcbac93c2005-03-03 20:24:28 +0000368 def test_communicate_stdin(self):
369 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000370 'import sys;'
371 'sys.exit(sys.stdin.read() == "pear")'],
Peter Astrandcbac93c2005-03-03 20:24:28 +0000372 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000373 p.communicate(b"pear")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000374 self.assertEqual(p.returncode, 1)
375
376 def test_communicate_stdout(self):
377 p = subprocess.Popen([sys.executable, "-c",
378 'import sys; sys.stdout.write("pineapple")'],
379 stdout=subprocess.PIPE)
380 (stdout, stderr) = p.communicate()
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000381 self.assertEqual(stdout, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000382 self.assertEqual(stderr, None)
383
384 def test_communicate_stderr(self):
385 p = subprocess.Popen([sys.executable, "-c",
386 'import sys; sys.stderr.write("pineapple")'],
387 stderr=subprocess.PIPE)
388 (stdout, stderr) = p.communicate()
389 self.assertEqual(stdout, None)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000390 self.assertStderrEqual(stderr, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000391
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000392 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000393 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000394 'import sys,os;'
395 'sys.stderr.write("pineapple");'
396 'sys.stdout.write(sys.stdin.read())'],
397 stdin=subprocess.PIPE,
398 stdout=subprocess.PIPE,
399 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +0000400 self.addCleanup(p.stdout.close)
401 self.addCleanup(p.stderr.close)
402 self.addCleanup(p.stdin.close)
Georg Brandl1abcbf82008-07-01 19:28:43 +0000403 (stdout, stderr) = p.communicate(b"banana")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000404 self.assertEqual(stdout, b"banana")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000405 self.assertStderrEqual(stderr, b"pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000406
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000407 # Test for the fd leak reported in http://bugs.python.org/issue2791.
408 def test_communicate_pipe_fd_leak(self):
Victor Stinner667d4b52010-12-25 22:40:32 +0000409 for stdin_pipe in (False, True):
410 for stdout_pipe in (False, True):
411 for stderr_pipe in (False, True):
412 options = {}
413 if stdin_pipe:
414 options['stdin'] = subprocess.PIPE
415 if stdout_pipe:
416 options['stdout'] = subprocess.PIPE
417 if stderr_pipe:
418 options['stderr'] = subprocess.PIPE
419 if not options:
420 continue
421 p = subprocess.Popen((sys.executable, "-c", "pass"), **options)
422 p.communicate()
423 if p.stdin is not None:
424 self.assertTrue(p.stdin.closed)
425 if p.stdout is not None:
426 self.assertTrue(p.stdout.closed)
427 if p.stderr is not None:
428 self.assertTrue(p.stderr.closed)
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000429
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000430 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000431 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000432 p = subprocess.Popen([sys.executable, "-c",
433 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000434 (stdout, stderr) = p.communicate()
435 self.assertEqual(stdout, None)
436 self.assertEqual(stderr, None)
437
438 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000439 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000440 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000441 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000442 x, y = os.pipe()
443 if mswindows:
444 pipe_buf = 512
445 else:
446 pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
447 os.close(x)
448 os.close(y)
449 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000450 'import sys,os;'
451 'sys.stdout.write(sys.stdin.read(47));'
452 'sys.stderr.write("xyz"*%d);'
453 'sys.stdout.write(sys.stdin.read())' % pipe_buf],
454 stdin=subprocess.PIPE,
455 stdout=subprocess.PIPE,
456 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +0000457 self.addCleanup(p.stdout.close)
458 self.addCleanup(p.stderr.close)
459 self.addCleanup(p.stdin.close)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000460 string_to_write = b"abc"*pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000461 (stdout, stderr) = p.communicate(string_to_write)
462 self.assertEqual(stdout, string_to_write)
463
464 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000465 # stdin.write before communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000466 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000467 'import sys,os;'
468 'sys.stdout.write(sys.stdin.read())'],
469 stdin=subprocess.PIPE,
470 stdout=subprocess.PIPE,
471 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +0000472 self.addCleanup(p.stdout.close)
473 self.addCleanup(p.stderr.close)
474 self.addCleanup(p.stdin.close)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000475 p.stdin.write(b"banana")
476 (stdout, stderr) = p.communicate(b"split")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000477 self.assertEqual(stdout, b"bananasplit")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000478 self.assertStderrEqual(stderr, b"")
Tim Peterse718f612004-10-12 21:51:32 +0000479
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000480 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000481 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000482 'import sys,os;' + SETBINARY +
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200483 'sys.stdout.write(sys.stdin.readline());'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000484 'sys.stdout.flush();'
485 'sys.stdout.write("line2\\n");'
486 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200487 'sys.stdout.write(sys.stdin.read());'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000488 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200489 'sys.stdout.write("line4\\n");'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000490 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200491 'sys.stdout.write("line5\\r\\n");'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000492 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200493 'sys.stdout.write("line6\\r");'
494 'sys.stdout.flush();'
495 'sys.stdout.write("\\nline7");'
496 'sys.stdout.flush();'
497 'sys.stdout.write("\\nline8");'],
498 stdin=subprocess.PIPE,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000499 stdout=subprocess.PIPE,
500 universal_newlines=1)
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200501 p.stdin.write("line1\n")
502 self.assertEqual(p.stdout.readline(), "line1\n")
503 p.stdin.write("line3\n")
504 p.stdin.close()
Brian Curtin3c6a9512010-11-05 03:58:52 +0000505 self.addCleanup(p.stdout.close)
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200506 self.assertEqual(p.stdout.readline(),
507 "line2\n")
508 self.assertEqual(p.stdout.read(6),
509 "line3\n")
510 self.assertEqual(p.stdout.read(),
511 "line4\nline5\nline6\nline7\nline8")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000512
513 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000514 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000515 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000516 'import sys,os;' + SETBINARY +
Guido van Rossum98297ee2007-11-06 21:34:58 +0000517 'sys.stdout.write("line2\\n");'
518 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200519 'sys.stdout.write("line4\\n");'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000520 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200521 'sys.stdout.write("line5\\r\\n");'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000522 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200523 'sys.stdout.write("line6\\r");'
Guido van Rossum98297ee2007-11-06 21:34:58 +0000524 'sys.stdout.flush();'
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200525 'sys.stdout.write("\\nline7");'
526 'sys.stdout.flush();'
527 'sys.stdout.write("\\nline8");'],
528 stderr=subprocess.PIPE,
529 stdout=subprocess.PIPE,
Guido van Rossum98297ee2007-11-06 21:34:58 +0000530 universal_newlines=1)
Brian Curtin19a53792010-11-05 17:09:05 +0000531 self.addCleanup(p.stdout.close)
532 self.addCleanup(p.stderr.close)
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200533 # BUG: can't give a non-empty stdin because it breaks both the
534 # select- and poll-based communicate() implementations.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000535 (stdout, stderr) = p.communicate()
Antoine Pitrouab85ff32011-07-23 22:03:45 +0200536 self.assertEqual(stdout,
537 "line2\nline4\nline5\nline6\nline7\nline8")
538
539 def test_universal_newlines_communicate_stdin(self):
540 # universal newlines through communicate(), with only stdin
541 p = subprocess.Popen([sys.executable, "-c",
542 'import sys,os;' + SETBINARY + '''\nif True:
543 s = sys.stdin.readline()
544 assert s == "line1\\n", repr(s)
545 s = sys.stdin.read()
546 assert s == "line3\\n", repr(s)
547 '''],
548 stdin=subprocess.PIPE,
549 universal_newlines=1)
550 (stdout, stderr) = p.communicate("line1\nline3\n")
551 self.assertEqual(p.returncode, 0)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000552
553 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000554 # Make sure we leak no resources
Antoine Pitrou8db30272010-09-18 22:38:48 +0000555 if not mswindows:
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000556 max_handles = 1026 # too much for most UNIX systems
557 else:
Antoine Pitrou8db30272010-09-18 22:38:48 +0000558 max_handles = 2050 # too much for (at least some) Windows setups
559 handles = []
Gregory P. Smith81ce6852011-03-15 02:04:11 -0400560 tmpdir = tempfile.mkdtemp()
Antoine Pitrou8db30272010-09-18 22:38:48 +0000561 try:
562 for i in range(max_handles):
563 try:
Gregory P. Smith81ce6852011-03-15 02:04:11 -0400564 tmpfile = os.path.join(tmpdir, support.TESTFN)
565 handles.append(os.open(tmpfile, os.O_WRONLY|os.O_CREAT))
Antoine Pitrou8db30272010-09-18 22:38:48 +0000566 except OSError as e:
567 if e.errno != errno.EMFILE:
568 raise
569 break
570 else:
571 self.skipTest("failed to reach the file descriptor limit "
572 "(tried %d)" % max_handles)
573 # Close a couple of them (should be enough for a subprocess)
574 for i in range(10):
575 os.close(handles.pop())
576 # Loop creating some subprocesses. If one of them leaks some fds,
577 # the next loop iteration will fail by reaching the max fd limit.
578 for i in range(15):
579 p = subprocess.Popen([sys.executable, "-c",
580 "import sys;"
581 "sys.stdout.write(sys.stdin.read())"],
582 stdin=subprocess.PIPE,
583 stdout=subprocess.PIPE,
584 stderr=subprocess.PIPE)
585 data = p.communicate(b"lime")[0]
586 self.assertEqual(data, b"lime")
587 finally:
588 for h in handles:
589 os.close(h)
Gregory P. Smith81ce6852011-03-15 02:04:11 -0400590 shutil.rmtree(tmpdir)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000591
592 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000593 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
594 '"a b c" d e')
595 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
596 'ab\\"c \\ d')
Christian Heimesfdab48e2008-01-20 09:06:41 +0000597 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
598 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000599 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
600 'a\\\\\\b "de fg" h')
601 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
602 'a\\\\\\"b c d')
603 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
604 '"a\\\\b c" d e')
605 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
606 '"a\\\\b\\ c" d e')
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000607 self.assertEqual(subprocess.list2cmdline(['ab', '']),
608 'ab ""')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000609
610
611 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000612 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000613 "-c", "import time; time.sleep(1)"])
614 count = 0
615 while p.poll() is None:
616 time.sleep(0.1)
617 count += 1
618 # We expect that the poll loop probably went around about 10 times,
619 # but, based on system scheduling we can't control, it's possible
620 # poll() never returned None. It "should be" very rare that it
621 # didn't go around at least twice.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000622 self.assertGreaterEqual(count, 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000623 # Subsequent invocations should just return the returncode
624 self.assertEqual(p.poll(), 0)
625
626
627 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000628 p = subprocess.Popen([sys.executable,
629 "-c", "import time; time.sleep(2)"])
630 self.assertEqual(p.wait(), 0)
631 # Subsequent invocations should just return the returncode
632 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000633
Peter Astrand738131d2004-11-30 21:04:45 +0000634
635 def test_invalid_bufsize(self):
636 # an invalid type of the bufsize argument should raise
637 # TypeError.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000638 with self.assertRaises(TypeError):
Peter Astrand738131d2004-11-30 21:04:45 +0000639 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
Peter Astrand738131d2004-11-30 21:04:45 +0000640
Guido van Rossum46a05a72007-06-07 21:56:45 +0000641 def test_bufsize_is_none(self):
642 # bufsize=None should be the same as bufsize=0.
643 p = subprocess.Popen([sys.executable, "-c", "pass"], None)
644 self.assertEqual(p.wait(), 0)
645 # Again with keyword arg
646 p = subprocess.Popen([sys.executable, "-c", "pass"], bufsize=None)
647 self.assertEqual(p.wait(), 0)
648
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000649 def test_leaking_fds_on_error(self):
650 # see bug #5179: Popen leaks file descriptors to PIPEs if
651 # the child fails to execute; this will eventually exhaust
652 # the maximum number of open fds. 1024 seems a very common
653 # value for that limit, but Windows has 2048, so we loop
654 # 1024 times (each call leaked two fds).
655 for i in range(1024):
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000656 # Windows raises IOError. Others raise OSError.
657 with self.assertRaises(EnvironmentError) as c:
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000658 subprocess.Popen(['nonexisting_i_hope'],
659 stdout=subprocess.PIPE,
660 stderr=subprocess.PIPE)
R David Murray384069c2011-03-13 22:26:53 -0400661 # ignore errors that indicate the command was not found
R David Murray6924bd72011-03-13 22:48:55 -0400662 if c.exception.errno not in (errno.ENOENT, errno.EACCES):
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000663 raise c.exception
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000664
Victor Stinnerb3693582010-05-21 20:13:12 +0000665 def test_issue8780(self):
666 # Ensure that stdout is inherited from the parent
667 # if stdout=PIPE is not used
668 code = ';'.join((
669 'import subprocess, sys',
670 'retcode = subprocess.call('
671 "[sys.executable, '-c', 'print(\"Hello World!\")'])",
672 'assert retcode == 0'))
673 output = subprocess.check_output([sys.executable, '-c', code])
Ezio Melottib3aedd42010-11-20 19:04:17 +0000674 self.assertTrue(output.startswith(b'Hello World!'), ascii(output))
Victor Stinnerb3693582010-05-21 20:13:12 +0000675
Tim Goldenaf5ac392010-08-06 13:03:56 +0000676 def test_handles_closed_on_exception(self):
677 # If CreateProcess exits with an error, ensure the
678 # duplicate output handles are released
679 ifhandle, ifname = mkstemp()
680 ofhandle, ofname = mkstemp()
681 efhandle, efname = mkstemp()
682 try:
683 subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle,
684 stderr=efhandle)
685 except OSError:
686 os.close(ifhandle)
687 os.remove(ifname)
688 os.close(ofhandle)
689 os.remove(ofname)
690 os.close(efhandle)
691 os.remove(efname)
692 self.assertFalse(os.path.exists(ifname))
693 self.assertFalse(os.path.exists(ofname))
694 self.assertFalse(os.path.exists(efname))
695
Ross Lagerwall4f61b022011-04-05 15:34:00 +0200696 def test_communicate_epipe(self):
697 # Issue 10963: communicate() should hide EPIPE
698 p = subprocess.Popen([sys.executable, "-c", 'pass'],
699 stdin=subprocess.PIPE,
700 stdout=subprocess.PIPE,
701 stderr=subprocess.PIPE)
702 self.addCleanup(p.stdout.close)
703 self.addCleanup(p.stderr.close)
704 self.addCleanup(p.stdin.close)
705 p.communicate(b"x" * 2**20)
706
707 def test_communicate_epipe_only_stdin(self):
708 # Issue 10963: communicate() should hide EPIPE
709 p = subprocess.Popen([sys.executable, "-c", 'pass'],
710 stdin=subprocess.PIPE)
711 self.addCleanup(p.stdin.close)
712 time.sleep(2)
713 p.communicate(b"x" * 2**20)
714
Victor Stinner1848db82011-07-05 14:49:46 +0200715 @unittest.skipUnless(hasattr(signal, 'SIGALRM'),
716 "Requires signal.SIGALRM")
Victor Stinner2cfb6f32011-07-05 14:00:56 +0200717 def test_communicate_eintr(self):
718 # Issue #12493: communicate() should handle EINTR
719 def handler(signum, frame):
720 pass
721 old_handler = signal.signal(signal.SIGALRM, handler)
722 self.addCleanup(signal.signal, signal.SIGALRM, old_handler)
723
724 # the process is running for 2 seconds
725 args = [sys.executable, "-c", 'import time; time.sleep(2)']
726 for stream in ('stdout', 'stderr'):
727 kw = {stream: subprocess.PIPE}
728 with subprocess.Popen(args, **kw) as process:
729 signal.alarm(1)
730 # communicate() will be interrupted by SIGALRM
731 process.communicate()
732
Tim Peterse718f612004-10-12 21:51:32 +0000733
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000734# context manager
735class _SuppressCoreFiles(object):
736 """Try to prevent core files from being created."""
737 old_limit = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000738
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000739 def __enter__(self):
740 """Try to save previous ulimit, then set it to (0, 0)."""
Benjamin Peterson964561b2011-12-10 12:31:42 -0500741 if resource is not None:
742 try:
743 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
744 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
745 except (ValueError, resource.error):
746 pass
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000747
Ronald Oussoren102d11a2010-07-23 09:50:05 +0000748 if sys.platform == 'darwin':
749 # Check if the 'Crash Reporter' on OSX was configured
750 # in 'Developer' mode and warn that it will get triggered
751 # when it is.
752 #
753 # This assumes that this context manager is used in tests
754 # that might trigger the next manager.
755 value = subprocess.Popen(['/usr/bin/defaults', 'read',
756 'com.apple.CrashReporter', 'DialogType'],
757 stdout=subprocess.PIPE).communicate()[0]
758 if value.strip() == b'developer':
759 print("this tests triggers the Crash Reporter, "
760 "that is intentional", end='')
761 sys.stdout.flush()
762
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000763 def __exit__(self, *args):
764 """Return core file behavior to default."""
765 if self.old_limit is None:
766 return
Benjamin Peterson964561b2011-12-10 12:31:42 -0500767 if resource is not None:
768 try:
769 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
770 except (ValueError, resource.error):
771 pass
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000772
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000773
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000774@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunac049d872010-03-27 22:47:23 +0000775class POSIXProcessTestCase(BaseTestCase):
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000776
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000777 def test_exceptions(self):
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000778 nonexistent_dir = "/_this/pa.th/does/not/exist"
779 try:
780 os.chdir(nonexistent_dir)
781 except OSError as e:
782 # This avoids hard coding the errno value or the OS perror()
783 # string and instead capture the exception that we want to see
784 # below for comparison.
785 desired_exception = e
Benjamin Peterson5f780402010-11-20 18:07:52 +0000786 desired_exception.strerror += ': ' + repr(sys.executable)
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000787 else:
788 self.fail("chdir to nonexistant directory %s succeeded." %
789 nonexistent_dir)
790
791 # Error in the child re-raised in the parent.
792 try:
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000793 p = subprocess.Popen([sys.executable, "-c", ""],
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000794 cwd=nonexistent_dir)
795 except OSError as e:
796 # Test that the child process chdir failure actually makes
797 # it up to the parent process as the correct exception.
798 self.assertEqual(desired_exception.errno, e.errno)
799 self.assertEqual(desired_exception.strerror, e.strerror)
800 else:
801 self.fail("Expected OSError: %s" % desired_exception)
802
803 def test_restore_signals(self):
804 # Code coverage for both values of restore_signals to make sure it
805 # at least does not blow up.
806 # A test for behavior would be complex. Contributions welcome.
807 subprocess.call([sys.executable, "-c", ""], restore_signals=True)
808 subprocess.call([sys.executable, "-c", ""], restore_signals=False)
809
810 def test_start_new_session(self):
811 # For code coverage of calling setsid(). We don't care if we get an
812 # EPERM error from it depending on the test execution environment, that
813 # still indicates that it was called.
814 try:
815 output = subprocess.check_output(
816 [sys.executable, "-c",
817 "import os; print(os.getpgid(os.getpid()))"],
818 start_new_session=True)
819 except OSError as e:
820 if e.errno != errno.EPERM:
821 raise
822 else:
823 parent_pgid = os.getpgid(os.getpid())
824 child_pgid = int(output)
825 self.assertNotEqual(parent_pgid, child_pgid)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000826
827 def test_run_abort(self):
828 # returncode handles signal termination
829 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000830 p = subprocess.Popen([sys.executable, "-c",
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000831 'import os; os.abort()'])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000832 p.wait()
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000833 self.assertEqual(-p.returncode, signal.SIGABRT)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000834
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000835 def test_preexec(self):
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000836 # DISCLAIMER: Setting environment variables is *not* a good use
837 # of a preexec_fn. This is merely a test.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000838 p = subprocess.Popen([sys.executable, "-c",
839 'import sys,os;'
840 'sys.stdout.write(os.getenv("FRUIT"))'],
841 stdout=subprocess.PIPE,
842 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
Brian Curtin3c6a9512010-11-05 03:58:52 +0000843 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000844 self.assertEqual(p.stdout.read(), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000845
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000846 def test_preexec_exception(self):
847 def raise_it():
848 raise ValueError("What if two swallows carried a coconut?")
849 try:
850 p = subprocess.Popen([sys.executable, "-c", ""],
851 preexec_fn=raise_it)
852 except RuntimeError as e:
853 self.assertTrue(
854 subprocess._posixsubprocess,
855 "Expected a ValueError from the preexec_fn")
856 except ValueError as e:
857 self.assertIn("coconut", e.args[0])
858 else:
859 self.fail("Exception raised by preexec_fn did not make it "
860 "to the parent process.")
861
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000862 @unittest.skipUnless(gc, "Requires a gc module.")
863 def test_preexec_gc_module_failure(self):
864 # This tests the code that disables garbage collection if the child
865 # process will execute any Python.
866 def raise_runtime_error():
867 raise RuntimeError("this shouldn't escape")
868 enabled = gc.isenabled()
869 orig_gc_disable = gc.disable
870 orig_gc_isenabled = gc.isenabled
871 try:
872 gc.disable()
873 self.assertFalse(gc.isenabled())
874 subprocess.call([sys.executable, '-c', ''],
875 preexec_fn=lambda: None)
876 self.assertFalse(gc.isenabled(),
877 "Popen enabled gc when it shouldn't.")
878
879 gc.enable()
880 self.assertTrue(gc.isenabled())
881 subprocess.call([sys.executable, '-c', ''],
882 preexec_fn=lambda: None)
883 self.assertTrue(gc.isenabled(), "Popen left gc disabled.")
884
885 gc.disable = raise_runtime_error
886 self.assertRaises(RuntimeError, subprocess.Popen,
887 [sys.executable, '-c', ''],
888 preexec_fn=lambda: None)
889
890 del gc.isenabled # force an AttributeError
891 self.assertRaises(AttributeError, subprocess.Popen,
892 [sys.executable, '-c', ''],
893 preexec_fn=lambda: None)
894 finally:
895 gc.disable = orig_gc_disable
896 gc.isenabled = orig_gc_isenabled
897 if not enabled:
898 gc.disable()
899
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000900 def test_args_string(self):
901 # args is a string
902 fd, fname = mkstemp()
903 # reopen in text mode
Victor Stinnerf6782ac2010-10-16 23:46:43 +0000904 with open(fd, "w", errors="surrogateescape") as fobj:
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000905 fobj.write("#!/bin/sh\n")
906 fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" %
907 sys.executable)
908 os.chmod(fname, 0o700)
909 p = subprocess.Popen(fname)
910 p.wait()
911 os.remove(fname)
912 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000913
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000914 def test_invalid_args(self):
915 # invalid arguments should raise ValueError
916 self.assertRaises(ValueError, subprocess.call,
917 [sys.executable, "-c",
918 "import sys; sys.exit(47)"],
919 startupinfo=47)
920 self.assertRaises(ValueError, subprocess.call,
921 [sys.executable, "-c",
922 "import sys; sys.exit(47)"],
923 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000924
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000925 def test_shell_sequence(self):
926 # Run command through the shell (sequence)
927 newenv = os.environ.copy()
928 newenv["FRUIT"] = "apple"
929 p = subprocess.Popen(["echo $FRUIT"], shell=1,
930 stdout=subprocess.PIPE,
931 env=newenv)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000932 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000933 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000934
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000935 def test_shell_string(self):
936 # Run command through the shell (string)
937 newenv = os.environ.copy()
938 newenv["FRUIT"] = "apple"
939 p = subprocess.Popen("echo $FRUIT", shell=1,
940 stdout=subprocess.PIPE,
941 env=newenv)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000942 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000943 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Christian Heimesa342c012008-04-20 21:01:16 +0000944
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000945 def test_call_string(self):
946 # call() function with string argument on UNIX
947 fd, fname = mkstemp()
948 # reopen in text mode
Victor Stinnerf6782ac2010-10-16 23:46:43 +0000949 with open(fd, "w", errors="surrogateescape") as fobj:
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000950 fobj.write("#!/bin/sh\n")
951 fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" %
952 sys.executable)
953 os.chmod(fname, 0o700)
954 rc = subprocess.call(fname)
955 os.remove(fname)
956 self.assertEqual(rc, 47)
Christian Heimesa342c012008-04-20 21:01:16 +0000957
Stefan Krah9542cc62010-07-19 14:20:53 +0000958 def test_specific_shell(self):
959 # Issue #9265: Incorrect name passed as arg[0].
960 shells = []
961 for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']:
962 for name in ['bash', 'ksh']:
963 sh = os.path.join(prefix, name)
964 if os.path.isfile(sh):
965 shells.append(sh)
966 if not shells: # Will probably work for any shell but csh.
967 self.skipTest("bash or ksh required for this test")
968 sh = '/bin/sh'
969 if os.path.isfile(sh) and not os.path.islink(sh):
970 # Test will fail if /bin/sh is a symlink to csh.
971 shells.append(sh)
972 for sh in shells:
973 p = subprocess.Popen("echo $0", executable=sh, shell=True,
974 stdout=subprocess.PIPE)
Brian Curtin3c6a9512010-11-05 03:58:52 +0000975 self.addCleanup(p.stdout.close)
Stefan Krah9542cc62010-07-19 14:20:53 +0000976 self.assertEqual(p.stdout.read().strip(), bytes(sh, 'ascii'))
977
Florent Xicluna4886d242010-03-08 13:27:26 +0000978 def _kill_process(self, method, *args):
Florent Xicluna1d8ee3a2010-03-05 20:26:54 +0000979 # Do not inherit file handles from the parent.
980 # It should fix failures on some platforms.
Antoine Pitrou3d8580f2010-09-20 01:33:21 +0000981 p = subprocess.Popen([sys.executable, "-c", """if 1:
982 import sys, time
983 sys.stdout.write('x\\n')
984 sys.stdout.flush()
985 time.sleep(30)
986 """],
987 close_fds=True,
988 stdin=subprocess.PIPE,
989 stdout=subprocess.PIPE,
990 stderr=subprocess.PIPE)
991 # Wait for the interpreter to be completely initialized before
992 # sending any signal.
993 p.stdout.read(1)
994 getattr(p, method)(*args)
Florent Xicluna4886d242010-03-08 13:27:26 +0000995 return p
996
997 def test_send_signal(self):
998 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunac049d872010-03-27 22:47:23 +0000999 _, stderr = p.communicate()
1000 self.assertIn(b'KeyboardInterrupt', stderr)
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001001 self.assertNotEqual(p.wait(), 0)
Christian Heimesa342c012008-04-20 21:01:16 +00001002
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001003 def test_kill(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00001004 p = self._kill_process('kill')
Florent Xiclunac049d872010-03-27 22:47:23 +00001005 _, stderr = p.communicate()
1006 self.assertStderrEqual(stderr, b'')
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001007 self.assertEqual(p.wait(), -signal.SIGKILL)
Tim Peterse718f612004-10-12 21:51:32 +00001008
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001009 def test_terminate(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00001010 p = self._kill_process('terminate')
Florent Xiclunac049d872010-03-27 22:47:23 +00001011 _, stderr = p.communicate()
1012 self.assertStderrEqual(stderr, b'')
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001013 self.assertEqual(p.wait(), -signal.SIGTERM)
1014
Antoine Pitrouc9c83ba2011-01-03 18:23:55 +00001015 def check_close_std_fds(self, fds):
1016 # Issue #9905: test that subprocess pipes still work properly with
1017 # some standard fds closed
1018 stdin = 0
1019 newfds = []
1020 for a in fds:
1021 b = os.dup(a)
1022 newfds.append(b)
1023 if a == 0:
1024 stdin = b
1025 try:
1026 for fd in fds:
1027 os.close(fd)
1028 out, err = subprocess.Popen([sys.executable, "-c",
1029 'import sys;'
1030 'sys.stdout.write("apple");'
1031 'sys.stdout.flush();'
1032 'sys.stderr.write("orange")'],
1033 stdin=stdin,
1034 stdout=subprocess.PIPE,
1035 stderr=subprocess.PIPE).communicate()
1036 err = support.strip_python_stderr(err)
1037 self.assertEqual((out, err), (b'apple', b'orange'))
1038 finally:
1039 for b, a in zip(newfds, fds):
1040 os.dup2(b, a)
1041 for b in newfds:
1042 os.close(b)
1043
1044 def test_close_fd_0(self):
1045 self.check_close_std_fds([0])
1046
1047 def test_close_fd_1(self):
1048 self.check_close_std_fds([1])
1049
1050 def test_close_fd_2(self):
1051 self.check_close_std_fds([2])
1052
1053 def test_close_fds_0_1(self):
1054 self.check_close_std_fds([0, 1])
1055
1056 def test_close_fds_0_2(self):
1057 self.check_close_std_fds([0, 2])
1058
1059 def test_close_fds_1_2(self):
1060 self.check_close_std_fds([1, 2])
1061
1062 def test_close_fds_0_1_2(self):
1063 # Issue #10806: test that subprocess pipes still work properly with
1064 # all standard fds closed.
1065 self.check_close_std_fds([0, 1, 2])
1066
Antoine Pitrou95aaeee2011-01-03 21:15:48 +00001067 def test_remapping_std_fds(self):
1068 # open up some temporary files
1069 temps = [mkstemp() for i in range(3)]
1070 try:
1071 temp_fds = [fd for fd, fname in temps]
1072
1073 # unlink the files -- we won't need to reopen them
1074 for fd, fname in temps:
1075 os.unlink(fname)
1076
1077 # write some data to what will become stdin, and rewind
1078 os.write(temp_fds[1], b"STDIN")
1079 os.lseek(temp_fds[1], 0, 0)
1080
1081 # move the standard file descriptors out of the way
1082 saved_fds = [os.dup(fd) for fd in range(3)]
1083 try:
1084 # duplicate the file objects over the standard fd's
1085 for fd, temp_fd in enumerate(temp_fds):
1086 os.dup2(temp_fd, fd)
1087
1088 # now use those files in the "wrong" order, so that subprocess
1089 # has to rearrange them in the child
1090 p = subprocess.Popen([sys.executable, "-c",
1091 'import sys; got = sys.stdin.read();'
1092 'sys.stdout.write("got %s"%got); sys.stderr.write("err")'],
1093 stdin=temp_fds[1],
1094 stdout=temp_fds[2],
1095 stderr=temp_fds[0])
1096 p.wait()
1097 finally:
1098 # restore the original fd's underneath sys.stdin, etc.
1099 for std, saved in enumerate(saved_fds):
1100 os.dup2(saved, std)
1101 os.close(saved)
1102
1103 for fd in temp_fds:
1104 os.lseek(fd, 0, 0)
1105
1106 out = os.read(temp_fds[2], 1024)
1107 err = support.strip_python_stderr(os.read(temp_fds[0], 1024))
1108 self.assertEqual(out, b"got STDIN")
1109 self.assertEqual(err, b"err")
1110
1111 finally:
1112 for fd in temp_fds:
1113 os.close(fd)
1114
Ross Lagerwalld98646e2011-07-27 07:16:31 +02001115 def check_swap_fds(self, stdin_no, stdout_no, stderr_no):
1116 # open up some temporary files
1117 temps = [mkstemp() for i in range(3)]
1118 temp_fds = [fd for fd, fname in temps]
1119 try:
1120 # unlink the files -- we won't need to reopen them
1121 for fd, fname in temps:
1122 os.unlink(fname)
1123
1124 # save a copy of the standard file descriptors
1125 saved_fds = [os.dup(fd) for fd in range(3)]
1126 try:
1127 # duplicate the temp files over the standard fd's 0, 1, 2
1128 for fd, temp_fd in enumerate(temp_fds):
1129 os.dup2(temp_fd, fd)
1130
1131 # write some data to what will become stdin, and rewind
1132 os.write(stdin_no, b"STDIN")
1133 os.lseek(stdin_no, 0, 0)
1134
1135 # now use those files in the given order, so that subprocess
1136 # has to rearrange them in the child
1137 p = subprocess.Popen([sys.executable, "-c",
1138 'import sys; got = sys.stdin.read();'
1139 'sys.stdout.write("got %s"%got); sys.stderr.write("err")'],
1140 stdin=stdin_no,
1141 stdout=stdout_no,
1142 stderr=stderr_no)
1143 p.wait()
1144
1145 for fd in temp_fds:
1146 os.lseek(fd, 0, 0)
1147
1148 out = os.read(stdout_no, 1024)
1149 err = support.strip_python_stderr(os.read(stderr_no, 1024))
1150 finally:
1151 for std, saved in enumerate(saved_fds):
1152 os.dup2(saved, std)
1153 os.close(saved)
1154
1155 self.assertEqual(out, b"got STDIN")
1156 self.assertEqual(err, b"err")
1157
1158 finally:
1159 for fd in temp_fds:
1160 os.close(fd)
1161
1162 # When duping fds, if there arises a situation where one of the fds is
1163 # either 0, 1 or 2, it is possible that it is overwritten (#12607).
1164 # This tests all combinations of this.
1165 def test_swap_fds(self):
1166 self.check_swap_fds(0, 1, 2)
1167 self.check_swap_fds(0, 2, 1)
1168 self.check_swap_fds(1, 0, 2)
1169 self.check_swap_fds(1, 2, 0)
1170 self.check_swap_fds(2, 0, 1)
1171 self.check_swap_fds(2, 1, 0)
1172
Victor Stinner13bb71c2010-04-23 21:41:56 +00001173 def test_surrogates_error_message(self):
Victor Stinner4d078042010-04-23 19:28:32 +00001174 def prepare():
1175 raise ValueError("surrogate:\uDCff")
1176
1177 try:
1178 subprocess.call(
1179 [sys.executable, "-c", "pass"],
1180 preexec_fn=prepare)
1181 except ValueError as err:
1182 # Pure Python implementations keeps the message
1183 self.assertIsNone(subprocess._posixsubprocess)
1184 self.assertEqual(str(err), "surrogate:\uDCff")
1185 except RuntimeError as err:
1186 # _posixsubprocess uses a default message
1187 self.assertIsNotNone(subprocess._posixsubprocess)
1188 self.assertEqual(str(err), "Exception occurred in preexec_fn.")
1189 else:
1190 self.fail("Expected ValueError or RuntimeError")
1191
Victor Stinner13bb71c2010-04-23 21:41:56 +00001192 def test_undecodable_env(self):
1193 for key, value in (('test', 'abc\uDCFF'), ('test\uDCFF', '42')):
Victor Stinner13bb71c2010-04-23 21:41:56 +00001194 # test str with surrogates
Antoine Pitroufb8db8f2010-09-19 22:46:05 +00001195 script = "import os; print(ascii(os.getenv(%s)))" % repr(key)
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001196 env = os.environ.copy()
1197 env[key] = value
Victor Stinner89f3ad12010-10-14 10:43:31 +00001198 # Use C locale to get ascii for the locale encoding to force
1199 # surrogate-escaping of \xFF in the child process; otherwise it can
1200 # be decoded as-is if the default locale is latin-1.
Victor Stinnerebc78d22010-10-14 10:38:17 +00001201 env['LC_ALL'] = 'C'
Victor Stinner13bb71c2010-04-23 21:41:56 +00001202 stdout = subprocess.check_output(
1203 [sys.executable, "-c", script],
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001204 env=env)
Victor Stinner13bb71c2010-04-23 21:41:56 +00001205 stdout = stdout.rstrip(b'\n\r')
Ezio Melottib3aedd42010-11-20 19:04:17 +00001206 self.assertEqual(stdout.decode('ascii'), ascii(value))
Victor Stinner13bb71c2010-04-23 21:41:56 +00001207
1208 # test bytes
1209 key = key.encode("ascii", "surrogateescape")
1210 value = value.encode("ascii", "surrogateescape")
Antoine Pitroufb8db8f2010-09-19 22:46:05 +00001211 script = "import os; print(ascii(os.getenvb(%s)))" % repr(key)
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001212 env = os.environ.copy()
1213 env[key] = value
Victor Stinner13bb71c2010-04-23 21:41:56 +00001214 stdout = subprocess.check_output(
1215 [sys.executable, "-c", script],
Victor Stinnerce2d24d2010-04-23 22:55:39 +00001216 env=env)
Victor Stinner13bb71c2010-04-23 21:41:56 +00001217 stdout = stdout.rstrip(b'\n\r')
Ezio Melottib3aedd42010-11-20 19:04:17 +00001218 self.assertEqual(stdout.decode('ascii'), ascii(value))
Victor Stinner13bb71c2010-04-23 21:41:56 +00001219
Victor Stinnerb745a742010-05-18 17:17:23 +00001220 def test_bytes_program(self):
1221 abs_program = os.fsencode(sys.executable)
1222 path, program = os.path.split(sys.executable)
1223 program = os.fsencode(program)
1224
1225 # absolute bytes path
1226 exitcode = subprocess.call([abs_program, "-c", "pass"])
Ezio Melottib3aedd42010-11-20 19:04:17 +00001227 self.assertEqual(exitcode, 0)
Victor Stinnerb745a742010-05-18 17:17:23 +00001228
1229 # bytes program, unicode PATH
1230 env = os.environ.copy()
1231 env["PATH"] = path
1232 exitcode = subprocess.call([program, "-c", "pass"], env=env)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001233 self.assertEqual(exitcode, 0)
Victor Stinnerb745a742010-05-18 17:17:23 +00001234
1235 # bytes program, bytes PATH
1236 envb = os.environb.copy()
1237 envb[b"PATH"] = os.fsencode(path)
1238 exitcode = subprocess.call([program, "-c", "pass"], env=envb)
Ezio Melottib3aedd42010-11-20 19:04:17 +00001239 self.assertEqual(exitcode, 0)
Victor Stinnerb745a742010-05-18 17:17:23 +00001240
Gregory P. Smith51ee2702010-12-13 07:59:39 +00001241 def test_pipe_cloexec(self):
1242 sleeper = support.findfile("input_reader.py", subdir="subprocessdata")
1243 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1244
1245 p1 = subprocess.Popen([sys.executable, sleeper],
1246 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1247 stderr=subprocess.PIPE, close_fds=False)
1248
1249 self.addCleanup(p1.communicate, b'')
1250
1251 p2 = subprocess.Popen([sys.executable, fd_status],
1252 stdout=subprocess.PIPE, close_fds=False)
1253
1254 output, error = p2.communicate()
1255 result_fds = set(map(int, output.split(b',')))
1256 unwanted_fds = set([p1.stdin.fileno(), p1.stdout.fileno(),
1257 p1.stderr.fileno()])
1258
1259 self.assertFalse(result_fds & unwanted_fds,
1260 "Expected no fds from %r to be open in child, "
1261 "found %r" %
1262 (unwanted_fds, result_fds & unwanted_fds))
1263
1264 def test_pipe_cloexec_real_tools(self):
1265 qcat = support.findfile("qcat.py", subdir="subprocessdata")
1266 qgrep = support.findfile("qgrep.py", subdir="subprocessdata")
1267
1268 subdata = b'zxcvbn'
1269 data = subdata * 4 + b'\n'
1270
1271 p1 = subprocess.Popen([sys.executable, qcat],
1272 stdin=subprocess.PIPE, stdout=subprocess.PIPE,
1273 close_fds=False)
1274
1275 p2 = subprocess.Popen([sys.executable, qgrep, subdata],
1276 stdin=p1.stdout, stdout=subprocess.PIPE,
1277 close_fds=False)
1278
1279 self.addCleanup(p1.wait)
1280 self.addCleanup(p2.wait)
1281 self.addCleanup(p1.terminate)
1282 self.addCleanup(p2.terminate)
1283
1284 p1.stdin.write(data)
1285 p1.stdin.close()
1286
1287 readfiles, ignored1, ignored2 = select.select([p2.stdout], [], [], 10)
1288
1289 self.assertTrue(readfiles, "The child hung")
1290 self.assertEqual(p2.stdout.read(), data)
1291
Victor Stinnerfaa8c132011-01-03 16:36:00 +00001292 p1.stdout.close()
1293 p2.stdout.close()
1294
Gregory P. Smith51ee2702010-12-13 07:59:39 +00001295 def test_close_fds(self):
1296 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1297
1298 fds = os.pipe()
1299 self.addCleanup(os.close, fds[0])
1300 self.addCleanup(os.close, fds[1])
1301
1302 open_fds = set(fds)
1303
1304 p = subprocess.Popen([sys.executable, fd_status],
1305 stdout=subprocess.PIPE, close_fds=False)
1306 output, ignored = p.communicate()
1307 remaining_fds = set(map(int, output.split(b',')))
1308
1309 self.assertEqual(remaining_fds & open_fds, open_fds,
1310 "Some fds were closed")
1311
1312 p = subprocess.Popen([sys.executable, fd_status],
1313 stdout=subprocess.PIPE, close_fds=True)
1314 output, ignored = p.communicate()
1315 remaining_fds = set(map(int, output.split(b',')))
1316
1317 self.assertFalse(remaining_fds & open_fds,
1318 "Some fds were left open")
1319 self.assertIn(1, remaining_fds, "Subprocess failed")
1320
Victor Stinner88701e22011-06-01 13:13:04 +02001321 # Mac OS X Tiger (10.4) has a kernel bug: sometimes, the file
1322 # descriptor of a pipe closed in the parent process is valid in the
1323 # child process according to fstat(), but the mode of the file
1324 # descriptor is invalid, and read or write raise an error.
1325 @support.requires_mac_ver(10, 5)
Gregory P. Smith8edd99d2010-12-14 13:43:30 +00001326 def test_pass_fds(self):
1327 fd_status = support.findfile("fd_status.py", subdir="subprocessdata")
1328
1329 open_fds = set()
1330
1331 for x in range(5):
1332 fds = os.pipe()
1333 self.addCleanup(os.close, fds[0])
1334 self.addCleanup(os.close, fds[1])
1335 open_fds.update(fds)
1336
1337 for fd in open_fds:
1338 p = subprocess.Popen([sys.executable, fd_status],
1339 stdout=subprocess.PIPE, close_fds=True,
1340 pass_fds=(fd, ))
1341 output, ignored = p.communicate()
1342
1343 remaining_fds = set(map(int, output.split(b',')))
1344 to_be_closed = open_fds - {fd}
1345
1346 self.assertIn(fd, remaining_fds, "fd to be passed not passed")
1347 self.assertFalse(remaining_fds & to_be_closed,
1348 "fd to be closed passed")
1349
1350 # pass_fds overrides close_fds with a warning.
1351 with self.assertWarns(RuntimeWarning) as context:
1352 self.assertFalse(subprocess.call(
1353 [sys.executable, "-c", "import sys; sys.exit(0)"],
1354 close_fds=False, pass_fds=(fd, )))
1355 self.assertIn('overriding close_fds', str(context.warning))
1356
Gregory P. Smithe14e9c22011-03-15 14:55:17 -04001357 def test_stdout_stdin_are_single_inout_fd(self):
1358 with io.open(os.devnull, "r+") as inout:
1359 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
1360 stdout=inout, stdin=inout)
1361 p.wait()
1362
1363 def test_stdout_stderr_are_single_inout_fd(self):
1364 with io.open(os.devnull, "r+") as inout:
1365 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
1366 stdout=inout, stderr=inout)
1367 p.wait()
1368
1369 def test_stderr_stdin_are_single_inout_fd(self):
1370 with io.open(os.devnull, "r+") as inout:
1371 p = subprocess.Popen([sys.executable, "-c", "import sys; sys.exit(0)"],
1372 stderr=inout, stdin=inout)
1373 p.wait()
1374
Gregory P. Smithe85db2b2010-12-14 14:38:00 +00001375 def test_wait_when_sigchild_ignored(self):
1376 # NOTE: sigchild_ignore.py may not be an effective test on all OSes.
1377 sigchild_ignore = support.findfile("sigchild_ignore.py",
1378 subdir="subprocessdata")
1379 p = subprocess.Popen([sys.executable, sigchild_ignore],
1380 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
1381 stdout, stderr = p.communicate()
1382 self.assertEqual(0, p.returncode, "sigchild_ignore.py exited"
Gregory P. Smitha80f4fb2010-12-14 15:23:02 +00001383 " non-zero with this error:\n%s" %
1384 stderr.decode('utf8'))
Gregory P. Smithe85db2b2010-12-14 14:38:00 +00001385
Antoine Pitrou7b98d022011-03-19 17:04:13 +01001386 def test_select_unbuffered(self):
1387 # Issue #11459: bufsize=0 should really set the pipes as
1388 # unbuffered (and therefore let select() work properly).
1389 select = support.import_module("select")
1390 p = subprocess.Popen([sys.executable, "-c",
1391 'import sys;'
1392 'sys.stdout.write("apple")'],
1393 stdout=subprocess.PIPE,
1394 bufsize=0)
1395 f = p.stdout
Ross Lagerwall17ace7a2011-03-26 21:21:46 +02001396 self.addCleanup(f.close)
Antoine Pitrou7b98d022011-03-19 17:04:13 +01001397 try:
1398 self.assertEqual(f.read(4), b"appl")
1399 self.assertIn(f, select.select([f], [], [], 0.0)[0])
1400 finally:
1401 p.wait()
1402
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001403 def test_zombie_fast_process_del(self):
1404 # Issue #12650: on Unix, if Popen.__del__() was called before the
1405 # process exited, it wouldn't be added to subprocess._active, and would
1406 # remain a zombie.
1407 # spawn a Popen, and delete its reference before it exits
1408 p = subprocess.Popen([sys.executable, "-c",
1409 'import sys, time;'
1410 'time.sleep(0.2)'],
1411 stdout=subprocess.PIPE,
1412 stderr=subprocess.PIPE)
Nadeem Vawda0d7cda32011-08-19 05:12:01 +02001413 self.addCleanup(p.stdout.close)
1414 self.addCleanup(p.stderr.close)
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001415 ident = id(p)
1416 pid = p.pid
1417 del p
1418 # check that p is in the active processes list
1419 self.assertIn(ident, [id(o) for o in subprocess._active])
1420
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001421 def test_leak_fast_process_del_killed(self):
1422 # Issue #12650: on Unix, if Popen.__del__() was called before the
1423 # process exited, and the process got killed by a signal, it would never
1424 # be removed from subprocess._active, which triggered a FD and memory
1425 # leak.
1426 # spawn a Popen, delete its reference and kill it
1427 p = subprocess.Popen([sys.executable, "-c",
1428 'import time;'
1429 'time.sleep(3)'],
1430 stdout=subprocess.PIPE,
1431 stderr=subprocess.PIPE)
Nadeem Vawda0d7cda32011-08-19 05:12:01 +02001432 self.addCleanup(p.stdout.close)
1433 self.addCleanup(p.stderr.close)
Charles-François Natali134a8ba2011-08-18 18:49:39 +02001434 ident = id(p)
1435 pid = p.pid
1436 del p
1437 os.kill(pid, signal.SIGKILL)
1438 # check that p is in the active processes list
1439 self.assertIn(ident, [id(o) for o in subprocess._active])
1440
1441 # let some time for the process to exit, and create a new Popen: this
1442 # should trigger the wait() of p
1443 time.sleep(0.2)
1444 with self.assertRaises(EnvironmentError) as c:
1445 with subprocess.Popen(['nonexisting_i_hope'],
1446 stdout=subprocess.PIPE,
1447 stderr=subprocess.PIPE) as proc:
1448 pass
1449 # p should have been wait()ed on, and removed from the _active list
1450 self.assertRaises(OSError, os.waitpid, pid, 0)
1451 self.assertNotIn(ident, [id(o) for o in subprocess._active])
1452
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001453
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001454@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunac049d872010-03-27 22:47:23 +00001455class Win32ProcessTestCase(BaseTestCase):
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001456
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001457 def test_startupinfo(self):
1458 # startupinfo argument
1459 # We uses hardcoded constants, because we do not want to
1460 # depend on win32all.
1461 STARTF_USESHOWWINDOW = 1
1462 SW_MAXIMIZE = 3
1463 startupinfo = subprocess.STARTUPINFO()
1464 startupinfo.dwFlags = STARTF_USESHOWWINDOW
1465 startupinfo.wShowWindow = SW_MAXIMIZE
1466 # Since Python is a console process, it won't be affected
1467 # by wShowWindow, but the argument should be silently
1468 # ignored
1469 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001470 startupinfo=startupinfo)
1471
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001472 def test_creationflags(self):
1473 # creationflags argument
1474 CREATE_NEW_CONSOLE = 16
1475 sys.stderr.write(" a DOS box should flash briefly ...\n")
1476 subprocess.call(sys.executable +
1477 ' -c "import time; time.sleep(0.25)"',
1478 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001479
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001480 def test_invalid_args(self):
1481 # invalid arguments should raise ValueError
1482 self.assertRaises(ValueError, subprocess.call,
1483 [sys.executable, "-c",
1484 "import sys; sys.exit(47)"],
1485 preexec_fn=lambda: 1)
1486 self.assertRaises(ValueError, subprocess.call,
1487 [sys.executable, "-c",
1488 "import sys; sys.exit(47)"],
1489 stdout=subprocess.PIPE,
1490 close_fds=True)
1491
1492 def test_close_fds(self):
1493 # close file descriptors
1494 rc = subprocess.call([sys.executable, "-c",
1495 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001496 close_fds=True)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001497 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001498
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001499 def test_shell_sequence(self):
1500 # Run command through the shell (sequence)
1501 newenv = os.environ.copy()
1502 newenv["FRUIT"] = "physalis"
1503 p = subprocess.Popen(["set"], shell=1,
1504 stdout=subprocess.PIPE,
1505 env=newenv)
Brian Curtin19a53792010-11-05 17:09:05 +00001506 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001507 self.assertIn(b"physalis", p.stdout.read())
Guido van Rossume7ba4952007-06-06 23:52:48 +00001508
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001509 def test_shell_string(self):
1510 # Run command through the shell (string)
1511 newenv = os.environ.copy()
1512 newenv["FRUIT"] = "physalis"
1513 p = subprocess.Popen("set", shell=1,
1514 stdout=subprocess.PIPE,
1515 env=newenv)
Brian Curtin19a53792010-11-05 17:09:05 +00001516 self.addCleanup(p.stdout.close)
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001517 self.assertIn(b"physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001518
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001519 def test_call_string(self):
1520 # call() function with string argument on Windows
1521 rc = subprocess.call(sys.executable +
1522 ' -c "import sys; sys.exit(47)"')
1523 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001524
Florent Xicluna4886d242010-03-08 13:27:26 +00001525 def _kill_process(self, method, *args):
1526 # Some win32 buildbot raises EOFError if stdin is inherited
Antoine Pitroua4024e22010-09-24 18:57:01 +00001527 p = subprocess.Popen([sys.executable, "-c", """if 1:
1528 import sys, time
1529 sys.stdout.write('x\\n')
1530 sys.stdout.flush()
1531 time.sleep(30)
1532 """],
1533 stdin=subprocess.PIPE,
1534 stdout=subprocess.PIPE,
1535 stderr=subprocess.PIPE)
Brian Curtin19a53792010-11-05 17:09:05 +00001536 self.addCleanup(p.stdout.close)
1537 self.addCleanup(p.stderr.close)
1538 self.addCleanup(p.stdin.close)
Antoine Pitroua4024e22010-09-24 18:57:01 +00001539 # Wait for the interpreter to be completely initialized before
1540 # sending any signal.
1541 p.stdout.read(1)
1542 getattr(p, method)(*args)
Florent Xiclunac049d872010-03-27 22:47:23 +00001543 _, stderr = p.communicate()
1544 self.assertStderrEqual(stderr, b'')
Antoine Pitroua4024e22010-09-24 18:57:01 +00001545 returncode = p.wait()
Florent Xicluna4886d242010-03-08 13:27:26 +00001546 self.assertNotEqual(returncode, 0)
1547
1548 def test_send_signal(self):
1549 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimesa342c012008-04-20 21:01:16 +00001550
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001551 def test_kill(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00001552 self._kill_process('kill')
Christian Heimesa342c012008-04-20 21:01:16 +00001553
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001554 def test_terminate(self):
Florent Xicluna4886d242010-03-08 13:27:26 +00001555 self._kill_process('terminate')
Christian Heimesa342c012008-04-20 21:01:16 +00001556
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001557
Brett Cannona23810f2008-05-26 19:04:21 +00001558# The module says:
1559# "NB This only works (and is only relevant) for UNIX."
1560#
1561# Actually, getoutput should work on any platform with an os.popen, but
1562# I'll take the comment as given, and skip this suite.
Florent Xiclunaf0cbd822010-03-04 21:50:56 +00001563@unittest.skipUnless(os.name == 'posix', "only relevant for UNIX")
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001564class CommandTests(unittest.TestCase):
1565 def test_getoutput(self):
1566 self.assertEqual(subprocess.getoutput('echo xyzzy'), 'xyzzy')
1567 self.assertEqual(subprocess.getstatusoutput('echo xyzzy'),
1568 (0, 'xyzzy'))
Brett Cannona23810f2008-05-26 19:04:21 +00001569
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001570 # we use mkdtemp in the next line to create an empty directory
1571 # under our exclusive control; from that, we can invent a pathname
1572 # that we _know_ won't exist. This is guaranteed to fail.
1573 dir = None
1574 try:
1575 dir = tempfile.mkdtemp()
1576 name = os.path.join(dir, "foo")
Brett Cannona23810f2008-05-26 19:04:21 +00001577
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001578 status, output = subprocess.getstatusoutput('cat ' + name)
1579 self.assertNotEqual(status, 0)
1580 finally:
1581 if dir is not None:
1582 os.rmdir(dir)
Brett Cannona23810f2008-05-26 19:04:21 +00001583
Gregory P. Smithd06fa472009-07-04 02:46:54 +00001584
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001585@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
1586 "poll system call not supported")
1587class ProcessTestCaseNoPoll(ProcessTestCase):
1588 def setUp(self):
1589 subprocess._has_poll = False
1590 ProcessTestCase.setUp(self)
Gregory P. Smithd06fa472009-07-04 02:46:54 +00001591
Florent Xiclunab1e94e82010-02-27 22:12:37 +00001592 def tearDown(self):
1593 subprocess._has_poll = True
1594 ProcessTestCase.tearDown(self)
Gregory P. Smithd06fa472009-07-04 02:46:54 +00001595
1596
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001597@unittest.skipUnless(getattr(subprocess, '_posixsubprocess', False),
1598 "_posixsubprocess extension module not found.")
1599class ProcessTestCasePOSIXPurePython(ProcessTestCase, POSIXProcessTestCase):
Gregory P. Smith7439e7b2011-05-28 09:06:02 -07001600 @classmethod
1601 def setUpClass(cls):
1602 global subprocess
1603 assert subprocess._posixsubprocess
1604 # Reimport subprocess while forcing _posixsubprocess to not exist.
1605 with support.check_warnings(('.*_posixsubprocess .* not being used.*',
1606 RuntimeWarning)):
1607 subprocess = support.import_fresh_module(
1608 'subprocess', blocked=['_posixsubprocess'])
1609 assert not subprocess._posixsubprocess
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001610
Gregory P. Smith7439e7b2011-05-28 09:06:02 -07001611 @classmethod
1612 def tearDownClass(cls):
1613 global subprocess
1614 # Reimport subprocess as it should be, restoring order to the universe.
1615 subprocess = support.import_fresh_module('subprocess')
1616 assert subprocess._posixsubprocess
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +00001617
1618
Gregory P. Smitha59c59f2010-03-01 00:17:40 +00001619class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithaf6d3b82010-03-01 02:56:44 +00001620 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smitha59c59f2010-03-01 00:17:40 +00001621 def test_eintr_retry_call(self):
1622 record_calls = []
1623 def fake_os_func(*args):
1624 record_calls.append(args)
1625 if len(record_calls) == 2:
1626 raise OSError(errno.EINTR, "fake interrupted system call")
1627 return tuple(reversed(args))
1628
1629 self.assertEqual((999, 256),
1630 subprocess._eintr_retry_call(fake_os_func, 256, 999))
1631 self.assertEqual([(256, 999)], record_calls)
1632 # This time there will be an EINTR so it will loop once.
1633 self.assertEqual((666,),
1634 subprocess._eintr_retry_call(fake_os_func, 666))
1635 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
1636
1637
Tim Golden126c2962010-08-11 14:20:40 +00001638@unittest.skipUnless(mswindows, "Windows-specific tests")
1639class CommandsWithSpaces (BaseTestCase):
1640
1641 def setUp(self):
1642 super().setUp()
1643 f, fname = mkstemp(".py", "te st")
1644 self.fname = fname.lower ()
1645 os.write(f, b"import sys;"
1646 b"sys.stdout.write('%d %s' % (len(sys.argv), [a.lower () for a in sys.argv]))"
1647 )
1648 os.close(f)
1649
1650 def tearDown(self):
1651 os.remove(self.fname)
1652 super().tearDown()
1653
1654 def with_spaces(self, *args, **kwargs):
1655 kwargs['stdout'] = subprocess.PIPE
1656 p = subprocess.Popen(*args, **kwargs)
Brian Curtin19a53792010-11-05 17:09:05 +00001657 self.addCleanup(p.stdout.close)
Tim Golden126c2962010-08-11 14:20:40 +00001658 self.assertEqual(
1659 p.stdout.read ().decode("mbcs"),
1660 "2 [%r, 'ab cd']" % self.fname
1661 )
1662
1663 def test_shell_string_with_spaces(self):
1664 # call() function with string argument with spaces on Windows
Brian Curtind835cf12010-08-13 20:42:57 +00001665 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
1666 "ab cd"), shell=1)
Tim Golden126c2962010-08-11 14:20:40 +00001667
1668 def test_shell_sequence_with_spaces(self):
1669 # call() function with sequence argument with spaces on Windows
Brian Curtind835cf12010-08-13 20:42:57 +00001670 self.with_spaces([sys.executable, self.fname, "ab cd"], shell=1)
Tim Golden126c2962010-08-11 14:20:40 +00001671
1672 def test_noshell_string_with_spaces(self):
1673 # call() function with string argument with spaces on Windows
1674 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
1675 "ab cd"))
1676
1677 def test_noshell_sequence_with_spaces(self):
1678 # call() function with sequence argument with spaces on Windows
1679 self.with_spaces([sys.executable, self.fname, "ab cd"])
1680
Brian Curtin79cdb662010-12-03 02:46:02 +00001681
1682class ContextManagerTests(ProcessTestCase):
1683
1684 def test_pipe(self):
1685 with subprocess.Popen([sys.executable, "-c",
1686 "import sys;"
1687 "sys.stdout.write('stdout');"
1688 "sys.stderr.write('stderr');"],
1689 stdout=subprocess.PIPE,
1690 stderr=subprocess.PIPE) as proc:
1691 self.assertEqual(proc.stdout.read(), b"stdout")
1692 self.assertStderrEqual(proc.stderr.read(), b"stderr")
1693
1694 self.assertTrue(proc.stdout.closed)
1695 self.assertTrue(proc.stderr.closed)
1696
1697 def test_returncode(self):
1698 with subprocess.Popen([sys.executable, "-c",
1699 "import sys; sys.exit(100)"]) as proc:
Gregory P. Smithc9557af2011-05-11 22:18:23 -07001700 pass
1701 # __exit__ calls wait(), so the returncode should be set
Brian Curtin79cdb662010-12-03 02:46:02 +00001702 self.assertEqual(proc.returncode, 100)
1703
1704 def test_communicate_stdin(self):
1705 with subprocess.Popen([sys.executable, "-c",
1706 "import sys;"
1707 "sys.exit(sys.stdin.read() == 'context')"],
1708 stdin=subprocess.PIPE) as proc:
1709 proc.communicate(b"context")
1710 self.assertEqual(proc.returncode, 1)
1711
1712 def test_invalid_args(self):
1713 with self.assertRaises(EnvironmentError) as c:
1714 with subprocess.Popen(['nonexisting_i_hope'],
1715 stdout=subprocess.PIPE,
1716 stderr=subprocess.PIPE) as proc:
1717 pass
1718
1719 if c.exception.errno != errno.ENOENT: # ignore "no such file"
1720 raise c.exception
1721
1722
Gregory P. Smith961e0e82011-03-15 15:43:39 -04001723def test_main():
1724 unit_tests = (ProcessTestCase,
1725 POSIXProcessTestCase,
1726 Win32ProcessTestCase,
1727 ProcessTestCasePOSIXPurePython,
1728 CommandTests,
1729 ProcessTestCaseNoPoll,
1730 HelperFunctionTests,
1731 CommandsWithSpaces,
Antoine Pitrouab85ff32011-07-23 22:03:45 +02001732 ContextManagerTests,
1733 )
Gregory P. Smith961e0e82011-03-15 15:43:39 -04001734
1735 support.run_unittest(*unit_tests)
1736 support.reap_children()
1737
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001738if __name__ == "__main__":
Gregory P. Smithe14e9c22011-03-15 14:55:17 -04001739 unittest.main()