blob: 4f9ccebcc36361c4cdbe5eee8683343f8bdf24f1 [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
Antoine Pitroub0b3bff2010-09-18 22:42:30 +0000457 if not mswindows:
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000458 max_handles = 1026 # too much for most UNIX systems
459 else:
Antoine Pitroub0b3bff2010-09-18 22:42:30 +0000460 max_handles = 2050 # too much for (at least some) Windows setups
461 handles = []
462 try:
463 for i in range(max_handles):
464 try:
465 handles.append(os.open(test_support.TESTFN,
466 os.O_WRONLY | os.O_CREAT))
467 except OSError as e:
468 if e.errno != errno.EMFILE:
469 raise
470 break
471 else:
472 self.skipTest("failed to reach the file descriptor limit "
473 "(tried %d)" % max_handles)
474 # Close a couple of them (should be enough for a subprocess)
475 for i in range(10):
476 os.close(handles.pop())
477 # Loop creating some subprocesses. If one of them leaks some fds,
478 # the next loop iteration will fail by reaching the max fd limit.
479 for i in range(15):
480 p = subprocess.Popen([sys.executable, "-c",
481 "import sys;"
482 "sys.stdout.write(sys.stdin.read())"],
483 stdin=subprocess.PIPE,
484 stdout=subprocess.PIPE,
485 stderr=subprocess.PIPE)
486 data = p.communicate(b"lime")[0]
487 self.assertEqual(data, b"lime")
488 finally:
489 for h in handles:
490 os.close(h)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000491
492 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000493 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
494 '"a b c" d e')
495 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
496 'ab\\"c \\ d')
Gregory P. Smithe047e6d2008-01-19 20:49:02 +0000497 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
498 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000499 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
500 'a\\\\\\b "de fg" h')
501 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
502 'a\\\\\\"b c d')
503 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
504 '"a\\\\b c" d e')
505 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
506 '"a\\\\b\\ c" d e')
Peter Astrand10514a72007-01-13 22:35:35 +0000507 self.assertEqual(subprocess.list2cmdline(['ab', '']),
508 'ab ""')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000509
510
511 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000512 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000513 "-c", "import time; time.sleep(1)"])
514 count = 0
515 while p.poll() is None:
516 time.sleep(0.1)
517 count += 1
518 # We expect that the poll loop probably went around about 10 times,
519 # but, based on system scheduling we can't control, it's possible
520 # poll() never returned None. It "should be" very rare that it
521 # didn't go around at least twice.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000522 self.assertGreaterEqual(count, 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000523 # Subsequent invocations should just return the returncode
524 self.assertEqual(p.poll(), 0)
525
526
527 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000528 p = subprocess.Popen([sys.executable,
529 "-c", "import time; time.sleep(2)"])
530 self.assertEqual(p.wait(), 0)
531 # Subsequent invocations should just return the returncode
532 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000533
Peter Astrand738131d2004-11-30 21:04:45 +0000534
535 def test_invalid_bufsize(self):
536 # an invalid type of the bufsize argument should raise
537 # TypeError.
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000538 with self.assertRaises(TypeError):
Peter Astrand738131d2004-11-30 21:04:45 +0000539 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
Peter Astrand738131d2004-11-30 21:04:45 +0000540
Georg Brandlf3715d22009-02-14 17:01:36 +0000541 def test_leaking_fds_on_error(self):
542 # see bug #5179: Popen leaks file descriptors to PIPEs if
543 # the child fails to execute; this will eventually exhaust
544 # the maximum number of open fds. 1024 seems a very common
545 # value for that limit, but Windows has 2048, so we loop
546 # 1024 times (each call leaked two fds).
547 for i in range(1024):
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000548 # Windows raises IOError. Others raise OSError.
549 with self.assertRaises(EnvironmentError) as c:
Georg Brandlf3715d22009-02-14 17:01:36 +0000550 subprocess.Popen(['nonexisting_i_hope'],
551 stdout=subprocess.PIPE,
552 stderr=subprocess.PIPE)
Antoine Pitrou767cbc42010-09-18 18:15:33 +0000553 if c.exception.errno != errno.ENOENT: # ignore "no such file"
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000554 raise c.exception
Georg Brandlf3715d22009-02-14 17:01:36 +0000555
Tim Golden90374f52010-08-06 13:14:33 +0000556 def test_handles_closed_on_exception(self):
557 # If CreateProcess exits with an error, ensure the
558 # duplicate output handles are released
559 ifhandle, ifname = mkstemp()
560 ofhandle, ofname = mkstemp()
561 efhandle, efname = mkstemp()
562 try:
563 subprocess.Popen (["*"], stdin=ifhandle, stdout=ofhandle,
564 stderr=efhandle)
565 except OSError:
566 os.close(ifhandle)
567 os.remove(ifname)
568 os.close(ofhandle)
569 os.remove(ofname)
570 os.close(efhandle)
571 os.remove(efname)
572 self.assertFalse(os.path.exists(ifname))
573 self.assertFalse(os.path.exists(ofname))
574 self.assertFalse(os.path.exists(efname))
575
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000576
577# context manager
578class _SuppressCoreFiles(object):
579 """Try to prevent core files from being created."""
580 old_limit = None
581
582 def __enter__(self):
583 """Try to save previous ulimit, then set it to (0, 0)."""
584 try:
585 import resource
586 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
587 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
588 except (ImportError, ValueError, resource.error):
589 pass
590
Ronald Oussoren21b44e02010-07-23 12:26:30 +0000591 if sys.platform == 'darwin':
592 # Check if the 'Crash Reporter' on OSX was configured
593 # in 'Developer' mode and warn that it will get triggered
594 # when it is.
595 #
596 # This assumes that this context manager is used in tests
597 # that might trigger the next manager.
598 value = subprocess.Popen(['/usr/bin/defaults', 'read',
599 'com.apple.CrashReporter', 'DialogType'],
600 stdout=subprocess.PIPE).communicate()[0]
601 if value.strip() == b'developer':
602 print "this tests triggers the Crash Reporter, that is intentional"
603 sys.stdout.flush()
604
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000605 def __exit__(self, *args):
606 """Return core file behavior to default."""
607 if self.old_limit is None:
608 return
609 try:
610 import resource
611 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
612 except (ImportError, ValueError, resource.error):
613 pass
614
615
Florent Xiclunabab22a72010-03-04 19:40:48 +0000616@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000617class POSIXProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000618
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000619 def test_exceptions(self):
620 # caught & re-raised exceptions
621 with self.assertRaises(OSError) as c:
622 p = subprocess.Popen([sys.executable, "-c", ""],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000623 cwd="/this/path/does/not/exist")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000624 # The attribute child_traceback should contain "os.chdir" somewhere.
625 self.assertIn("os.chdir", c.exception.child_traceback)
Tim Peterse718f612004-10-12 21:51:32 +0000626
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000627 def test_run_abort(self):
628 # returncode handles signal termination
629 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000630 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000631 "import os; os.abort()"])
632 p.wait()
633 self.assertEqual(-p.returncode, signal.SIGABRT)
634
635 def test_preexec(self):
636 # preexec function
637 p = subprocess.Popen([sys.executable, "-c",
638 "import sys, os;"
639 "sys.stdout.write(os.getenv('FRUIT'))"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000640 stdout=subprocess.PIPE,
641 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000642 self.assertEqual(p.stdout.read(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000643
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000644 def test_args_string(self):
645 # args is a string
646 f, fname = mkstemp()
647 os.write(f, "#!/bin/sh\n")
648 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
649 sys.executable)
650 os.close(f)
651 os.chmod(fname, 0o700)
652 p = subprocess.Popen(fname)
653 p.wait()
654 os.remove(fname)
655 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000656
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000657 def test_invalid_args(self):
658 # invalid arguments should raise ValueError
659 self.assertRaises(ValueError, subprocess.call,
660 [sys.executable, "-c",
661 "import sys; sys.exit(47)"],
662 startupinfo=47)
663 self.assertRaises(ValueError, subprocess.call,
664 [sys.executable, "-c",
665 "import sys; sys.exit(47)"],
666 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000667
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000668 def test_shell_sequence(self):
669 # Run command through the shell (sequence)
670 newenv = os.environ.copy()
671 newenv["FRUIT"] = "apple"
672 p = subprocess.Popen(["echo $FRUIT"], shell=1,
673 stdout=subprocess.PIPE,
674 env=newenv)
675 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000676
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000677 def test_shell_string(self):
678 # Run command through the shell (string)
679 newenv = os.environ.copy()
680 newenv["FRUIT"] = "apple"
681 p = subprocess.Popen("echo $FRUIT", shell=1,
682 stdout=subprocess.PIPE,
683 env=newenv)
684 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000685
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000686 def test_call_string(self):
687 # call() function with string argument on UNIX
688 f, fname = mkstemp()
689 os.write(f, "#!/bin/sh\n")
690 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
691 sys.executable)
692 os.close(f)
693 os.chmod(fname, 0700)
694 rc = subprocess.call(fname)
695 os.remove(fname)
696 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000697
Stefan Krahe9a6a7d2010-07-19 14:41:08 +0000698 def test_specific_shell(self):
699 # Issue #9265: Incorrect name passed as arg[0].
700 shells = []
701 for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']:
702 for name in ['bash', 'ksh']:
703 sh = os.path.join(prefix, name)
704 if os.path.isfile(sh):
705 shells.append(sh)
706 if not shells: # Will probably work for any shell but csh.
707 self.skipTest("bash or ksh required for this test")
708 sh = '/bin/sh'
709 if os.path.isfile(sh) and not os.path.islink(sh):
710 # Test will fail if /bin/sh is a symlink to csh.
711 shells.append(sh)
712 for sh in shells:
713 p = subprocess.Popen("echo $0", executable=sh, shell=True,
714 stdout=subprocess.PIPE)
715 self.assertEqual(p.stdout.read().strip(), sh)
716
Florent Xiclunac0838642010-03-07 15:27:39 +0000717 def _kill_process(self, method, *args):
Florent Xiclunacecef392010-03-05 19:31:21 +0000718 # Do not inherit file handles from the parent.
719 # It should fix failures on some platforms.
720 p = subprocess.Popen([sys.executable, "-c", "input()"], close_fds=True,
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000721 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Christian Heimese74c8f22008-04-19 02:23:57 +0000722
Florent Xiclunac0838642010-03-07 15:27:39 +0000723 # Let the process initialize (Issue #3137)
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000724 time.sleep(0.1)
Florent Xiclunac0838642010-03-07 15:27:39 +0000725 # The process should not terminate prematurely
Florent Xiclunad6935632010-03-05 01:05:55 +0000726 self.assertIsNone(p.poll())
Florent Xiclunac0838642010-03-07 15:27:39 +0000727 # Retry if the process do not receive the signal.
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000728 count, maxcount = 0, 3
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000729 while count < maxcount and p.poll() is None:
Florent Xiclunac0838642010-03-07 15:27:39 +0000730 getattr(p, method)(*args)
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000731 time.sleep(0.1)
732 count += 1
Florent Xiclunac0838642010-03-07 15:27:39 +0000733
734 self.assertIsNotNone(p.poll(), "the subprocess did not terminate")
Florent Xiclunad6935632010-03-05 01:05:55 +0000735 if count > 1:
Florent Xiclunac0838642010-03-07 15:27:39 +0000736 print >>sys.stderr, ("p.{}{} succeeded after "
737 "{} attempts".format(method, args, count))
738 return p
739
740 def test_send_signal(self):
741 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000742 _, stderr = p.communicate()
Florent Xicluna3c919cf2010-03-23 19:19:16 +0000743 self.assertIn('KeyboardInterrupt', stderr)
Florent Xicluna446ff142010-03-23 15:05:30 +0000744 self.assertNotEqual(p.wait(), 0)
Christian Heimese74c8f22008-04-19 02:23:57 +0000745
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000746 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000747 p = self._kill_process('kill')
Florent Xicluna446ff142010-03-23 15:05:30 +0000748 _, stderr = p.communicate()
749 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000750 self.assertEqual(p.wait(), -signal.SIGKILL)
Christian Heimese74c8f22008-04-19 02:23:57 +0000751
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000752 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000753 p = self._kill_process('terminate')
Florent Xicluna446ff142010-03-23 15:05:30 +0000754 _, stderr = p.communicate()
755 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000756 self.assertEqual(p.wait(), -signal.SIGTERM)
Tim Peterse718f612004-10-12 21:51:32 +0000757
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000758
Florent Xiclunabab22a72010-03-04 19:40:48 +0000759@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000760class Win32ProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000761
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000762 def test_startupinfo(self):
763 # startupinfo argument
764 # We uses hardcoded constants, because we do not want to
765 # depend on win32all.
766 STARTF_USESHOWWINDOW = 1
767 SW_MAXIMIZE = 3
768 startupinfo = subprocess.STARTUPINFO()
769 startupinfo.dwFlags = STARTF_USESHOWWINDOW
770 startupinfo.wShowWindow = SW_MAXIMIZE
771 # Since Python is a console process, it won't be affected
772 # by wShowWindow, but the argument should be silently
773 # ignored
774 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000775 startupinfo=startupinfo)
776
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000777 def test_creationflags(self):
778 # creationflags argument
779 CREATE_NEW_CONSOLE = 16
780 sys.stderr.write(" a DOS box should flash briefly ...\n")
781 subprocess.call(sys.executable +
782 ' -c "import time; time.sleep(0.25)"',
783 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000784
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000785 def test_invalid_args(self):
786 # invalid arguments should raise ValueError
787 self.assertRaises(ValueError, subprocess.call,
788 [sys.executable, "-c",
789 "import sys; sys.exit(47)"],
790 preexec_fn=lambda: 1)
791 self.assertRaises(ValueError, subprocess.call,
792 [sys.executable, "-c",
793 "import sys; sys.exit(47)"],
794 stdout=subprocess.PIPE,
795 close_fds=True)
796
797 def test_close_fds(self):
798 # close file descriptors
799 rc = subprocess.call([sys.executable, "-c",
800 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000801 close_fds=True)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000802 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000803
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000804 def test_shell_sequence(self):
805 # Run command through the shell (sequence)
806 newenv = os.environ.copy()
807 newenv["FRUIT"] = "physalis"
808 p = subprocess.Popen(["set"], shell=1,
809 stdout=subprocess.PIPE,
810 env=newenv)
811 self.assertIn("physalis", p.stdout.read())
Peter Astrand81a191b2007-05-26 22:18:20 +0000812
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000813 def test_shell_string(self):
814 # Run command through the shell (string)
815 newenv = os.environ.copy()
816 newenv["FRUIT"] = "physalis"
817 p = subprocess.Popen("set", shell=1,
818 stdout=subprocess.PIPE,
819 env=newenv)
820 self.assertIn("physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000821
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000822 def test_call_string(self):
823 # call() function with string argument on Windows
824 rc = subprocess.call(sys.executable +
825 ' -c "import sys; sys.exit(47)"')
826 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000827
Florent Xiclunac0838642010-03-07 15:27:39 +0000828 def _kill_process(self, method, *args):
Florent Xicluna400efc22010-03-07 17:12:23 +0000829 # Some win32 buildbot raises EOFError if stdin is inherited
830 p = subprocess.Popen([sys.executable, "-c", "input()"],
Florent Xicluna446ff142010-03-23 15:05:30 +0000831 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000832
Florent Xiclunafaf17532010-03-08 10:59:33 +0000833 # Let the process initialize (Issue #3137)
Florent Xiclunac0838642010-03-07 15:27:39 +0000834 time.sleep(0.1)
835 # The process should not terminate prematurely
836 self.assertIsNone(p.poll())
837 # Retry if the process do not receive the signal.
838 count, maxcount = 0, 3
839 while count < maxcount and p.poll() is None:
840 getattr(p, method)(*args)
841 time.sleep(0.1)
842 count += 1
843
844 returncode = p.poll()
845 self.assertIsNotNone(returncode, "the subprocess did not terminate")
846 if count > 1:
847 print >>sys.stderr, ("p.{}{} succeeded after "
848 "{} attempts".format(method, args, count))
Florent Xicluna446ff142010-03-23 15:05:30 +0000849 _, stderr = p.communicate()
850 self.assertStderrEqual(stderr, '')
Florent Xiclunac0838642010-03-07 15:27:39 +0000851 self.assertEqual(p.wait(), returncode)
Florent Xiclunafaf17532010-03-08 10:59:33 +0000852 self.assertNotEqual(returncode, 0)
Florent Xiclunac0838642010-03-07 15:27:39 +0000853
854 def test_send_signal(self):
855 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimese74c8f22008-04-19 02:23:57 +0000856
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000857 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000858 self._kill_process('kill')
Christian Heimese74c8f22008-04-19 02:23:57 +0000859
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000860 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000861 self._kill_process('terminate')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000862
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000863
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000864@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
865 "poll system call not supported")
866class ProcessTestCaseNoPoll(ProcessTestCase):
867 def setUp(self):
868 subprocess._has_poll = False
869 ProcessTestCase.setUp(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000870
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000871 def tearDown(self):
872 subprocess._has_poll = True
873 ProcessTestCase.tearDown(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000874
875
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000876class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithc1baf4a2010-03-01 02:53:24 +0000877 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000878 def test_eintr_retry_call(self):
879 record_calls = []
880 def fake_os_func(*args):
881 record_calls.append(args)
882 if len(record_calls) == 2:
883 raise OSError(errno.EINTR, "fake interrupted system call")
884 return tuple(reversed(args))
885
886 self.assertEqual((999, 256),
887 subprocess._eintr_retry_call(fake_os_func, 256, 999))
888 self.assertEqual([(256, 999)], record_calls)
889 # This time there will be an EINTR so it will loop once.
890 self.assertEqual((666,),
891 subprocess._eintr_retry_call(fake_os_func, 666))
892 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
893
894
Tim Golden8e4756c2010-08-12 11:00:35 +0000895@unittest.skipUnless(mswindows, "mswindows only")
896class CommandsWithSpaces (BaseTestCase):
897
898 def setUp(self):
899 super(CommandsWithSpaces, self).setUp()
900 f, fname = mkstemp(".py", "te st")
901 self.fname = fname.lower ()
902 os.write(f, b"import sys;"
903 b"sys.stdout.write('%d %s' % (len(sys.argv), [a.lower () for a in sys.argv]))"
904 )
905 os.close(f)
906
907 def tearDown(self):
908 os.remove(self.fname)
909 super(CommandsWithSpaces, self).tearDown()
910
911 def with_spaces(self, *args, **kwargs):
912 kwargs['stdout'] = subprocess.PIPE
913 p = subprocess.Popen(*args, **kwargs)
914 self.assertEqual(
915 p.stdout.read ().decode("mbcs"),
916 "2 [%r, 'ab cd']" % self.fname
917 )
918
919 def test_shell_string_with_spaces(self):
920 # call() function with string argument with spaces on Windows
Brian Curtine8c49202010-08-13 21:01:52 +0000921 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
922 "ab cd"), shell=1)
Tim Golden8e4756c2010-08-12 11:00:35 +0000923
924 def test_shell_sequence_with_spaces(self):
925 # call() function with sequence argument with spaces on Windows
Brian Curtine8c49202010-08-13 21:01:52 +0000926 self.with_spaces([sys.executable, self.fname, "ab cd"], shell=1)
Tim Golden8e4756c2010-08-12 11:00:35 +0000927
928 def test_noshell_string_with_spaces(self):
929 # call() function with string argument with spaces on Windows
930 self.with_spaces('"%s" "%s" "%s"' % (sys.executable, self.fname,
931 "ab cd"))
932
933 def test_noshell_sequence_with_spaces(self):
934 # call() function with sequence argument with spaces on Windows
935 self.with_spaces([sys.executable, self.fname, "ab cd"])
936
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000937def test_main():
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000938 unit_tests = (ProcessTestCase,
939 POSIXProcessTestCase,
940 Win32ProcessTestCase,
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000941 ProcessTestCaseNoPoll,
Tim Golden8e4756c2010-08-12 11:00:35 +0000942 HelperFunctionTests,
943 CommandsWithSpaces)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000944
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000945 test_support.run_unittest(*unit_tests)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000946 test_support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000947
948if __name__ == "__main__":
949 test_main()