blob: 15ca19753f0d0393b8d56f7b88def05a91671ac7 [file] [log] [blame]
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001import unittest
2from test import test_support
3import subprocess
4import sys
5import signal
6import os
Gregory P. Smithcce211f2010-03-01 00:05:08 +00007import errno
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00008import tempfile
9import time
Tim Peters3761e8d2004-10-13 04:07:12 +000010import re
Ezio Melotti8f6a2872010-02-10 21:40:33 +000011import sysconfig
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000012
13mswindows = (sys.platform == "win32")
14
15#
16# Depends on the following external programs: Python
17#
18
19if mswindows:
Tim Peters3b01a702004-10-12 22:19:32 +000020 SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
21 'os.O_BINARY);')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000022else:
23 SETBINARY = ''
24
Florent Xicluna98e3fc32010-02-27 19:20:50 +000025
26try:
27 mkstemp = tempfile.mkstemp
28except AttributeError:
29 # tempfile.mkstemp is not available
30 def mkstemp():
31 """Replacement for mkstemp, calling mktemp."""
32 fname = tempfile.mktemp()
33 return os.open(fname, os.O_RDWR|os.O_CREAT), fname
34
Tim Peters3761e8d2004-10-13 04:07:12 +000035
Florent Xiclunafc4d6d72010-03-23 14:36:45 +000036class BaseTestCase(unittest.TestCase):
Neal Norwitzb15ac312006-06-29 04:10:08 +000037 def setUp(self):
Tim Peters38ff36c2006-06-30 06:18:39 +000038 # Try to minimize the number of children we have so this test
39 # doesn't crash on some buildbots (Alphas in particular).
Florent Xicluna98e3fc32010-02-27 19:20:50 +000040 test_support.reap_children()
Neal Norwitzb15ac312006-06-29 04:10:08 +000041
Florent Xiclunaab5e17f2010-03-04 21:31:58 +000042 def tearDown(self):
43 for inst in subprocess._active:
44 inst.wait()
45 subprocess._cleanup()
46 self.assertFalse(subprocess._active, "subprocess._active not empty")
47
Florent Xicluna98e3fc32010-02-27 19:20:50 +000048 def assertStderrEqual(self, stderr, expected, msg=None):
49 # In a debug build, stuff like "[6580 refs]" is printed to stderr at
50 # shutdown time. That frustrates tests trying to check stderr produced
51 # from a spawned Python process.
52 actual = re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr)
53 self.assertEqual(actual, expected, msg)
Neal Norwitzb15ac312006-06-29 04:10:08 +000054
Florent Xiclunafc4d6d72010-03-23 14:36:45 +000055
56class ProcessTestCase(BaseTestCase):
57
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000058 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +000059 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +000060 rc = subprocess.call([sys.executable, "-c",
61 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000062 self.assertEqual(rc, 47)
63
Peter Astrand454f7672005-01-01 09:36:35 +000064 def test_check_call_zero(self):
65 # check_call() function with zero return code
66 rc = subprocess.check_call([sys.executable, "-c",
67 "import sys; sys.exit(0)"])
68 self.assertEqual(rc, 0)
69
70 def test_check_call_nonzero(self):
71 # check_call() function with non-zero return code
Florent Xicluna98e3fc32010-02-27 19:20:50 +000072 with self.assertRaises(subprocess.CalledProcessError) as c:
Peter Astrand454f7672005-01-01 09:36:35 +000073 subprocess.check_call([sys.executable, "-c",
74 "import sys; sys.exit(47)"])
Florent Xicluna98e3fc32010-02-27 19:20:50 +000075 self.assertEqual(c.exception.returncode, 47)
Peter Astrand454f7672005-01-01 09:36:35 +000076
Gregory P. Smith26576802008-12-05 02:27:01 +000077 def test_check_output(self):
78 # check_output() function with zero return code
79 output = subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +000080 [sys.executable, "-c", "print 'BDFL'"])
Ezio Melottiaa980582010-01-23 23:04:36 +000081 self.assertIn('BDFL', output)
Gregory P. Smith97f49f42008-12-04 20:21:09 +000082
Gregory P. Smith26576802008-12-05 02:27:01 +000083 def test_check_output_nonzero(self):
Gregory P. Smith97f49f42008-12-04 20:21:09 +000084 # check_call() function with non-zero return code
Florent Xicluna98e3fc32010-02-27 19:20:50 +000085 with self.assertRaises(subprocess.CalledProcessError) as c:
Gregory P. Smith26576802008-12-05 02:27:01 +000086 subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +000087 [sys.executable, "-c", "import sys; sys.exit(5)"])
Florent Xicluna98e3fc32010-02-27 19:20:50 +000088 self.assertEqual(c.exception.returncode, 5)
Gregory P. Smith97f49f42008-12-04 20:21:09 +000089
Gregory P. Smith26576802008-12-05 02:27:01 +000090 def test_check_output_stderr(self):
91 # check_output() function stderr redirected to stdout
92 output = subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +000093 [sys.executable, "-c", "import sys; sys.stderr.write('BDFL')"],
94 stderr=subprocess.STDOUT)
Ezio Melottiaa980582010-01-23 23:04:36 +000095 self.assertIn('BDFL', output)
Gregory P. Smith97f49f42008-12-04 20:21:09 +000096
Gregory P. Smith26576802008-12-05 02:27:01 +000097 def test_check_output_stdout_arg(self):
98 # check_output() function stderr redirected to stdout
Florent Xicluna98e3fc32010-02-27 19:20:50 +000099 with self.assertRaises(ValueError) as c:
Gregory P. Smith26576802008-12-05 02:27:01 +0000100 output = subprocess.check_output(
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000101 [sys.executable, "-c", "print 'will not be run'"],
102 stdout=sys.stdout)
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000103 self.fail("Expected ValueError when stdout arg supplied.")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000104 self.assertIn('stdout', c.exception.args[0])
Gregory P. Smith97f49f42008-12-04 20:21:09 +0000105
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000106 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000107 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000108 newenv = os.environ.copy()
109 newenv["FRUIT"] = "banana"
110 rc = subprocess.call([sys.executable, "-c",
Florent Xiclunabab22a72010-03-04 19:40:48 +0000111 'import sys, os;'
112 'sys.exit(os.getenv("FRUIT")=="banana")'],
113 env=newenv)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000114 self.assertEqual(rc, 1)
115
116 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000117 # .stdin is None when not redirected
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000118 p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
119 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
120 p.wait()
121 self.assertEqual(p.stdin, None)
122
123 def test_stdout_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000124 # .stdout is None when not redirected
Tim Peters29b6b4f2004-10-13 03:43:40 +0000125 p = subprocess.Popen([sys.executable, "-c",
Tim Peters4052fe52004-10-13 03:29:54 +0000126 'print " this bit of output is from a '
127 'test of stdout in a different '
128 'process ..."'],
129 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000130 p.wait()
131 self.assertEqual(p.stdout, None)
132
133 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000134 # .stderr is None when not redirected
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000135 p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
136 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
137 p.wait()
138 self.assertEqual(p.stderr, None)
139
Ezio Melotti8f6a2872010-02-10 21:40:33 +0000140 def test_executable_with_cwd(self):
Florent Xicluna63763702010-03-11 01:50:48 +0000141 python_dir = os.path.dirname(os.path.realpath(sys.executable))
Ezio Melotti8f6a2872010-02-10 21:40:33 +0000142 p = subprocess.Popen(["somethingyoudonthave", "-c",
143 "import sys; sys.exit(47)"],
144 executable=sys.executable, cwd=python_dir)
145 p.wait()
146 self.assertEqual(p.returncode, 47)
147
148 @unittest.skipIf(sysconfig.is_python_build(),
149 "need an installed Python. See #7774")
150 def test_executable_without_cwd(self):
151 # For a normal installation, it should work without 'cwd'
152 # argument. For test runs in the build directory, see #7774.
153 p = subprocess.Popen(["somethingyoudonthave", "-c",
154 "import sys; sys.exit(47)"],
Tim Peters3b01a702004-10-12 22:19:32 +0000155 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000156 p.wait()
157 self.assertEqual(p.returncode, 47)
158
159 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000160 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000161 p = subprocess.Popen([sys.executable, "-c",
162 'import sys; sys.exit(sys.stdin.read() == "pear")'],
163 stdin=subprocess.PIPE)
164 p.stdin.write("pear")
165 p.stdin.close()
166 p.wait()
167 self.assertEqual(p.returncode, 1)
168
169 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000170 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000171 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000172 d = tf.fileno()
173 os.write(d, "pear")
174 os.lseek(d, 0, 0)
175 p = subprocess.Popen([sys.executable, "-c",
176 'import sys; sys.exit(sys.stdin.read() == "pear")'],
177 stdin=d)
178 p.wait()
179 self.assertEqual(p.returncode, 1)
180
181 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000182 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000183 tf = tempfile.TemporaryFile()
184 tf.write("pear")
185 tf.seek(0)
186 p = subprocess.Popen([sys.executable, "-c",
187 'import sys; sys.exit(sys.stdin.read() == "pear")'],
188 stdin=tf)
189 p.wait()
190 self.assertEqual(p.returncode, 1)
191
192 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000193 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000194 p = subprocess.Popen([sys.executable, "-c",
195 'import sys; sys.stdout.write("orange")'],
196 stdout=subprocess.PIPE)
197 self.assertEqual(p.stdout.read(), "orange")
198
199 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000200 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000201 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000202 d = tf.fileno()
203 p = subprocess.Popen([sys.executable, "-c",
204 'import sys; sys.stdout.write("orange")'],
205 stdout=d)
206 p.wait()
207 os.lseek(d, 0, 0)
208 self.assertEqual(os.read(d, 1024), "orange")
209
210 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000211 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000212 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000213 p = subprocess.Popen([sys.executable, "-c",
214 'import sys; sys.stdout.write("orange")'],
215 stdout=tf)
216 p.wait()
217 tf.seek(0)
218 self.assertEqual(tf.read(), "orange")
219
220 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000221 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000222 p = subprocess.Popen([sys.executable, "-c",
223 'import sys; sys.stderr.write("strawberry")'],
224 stderr=subprocess.PIPE)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000225 self.assertStderrEqual(p.stderr.read(), "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000226
227 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000228 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000229 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000230 d = tf.fileno()
231 p = subprocess.Popen([sys.executable, "-c",
232 'import sys; sys.stderr.write("strawberry")'],
233 stderr=d)
234 p.wait()
235 os.lseek(d, 0, 0)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000236 self.assertStderrEqual(os.read(d, 1024), "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000237
238 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000239 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000240 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000241 p = subprocess.Popen([sys.executable, "-c",
242 'import sys; sys.stderr.write("strawberry")'],
243 stderr=tf)
244 p.wait()
245 tf.seek(0)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000246 self.assertStderrEqual(tf.read(), "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000247
248 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000249 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000250 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000251 'import sys;'
252 'sys.stdout.write("apple");'
253 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000254 'sys.stderr.write("orange")'],
255 stdout=subprocess.PIPE,
256 stderr=subprocess.STDOUT)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000257 self.assertStderrEqual(p.stdout.read(), "appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000258
259 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000260 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000261 tf = tempfile.TemporaryFile()
262 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000263 'import sys;'
264 'sys.stdout.write("apple");'
265 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000266 'sys.stderr.write("orange")'],
267 stdout=tf,
268 stderr=tf)
269 p.wait()
270 tf.seek(0)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000271 self.assertStderrEqual(tf.read(), "appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000272
Gustavo Niemeyerc36bede2006-09-07 00:48:33 +0000273 def test_stdout_filedes_of_stdout(self):
274 # stdout is set to 1 (#1531862).
275 cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
276 rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000277 self.assertEqual(rc, 2)
Gustavo Niemeyerc36bede2006-09-07 00:48:33 +0000278
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000279 def test_cwd(self):
Guido van Rossume9a0e882007-12-20 17:28:10 +0000280 tmpdir = tempfile.gettempdir()
Peter Astrand195404f2004-11-12 15:51:48 +0000281 # We cannot use os.path.realpath to canonicalize the path,
282 # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
283 cwd = os.getcwd()
284 os.chdir(tmpdir)
285 tmpdir = os.getcwd()
286 os.chdir(cwd)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000287 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000288 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000289 'sys.stdout.write(os.getcwd())'],
290 stdout=subprocess.PIPE,
291 cwd=tmpdir)
Fredrik Lundh59c05592004-10-13 06:55:40 +0000292 normcase = os.path.normcase
293 self.assertEqual(normcase(p.stdout.read()), normcase(tmpdir))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000294
295 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000296 newenv = os.environ.copy()
297 newenv["FRUIT"] = "orange"
298 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000299 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000300 'sys.stdout.write(os.getenv("FRUIT"))'],
301 stdout=subprocess.PIPE,
302 env=newenv)
303 self.assertEqual(p.stdout.read(), "orange")
304
Peter Astrandcbac93c2005-03-03 20:24:28 +0000305 def test_communicate_stdin(self):
306 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000307 'import sys;'
308 'sys.exit(sys.stdin.read() == "pear")'],
Peter Astrandcbac93c2005-03-03 20:24:28 +0000309 stdin=subprocess.PIPE)
310 p.communicate("pear")
311 self.assertEqual(p.returncode, 1)
312
313 def test_communicate_stdout(self):
314 p = subprocess.Popen([sys.executable, "-c",
315 'import sys; sys.stdout.write("pineapple")'],
316 stdout=subprocess.PIPE)
317 (stdout, stderr) = p.communicate()
318 self.assertEqual(stdout, "pineapple")
319 self.assertEqual(stderr, None)
320
321 def test_communicate_stderr(self):
322 p = subprocess.Popen([sys.executable, "-c",
323 'import sys; sys.stderr.write("pineapple")'],
324 stderr=subprocess.PIPE)
325 (stdout, stderr) = p.communicate()
326 self.assertEqual(stdout, None)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000327 self.assertStderrEqual(stderr, "pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000328
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000329 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000330 p = subprocess.Popen([sys.executable, "-c",
Gregory P. Smith4036fd42008-05-26 20:22:14 +0000331 'import sys,os;'
332 'sys.stderr.write("pineapple");'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000333 'sys.stdout.write(sys.stdin.read())'],
Tim Peters3b01a702004-10-12 22:19:32 +0000334 stdin=subprocess.PIPE,
335 stdout=subprocess.PIPE,
336 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000337 (stdout, stderr) = p.communicate("banana")
338 self.assertEqual(stdout, "banana")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000339 self.assertStderrEqual(stderr, "pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000340
Gregory P. Smith4036fd42008-05-26 20:22:14 +0000341 # This test is Linux specific for simplicity to at least have
342 # some coverage. It is not a platform specific bug.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000343 @unittest.skipUnless(os.path.isdir('/proc/%d/fd' % os.getpid()),
344 "Linux specific")
345 # Test for the fd leak reported in http://bugs.python.org/issue2791.
346 def test_communicate_pipe_fd_leak(self):
347 fd_directory = '/proc/%d/fd' % os.getpid()
348 num_fds_before_popen = len(os.listdir(fd_directory))
349 p = subprocess.Popen([sys.executable, "-c", "print()"],
350 stdout=subprocess.PIPE)
351 p.communicate()
352 num_fds_after_communicate = len(os.listdir(fd_directory))
353 del p
354 num_fds_after_destruction = len(os.listdir(fd_directory))
355 self.assertEqual(num_fds_before_popen, num_fds_after_destruction)
356 self.assertEqual(num_fds_before_popen, num_fds_after_communicate)
Gregory P. Smith4036fd42008-05-26 20:22:14 +0000357
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000358 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000359 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000360 p = subprocess.Popen([sys.executable, "-c",
361 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000362 (stdout, stderr) = p.communicate()
363 self.assertEqual(stdout, None)
364 self.assertEqual(stderr, None)
365
366 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000367 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000368 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000369 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000370 x, y = os.pipe()
371 if mswindows:
372 pipe_buf = 512
373 else:
374 pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
375 os.close(x)
376 os.close(y)
377 p = subprocess.Popen([sys.executable, "-c",
Tim Peterse718f612004-10-12 21:51:32 +0000378 'import sys,os;'
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000379 'sys.stdout.write(sys.stdin.read(47));'
380 'sys.stderr.write("xyz"*%d);'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000381 'sys.stdout.write(sys.stdin.read())' % pipe_buf],
Tim Peters3b01a702004-10-12 22:19:32 +0000382 stdin=subprocess.PIPE,
383 stdout=subprocess.PIPE,
384 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000385 string_to_write = "abc"*pipe_buf
386 (stdout, stderr) = p.communicate(string_to_write)
387 self.assertEqual(stdout, string_to_write)
388
389 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000390 # stdin.write before communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000391 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000392 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000393 'sys.stdout.write(sys.stdin.read())'],
Tim Peters3b01a702004-10-12 22:19:32 +0000394 stdin=subprocess.PIPE,
395 stdout=subprocess.PIPE,
396 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000397 p.stdin.write("banana")
398 (stdout, stderr) = p.communicate("split")
399 self.assertEqual(stdout, "bananasplit")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000400 self.assertStderrEqual(stderr, "")
Tim Peterse718f612004-10-12 21:51:32 +0000401
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000402 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000403 p = subprocess.Popen([sys.executable, "-c",
Tim Peters3b01a702004-10-12 22:19:32 +0000404 'import sys,os;' + SETBINARY +
405 'sys.stdout.write("line1\\n");'
406 'sys.stdout.flush();'
407 'sys.stdout.write("line2\\r");'
408 'sys.stdout.flush();'
409 'sys.stdout.write("line3\\r\\n");'
410 'sys.stdout.flush();'
411 'sys.stdout.write("line4\\r");'
412 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000413 'sys.stdout.write("\\nline5");'
Tim Peters3b01a702004-10-12 22:19:32 +0000414 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000415 'sys.stdout.write("\\nline6");'],
416 stdout=subprocess.PIPE,
417 universal_newlines=1)
418 stdout = p.stdout.read()
Neal Norwitza6d01ce2006-05-02 06:23:22 +0000419 if hasattr(file, 'newlines'):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000420 # Interpreter with universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000421 self.assertEqual(stdout,
422 "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000423 else:
424 # Interpreter without universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000425 self.assertEqual(stdout,
426 "line1\nline2\rline3\r\nline4\r\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000427
428 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000429 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000430 p = subprocess.Popen([sys.executable, "-c",
Tim Peters3b01a702004-10-12 22:19:32 +0000431 'import sys,os;' + SETBINARY +
432 'sys.stdout.write("line1\\n");'
433 'sys.stdout.flush();'
434 'sys.stdout.write("line2\\r");'
435 'sys.stdout.flush();'
436 'sys.stdout.write("line3\\r\\n");'
437 'sys.stdout.flush();'
438 'sys.stdout.write("line4\\r");'
439 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000440 'sys.stdout.write("\\nline5");'
Tim Peters3b01a702004-10-12 22:19:32 +0000441 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000442 'sys.stdout.write("\\nline6");'],
443 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
444 universal_newlines=1)
445 (stdout, stderr) = p.communicate()
Neal Norwitza6d01ce2006-05-02 06:23:22 +0000446 if hasattr(file, 'newlines'):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000447 # Interpreter with universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000448 self.assertEqual(stdout,
449 "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000450 else:
451 # Interpreter without universal newline support
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000452 self.assertEqual(stdout,
453 "line1\nline2\rline3\r\nline4\r\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000454
455 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000456 # Make sure we leak no resources
Peter Astrandd6b24302006-06-22 20:06:46 +0000457 if not hasattr(test_support, "is_resource_enabled") \
458 or test_support.is_resource_enabled("subprocess") and not mswindows:
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000459 max_handles = 1026 # too much for most UNIX systems
460 else:
Tim Peterseba28be2005-03-28 01:08:02 +0000461 max_handles = 65
Fredrik Lundh9e29fc52004-10-13 07:54:54 +0000462 for i in range(max_handles):
Tim Peters3b01a702004-10-12 22:19:32 +0000463 p = subprocess.Popen([sys.executable, "-c",
464 "import sys;sys.stdout.write(sys.stdin.read())"],
465 stdin=subprocess.PIPE,
466 stdout=subprocess.PIPE,
467 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000468 data = p.communicate("lime")[0]
469 self.assertEqual(data, "lime")
470
471
472 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000473 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
474 '"a b c" d e')
475 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
476 'ab\\"c \\ d')
Gregory P. Smithe047e6d2008-01-19 20:49:02 +0000477 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
478 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000479 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
480 'a\\\\\\b "de fg" h')
481 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
482 'a\\\\\\"b c d')
483 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
484 '"a\\\\b c" d e')
485 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
486 '"a\\\\b\\ c" d e')
Peter Astrand10514a72007-01-13 22:35:35 +0000487 self.assertEqual(subprocess.list2cmdline(['ab', '']),
488 'ab ""')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000489
490
491 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000492 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000493 "-c", "import time; time.sleep(1)"])
494 count = 0
495 while p.poll() is None:
496 time.sleep(0.1)
497 count += 1
498 # We expect that the poll loop probably went around about 10 times,
499 # but, based on system scheduling we can't control, it's possible
500 # poll() never returned None. It "should be" very rare that it
501 # didn't go around at least twice.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000502 self.assertGreaterEqual(count, 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000503 # Subsequent invocations should just return the returncode
504 self.assertEqual(p.poll(), 0)
505
506
507 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000508 p = subprocess.Popen([sys.executable,
509 "-c", "import time; time.sleep(2)"])
510 self.assertEqual(p.wait(), 0)
511 # Subsequent invocations should just return the returncode
512 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000513
Peter Astrand738131d2004-11-30 21:04:45 +0000514
515 def test_invalid_bufsize(self):
516 # an invalid type of the bufsize argument should raise
517 # TypeError.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000518 with self.assertRaises(TypeError):
Peter Astrand738131d2004-11-30 21:04:45 +0000519 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
Peter Astrand738131d2004-11-30 21:04:45 +0000520
Georg Brandlf3715d22009-02-14 17:01:36 +0000521 def test_leaking_fds_on_error(self):
522 # see bug #5179: Popen leaks file descriptors to PIPEs if
523 # the child fails to execute; this will eventually exhaust
524 # the maximum number of open fds. 1024 seems a very common
525 # value for that limit, but Windows has 2048, so we loop
526 # 1024 times (each call leaked two fds).
527 for i in range(1024):
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000528 # Windows raises IOError. Others raise OSError.
529 with self.assertRaises(EnvironmentError) as c:
Georg Brandlf3715d22009-02-14 17:01:36 +0000530 subprocess.Popen(['nonexisting_i_hope'],
531 stdout=subprocess.PIPE,
532 stderr=subprocess.PIPE)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000533 if c.exception.errno != 2: # ignore "no such file"
534 raise c.exception
Georg Brandlf3715d22009-02-14 17:01:36 +0000535
Tim Golden90374f52010-08-06 13:14:33 +0000536 def test_handles_closed_on_exception(self):
537 # If CreateProcess exits with an error, ensure the
538 # duplicate output handles are released
539 ifhandle, ifname = mkstemp()
540 ofhandle, ofname = mkstemp()
541 efhandle, efname = mkstemp()
542 try:
543 subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle,
544 stderr=efhandle)
545 except OSError:
546 os.close(ifhandle)
547 os.remove(ifname)
548 os.close(ofhandle)
549 os.remove(ofname)
550 os.close(efhandle)
551 os.remove(efname)
552 self.assertFalse(os.path.exists(ifname))
553 self.assertFalse(os.path.exists(ofname))
554 self.assertFalse(os.path.exists(efname))
555
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000556
557# context manager
558class _SuppressCoreFiles(object):
559 """Try to prevent core files from being created."""
560 old_limit = None
561
562 def __enter__(self):
563 """Try to save previous ulimit, then set it to (0, 0)."""
564 try:
565 import resource
566 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
567 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
568 except (ImportError, ValueError, resource.error):
569 pass
570
Ronald Oussoren21b44e02010-07-23 12:26:30 +0000571 if sys.platform == 'darwin':
572 # Check if the 'Crash Reporter' on OSX was configured
573 # in 'Developer' mode and warn that it will get triggered
574 # when it is.
575 #
576 # This assumes that this context manager is used in tests
577 # that might trigger the next manager.
578 value = subprocess.Popen(['/usr/bin/defaults', 'read',
579 'com.apple.CrashReporter', 'DialogType'],
580 stdout=subprocess.PIPE).communicate()[0]
581 if value.strip() == b'developer':
582 print "this tests triggers the Crash Reporter, that is intentional"
583 sys.stdout.flush()
584
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000585 def __exit__(self, *args):
586 """Return core file behavior to default."""
587 if self.old_limit is None:
588 return
589 try:
590 import resource
591 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
592 except (ImportError, ValueError, resource.error):
593 pass
594
595
Florent Xiclunabab22a72010-03-04 19:40:48 +0000596@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000597class POSIXProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000598
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000599 def test_exceptions(self):
600 # caught & re-raised exceptions
601 with self.assertRaises(OSError) as c:
602 p = subprocess.Popen([sys.executable, "-c", ""],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000603 cwd="/this/path/does/not/exist")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000604 # The attribute child_traceback should contain "os.chdir" somewhere.
605 self.assertIn("os.chdir", c.exception.child_traceback)
Tim Peterse718f612004-10-12 21:51:32 +0000606
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000607 def test_run_abort(self):
608 # returncode handles signal termination
609 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000610 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000611 "import os; os.abort()"])
612 p.wait()
613 self.assertEqual(-p.returncode, signal.SIGABRT)
614
615 def test_preexec(self):
616 # preexec function
617 p = subprocess.Popen([sys.executable, "-c",
618 "import sys, os;"
619 "sys.stdout.write(os.getenv('FRUIT'))"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000620 stdout=subprocess.PIPE,
621 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000622 self.assertEqual(p.stdout.read(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000623
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000624 def test_args_string(self):
625 # args is a string
626 f, fname = mkstemp()
627 os.write(f, "#!/bin/sh\n")
628 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
629 sys.executable)
630 os.close(f)
631 os.chmod(fname, 0o700)
632 p = subprocess.Popen(fname)
633 p.wait()
634 os.remove(fname)
635 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000636
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000637 def test_invalid_args(self):
638 # invalid arguments should raise ValueError
639 self.assertRaises(ValueError, subprocess.call,
640 [sys.executable, "-c",
641 "import sys; sys.exit(47)"],
642 startupinfo=47)
643 self.assertRaises(ValueError, subprocess.call,
644 [sys.executable, "-c",
645 "import sys; sys.exit(47)"],
646 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000647
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000648 def test_shell_sequence(self):
649 # Run command through the shell (sequence)
650 newenv = os.environ.copy()
651 newenv["FRUIT"] = "apple"
652 p = subprocess.Popen(["echo $FRUIT"], shell=1,
653 stdout=subprocess.PIPE,
654 env=newenv)
655 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000656
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000657 def test_shell_string(self):
658 # Run command through the shell (string)
659 newenv = os.environ.copy()
660 newenv["FRUIT"] = "apple"
661 p = subprocess.Popen("echo $FRUIT", shell=1,
662 stdout=subprocess.PIPE,
663 env=newenv)
664 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000665
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000666 def test_call_string(self):
667 # call() function with string argument on UNIX
668 f, fname = mkstemp()
669 os.write(f, "#!/bin/sh\n")
670 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
671 sys.executable)
672 os.close(f)
673 os.chmod(fname, 0700)
674 rc = subprocess.call(fname)
675 os.remove(fname)
676 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000677
Stefan Krahe9a6a7d2010-07-19 14:41:08 +0000678 def test_specific_shell(self):
679 # Issue #9265: Incorrect name passed as arg[0].
680 shells = []
681 for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']:
682 for name in ['bash', 'ksh']:
683 sh = os.path.join(prefix, name)
684 if os.path.isfile(sh):
685 shells.append(sh)
686 if not shells: # Will probably work for any shell but csh.
687 self.skipTest("bash or ksh required for this test")
688 sh = '/bin/sh'
689 if os.path.isfile(sh) and not os.path.islink(sh):
690 # Test will fail if /bin/sh is a symlink to csh.
691 shells.append(sh)
692 for sh in shells:
693 p = subprocess.Popen("echo $0", executable=sh, shell=True,
694 stdout=subprocess.PIPE)
695 self.assertEqual(p.stdout.read().strip(), sh)
696
Florent Xiclunac0838642010-03-07 15:27:39 +0000697 def _kill_process(self, method, *args):
Florent Xiclunacecef392010-03-05 19:31:21 +0000698 # Do not inherit file handles from the parent.
699 # It should fix failures on some platforms.
700 p = subprocess.Popen([sys.executable, "-c", "input()"], close_fds=True,
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000701 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Christian Heimese74c8f22008-04-19 02:23:57 +0000702
Florent Xiclunac0838642010-03-07 15:27:39 +0000703 # Let the process initialize (Issue #3137)
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000704 time.sleep(0.1)
Florent Xiclunac0838642010-03-07 15:27:39 +0000705 # The process should not terminate prematurely
Florent Xiclunad6935632010-03-05 01:05:55 +0000706 self.assertIsNone(p.poll())
Florent Xiclunac0838642010-03-07 15:27:39 +0000707 # Retry if the process do not receive the signal.
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000708 count, maxcount = 0, 3
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000709 while count < maxcount and p.poll() is None:
Florent Xiclunac0838642010-03-07 15:27:39 +0000710 getattr(p, method)(*args)
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000711 time.sleep(0.1)
712 count += 1
Florent Xiclunac0838642010-03-07 15:27:39 +0000713
714 self.assertIsNotNone(p.poll(), "the subprocess did not terminate")
Florent Xiclunad6935632010-03-05 01:05:55 +0000715 if count > 1:
Florent Xiclunac0838642010-03-07 15:27:39 +0000716 print >>sys.stderr, ("p.{}{} succeeded after "
717 "{} attempts".format(method, args, count))
718 return p
719
720 def test_send_signal(self):
721 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000722 _, stderr = p.communicate()
Florent Xicluna3c919cf2010-03-23 19:19:16 +0000723 self.assertIn('KeyboardInterrupt', stderr)
Florent Xicluna446ff142010-03-23 15:05:30 +0000724 self.assertNotEqual(p.wait(), 0)
Christian Heimese74c8f22008-04-19 02:23:57 +0000725
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000726 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000727 p = self._kill_process('kill')
Florent Xicluna446ff142010-03-23 15:05:30 +0000728 _, stderr = p.communicate()
729 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000730 self.assertEqual(p.wait(), -signal.SIGKILL)
Christian Heimese74c8f22008-04-19 02:23:57 +0000731
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000732 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000733 p = self._kill_process('terminate')
Florent Xicluna446ff142010-03-23 15:05:30 +0000734 _, stderr = p.communicate()
735 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000736 self.assertEqual(p.wait(), -signal.SIGTERM)
Tim Peterse718f612004-10-12 21:51:32 +0000737
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000738
Florent Xiclunabab22a72010-03-04 19:40:48 +0000739@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000740class Win32ProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000741
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000742 def test_startupinfo(self):
743 # startupinfo argument
744 # We uses hardcoded constants, because we do not want to
745 # depend on win32all.
746 STARTF_USESHOWWINDOW = 1
747 SW_MAXIMIZE = 3
748 startupinfo = subprocess.STARTUPINFO()
749 startupinfo.dwFlags = STARTF_USESHOWWINDOW
750 startupinfo.wShowWindow = SW_MAXIMIZE
751 # Since Python is a console process, it won't be affected
752 # by wShowWindow, but the argument should be silently
753 # ignored
754 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000755 startupinfo=startupinfo)
756
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000757 def test_creationflags(self):
758 # creationflags argument
759 CREATE_NEW_CONSOLE = 16
760 sys.stderr.write(" a DOS box should flash briefly ...\n")
761 subprocess.call(sys.executable +
762 ' -c "import time; time.sleep(0.25)"',
763 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000764
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000765 def test_invalid_args(self):
766 # invalid arguments should raise ValueError
767 self.assertRaises(ValueError, subprocess.call,
768 [sys.executable, "-c",
769 "import sys; sys.exit(47)"],
770 preexec_fn=lambda: 1)
771 self.assertRaises(ValueError, subprocess.call,
772 [sys.executable, "-c",
773 "import sys; sys.exit(47)"],
774 stdout=subprocess.PIPE,
775 close_fds=True)
776
777 def test_close_fds(self):
778 # close file descriptors
779 rc = subprocess.call([sys.executable, "-c",
780 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000781 close_fds=True)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000782 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000783
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000784 def test_shell_sequence(self):
785 # Run command through the shell (sequence)
786 newenv = os.environ.copy()
787 newenv["FRUIT"] = "physalis"
788 p = subprocess.Popen(["set"], shell=1,
789 stdout=subprocess.PIPE,
790 env=newenv)
791 self.assertIn("physalis", p.stdout.read())
Peter Astrand81a191b2007-05-26 22:18:20 +0000792
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000793 def test_shell_string(self):
794 # Run command through the shell (string)
795 newenv = os.environ.copy()
796 newenv["FRUIT"] = "physalis"
797 p = subprocess.Popen("set", shell=1,
798 stdout=subprocess.PIPE,
799 env=newenv)
800 self.assertIn("physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000801
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000802 def test_call_string(self):
803 # call() function with string argument on Windows
804 rc = subprocess.call(sys.executable +
805 ' -c "import sys; sys.exit(47)"')
806 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000807
Florent Xiclunac0838642010-03-07 15:27:39 +0000808 def _kill_process(self, method, *args):
Florent Xicluna400efc22010-03-07 17:12:23 +0000809 # Some win32 buildbot raises EOFError if stdin is inherited
810 p = subprocess.Popen([sys.executable, "-c", "input()"],
Florent Xicluna446ff142010-03-23 15:05:30 +0000811 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000812
Florent Xiclunafaf17532010-03-08 10:59:33 +0000813 # Let the process initialize (Issue #3137)
Florent Xiclunac0838642010-03-07 15:27:39 +0000814 time.sleep(0.1)
815 # The process should not terminate prematurely
816 self.assertIsNone(p.poll())
817 # Retry if the process do not receive the signal.
818 count, maxcount = 0, 3
819 while count < maxcount and p.poll() is None:
820 getattr(p, method)(*args)
821 time.sleep(0.1)
822 count += 1
823
824 returncode = p.poll()
825 self.assertIsNotNone(returncode, "the subprocess did not terminate")
826 if count > 1:
827 print >>sys.stderr, ("p.{}{} succeeded after "
828 "{} attempts".format(method, args, count))
Florent Xicluna446ff142010-03-23 15:05:30 +0000829 _, stderr = p.communicate()
830 self.assertStderrEqual(stderr, '')
Florent Xiclunac0838642010-03-07 15:27:39 +0000831 self.assertEqual(p.wait(), returncode)
Florent Xiclunafaf17532010-03-08 10:59:33 +0000832 self.assertNotEqual(returncode, 0)
Florent Xiclunac0838642010-03-07 15:27:39 +0000833
834 def test_send_signal(self):
835 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimese74c8f22008-04-19 02:23:57 +0000836
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000837 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000838 self._kill_process('kill')
Christian Heimese74c8f22008-04-19 02:23:57 +0000839
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000840 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000841 self._kill_process('terminate')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000842
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000843
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000844@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
845 "poll system call not supported")
846class ProcessTestCaseNoPoll(ProcessTestCase):
847 def setUp(self):
848 subprocess._has_poll = False
849 ProcessTestCase.setUp(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000850
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000851 def tearDown(self):
852 subprocess._has_poll = True
853 ProcessTestCase.tearDown(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000854
855
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000856class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithc1baf4a2010-03-01 02:53:24 +0000857 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000858 def test_eintr_retry_call(self):
859 record_calls = []
860 def fake_os_func(*args):
861 record_calls.append(args)
862 if len(record_calls) == 2:
863 raise OSError(errno.EINTR, "fake interrupted system call")
864 return tuple(reversed(args))
865
866 self.assertEqual((999, 256),
867 subprocess._eintr_retry_call(fake_os_func, 256, 999))
868 self.assertEqual([(256, 999)], record_calls)
869 # This time there will be an EINTR so it will loop once.
870 self.assertEqual((666,),
871 subprocess._eintr_retry_call(fake_os_func, 666))
872 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
873
874
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000875def test_main():
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000876 unit_tests = (ProcessTestCase,
877 POSIXProcessTestCase,
878 Win32ProcessTestCase,
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000879 ProcessTestCaseNoPoll,
Benjamin Peterson718f2222010-08-08 19:14:28 +0000880 HelperFunctionTests)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000881
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000882 test_support.run_unittest(*unit_tests)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000883 test_support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000884
885if __name__ == "__main__":
886 test_main()