blob: f471c7bd86e118bc4d0d3a3369c935185b7e3426 [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
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000536
537# context manager
538class _SuppressCoreFiles(object):
539 """Try to prevent core files from being created."""
540 old_limit = None
541
542 def __enter__(self):
543 """Try to save previous ulimit, then set it to (0, 0)."""
544 try:
545 import resource
546 self.old_limit = resource.getrlimit(resource.RLIMIT_CORE)
547 resource.setrlimit(resource.RLIMIT_CORE, (0, 0))
548 except (ImportError, ValueError, resource.error):
549 pass
550
551 def __exit__(self, *args):
552 """Return core file behavior to default."""
553 if self.old_limit is None:
554 return
555 try:
556 import resource
557 resource.setrlimit(resource.RLIMIT_CORE, self.old_limit)
558 except (ImportError, ValueError, resource.error):
559 pass
560
561
Florent Xiclunabab22a72010-03-04 19:40:48 +0000562@unittest.skipIf(mswindows, "POSIX specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000563class POSIXProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000564
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000565 def test_exceptions(self):
566 # caught & re-raised exceptions
567 with self.assertRaises(OSError) as c:
568 p = subprocess.Popen([sys.executable, "-c", ""],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000569 cwd="/this/path/does/not/exist")
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000570 # The attribute child_traceback should contain "os.chdir" somewhere.
571 self.assertIn("os.chdir", c.exception.child_traceback)
Tim Peterse718f612004-10-12 21:51:32 +0000572
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000573 def test_run_abort(self):
574 # returncode handles signal termination
575 with _SuppressCoreFiles():
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000576 p = subprocess.Popen([sys.executable, "-c",
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000577 "import os; os.abort()"])
578 p.wait()
579 self.assertEqual(-p.returncode, signal.SIGABRT)
580
581 def test_preexec(self):
582 # preexec function
583 p = subprocess.Popen([sys.executable, "-c",
584 "import sys, os;"
585 "sys.stdout.write(os.getenv('FRUIT'))"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000586 stdout=subprocess.PIPE,
587 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000588 self.assertEqual(p.stdout.read(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000589
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000590 def test_args_string(self):
591 # args is a string
592 f, fname = mkstemp()
593 os.write(f, "#!/bin/sh\n")
594 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
595 sys.executable)
596 os.close(f)
597 os.chmod(fname, 0o700)
598 p = subprocess.Popen(fname)
599 p.wait()
600 os.remove(fname)
601 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000602
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000603 def test_invalid_args(self):
604 # invalid arguments should raise ValueError
605 self.assertRaises(ValueError, subprocess.call,
606 [sys.executable, "-c",
607 "import sys; sys.exit(47)"],
608 startupinfo=47)
609 self.assertRaises(ValueError, subprocess.call,
610 [sys.executable, "-c",
611 "import sys; sys.exit(47)"],
612 creationflags=47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000613
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000614 def test_shell_sequence(self):
615 # Run command through the shell (sequence)
616 newenv = os.environ.copy()
617 newenv["FRUIT"] = "apple"
618 p = subprocess.Popen(["echo $FRUIT"], shell=1,
619 stdout=subprocess.PIPE,
620 env=newenv)
621 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000622
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000623 def test_shell_string(self):
624 # Run command through the shell (string)
625 newenv = os.environ.copy()
626 newenv["FRUIT"] = "apple"
627 p = subprocess.Popen("echo $FRUIT", shell=1,
628 stdout=subprocess.PIPE,
629 env=newenv)
630 self.assertEqual(p.stdout.read().strip(), "apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000631
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000632 def test_call_string(self):
633 # call() function with string argument on UNIX
634 f, fname = mkstemp()
635 os.write(f, "#!/bin/sh\n")
636 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
637 sys.executable)
638 os.close(f)
639 os.chmod(fname, 0700)
640 rc = subprocess.call(fname)
641 os.remove(fname)
642 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000643
Stefan Krahe9a6a7d2010-07-19 14:41:08 +0000644 def test_specific_shell(self):
645 # Issue #9265: Incorrect name passed as arg[0].
646 shells = []
647 for prefix in ['/bin', '/usr/bin/', '/usr/local/bin']:
648 for name in ['bash', 'ksh']:
649 sh = os.path.join(prefix, name)
650 if os.path.isfile(sh):
651 shells.append(sh)
652 if not shells: # Will probably work for any shell but csh.
653 self.skipTest("bash or ksh required for this test")
654 sh = '/bin/sh'
655 if os.path.isfile(sh) and not os.path.islink(sh):
656 # Test will fail if /bin/sh is a symlink to csh.
657 shells.append(sh)
658 for sh in shells:
659 p = subprocess.Popen("echo $0", executable=sh, shell=True,
660 stdout=subprocess.PIPE)
661 self.assertEqual(p.stdout.read().strip(), sh)
662
Florent Xiclunac0838642010-03-07 15:27:39 +0000663 def _kill_process(self, method, *args):
Florent Xiclunacecef392010-03-05 19:31:21 +0000664 # Do not inherit file handles from the parent.
665 # It should fix failures on some platforms.
666 p = subprocess.Popen([sys.executable, "-c", "input()"], close_fds=True,
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000667 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Christian Heimese74c8f22008-04-19 02:23:57 +0000668
Florent Xiclunac0838642010-03-07 15:27:39 +0000669 # Let the process initialize (Issue #3137)
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000670 time.sleep(0.1)
Florent Xiclunac0838642010-03-07 15:27:39 +0000671 # The process should not terminate prematurely
Florent Xiclunad6935632010-03-05 01:05:55 +0000672 self.assertIsNone(p.poll())
Florent Xiclunac0838642010-03-07 15:27:39 +0000673 # Retry if the process do not receive the signal.
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000674 count, maxcount = 0, 3
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000675 while count < maxcount and p.poll() is None:
Florent Xiclunac0838642010-03-07 15:27:39 +0000676 getattr(p, method)(*args)
Florent Xicluna80e0e2d2010-03-05 00:47:40 +0000677 time.sleep(0.1)
678 count += 1
Florent Xiclunac0838642010-03-07 15:27:39 +0000679
680 self.assertIsNotNone(p.poll(), "the subprocess did not terminate")
Florent Xiclunad6935632010-03-05 01:05:55 +0000681 if count > 1:
Florent Xiclunac0838642010-03-07 15:27:39 +0000682 print >>sys.stderr, ("p.{}{} succeeded after "
683 "{} attempts".format(method, args, count))
684 return p
685
686 def test_send_signal(self):
687 p = self._kill_process('send_signal', signal.SIGINT)
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000688 _, stderr = p.communicate()
Florent Xicluna3c919cf2010-03-23 19:19:16 +0000689 self.assertIn('KeyboardInterrupt', stderr)
Florent Xicluna446ff142010-03-23 15:05:30 +0000690 self.assertNotEqual(p.wait(), 0)
Christian Heimese74c8f22008-04-19 02:23:57 +0000691
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000692 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000693 p = self._kill_process('kill')
Florent Xicluna446ff142010-03-23 15:05:30 +0000694 _, stderr = p.communicate()
695 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000696 self.assertEqual(p.wait(), -signal.SIGKILL)
Christian Heimese74c8f22008-04-19 02:23:57 +0000697
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000698 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000699 p = self._kill_process('terminate')
Florent Xicluna446ff142010-03-23 15:05:30 +0000700 _, stderr = p.communicate()
701 self.assertStderrEqual(stderr, '')
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000702 self.assertEqual(p.wait(), -signal.SIGTERM)
Tim Peterse718f612004-10-12 21:51:32 +0000703
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000704
Florent Xiclunabab22a72010-03-04 19:40:48 +0000705@unittest.skipUnless(mswindows, "Windows specific tests")
Florent Xiclunafc4d6d72010-03-23 14:36:45 +0000706class Win32ProcessTestCase(BaseTestCase):
Florent Xiclunaab5e17f2010-03-04 21:31:58 +0000707
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000708 def test_startupinfo(self):
709 # startupinfo argument
710 # We uses hardcoded constants, because we do not want to
711 # depend on win32all.
712 STARTF_USESHOWWINDOW = 1
713 SW_MAXIMIZE = 3
714 startupinfo = subprocess.STARTUPINFO()
715 startupinfo.dwFlags = STARTF_USESHOWWINDOW
716 startupinfo.wShowWindow = SW_MAXIMIZE
717 # Since Python is a console process, it won't be affected
718 # by wShowWindow, but the argument should be silently
719 # ignored
720 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000721 startupinfo=startupinfo)
722
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000723 def test_creationflags(self):
724 # creationflags argument
725 CREATE_NEW_CONSOLE = 16
726 sys.stderr.write(" a DOS box should flash briefly ...\n")
727 subprocess.call(sys.executable +
728 ' -c "import time; time.sleep(0.25)"',
729 creationflags=CREATE_NEW_CONSOLE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000730
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000731 def test_invalid_args(self):
732 # invalid arguments should raise ValueError
733 self.assertRaises(ValueError, subprocess.call,
734 [sys.executable, "-c",
735 "import sys; sys.exit(47)"],
736 preexec_fn=lambda: 1)
737 self.assertRaises(ValueError, subprocess.call,
738 [sys.executable, "-c",
739 "import sys; sys.exit(47)"],
740 stdout=subprocess.PIPE,
741 close_fds=True)
742
743 def test_close_fds(self):
744 # close file descriptors
745 rc = subprocess.call([sys.executable, "-c",
746 "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000747 close_fds=True)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000748 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000749
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000750 def test_shell_sequence(self):
751 # Run command through the shell (sequence)
752 newenv = os.environ.copy()
753 newenv["FRUIT"] = "physalis"
754 p = subprocess.Popen(["set"], shell=1,
755 stdout=subprocess.PIPE,
756 env=newenv)
757 self.assertIn("physalis", p.stdout.read())
Peter Astrand81a191b2007-05-26 22:18:20 +0000758
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000759 def test_shell_string(self):
760 # Run command through the shell (string)
761 newenv = os.environ.copy()
762 newenv["FRUIT"] = "physalis"
763 p = subprocess.Popen("set", shell=1,
764 stdout=subprocess.PIPE,
765 env=newenv)
766 self.assertIn("physalis", p.stdout.read())
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000767
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000768 def test_call_string(self):
769 # call() function with string argument on Windows
770 rc = subprocess.call(sys.executable +
771 ' -c "import sys; sys.exit(47)"')
772 self.assertEqual(rc, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000773
Florent Xiclunac0838642010-03-07 15:27:39 +0000774 def _kill_process(self, method, *args):
Florent Xicluna400efc22010-03-07 17:12:23 +0000775 # Some win32 buildbot raises EOFError if stdin is inherited
776 p = subprocess.Popen([sys.executable, "-c", "input()"],
Florent Xicluna446ff142010-03-23 15:05:30 +0000777 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000778
Florent Xiclunafaf17532010-03-08 10:59:33 +0000779 # Let the process initialize (Issue #3137)
Florent Xiclunac0838642010-03-07 15:27:39 +0000780 time.sleep(0.1)
781 # The process should not terminate prematurely
782 self.assertIsNone(p.poll())
783 # Retry if the process do not receive the signal.
784 count, maxcount = 0, 3
785 while count < maxcount and p.poll() is None:
786 getattr(p, method)(*args)
787 time.sleep(0.1)
788 count += 1
789
790 returncode = p.poll()
791 self.assertIsNotNone(returncode, "the subprocess did not terminate")
792 if count > 1:
793 print >>sys.stderr, ("p.{}{} succeeded after "
794 "{} attempts".format(method, args, count))
Florent Xicluna446ff142010-03-23 15:05:30 +0000795 _, stderr = p.communicate()
796 self.assertStderrEqual(stderr, '')
Florent Xiclunac0838642010-03-07 15:27:39 +0000797 self.assertEqual(p.wait(), returncode)
Florent Xiclunafaf17532010-03-08 10:59:33 +0000798 self.assertNotEqual(returncode, 0)
Florent Xiclunac0838642010-03-07 15:27:39 +0000799
800 def test_send_signal(self):
801 self._kill_process('send_signal', signal.SIGTERM)
Christian Heimese74c8f22008-04-19 02:23:57 +0000802
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000803 def test_kill(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000804 self._kill_process('kill')
Christian Heimese74c8f22008-04-19 02:23:57 +0000805
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000806 def test_terminate(self):
Florent Xiclunac0838642010-03-07 15:27:39 +0000807 self._kill_process('terminate')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000808
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000809
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000810@unittest.skipUnless(getattr(subprocess, '_has_poll', False),
811 "poll system call not supported")
812class ProcessTestCaseNoPoll(ProcessTestCase):
813 def setUp(self):
814 subprocess._has_poll = False
815 ProcessTestCase.setUp(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000816
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000817 def tearDown(self):
818 subprocess._has_poll = True
819 ProcessTestCase.tearDown(self)
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000820
821
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000822class HelperFunctionTests(unittest.TestCase):
Gregory P. Smithc1baf4a2010-03-01 02:53:24 +0000823 @unittest.skipIf(mswindows, "errno and EINTR make no sense on windows")
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000824 def test_eintr_retry_call(self):
825 record_calls = []
826 def fake_os_func(*args):
827 record_calls.append(args)
828 if len(record_calls) == 2:
829 raise OSError(errno.EINTR, "fake interrupted system call")
830 return tuple(reversed(args))
831
832 self.assertEqual((999, 256),
833 subprocess._eintr_retry_call(fake_os_func, 256, 999))
834 self.assertEqual([(256, 999)], record_calls)
835 # This time there will be an EINTR so it will loop once.
836 self.assertEqual((666,),
837 subprocess._eintr_retry_call(fake_os_func, 666))
838 self.assertEqual([(256, 999), (666,), (666,)], record_calls)
839
840
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000841def test_main():
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000842 unit_tests = (ProcessTestCase,
843 POSIXProcessTestCase,
844 Win32ProcessTestCase,
Gregory P. Smithcce211f2010-03-01 00:05:08 +0000845 ProcessTestCaseNoPoll,
846 HelperFunctionTests)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000847
Gregory P. Smithdd7ca242009-07-04 01:49:29 +0000848 test_support.run_unittest(*unit_tests)
Florent Xicluna98e3fc32010-02-27 19:20:50 +0000849 test_support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000850
851if __name__ == "__main__":
852 test_main()