blob: 9f8512d7cc3b06bfd1a537222a00dbb9c8cfdfd1 [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
6import os
Gregory P. Smitha59c59f2010-03-01 00:17:40 +00007import errno
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00008import tempfile
9import time
Tim Peters3761e8d2004-10-13 04:07:12 +000010import re
Ezio Melotti184bdfb2010-02-18 09:37:05 +000011import sysconfig
Gregory P. Smith32ec9da2010-03-19 16:53:08 +000012try:
13 import gc
14except ImportError:
15 gc = None
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000016
17mswindows = (sys.platform == "win32")
18
19#
20# Depends on the following external programs: Python
21#
22
23if mswindows:
Tim Peters3b01a702004-10-12 22:19:32 +000024 SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
25 'os.O_BINARY);')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000026else:
27 SETBINARY = ''
28
Florent Xiclunab1e94e82010-02-27 22:12:37 +000029
30try:
31 mkstemp = tempfile.mkstemp
32except AttributeError:
33 # tempfile.mkstemp is not available
34 def mkstemp():
35 """Replacement for mkstemp, calling mktemp."""
36 fname = tempfile.mktemp()
37 return os.open(fname, os.O_RDWR|os.O_CREAT), fname
38
Tim Peters3761e8d2004-10-13 04:07:12 +000039
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000040class ProcessTestCase(unittest.TestCase):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000041 def setUp(self):
42 # Try to minimize the number of children we have so this test
43 # doesn't crash on some buildbots (Alphas in particular).
Florent Xiclunab1e94e82010-02-27 22:12:37 +000044 support.reap_children()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000045
Florent Xiclunaf0cbd822010-03-04 21:50:56 +000046 def tearDown(self):
47 for inst in subprocess._active:
48 inst.wait()
49 subprocess._cleanup()
50 self.assertFalse(subprocess._active, "subprocess._active not empty")
51
Florent Xiclunab1e94e82010-02-27 22:12:37 +000052 def assertStderrEqual(self, stderr, expected, msg=None):
53 # In a debug build, stuff like "[6580 refs]" is printed to stderr at
54 # shutdown time. That frustrates tests trying to check stderr produced
55 # from a spawned Python process.
56 actual = re.sub("\[\d+ refs\]\r?\n?$", "", stderr.decode()).encode()
57 self.assertEqual(actual, expected, msg)
Thomas Wouters0e3f5912006-08-11 14:57:12 +000058
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000059 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +000060 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +000061 rc = subprocess.call([sys.executable, "-c",
62 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000063 self.assertEqual(rc, 47)
64
Peter Astrand454f7672005-01-01 09:36:35 +000065 def test_check_call_zero(self):
66 # check_call() function with zero return code
67 rc = subprocess.check_call([sys.executable, "-c",
68 "import sys; sys.exit(0)"])
69 self.assertEqual(rc, 0)
70
71 def test_check_call_nonzero(self):
72 # check_call() function with non-zero return code
Florent Xiclunab1e94e82010-02-27 22:12:37 +000073 with self.assertRaises(subprocess.CalledProcessError) as c:
Peter Astrand454f7672005-01-01 09:36:35 +000074 subprocess.check_call([sys.executable, "-c",
75 "import sys; sys.exit(47)"])
Florent Xiclunab1e94e82010-02-27 22:12:37 +000076 self.assertEqual(c.exception.returncode, 47)
Peter Astrand454f7672005-01-01 09:36:35 +000077
Georg Brandlf9734072008-12-07 15:30:06 +000078 def test_check_output(self):
79 # check_output() function with zero return code
80 output = subprocess.check_output(
81 [sys.executable, "-c", "print('BDFL')"])
Benjamin Peterson577473f2010-01-19 00:09:57 +000082 self.assertIn(b'BDFL', output)
Georg Brandlf9734072008-12-07 15:30:06 +000083
84 def test_check_output_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:
Georg Brandlf9734072008-12-07 15:30:06 +000087 subprocess.check_output(
88 [sys.executable, "-c", "import sys; sys.exit(5)"])
Florent Xiclunab1e94e82010-02-27 22:12:37 +000089 self.assertEqual(c.exception.returncode, 5)
Georg Brandlf9734072008-12-07 15:30:06 +000090
91 def test_check_output_stderr(self):
92 # check_output() function stderr redirected to stdout
93 output = subprocess.check_output(
94 [sys.executable, "-c", "import sys; sys.stderr.write('BDFL')"],
95 stderr=subprocess.STDOUT)
Benjamin Peterson577473f2010-01-19 00:09:57 +000096 self.assertIn(b'BDFL', output)
Georg Brandlf9734072008-12-07 15:30:06 +000097
98 def test_check_output_stdout_arg(self):
99 # check_output() function stderr redirected to stdout
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000100 with self.assertRaises(ValueError) as c:
Georg Brandlf9734072008-12-07 15:30:06 +0000101 output = subprocess.check_output(
102 [sys.executable, "-c", "print('will not be run')"],
103 stdout=sys.stdout)
Georg Brandlf9734072008-12-07 15:30:06 +0000104 self.fail("Expected ValueError when stdout arg supplied.")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000105 self.assertIn('stdout', c.exception.args[0])
Georg Brandlf9734072008-12-07 15:30:06 +0000106
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000107 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000108 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000109 newenv = os.environ.copy()
110 newenv["FRUIT"] = "banana"
111 rc = subprocess.call([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000112 'import sys, os;'
113 'sys.exit(os.getenv("FRUIT")=="banana")'],
114 env=newenv)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000115 self.assertEqual(rc, 1)
116
117 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000118 # .stdin is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000119 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000120 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
121 p.wait()
122 self.assertEqual(p.stdin, None)
123
124 def test_stdout_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000125 # .stdout is None when not redirected
Tim Peters29b6b4f2004-10-13 03:43:40 +0000126 p = subprocess.Popen([sys.executable, "-c",
Georg Brandl88fc6642007-02-09 21:28:07 +0000127 'print(" this bit of output is from a '
Tim Peters4052fe52004-10-13 03:29:54 +0000128 'test of stdout in a different '
Georg Brandl88fc6642007-02-09 21:28:07 +0000129 'process ...")'],
Tim Peters4052fe52004-10-13 03:29:54 +0000130 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000131 p.wait()
132 self.assertEqual(p.stdout, None)
133
134 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000135 # .stderr is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000136 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000137 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
138 p.wait()
139 self.assertEqual(p.stderr, None)
140
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000141 def test_executable_with_cwd(self):
Florent Xicluna1d1ab972010-03-11 01:53:10 +0000142 python_dir = os.path.dirname(os.path.realpath(sys.executable))
Ezio Melotti184bdfb2010-02-18 09:37:05 +0000143 p = subprocess.Popen(["somethingyoudonthave", "-c",
144 "import sys; sys.exit(47)"],
145 executable=sys.executable, cwd=python_dir)
146 p.wait()
147 self.assertEqual(p.returncode, 47)
148
149 @unittest.skipIf(sysconfig.is_python_build(),
150 "need an installed Python. See #7774")
151 def test_executable_without_cwd(self):
152 # For a normal installation, it should work without 'cwd'
153 # argument. For test runs in the build directory, see #7774.
154 p = subprocess.Popen(["somethingyoudonthave", "-c",
155 "import sys; sys.exit(47)"],
Tim Peters3b01a702004-10-12 22:19:32 +0000156 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000157 p.wait()
158 self.assertEqual(p.returncode, 47)
159
160 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000161 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000162 p = subprocess.Popen([sys.executable, "-c",
163 'import sys; sys.exit(sys.stdin.read() == "pear")'],
164 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000165 p.stdin.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000166 p.stdin.close()
167 p.wait()
168 self.assertEqual(p.returncode, 1)
169
170 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000171 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000172 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000173 d = tf.fileno()
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000174 os.write(d, b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000175 os.lseek(d, 0, 0)
176 p = subprocess.Popen([sys.executable, "-c",
177 'import sys; sys.exit(sys.stdin.read() == "pear")'],
178 stdin=d)
179 p.wait()
180 self.assertEqual(p.returncode, 1)
181
182 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000183 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000184 tf = tempfile.TemporaryFile()
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000185 tf.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000186 tf.seek(0)
187 p = subprocess.Popen([sys.executable, "-c",
188 'import sys; sys.exit(sys.stdin.read() == "pear")'],
189 stdin=tf)
190 p.wait()
191 self.assertEqual(p.returncode, 1)
192
193 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000194 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000195 p = subprocess.Popen([sys.executable, "-c",
196 'import sys; sys.stdout.write("orange")'],
197 stdout=subprocess.PIPE)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000198 self.assertEqual(p.stdout.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000199
200 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000201 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000202 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000203 d = tf.fileno()
204 p = subprocess.Popen([sys.executable, "-c",
205 'import sys; sys.stdout.write("orange")'],
206 stdout=d)
207 p.wait()
208 os.lseek(d, 0, 0)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000209 self.assertEqual(os.read(d, 1024), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000210
211 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000212 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000213 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000214 p = subprocess.Popen([sys.executable, "-c",
215 'import sys; sys.stdout.write("orange")'],
216 stdout=tf)
217 p.wait()
218 tf.seek(0)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000219 self.assertEqual(tf.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000220
221 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000222 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000223 p = subprocess.Popen([sys.executable, "-c",
224 'import sys; sys.stderr.write("strawberry")'],
225 stderr=subprocess.PIPE)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000226 self.assertStderrEqual(p.stderr.read(), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000227
228 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000229 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000230 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000231 d = tf.fileno()
232 p = subprocess.Popen([sys.executable, "-c",
233 'import sys; sys.stderr.write("strawberry")'],
234 stderr=d)
235 p.wait()
236 os.lseek(d, 0, 0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000237 self.assertStderrEqual(os.read(d, 1024), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000238
239 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000240 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000241 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000242 p = subprocess.Popen([sys.executable, "-c",
243 'import sys; sys.stderr.write("strawberry")'],
244 stderr=tf)
245 p.wait()
246 tf.seek(0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000247 self.assertStderrEqual(tf.read(), b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000248
249 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000250 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000251 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000252 'import sys;'
253 'sys.stdout.write("apple");'
254 'sys.stdout.flush();'
255 'sys.stderr.write("orange")'],
256 stdout=subprocess.PIPE,
257 stderr=subprocess.STDOUT)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000258 self.assertStderrEqual(p.stdout.read(), b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000259
260 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000261 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000262 tf = tempfile.TemporaryFile()
263 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000264 'import sys;'
265 'sys.stdout.write("apple");'
266 'sys.stdout.flush();'
267 'sys.stderr.write("orange")'],
268 stdout=tf,
269 stderr=tf)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000270 p.wait()
271 tf.seek(0)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000272 self.assertStderrEqual(tf.read(), b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000273
Thomas Wouters89f507f2006-12-13 04:49:30 +0000274 def test_stdout_filedes_of_stdout(self):
275 # stdout is set to 1 (#1531862).
Antoine Pitrou9cadb1b2008-09-15 23:02:56 +0000276 cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), b'.\n'))"
Thomas Wouters89f507f2006-12-13 04:49:30 +0000277 rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000278 self.assertEqual(rc, 2)
Thomas Wouters89f507f2006-12-13 04:49:30 +0000279
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000280 def test_cwd(self):
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000281 tmpdir = tempfile.gettempdir()
Peter Astrand195404f2004-11-12 15:51:48 +0000282 # We cannot use os.path.realpath to canonicalize the path,
283 # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
284 cwd = os.getcwd()
285 os.chdir(tmpdir)
286 tmpdir = os.getcwd()
287 os.chdir(cwd)
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,os;'
290 'sys.stdout.write(os.getcwd())'],
291 stdout=subprocess.PIPE,
292 cwd=tmpdir)
Fredrik Lundh59c05592004-10-13 06:55:40 +0000293 normcase = os.path.normcase
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000294 self.assertEqual(normcase(p.stdout.read().decode("utf-8")),
295 normcase(tmpdir))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000296
297 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000298 newenv = os.environ.copy()
299 newenv["FRUIT"] = "orange"
300 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000301 'import sys,os;'
302 'sys.stdout.write(os.getenv("FRUIT"))'],
303 stdout=subprocess.PIPE,
304 env=newenv)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000305 self.assertEqual(p.stdout.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000306
Peter Astrandcbac93c2005-03-03 20:24:28 +0000307 def test_communicate_stdin(self):
308 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000309 'import sys;'
310 'sys.exit(sys.stdin.read() == "pear")'],
Peter Astrandcbac93c2005-03-03 20:24:28 +0000311 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000312 p.communicate(b"pear")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000313 self.assertEqual(p.returncode, 1)
314
315 def test_communicate_stdout(self):
316 p = subprocess.Popen([sys.executable, "-c",
317 'import sys; sys.stdout.write("pineapple")'],
318 stdout=subprocess.PIPE)
319 (stdout, stderr) = p.communicate()
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000320 self.assertEqual(stdout, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000321 self.assertEqual(stderr, None)
322
323 def test_communicate_stderr(self):
324 p = subprocess.Popen([sys.executable, "-c",
325 'import sys; sys.stderr.write("pineapple")'],
326 stderr=subprocess.PIPE)
327 (stdout, stderr) = p.communicate()
328 self.assertEqual(stdout, None)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000329 self.assertStderrEqual(stderr, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000330
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000331 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000332 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000333 'import sys,os;'
334 'sys.stderr.write("pineapple");'
335 'sys.stdout.write(sys.stdin.read())'],
336 stdin=subprocess.PIPE,
337 stdout=subprocess.PIPE,
338 stderr=subprocess.PIPE)
Georg Brandl1abcbf82008-07-01 19:28:43 +0000339 (stdout, stderr) = p.communicate(b"banana")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000340 self.assertEqual(stdout, b"banana")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000341 self.assertStderrEqual(stderr, b"pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000342
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000343 # This test is Linux specific for simplicity to at least have
344 # some coverage. It is not a platform specific bug.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000345 @unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()),
346 "Linux specific")
347 # Test for the fd leak reported in http://bugs.python.org/issue2791.
348 def test_communicate_pipe_fd_leak(self):
349 fd_directory = '/proc/%d/fd' % os.getpid()
350 num_fds_before_popen = len(os.listdir(fd_directory))
351 p = subprocess.Popen([sys.executable, "-c", "print()"],
352 stdout=subprocess.PIPE)
353 p.communicate()
354 num_fds_after_communicate = len(os.listdir(fd_directory))
355 del p
356 num_fds_after_destruction = len(os.listdir(fd_directory))
357 self.assertEqual(num_fds_before_popen, num_fds_after_destruction)
358 self.assertEqual(num_fds_before_popen, num_fds_after_communicate)
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000359
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000360 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000361 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000362 p = subprocess.Popen([sys.executable, "-c",
363 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000364 (stdout, stderr) = p.communicate()
365 self.assertEqual(stdout, None)
366 self.assertEqual(stderr, None)
367
368 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000369 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000370 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000371 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000372 x, y = os.pipe()
373 if mswindows:
374 pipe_buf = 512
375 else:
376 pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
377 os.close(x)
378 os.close(y)
379 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000380 'import sys,os;'
381 'sys.stdout.write(sys.stdin.read(47));'
382 'sys.stderr.write("xyz"*%d);'
383 'sys.stdout.write(sys.stdin.read())' % pipe_buf],
384 stdin=subprocess.PIPE,
385 stdout=subprocess.PIPE,
386 stderr=subprocess.PIPE)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000387 string_to_write = b"abc"*pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000388 (stdout, stderr) = p.communicate(string_to_write)
389 self.assertEqual(stdout, string_to_write)
390
391 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000392 # stdin.write before communicate()
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.stdout.write(sys.stdin.read())'],
396 stdin=subprocess.PIPE,
397 stdout=subprocess.PIPE,
398 stderr=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000399 p.stdin.write(b"banana")
400 (stdout, stderr) = p.communicate(b"split")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000401 self.assertEqual(stdout, b"bananasplit")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000402 self.assertStderrEqual(stderr, b"")
Tim Peterse718f612004-10-12 21:51:32 +0000403
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000404 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000405 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000406 'import sys,os;' + SETBINARY +
407 'sys.stdout.write("line1\\n");'
408 'sys.stdout.flush();'
409 'sys.stdout.write("line2\\n");'
410 'sys.stdout.flush();'
411 'sys.stdout.write("line3\\r\\n");'
412 'sys.stdout.flush();'
413 'sys.stdout.write("line4\\r");'
414 'sys.stdout.flush();'
415 'sys.stdout.write("\\nline5");'
416 'sys.stdout.flush();'
417 'sys.stdout.write("\\nline6");'],
418 stdout=subprocess.PIPE,
419 universal_newlines=1)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000420 stdout = p.stdout.read()
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000421 self.assertEqual(stdout, "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000422
423 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000424 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000425 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000426 'import sys,os;' + SETBINARY +
427 'sys.stdout.write("line1\\n");'
428 'sys.stdout.flush();'
429 'sys.stdout.write("line2\\n");'
430 'sys.stdout.flush();'
431 'sys.stdout.write("line3\\r\\n");'
432 'sys.stdout.flush();'
433 'sys.stdout.write("line4\\r");'
434 'sys.stdout.flush();'
435 'sys.stdout.write("\\nline5");'
436 'sys.stdout.flush();'
437 'sys.stdout.write("\\nline6");'],
438 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
439 universal_newlines=1)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000440 (stdout, stderr) = p.communicate()
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000441 self.assertEqual(stdout, "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000442
443 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000444 # Make sure we leak no resources
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000445 if (not hasattr(support, "is_resource_enabled") or
446 support.is_resource_enabled("subprocess") and not mswindows):
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000447 max_handles = 1026 # too much for most UNIX systems
448 else:
Tim Peterseba28be2005-03-28 01:08:02 +0000449 max_handles = 65
Fredrik Lundh9e29fc52004-10-13 07:54:54 +0000450 for i in range(max_handles):
Tim Peters3b01a702004-10-12 22:19:32 +0000451 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000452 "import sys;"
453 "sys.stdout.write(sys.stdin.read())"],
454 stdin=subprocess.PIPE,
455 stdout=subprocess.PIPE,
456 stderr=subprocess.PIPE)
Georg Brandl1abcbf82008-07-01 19:28:43 +0000457 data = p.communicate(b"lime")[0]
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000458 self.assertEqual(data, b"lime")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000459
460
461 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000462 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
463 '"a b c" d e')
464 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
465 'ab\\"c \\ d')
Christian Heimesfdab48e2008-01-20 09:06:41 +0000466 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
467 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000468 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
469 'a\\\\\\b "de fg" h')
470 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
471 'a\\\\\\"b c d')
472 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
473 '"a\\\\b c" d e')
474 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
475 '"a\\\\b\\ c" d e')
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000476 self.assertEqual(subprocess.list2cmdline(['ab', '']),
477 'ab ""')
Christian Heimesfdab48e2008-01-20 09:06:41 +0000478 self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']),
479 'echo "foo|bar"')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000480
481
482 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000483 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000484 "-c", "import time; time.sleep(1)"])
485 count = 0
486 while p.poll() is None:
487 time.sleep(0.1)
488 count += 1
489 # We expect that the poll loop probably went around about 10 times,
490 # but, based on system scheduling we can't control, it's possible
491 # poll() never returned None. It "should be" very rare that it
492 # didn't go around at least twice.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000493 self.assertGreaterEqual(count, 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000494 # Subsequent invocations should just return the returncode
495 self.assertEqual(p.poll(), 0)
496
497
498 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000499 p = subprocess.Popen([sys.executable,
500 "-c", "import time; time.sleep(2)"])
501 self.assertEqual(p.wait(), 0)
502 # Subsequent invocations should just return the returncode
503 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000504
Peter Astrand738131d2004-11-30 21:04:45 +0000505
506 def test_invalid_bufsize(self):
507 # an invalid type of the bufsize argument should raise
508 # TypeError.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000509 with self.assertRaises(TypeError):
Peter Astrand738131d2004-11-30 21:04:45 +0000510 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
Peter Astrand738131d2004-11-30 21:04:45 +0000511
Guido van Rossum46a05a72007-06-07 21:56:45 +0000512 def test_bufsize_is_none(self):
513 # bufsize=None should be the same as bufsize=0.
514 p = subprocess.Popen([sys.executable, "-c", "pass"], None)
515 self.assertEqual(p.wait(), 0)
516 # Again with keyword arg
517 p = subprocess.Popen([sys.executable, "-c", "pass"], bufsize=None)
518 self.assertEqual(p.wait(), 0)
519
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000520 def test_leaking_fds_on_error(self):
521 # see bug #5179: Popen leaks file descriptors to PIPEs if
522 # the child fails to execute; this will eventually exhaust
523 # the maximum number of open fds. 1024 seems a very common
524 # value for that limit, but Windows has 2048, so we loop
525 # 1024 times (each call leaked two fds).
526 for i in range(1024):
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000527 # Windows raises IOError. Others raise OSError.
528 with self.assertRaises(EnvironmentError) as c:
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000529 subprocess.Popen(['nonexisting_i_hope'],
530 stdout=subprocess.PIPE,
531 stderr=subprocess.PIPE)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000532 if c.exception.errno != 2: # ignore "no such file"
533 raise c.exception
Benjamin Petersond75fcb42009-02-19 04:22:03 +0000534
Tim Peterse718f612004-10-12 21:51:32 +0000535
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000536# context manager
537class _SuppressCoreFiles(object):
538 """Try to prevent core files from being created."""
539 old_limit = None
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000540
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000541 def __enter__(self):
542 """Try to save previous ulimit, then set it to (0, 0)."""
543 try:
544 import resource
545 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
546 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
547 except (ImportError, ValueError, resource.error):
548 pass
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000549
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000550 def __exit__(self, *args):
551 """Return core file behavior to default."""
552 if self.old_limit is None:
553 return
554 try:
555 import resource
556 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
557 except (ImportError, ValueError, resource.error):
558 pass
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000559
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000560
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000561@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000562class POSIXProcessTestCase(unittest.TestCase):
563 def setUp(self):
564 # Try to minimize the number of children we have so this test
565 # doesn't crash on some buildbots (Alphas in particular).
566 support.reap_children()
567
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000568 def tearDown(self):
569 for inst in subprocess._active:
570 inst.wait()
571 subprocess._cleanup()
572 self.assertFalse(subprocess._active, "subprocess._active not empty")
573
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000574 def test_exceptions(self):
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000575 nonexistent_dir = "/_this/pa.th/does/not/exist"
576 try:
577 os.chdir(nonexistent_dir)
578 except OSError as e:
579 # This avoids hard coding the errno value or the OS perror()
580 # string and instead capture the exception that we want to see
581 # below for comparison.
582 desired_exception = e
583 else:
584 self.fail("chdir to nonexistant directory %s succeeded." %
585 nonexistent_dir)
586
587 # Error in the child re-raised in the parent.
588 try:
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000589 p = subprocess.Popen([sys.executable, "-c", ""],
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000590 cwd=nonexistent_dir)
591 except OSError as e:
592 # Test that the child process chdir failure actually makes
593 # it up to the parent process as the correct exception.
594 self.assertEqual(desired_exception.errno, e.errno)
595 self.assertEqual(desired_exception.strerror, e.strerror)
596 else:
597 self.fail("Expected OSError: %s" % desired_exception)
598
599 def test_restore_signals(self):
600 # Code coverage for both values of restore_signals to make sure it
601 # at least does not blow up.
602 # A test for behavior would be complex. Contributions welcome.
603 subprocess.call([sys.executable, "-c", ""], restore_signals=True)
604 subprocess.call([sys.executable, "-c", ""], restore_signals=False)
605
606 def test_start_new_session(self):
607 # For code coverage of calling setsid(). We don't care if we get an
608 # EPERM error from it depending on the test execution environment, that
609 # still indicates that it was called.
610 try:
611 output = subprocess.check_output(
612 [sys.executable, "-c",
613 "import os; print(os.getpgid(os.getpid()))"],
614 start_new_session=True)
615 except OSError as e:
616 if e.errno != errno.EPERM:
617 raise
618 else:
619 parent_pgid = os.getpgid(os.getpid())
620 child_pgid = int(output)
621 self.assertNotEqual(parent_pgid, child_pgid)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000622
623 def test_run_abort(self):
624 # returncode handles signal termination
625 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000626 p = subprocess.Popen([sys.executable, "-c",
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000627 'import os; os.abort()'])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000628 p.wait()
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000629 self.assertEqual(-p.returncode, signal.SIGABRT)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000630
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000631 def test_preexec(self):
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000632 # DISCLAIMER: Setting environment variables is *not* a good use
633 # of a preexec_fn. This is merely a test.
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000634 p = subprocess.Popen([sys.executable, "-c",
635 'import sys,os;'
636 'sys.stdout.write(os.getenv("FRUIT"))'],
637 stdout=subprocess.PIPE,
638 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
639 self.assertEqual(p.stdout.read(), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000640
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000641 def test_preexec_exception(self):
642 def raise_it():
643 raise ValueError("What if two swallows carried a coconut?")
644 try:
645 p = subprocess.Popen([sys.executable, "-c", ""],
646 preexec_fn=raise_it)
647 except RuntimeError as e:
648 self.assertTrue(
649 subprocess._posixsubprocess,
650 "Expected a ValueError from the preexec_fn")
651 except ValueError as e:
652 self.assertIn("coconut", e.args[0])
653 else:
654 self.fail("Exception raised by preexec_fn did not make it "
655 "to the parent process.")
656
Gregory P. Smith32ec9da2010-03-19 16:53:08 +0000657 @unittest.skipUnless(gc, "Requires a gc module.")
658 def test_preexec_gc_module_failure(self):
659 # This tests the code that disables garbage collection if the child
660 # process will execute any Python.
661 def raise_runtime_error():
662 raise RuntimeError("this shouldn't escape")
663 enabled = gc.isenabled()
664 orig_gc_disable = gc.disable
665 orig_gc_isenabled = gc.isenabled
666 try:
667 gc.disable()
668 self.assertFalse(gc.isenabled())
669 subprocess.call([sys.executable, '-c', ''],
670 preexec_fn=lambda: None)
671 self.assertFalse(gc.isenabled(),
672 "Popen enabled gc when it shouldn't.")
673
674 gc.enable()
675 self.assertTrue(gc.isenabled())
676 subprocess.call([sys.executable, '-c', ''],
677 preexec_fn=lambda: None)
678 self.assertTrue(gc.isenabled(), "Popen left gc disabled.")
679
680 gc.disable = raise_runtime_error
681 self.assertRaises(RuntimeError, subprocess.Popen,
682 [sys.executable, '-c', ''],
683 preexec_fn=lambda: None)
684
685 del gc.isenabled # force an AttributeError
686 self.assertRaises(AttributeError, subprocess.Popen,
687 [sys.executable, '-c', ''],
688 preexec_fn=lambda: None)
689 finally:
690 gc.disable = orig_gc_disable
691 gc.isenabled = orig_gc_isenabled
692 if not enabled:
693 gc.disable()
694
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000695 def test_args_string(self):
696 # args is a string
697 fd, fname = mkstemp()
698 # reopen in text mode
699 with open(fd, "w") as fobj:
700 fobj.write("#!/bin/sh\n")
701 fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" %
702 sys.executable)
703 os.chmod(fname, 0o700)
704 p = subprocess.Popen(fname)
705 p.wait()
706 os.remove(fname)
707 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000708
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000709 def test_invalid_args(self):
710 # invalid arguments should raise ValueError
711 self.assertRaises(ValueError, subprocess.call,
712 [sys.executable, "-c",
713 "import sys; sys.exit(47)"],
714 startupinfo=47)
715 self.assertRaises(ValueError, subprocess.call,
716 [sys.executable, "-c",
717 "import sys; sys.exit(47)"],
718 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000719
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000720 def test_shell_sequence(self):
721 # Run command through the shell (sequence)
722 newenv = os.environ.copy()
723 newenv["FRUIT"] = "apple"
724 p = subprocess.Popen(["echo $FRUIT"], shell=1,
725 stdout=subprocess.PIPE,
726 env=newenv)
727 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000728
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000729 def test_shell_string(self):
730 # Run command through the shell (string)
731 newenv = os.environ.copy()
732 newenv["FRUIT"] = "apple"
733 p = subprocess.Popen("echo $FRUIT", shell=1,
734 stdout=subprocess.PIPE,
735 env=newenv)
736 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Christian Heimesa342c012008-04-20 21:01:16 +0000737
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000738 def test_call_string(self):
739 # call() function with string argument on UNIX
740 fd, fname = mkstemp()
741 # reopen in text mode
742 with open(fd, "w") as fobj:
743 fobj.write("#!/bin/sh\n")
744 fobj.write("exec '%s' -c 'import sys; sys.exit(47)'\n" %
745 sys.executable)
746 os.chmod(fname, 0o700)
747 rc = subprocess.call(fname)
748 os.remove(fname)
749 self.assertEqual(rc, 47)
Christian Heimesa342c012008-04-20 21:01:16 +0000750
Florent Xicluna4886d242010-03-08 13:27:26 +0000751 def _kill_process(self, method, *args):
Florent Xicluna1d8ee3a2010-03-05 20:26:54 +0000752 # Do not inherit file handles from the parent.
753 # It should fix failures on some platforms.
754 p = subprocess.Popen([sys.executable, "-c", "input()"], close_fds=True,
Florent Xicluna4886d242010-03-08 13:27:26 +0000755 stdin=subprocess.PIPE)
Christian Heimesa342c012008-04-20 21:01:16 +0000756
Florent Xicluna4886d242010-03-08 13:27:26 +0000757 # Let the process initialize (Issue #3137)
Florent Xicluna129226d2010-03-05 00:52:00 +0000758 time.sleep(0.1)
Florent Xicluna4886d242010-03-08 13:27:26 +0000759 # The process should not terminate prematurely
Florent Xiclunab8f22b12010-03-05 01:18:04 +0000760 self.assertIsNone(p.poll())
Florent Xicluna4886d242010-03-08 13:27:26 +0000761 # Retry if the process do not receive the signal.
Florent Xicluna129226d2010-03-05 00:52:00 +0000762 count, maxcount = 0, 3
Florent Xicluna129226d2010-03-05 00:52:00 +0000763 while count < maxcount and p.poll() is None:
Florent Xicluna4886d242010-03-08 13:27:26 +0000764 getattr(p, method)(*args)
Florent Xicluna129226d2010-03-05 00:52:00 +0000765 time.sleep(0.1)
766 count += 1
Florent Xicluna4886d242010-03-08 13:27:26 +0000767
768 self.assertIsNotNone(p.poll(), "the subprocess did not terminate")
Florent Xiclunab8f22b12010-03-05 01:18:04 +0000769 if count > 1:
Florent Xicluna4886d242010-03-08 13:27:26 +0000770 print("p.{}{} succeeded after "
771 "{} attempts".format(method, args, count), file=sys.stderr)
772 return p
773
774 def test_send_signal(self):
775 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000776 self.assertNotEqual(p.wait(), 0)
Christian Heimesa342c012008-04-20 21:01:16 +0000777
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000778 def test_kill(self):
Florent Xicluna4886d242010-03-08 13:27:26 +0000779 p = self._kill_process('kill')
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000780 self.assertEqual(p.wait(), -signal.SIGKILL)
Tim Peterse718f612004-10-12 21:51:32 +0000781
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000782 def test_terminate(self):
Florent Xicluna4886d242010-03-08 13:27:26 +0000783 p = self._kill_process('terminate')
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000784 self.assertEqual(p.wait(), -signal.SIGTERM)
785
786
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000787@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000788class Win32ProcessTestCase(unittest.TestCase):
789 def setUp(self):
790 # Try to minimize the number of children we have so this test
791 # doesn't crash on some buildbots (Alphas in particular).
792 support.reap_children()
793
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000794 def tearDown(self):
795 for inst in subprocess._active:
796 inst.wait()
797 subprocess._cleanup()
798 self.assertFalse(subprocess._active, "subprocess._active not empty")
799
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000800 def test_startupinfo(self):
801 # startupinfo argument
802 # We uses hardcoded constants, because we do not want to
803 # depend on win32all.
804 STARTF_USESHOWWINDOW = 1
805 SW_MAXIMIZE = 3
806 startupinfo = subprocess.STARTUPINFO()
807 startupinfo.dwFlags = STARTF_USESHOWWINDOW
808 startupinfo.wShowWindow = SW_MAXIMIZE
809 # Since Python is a console process, it won't be affected
810 # by wShowWindow, but the argument should be silently
811 # ignored
812 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000813 startupinfo=startupinfo)
814
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000815 def test_creationflags(self):
816 # creationflags argument
817 CREATE_NEW_CONSOLE = 16
818 sys.stderr.write(" a DOS box should flash briefly ...\n")
819 subprocess.call(sys.executable +
820 ' -c "import time; time.sleep(0.25)"',
821 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000822
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000823 def test_invalid_args(self):
824 # invalid arguments should raise ValueError
825 self.assertRaises(ValueError, subprocess.call,
826 [sys.executable, "-c",
827 "import sys; sys.exit(47)"],
828 preexec_fn=lambda: 1)
829 self.assertRaises(ValueError, subprocess.call,
830 [sys.executable, "-c",
831 "import sys; sys.exit(47)"],
832 stdout=subprocess.PIPE,
833 close_fds=True)
834
835 def test_close_fds(self):
836 # close file descriptors
837 rc = subprocess.call([sys.executable, "-c",
838 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000839 close_fds=True)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000840 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000841
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000842 def test_shell_sequence(self):
843 # Run command through the shell (sequence)
844 newenv = os.environ.copy()
845 newenv["FRUIT"] = "physalis"
846 p = subprocess.Popen(["set"], shell=1,
847 stdout=subprocess.PIPE,
848 env=newenv)
849 self.assertIn(b"physalis", p.stdout.read())
Guido van Rossume7ba4952007-06-06 23:52:48 +0000850
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000851 def test_shell_string(self):
852 # Run command through the shell (string)
853 newenv = os.environ.copy()
854 newenv["FRUIT"] = "physalis"
855 p = subprocess.Popen("set", shell=1,
856 stdout=subprocess.PIPE,
857 env=newenv)
858 self.assertIn(b"physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000859
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000860 def test_call_string(self):
861 # call() function with string argument on Windows
862 rc = subprocess.call(sys.executable +
863 ' -c "import sys; sys.exit(47)"')
864 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000865
Florent Xicluna4886d242010-03-08 13:27:26 +0000866 def _kill_process(self, method, *args):
867 # Some win32 buildbot raises EOFError if stdin is inherited
868 p = subprocess.Popen([sys.executable, "-c", "input()"],
869 stdin=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000870
Florent Xicluna4886d242010-03-08 13:27:26 +0000871 # Let the process initialize (Issue #3137)
872 time.sleep(0.1)
873 # The process should not terminate prematurely
874 self.assertIsNone(p.poll())
875 # Retry if the process do not receive the signal.
876 count, maxcount = 0, 3
877 while count < maxcount and p.poll() is None:
878 getattr(p, method)(*args)
879 time.sleep(0.1)
880 count += 1
881
882 returncode = p.poll()
883 self.assertIsNotNone(returncode, "the subprocess did not terminate")
884 if count > 1:
885 print("p.{}{} succeeded after "
886 "{} attempts".format(method, args, count), file=sys.stderr)
887 self.assertEqual(p.wait(), returncode)
888 self.assertNotEqual(returncode, 0)
889
890 def test_send_signal(self):
891 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimesa342c012008-04-20 21:01:16 +0000892
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000893 def test_kill(self):
Florent Xicluna4886d242010-03-08 13:27:26 +0000894 self._kill_process('kill')
Christian Heimesa342c012008-04-20 21:01:16 +0000895
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000896 def test_terminate(self):
Florent Xicluna4886d242010-03-08 13:27:26 +0000897 self._kill_process('terminate')
Christian Heimesa342c012008-04-20 21:01:16 +0000898
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000899
Brett Cannona23810f2008-05-26 19:04:21 +0000900# The module says:
901# "NB This only works (and is only relevant) for UNIX."
902#
903# Actually, getoutput should work on any platform with an os.popen, but
904# I'll take the comment as given, and skip this suite.
Florent Xiclunaf0cbd822010-03-04 21:50:56 +0000905@unittest.skipUnless(os.name == 'posix', "only relevant for UNIX")
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000906class CommandTests(unittest.TestCase):
907 def test_getoutput(self):
908 self.assertEqual(subprocess.getoutput('echo xyzzy'), 'xyzzy')
909 self.assertEqual(subprocess.getstatusoutput('echo xyzzy'),
910 (0, 'xyzzy'))
Brett Cannona23810f2008-05-26 19:04:21 +0000911
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000912 # we use mkdtemp in the next line to create an empty directory
913 # under our exclusive control; from that, we can invent a pathname
914 # that we _know_ won't exist. This is guaranteed to fail.
915 dir = None
916 try:
917 dir = tempfile.mkdtemp()
918 name = os.path.join(dir, "foo")
Brett Cannona23810f2008-05-26 19:04:21 +0000919
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000920 status, output = subprocess.getstatusoutput('cat ' + name)
921 self.assertNotEqual(status, 0)
922 finally:
923 if dir is not None:
924 os.rmdir(dir)
Brett Cannona23810f2008-05-26 19:04:21 +0000925
Gregory P. Smithd06fa472009-07-04 02:46:54 +0000926
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000927@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
928 "poll system call not supported")
929class ProcessTestCaseNoPoll(ProcessTestCase):
930 def setUp(self):
931 subprocess._has_poll = False
932 ProcessTestCase.setUp(self)
Gregory P. Smithd06fa472009-07-04 02:46:54 +0000933
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000934 def tearDown(self):
935 subprocess._has_poll = True
936 ProcessTestCase.tearDown(self)
Gregory P. Smithd06fa472009-07-04 02:46:54 +0000937
938
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000939@unittest.skipUnless(getattr(subprocess, '_posixsubprocess', False),
940 "_posixsubprocess extension module not found.")
941class ProcessTestCasePOSIXPurePython(ProcessTestCase, POSIXProcessTestCase):
942 def setUp(self):
943 subprocess._posixsubprocess = None
944 ProcessTestCase.setUp(self)
945 POSIXProcessTestCase.setUp(self)
946
947 def tearDown(self):
948 subprocess._posixsubprocess = sys.modules['_posixsubprocess']
949 POSIXProcessTestCase.tearDown(self)
950 ProcessTestCase.tearDown(self)
951
952
Gregory P. Smitha59c59f2010-03-01 00:17:40 +0000953class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithaf6d3b82010-03-01 02:56:44 +0000954 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smitha59c59f2010-03-01 00:17:40 +0000955 def test_eintr_retry_call(self):
956 record_calls = []
957 def fake_os_func(*args):
958 record_calls.append(args)
959 if len(record_calls) == 2:
960 raise OSError(errno.EINTR, "fake interrupted system call")
961 return tuple(reversed(args))
962
963 self.assertEqual((999, 256),
964 subprocess._eintr_retry_call(fake_os_func, 256, 999))
965 self.assertEqual([(256, 999)], record_calls)
966 # This time there will be an EINTR so it will loop once.
967 self.assertEqual((666,),
968 subprocess._eintr_retry_call(fake_os_func, 666))
969 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
970
971
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000972def test_main():
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000973 unit_tests = (ProcessTestCase,
974 POSIXProcessTestCase,
975 Win32ProcessTestCase,
Gregory P. Smithfb94c5f2010-03-14 06:49:55 +0000976 ProcessTestCasePOSIXPurePython,
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000977 CommandTests,
Gregory P. Smitha59c59f2010-03-01 00:17:40 +0000978 ProcessTestCaseNoPoll,
979 HelperFunctionTests)
Florent Xiclunab1e94e82010-02-27 22:12:37 +0000980
Gregory P. Smithd06fa472009-07-04 02:46:54 +0000981 support.run_unittest(*unit_tests)
Brett Cannona23810f2008-05-26 19:04:21 +0000982 support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000983
984if __name__ == "__main__":
Brett Cannona23810f2008-05-26 19:04:21 +0000985 test_main()