blob: fe916c2a8511a8bf87a6ffa0a2534256dd4b5eac [file] [log] [blame]
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Fredrik Lundh5b3687d2004-10-12 15:26:28 +00003import subprocess
4import sys
5import signal
6import os
7import tempfile
8import time
Tim Peters3761e8d2004-10-13 04:07:12 +00009import re
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000010
11mswindows = (sys.platform == "win32")
12
13#
14# Depends on the following external programs: Python
15#
16
17if mswindows:
Tim Peters3b01a702004-10-12 22:19:32 +000018 SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
19 'os.O_BINARY);')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000020else:
21 SETBINARY = ''
22
Tim Peters3761e8d2004-10-13 04:07:12 +000023# In a debug build, stuff like "[6580 refs]" is printed to stderr at
24# shutdown time. That frustrates tests trying to check stderr produced
25# from a spawned Python process.
26def remove_stderr_debug_decorations(stderr):
Guido van Rossum98297ee2007-11-06 21:34:58 +000027 return re.sub("\[\d+ refs\]\r?\n?$", "", stderr.decode()).encode()
28 #return re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr)
Tim Peters3761e8d2004-10-13 04:07:12 +000029
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000030class ProcessTestCase(unittest.TestCase):
Thomas Wouters0e3f5912006-08-11 14:57:12 +000031 def setUp(self):
32 # Try to minimize the number of children we have so this test
33 # doesn't crash on some buildbots (Alphas in particular).
Benjamin Petersonee8712c2008-05-20 21:35:26 +000034 if hasattr(support, "reap_children"):
35 support.reap_children()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000036
37 def tearDown(self):
38 # Try to minimize the number of children we have so this test
39 # doesn't crash on some buildbots (Alphas in particular).
Benjamin Petersonee8712c2008-05-20 21:35:26 +000040 if hasattr(support, "reap_children"):
41 support.reap_children()
Thomas Wouters0e3f5912006-08-11 14:57:12 +000042
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000043 def mkstemp(self):
44 """wrapper for mkstemp, calling mktemp if mkstemp is not available"""
45 if hasattr(tempfile, "mkstemp"):
46 return tempfile.mkstemp()
47 else:
48 fname = tempfile.mktemp()
49 return os.open(fname, os.O_RDWR|os.O_CREAT), fname
Tim Peterse718f612004-10-12 21:51:32 +000050
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000051 #
52 # Generic tests
53 #
54 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +000055 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +000056 rc = subprocess.call([sys.executable, "-c",
57 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000058 self.assertEqual(rc, 47)
59
Peter Astrand454f7672005-01-01 09:36:35 +000060 def test_check_call_zero(self):
61 # check_call() function with zero return code
62 rc = subprocess.check_call([sys.executable, "-c",
63 "import sys; sys.exit(0)"])
64 self.assertEqual(rc, 0)
65
66 def test_check_call_nonzero(self):
67 # check_call() function with non-zero return code
68 try:
69 subprocess.check_call([sys.executable, "-c",
70 "import sys; sys.exit(47)"])
Guido van Rossumb940e112007-01-10 16:19:56 +000071 except subprocess.CalledProcessError as e:
Thomas Wouters0e3f5912006-08-11 14:57:12 +000072 self.assertEqual(e.returncode, 47)
Peter Astrand454f7672005-01-01 09:36:35 +000073 else:
74 self.fail("Expected CalledProcessError")
75
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000076 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +000077 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000078 newenv = os.environ.copy()
79 newenv["FRUIT"] = "banana"
80 rc = subprocess.call([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +000081 'import sys, os;'
82 'sys.exit(os.getenv("FRUIT")=="banana")'],
83 env=newenv)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000084 self.assertEqual(rc, 1)
85
86 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +000087 # .stdin is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +000088 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000089 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
90 p.wait()
91 self.assertEqual(p.stdin, None)
92
93 def test_stdout_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +000094 # .stdout is None when not redirected
Tim Peters29b6b4f2004-10-13 03:43:40 +000095 p = subprocess.Popen([sys.executable, "-c",
Georg Brandl88fc6642007-02-09 21:28:07 +000096 'print(" this bit of output is from a '
Tim Peters4052fe52004-10-13 03:29:54 +000097 'test of stdout in a different '
Georg Brandl88fc6642007-02-09 21:28:07 +000098 'process ...")'],
Tim Peters4052fe52004-10-13 03:29:54 +000099 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000100 p.wait()
101 self.assertEqual(p.stdout, None)
102
103 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000104 # .stderr is None when not redirected
Georg Brandl88fc6642007-02-09 21:28:07 +0000105 p = subprocess.Popen([sys.executable, "-c", 'print("banana")'],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000106 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
107 p.wait()
108 self.assertEqual(p.stderr, None)
109
110 def test_executable(self):
Tim Peters3b01a702004-10-12 22:19:32 +0000111 p = subprocess.Popen(["somethingyoudonthave",
112 "-c", "import sys; sys.exit(47)"],
113 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000114 p.wait()
115 self.assertEqual(p.returncode, 47)
116
117 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000118 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000119 p = subprocess.Popen([sys.executable, "-c",
120 'import sys; sys.exit(sys.stdin.read() == "pear")'],
121 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000122 p.stdin.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000123 p.stdin.close()
124 p.wait()
125 self.assertEqual(p.returncode, 1)
126
127 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000128 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000129 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000130 d = tf.fileno()
131 os.write(d, "pear")
132 os.lseek(d, 0, 0)
133 p = subprocess.Popen([sys.executable, "-c",
134 'import sys; sys.exit(sys.stdin.read() == "pear")'],
135 stdin=d)
136 p.wait()
137 self.assertEqual(p.returncode, 1)
138
139 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000140 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000141 tf = tempfile.TemporaryFile()
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000142 tf.write(b"pear")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000143 tf.seek(0)
144 p = subprocess.Popen([sys.executable, "-c",
145 'import sys; sys.exit(sys.stdin.read() == "pear")'],
146 stdin=tf)
147 p.wait()
148 self.assertEqual(p.returncode, 1)
149
150 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000151 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000152 p = subprocess.Popen([sys.executable, "-c",
153 'import sys; sys.stdout.write("orange")'],
154 stdout=subprocess.PIPE)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000155 self.assertEqual(p.stdout.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000156
157 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000158 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000159 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000160 d = tf.fileno()
161 p = subprocess.Popen([sys.executable, "-c",
162 'import sys; sys.stdout.write("orange")'],
163 stdout=d)
164 p.wait()
165 os.lseek(d, 0, 0)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000166 self.assertEqual(os.read(d, 1024), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000167
168 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000169 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000170 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000171 p = subprocess.Popen([sys.executable, "-c",
172 'import sys; sys.stdout.write("orange")'],
173 stdout=tf)
174 p.wait()
175 tf.seek(0)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000176 self.assertEqual(tf.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000177
178 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000179 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000180 p = subprocess.Popen([sys.executable, "-c",
181 'import sys; sys.stderr.write("strawberry")'],
182 stderr=subprocess.PIPE)
Tim Peters3761e8d2004-10-13 04:07:12 +0000183 self.assertEqual(remove_stderr_debug_decorations(p.stderr.read()),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000184 b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000185
186 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000187 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000188 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000189 d = tf.fileno()
190 p = subprocess.Popen([sys.executable, "-c",
191 'import sys; sys.stderr.write("strawberry")'],
192 stderr=d)
193 p.wait()
194 os.lseek(d, 0, 0)
Tim Peters3761e8d2004-10-13 04:07:12 +0000195 self.assertEqual(remove_stderr_debug_decorations(os.read(d, 1024)),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000196 b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000197
198 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000199 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000200 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000201 p = subprocess.Popen([sys.executable, "-c",
202 'import sys; sys.stderr.write("strawberry")'],
203 stderr=tf)
204 p.wait()
205 tf.seek(0)
Tim Peters3761e8d2004-10-13 04:07:12 +0000206 self.assertEqual(remove_stderr_debug_decorations(tf.read()),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000207 b"strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000208
209 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000210 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000211 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000212 'import sys;'
213 'sys.stdout.write("apple");'
214 'sys.stdout.flush();'
215 'sys.stderr.write("orange")'],
216 stdout=subprocess.PIPE,
217 stderr=subprocess.STDOUT)
Tim Peters3761e8d2004-10-13 04:07:12 +0000218 output = p.stdout.read()
219 stripped = remove_stderr_debug_decorations(output)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000220 self.assertEqual(stripped, b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000221
222 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000223 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000224 tf = tempfile.TemporaryFile()
225 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000226 'import sys;'
227 'sys.stdout.write("apple");'
228 'sys.stdout.flush();'
229 'sys.stderr.write("orange")'],
230 stdout=tf,
231 stderr=tf)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000232 p.wait()
233 tf.seek(0)
Tim Peters3761e8d2004-10-13 04:07:12 +0000234 output = tf.read()
235 stripped = remove_stderr_debug_decorations(output)
Guido van Rossum98297ee2007-11-06 21:34:58 +0000236 self.assertEqual(stripped, b"appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000237
Thomas Wouters89f507f2006-12-13 04:49:30 +0000238 def test_stdout_filedes_of_stdout(self):
239 # stdout is set to 1 (#1531862).
240 cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
241 rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
242 self.assertEquals(rc, 2)
243
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000244 def test_cwd(self):
Christian Heimes5fb7c2a2007-12-24 08:52:31 +0000245 tmpdir = tempfile.gettempdir()
Peter Astrand195404f2004-11-12 15:51:48 +0000246 # We cannot use os.path.realpath to canonicalize the path,
247 # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
248 cwd = os.getcwd()
249 os.chdir(tmpdir)
250 tmpdir = os.getcwd()
251 os.chdir(cwd)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000252 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000253 'import sys,os;'
254 'sys.stdout.write(os.getcwd())'],
255 stdout=subprocess.PIPE,
256 cwd=tmpdir)
Fredrik Lundh59c05592004-10-13 06:55:40 +0000257 normcase = os.path.normcase
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000258 self.assertEqual(normcase(p.stdout.read().decode("utf-8")),
259 normcase(tmpdir))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000260
261 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000262 newenv = os.environ.copy()
263 newenv["FRUIT"] = "orange"
264 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000265 'import sys,os;'
266 'sys.stdout.write(os.getenv("FRUIT"))'],
267 stdout=subprocess.PIPE,
268 env=newenv)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000269 self.assertEqual(p.stdout.read(), b"orange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000270
Peter Astrandcbac93c2005-03-03 20:24:28 +0000271 def test_communicate_stdin(self):
272 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000273 'import sys;'
274 'sys.exit(sys.stdin.read() == "pear")'],
Peter Astrandcbac93c2005-03-03 20:24:28 +0000275 stdin=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000276 p.communicate(b"pear")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000277 self.assertEqual(p.returncode, 1)
278
279 def test_communicate_stdout(self):
280 p = subprocess.Popen([sys.executable, "-c",
281 'import sys; sys.stdout.write("pineapple")'],
282 stdout=subprocess.PIPE)
283 (stdout, stderr) = p.communicate()
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000284 self.assertEqual(stdout, b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000285 self.assertEqual(stderr, None)
286
287 def test_communicate_stderr(self):
288 p = subprocess.Popen([sys.executable, "-c",
289 'import sys; sys.stderr.write("pineapple")'],
290 stderr=subprocess.PIPE)
291 (stdout, stderr) = p.communicate()
292 self.assertEqual(stdout, None)
Brett Cannon653a5ad2005-03-05 06:40:52 +0000293 # When running with a pydebug build, the # of references is outputted
294 # to stderr, so just check if stderr at least started with "pinapple"
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000295 self.assertEqual(remove_stderr_debug_decorations(stderr), b"pineapple")
Peter Astrandcbac93c2005-03-03 20:24:28 +0000296
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000297 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000298 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000299 'import sys,os;'
300 'sys.stderr.write("pineapple");'
301 'sys.stdout.write(sys.stdin.read())'],
302 stdin=subprocess.PIPE,
303 stdout=subprocess.PIPE,
304 stderr=subprocess.PIPE)
Georg Brandl1abcbf82008-07-01 19:28:43 +0000305 (stdout, stderr) = p.communicate(b"banana")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000306 self.assertEqual(stdout, b"banana")
Tim Peters3761e8d2004-10-13 04:07:12 +0000307 self.assertEqual(remove_stderr_debug_decorations(stderr),
Guido van Rossum98297ee2007-11-06 21:34:58 +0000308 b"pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000309
Georg Brandlf08a9dd2008-06-10 16:57:31 +0000310 # This test is Linux specific for simplicity to at least have
311 # some coverage. It is not a platform specific bug.
312 if os.path.isdir('/proc/%d/fd' % os.getpid()):
313 # Test for the fd leak reported in http://bugs.python.org/issue2791.
314 def test_communicate_pipe_fd_leak(self):
315 fd_directory = '/proc/%d/fd' % os.getpid()
316 num_fds_before_popen = len(os.listdir(fd_directory))
317 p = subprocess.Popen([sys.executable, '-c', 'print()'],
318 stdout=subprocess.PIPE)
319 p.communicate()
320 num_fds_after_communicate = len(os.listdir(fd_directory))
321 del p
322 num_fds_after_destruction = len(os.listdir(fd_directory))
323 self.assertEqual(num_fds_before_popen, num_fds_after_destruction)
324 self.assertEqual(num_fds_before_popen, num_fds_after_communicate)
325
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000326 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000327 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000328 p = subprocess.Popen([sys.executable, "-c",
329 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000330 (stdout, stderr) = p.communicate()
331 self.assertEqual(stdout, None)
332 self.assertEqual(stderr, None)
333
334 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000335 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000336 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000337 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000338 x, y = os.pipe()
339 if mswindows:
340 pipe_buf = 512
341 else:
342 pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
343 os.close(x)
344 os.close(y)
345 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000346 'import sys,os;'
347 'sys.stdout.write(sys.stdin.read(47));'
348 'sys.stderr.write("xyz"*%d);'
349 'sys.stdout.write(sys.stdin.read())' % pipe_buf],
350 stdin=subprocess.PIPE,
351 stdout=subprocess.PIPE,
352 stderr=subprocess.PIPE)
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000353 string_to_write = b"abc"*pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000354 (stdout, stderr) = p.communicate(string_to_write)
355 self.assertEqual(stdout, string_to_write)
356
357 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000358 # stdin.write before communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000359 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000360 'import sys,os;'
361 'sys.stdout.write(sys.stdin.read())'],
362 stdin=subprocess.PIPE,
363 stdout=subprocess.PIPE,
364 stderr=subprocess.PIPE)
Guido van Rossumbb839ef2007-08-27 23:58:21 +0000365 p.stdin.write(b"banana")
366 (stdout, stderr) = p.communicate(b"split")
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000367 self.assertEqual(stdout, b"bananasplit")
Guido van Rossum98297ee2007-11-06 21:34:58 +0000368 self.assertEqual(remove_stderr_debug_decorations(stderr), b"")
Tim Peterse718f612004-10-12 21:51:32 +0000369
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000370 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000371 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000372 'import sys,os;' + SETBINARY +
373 'sys.stdout.write("line1\\n");'
374 'sys.stdout.flush();'
375 'sys.stdout.write("line2\\n");'
376 'sys.stdout.flush();'
377 'sys.stdout.write("line3\\r\\n");'
378 'sys.stdout.flush();'
379 'sys.stdout.write("line4\\r");'
380 'sys.stdout.flush();'
381 'sys.stdout.write("\\nline5");'
382 'sys.stdout.flush();'
383 'sys.stdout.write("\\nline6");'],
384 stdout=subprocess.PIPE,
385 universal_newlines=1)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000386 stdout = p.stdout.read()
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000387 self.assertEqual(stdout, "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000388
389 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000390 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000391 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000392 'import sys,os;' + SETBINARY +
393 'sys.stdout.write("line1\\n");'
394 'sys.stdout.flush();'
395 'sys.stdout.write("line2\\n");'
396 'sys.stdout.flush();'
397 'sys.stdout.write("line3\\r\\n");'
398 'sys.stdout.flush();'
399 'sys.stdout.write("line4\\r");'
400 'sys.stdout.flush();'
401 'sys.stdout.write("\\nline5");'
402 'sys.stdout.flush();'
403 'sys.stdout.write("\\nline6");'],
404 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
405 universal_newlines=1)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000406 (stdout, stderr) = p.communicate()
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000407 self.assertEqual(stdout, "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000408
409 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000410 # Make sure we leak no resources
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000411 if (not hasattr(support, "is_resource_enabled") or
412 support.is_resource_enabled("subprocess") and not mswindows):
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000413 max_handles = 1026 # too much for most UNIX systems
414 else:
Tim Peterseba28be2005-03-28 01:08:02 +0000415 max_handles = 65
Fredrik Lundh9e29fc52004-10-13 07:54:54 +0000416 for i in range(max_handles):
Tim Peters3b01a702004-10-12 22:19:32 +0000417 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000418 "import sys;"
419 "sys.stdout.write(sys.stdin.read())"],
420 stdin=subprocess.PIPE,
421 stdout=subprocess.PIPE,
422 stderr=subprocess.PIPE)
Georg Brandl1abcbf82008-07-01 19:28:43 +0000423 data = p.communicate(b"lime")[0]
Guido van Rossumc9e363c2007-05-15 23:18:55 +0000424 self.assertEqual(data, b"lime")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000425
426
427 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000428 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
429 '"a b c" d e')
430 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
431 'ab\\"c \\ d')
Christian Heimesfdab48e2008-01-20 09:06:41 +0000432 self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
433 'ab\\"c " \\\\" d')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000434 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
435 'a\\\\\\b "de fg" h')
436 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
437 'a\\\\\\"b c d')
438 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
439 '"a\\\\b c" d e')
440 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
441 '"a\\\\b\\ c" d e')
Thomas Woutersfc7bb8c2007-01-15 15:49:28 +0000442 self.assertEqual(subprocess.list2cmdline(['ab', '']),
443 'ab ""')
Christian Heimesfdab48e2008-01-20 09:06:41 +0000444 self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']),
445 'echo "foo|bar"')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000446
447
448 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000449 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000450 "-c", "import time; time.sleep(1)"])
451 count = 0
452 while p.poll() is None:
453 time.sleep(0.1)
454 count += 1
455 # We expect that the poll loop probably went around about 10 times,
456 # but, based on system scheduling we can't control, it's possible
457 # poll() never returned None. It "should be" very rare that it
458 # didn't go around at least twice.
459 self.assert_(count >= 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000460 # Subsequent invocations should just return the returncode
461 self.assertEqual(p.poll(), 0)
462
463
464 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000465 p = subprocess.Popen([sys.executable,
466 "-c", "import time; time.sleep(2)"])
467 self.assertEqual(p.wait(), 0)
468 # Subsequent invocations should just return the returncode
469 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000470
Peter Astrand738131d2004-11-30 21:04:45 +0000471
472 def test_invalid_bufsize(self):
473 # an invalid type of the bufsize argument should raise
474 # TypeError.
475 try:
476 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
477 except TypeError:
478 pass
479 else:
480 self.fail("Expected TypeError")
481
Guido van Rossum46a05a72007-06-07 21:56:45 +0000482 def test_bufsize_is_none(self):
483 # bufsize=None should be the same as bufsize=0.
484 p = subprocess.Popen([sys.executable, "-c", "pass"], None)
485 self.assertEqual(p.wait(), 0)
486 # Again with keyword arg
487 p = subprocess.Popen([sys.executable, "-c", "pass"], bufsize=None)
488 self.assertEqual(p.wait(), 0)
489
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000490 #
491 # POSIX tests
492 #
493 if not mswindows:
494 def test_exceptions(self):
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000495 # caught & re-raised exceptions
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000496 try:
497 p = subprocess.Popen([sys.executable, "-c", ""],
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000498 cwd="/this/path/does/not/exist")
Guido van Rossumb940e112007-01-10 16:19:56 +0000499 except OSError as e:
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000500 # The attribute child_traceback should contain "os.chdir"
501 # somewhere.
502 self.assertNotEqual(e.child_traceback.find("os.chdir"), -1)
503 else:
504 self.fail("Expected OSError")
Tim Peterse718f612004-10-12 21:51:32 +0000505
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000506 def _suppress_core_files(self):
507 """Try to prevent core files from being created.
508 Returns previous ulimit if successful, else None.
509 """
510 try:
511 import resource
512 old_limit = resource.getrlimit(resource.RLIMIT_CORE)
513 resource.setrlimit(resource.RLIMIT_CORE, (0,0))
514 return old_limit
515 except (ImportError, ValueError, resource.error):
516 return None
517
518 def _unsuppress_core_files(self, old_limit):
519 """Return core file behavior to default."""
520 if old_limit is None:
521 return
522 try:
523 import resource
524 resource.setrlimit(resource.RLIMIT_CORE, old_limit)
525 except (ImportError, ValueError, resource.error):
526 return
527
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000528 def test_run_abort(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000529 # returncode handles signal termination
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000530 old_limit = self._suppress_core_files()
531 try:
532 p = subprocess.Popen([sys.executable,
533 "-c", "import os; os.abort()"])
534 finally:
535 self._unsuppress_core_files(old_limit)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000536 p.wait()
537 self.assertEqual(-p.returncode, signal.SIGABRT)
538
539 def test_preexec(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000540 # preexec function
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000541 p = subprocess.Popen([sys.executable, "-c",
Guido van Rossum98297ee2007-11-06 21:34:58 +0000542 'import sys,os;'
543 'sys.stdout.write(os.getenv("FRUIT"))'],
544 stdout=subprocess.PIPE,
545 preexec_fn=lambda: os.putenv("FRUIT",
546 "apple"))
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000547 self.assertEqual(p.stdout.read(), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000548
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000549 def test_args_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000550 # args is a string
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000551 f, fname = self.mkstemp()
552 os.write(f, "#!/bin/sh\n")
Benjamin Petersona37cfc62008-05-26 13:48:34 +0000553 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
Tim Peters3b01a702004-10-12 22:19:32 +0000554 sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000555 os.close(f)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000556 os.chmod(fname, 0o700)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000557 p = subprocess.Popen(fname)
558 p.wait()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000559 os.remove(fname)
Peter Astrand2224be62004-11-17 20:06:35 +0000560 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000561
562 def test_invalid_args(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000563 # invalid arguments should raise ValueError
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000564 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000565 [sys.executable,
566 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000567 startupinfo=47)
568 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000569 [sys.executable,
570 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000571 creationflags=47)
572
573 def test_shell_sequence(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000574 # Run command through the shell (sequence)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000575 newenv = os.environ.copy()
576 newenv["FRUIT"] = "apple"
577 p = subprocess.Popen(["echo $FRUIT"], shell=1,
578 stdout=subprocess.PIPE,
579 env=newenv)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000580 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000581
582 def test_shell_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000583 # Run command through the shell (string)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000584 newenv = os.environ.copy()
585 newenv["FRUIT"] = "apple"
586 p = subprocess.Popen("echo $FRUIT", shell=1,
587 stdout=subprocess.PIPE,
588 env=newenv)
Guido van Rossumfa0054a2007-05-24 04:05:35 +0000589 self.assertEqual(p.stdout.read().strip(b" \t\r\n\f"), b"apple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000590
591 def test_call_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000592 # call() function with string argument on UNIX
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000593 f, fname = self.mkstemp()
594 os.write(f, "#!/bin/sh\n")
Benjamin Petersona37cfc62008-05-26 13:48:34 +0000595 os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
Tim Peters3b01a702004-10-12 22:19:32 +0000596 sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000597 os.close(f)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000598 os.chmod(fname, 0o700)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000599 rc = subprocess.call(fname)
Peter Astrand2224be62004-11-17 20:06:35 +0000600 os.remove(fname)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000601 self.assertEqual(rc, 47)
602
Christian Heimes75ca4ea2008-05-06 23:48:04 +0000603 def DISABLED_test_send_signal(self):
Christian Heimesa342c012008-04-20 21:01:16 +0000604 p = subprocess.Popen([sys.executable,
605 "-c", "input()"])
606
607 self.assert_(p.poll() is None, p.poll())
608 p.send_signal(signal.SIGINT)
609 self.assertNotEqual(p.wait(), 0)
610
Christian Heimes75ca4ea2008-05-06 23:48:04 +0000611 def DISABLED_test_kill(self):
Christian Heimesa342c012008-04-20 21:01:16 +0000612 p = subprocess.Popen([sys.executable,
613 "-c", "input()"])
614
615 self.assert_(p.poll() is None, p.poll())
616 p.kill()
617 self.assertEqual(p.wait(), -signal.SIGKILL)
618
Christian Heimes75ca4ea2008-05-06 23:48:04 +0000619 def DISABLED_test_terminate(self):
Christian Heimesa342c012008-04-20 21:01:16 +0000620 p = subprocess.Popen([sys.executable,
621 "-c", "input()"])
622
623 self.assert_(p.poll() is None, p.poll())
624 p.terminate()
625 self.assertEqual(p.wait(), -signal.SIGTERM)
Tim Peterse718f612004-10-12 21:51:32 +0000626
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000627 #
628 # Windows tests
629 #
630 if mswindows:
631 def test_startupinfo(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000632 # startupinfo argument
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000633 # We uses hardcoded constants, because we do not want to
Tim Peterse718f612004-10-12 21:51:32 +0000634 # depend on win32all.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000635 STARTF_USESHOWWINDOW = 1
636 SW_MAXIMIZE = 3
637 startupinfo = subprocess.STARTUPINFO()
638 startupinfo.dwFlags = STARTF_USESHOWWINDOW
639 startupinfo.wShowWindow = SW_MAXIMIZE
640 # Since Python is a console process, it won't be affected
641 # by wShowWindow, but the argument should be silently
642 # ignored
643 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
644 startupinfo=startupinfo)
645
646 def test_creationflags(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000647 # creationflags argument
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000648 CREATE_NEW_CONSOLE = 16
Tim Peters876c4322004-10-13 03:21:35 +0000649 sys.stderr.write(" a DOS box should flash briefly ...\n")
Tim Peters3b01a702004-10-12 22:19:32 +0000650 subprocess.call(sys.executable +
Tim Peters876c4322004-10-13 03:21:35 +0000651 ' -c "import time; time.sleep(0.25)"',
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000652 creationflags=CREATE_NEW_CONSOLE)
653
654 def test_invalid_args(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000655 # invalid arguments should raise ValueError
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000656 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000657 [sys.executable,
658 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000659 preexec_fn=lambda: 1)
660 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000661 [sys.executable,
662 "-c", "import sys; sys.exit(47)"],
Guido van Rossume7ba4952007-06-06 23:52:48 +0000663 stdout=subprocess.PIPE,
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000664 close_fds=True)
665
Guido van Rossume7ba4952007-06-06 23:52:48 +0000666 def test_close_fds(self):
667 # close file descriptors
668 rc = subprocess.call([sys.executable, "-c",
669 "import sys; sys.exit(47)"],
670 close_fds=True)
671 self.assertEqual(rc, 47)
672
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000673 def test_shell_sequence(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000674 # Run command through the shell (sequence)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000675 newenv = os.environ.copy()
676 newenv["FRUIT"] = "physalis"
677 p = subprocess.Popen(["set"], shell=1,
Tim Peterse718f612004-10-12 21:51:32 +0000678 stdout=subprocess.PIPE,
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000679 env=newenv)
Guido van Rossumc12a8132007-10-26 04:29:23 +0000680 self.assertNotEqual(p.stdout.read().find(b"physalis"), -1)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000681
682 def test_shell_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000683 # Run command through the shell (string)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000684 newenv = os.environ.copy()
685 newenv["FRUIT"] = "physalis"
686 p = subprocess.Popen("set", shell=1,
Tim Peterse718f612004-10-12 21:51:32 +0000687 stdout=subprocess.PIPE,
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000688 env=newenv)
Guido van Rossumc12a8132007-10-26 04:29:23 +0000689 self.assertNotEqual(p.stdout.read().find(b"physalis"), -1)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000690
691 def test_call_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000692 # call() function with string argument on Windows
Tim Peters3b01a702004-10-12 22:19:32 +0000693 rc = subprocess.call(sys.executable +
694 ' -c "import sys; sys.exit(47)"')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000695 self.assertEqual(rc, 47)
696
Christian Heimes75ca4ea2008-05-06 23:48:04 +0000697 def DISABLED_test_send_signal(self):
Christian Heimesa342c012008-04-20 21:01:16 +0000698 p = subprocess.Popen([sys.executable,
699 "-c", "input()"])
700
701 self.assert_(p.poll() is None, p.poll())
702 p.send_signal(signal.SIGTERM)
703 self.assertNotEqual(p.wait(), 0)
704
Christian Heimes75ca4ea2008-05-06 23:48:04 +0000705 def DISABLED_test_kill(self):
Christian Heimesa342c012008-04-20 21:01:16 +0000706 p = subprocess.Popen([sys.executable,
707 "-c", "input()"])
708
709 self.assert_(p.poll() is None, p.poll())
710 p.kill()
711 self.assertNotEqual(p.wait(), 0)
712
Christian Heimes75ca4ea2008-05-06 23:48:04 +0000713 def DISABLED_test_terminate(self):
Christian Heimesa342c012008-04-20 21:01:16 +0000714 p = subprocess.Popen([sys.executable,
715 "-c", "input()"])
716
717 self.assert_(p.poll() is None, p.poll())
718 p.terminate()
719 self.assertNotEqual(p.wait(), 0)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000720
Brett Cannona23810f2008-05-26 19:04:21 +0000721class CommandTests(unittest.TestCase):
722# The module says:
723# "NB This only works (and is only relevant) for UNIX."
724#
725# Actually, getoutput should work on any platform with an os.popen, but
726# I'll take the comment as given, and skip this suite.
727 if os.name == 'posix':
728
729 def test_getoutput(self):
730 self.assertEquals(subprocess.getoutput('echo xyzzy'), 'xyzzy')
731 self.assertEquals(subprocess.getstatusoutput('echo xyzzy'),
732 (0, 'xyzzy'))
733
734 # we use mkdtemp in the next line to create an empty directory
735 # under our exclusive control; from that, we can invent a pathname
736 # that we _know_ won't exist. This is guaranteed to fail.
737 dir = None
738 try:
739 dir = tempfile.mkdtemp()
740 name = os.path.join(dir, "foo")
741
742 status, output = subprocess.getstatusoutput('cat ' + name)
743 self.assertNotEquals(status, 0)
744 finally:
745 if dir is not None:
746 os.rmdir(dir)
747
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000748def test_main():
Brett Cannona23810f2008-05-26 19:04:21 +0000749 support.run_unittest(ProcessTestCase, CommandTests)
750 support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000751
752if __name__ == "__main__":
Brett Cannona23810f2008-05-26 19:04:21 +0000753 test_main()