blob: b4e6c00d2ee47e0f55480fb0cd3db0cdf49515d1 [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
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):
Tim Peters1dbf2432004-10-14 04:16:54 +000027 return re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr)
Tim Peters3761e8d2004-10-13 04:07:12 +000028
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000029class ProcessTestCase(unittest.TestCase):
Neal Norwitzb15ac312006-06-29 04:10:08 +000030 def setUp(self):
31 # Try to minimize the number of children we have so this test
32 # doesn't crash on some buildbots (Alphas in particular).
33 test_support.reap_children()
34
35 def tearDown(self):
36 # Try to minimize the number of children we have so this test
37 # doesn't crash on some buildbots (Alphas in particular).
38 test_support.reap_children()
39
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000040 def mkstemp(self):
41 """wrapper for mkstemp, calling mktemp if mkstemp is not available"""
42 if hasattr(tempfile, "mkstemp"):
43 return tempfile.mkstemp()
44 else:
45 fname = tempfile.mktemp()
46 return os.open(fname, os.O_RDWR|os.O_CREAT), fname
Tim Peterse718f612004-10-12 21:51:32 +000047
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000048 #
49 # Generic tests
50 #
51 def test_call_seq(self):
Tim Peters7b759da2004-10-12 22:29:54 +000052 # call() function with sequence argument
Tim Peters3b01a702004-10-12 22:19:32 +000053 rc = subprocess.call([sys.executable, "-c",
54 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000055 self.assertEqual(rc, 47)
56
Peter Astrand454f7672005-01-01 09:36:35 +000057 def test_check_call_zero(self):
58 # check_call() function with zero return code
59 rc = subprocess.check_call([sys.executable, "-c",
60 "import sys; sys.exit(0)"])
61 self.assertEqual(rc, 0)
62
63 def test_check_call_nonzero(self):
64 # check_call() function with non-zero return code
65 try:
66 subprocess.check_call([sys.executable, "-c",
67 "import sys; sys.exit(47)"])
68 except subprocess.CalledProcessError, e:
69 self.assertEqual(e.errno, 47)
70 else:
71 self.fail("Expected CalledProcessError")
72
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000073 def test_call_kwargs(self):
Tim Peters7b759da2004-10-12 22:29:54 +000074 # call() function with keyword args
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000075 newenv = os.environ.copy()
76 newenv["FRUIT"] = "banana"
77 rc = subprocess.call([sys.executable, "-c",
78 'import sys, os;' \
79 'sys.exit(os.getenv("FRUIT")=="banana")'],
80 env=newenv)
81 self.assertEqual(rc, 1)
82
83 def test_stdin_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +000084 # .stdin is None when not redirected
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000085 p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
86 stdout=subprocess.PIPE, stderr=subprocess.PIPE)
87 p.wait()
88 self.assertEqual(p.stdin, None)
89
90 def test_stdout_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +000091 # .stdout is None when not redirected
Tim Peters29b6b4f2004-10-13 03:43:40 +000092 p = subprocess.Popen([sys.executable, "-c",
Tim Peters4052fe52004-10-13 03:29:54 +000093 'print " this bit of output is from a '
94 'test of stdout in a different '
95 'process ..."'],
96 stdin=subprocess.PIPE, stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +000097 p.wait()
98 self.assertEqual(p.stdout, None)
99
100 def test_stderr_none(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000101 # .stderr is None when not redirected
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000102 p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
103 stdin=subprocess.PIPE, stdout=subprocess.PIPE)
104 p.wait()
105 self.assertEqual(p.stderr, None)
106
107 def test_executable(self):
Tim Peters3b01a702004-10-12 22:19:32 +0000108 p = subprocess.Popen(["somethingyoudonthave",
109 "-c", "import sys; sys.exit(47)"],
110 executable=sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000111 p.wait()
112 self.assertEqual(p.returncode, 47)
113
114 def test_stdin_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000115 # stdin redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000116 p = subprocess.Popen([sys.executable, "-c",
117 'import sys; sys.exit(sys.stdin.read() == "pear")'],
118 stdin=subprocess.PIPE)
119 p.stdin.write("pear")
120 p.stdin.close()
121 p.wait()
122 self.assertEqual(p.returncode, 1)
123
124 def test_stdin_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000125 # stdin is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000126 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000127 d = tf.fileno()
128 os.write(d, "pear")
129 os.lseek(d, 0, 0)
130 p = subprocess.Popen([sys.executable, "-c",
131 'import sys; sys.exit(sys.stdin.read() == "pear")'],
132 stdin=d)
133 p.wait()
134 self.assertEqual(p.returncode, 1)
135
136 def test_stdin_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000137 # stdin is set to open file object
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000138 tf = tempfile.TemporaryFile()
139 tf.write("pear")
140 tf.seek(0)
141 p = subprocess.Popen([sys.executable, "-c",
142 'import sys; sys.exit(sys.stdin.read() == "pear")'],
143 stdin=tf)
144 p.wait()
145 self.assertEqual(p.returncode, 1)
146
147 def test_stdout_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000148 # stdout redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000149 p = subprocess.Popen([sys.executable, "-c",
150 'import sys; sys.stdout.write("orange")'],
151 stdout=subprocess.PIPE)
152 self.assertEqual(p.stdout.read(), "orange")
153
154 def test_stdout_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000155 # stdout is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000156 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000157 d = tf.fileno()
158 p = subprocess.Popen([sys.executable, "-c",
159 'import sys; sys.stdout.write("orange")'],
160 stdout=d)
161 p.wait()
162 os.lseek(d, 0, 0)
163 self.assertEqual(os.read(d, 1024), "orange")
164
165 def test_stdout_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000166 # stdout is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000167 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000168 p = subprocess.Popen([sys.executable, "-c",
169 'import sys; sys.stdout.write("orange")'],
170 stdout=tf)
171 p.wait()
172 tf.seek(0)
173 self.assertEqual(tf.read(), "orange")
174
175 def test_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000176 # stderr redirection
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000177 p = subprocess.Popen([sys.executable, "-c",
178 'import sys; sys.stderr.write("strawberry")'],
179 stderr=subprocess.PIPE)
Tim Peters3761e8d2004-10-13 04:07:12 +0000180 self.assertEqual(remove_stderr_debug_decorations(p.stderr.read()),
181 "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000182
183 def test_stderr_filedes(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000184 # stderr is set to open file descriptor
Tim Peterse718f612004-10-12 21:51:32 +0000185 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000186 d = tf.fileno()
187 p = subprocess.Popen([sys.executable, "-c",
188 'import sys; sys.stderr.write("strawberry")'],
189 stderr=d)
190 p.wait()
191 os.lseek(d, 0, 0)
Tim Peters3761e8d2004-10-13 04:07:12 +0000192 self.assertEqual(remove_stderr_debug_decorations(os.read(d, 1024)),
193 "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000194
195 def test_stderr_fileobj(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000196 # stderr is set to open file object
Tim Peterse718f612004-10-12 21:51:32 +0000197 tf = tempfile.TemporaryFile()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000198 p = subprocess.Popen([sys.executable, "-c",
199 'import sys; sys.stderr.write("strawberry")'],
200 stderr=tf)
201 p.wait()
202 tf.seek(0)
Tim Peters3761e8d2004-10-13 04:07:12 +0000203 self.assertEqual(remove_stderr_debug_decorations(tf.read()),
204 "strawberry")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000205
206 def test_stdout_stderr_pipe(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000207 # capture stdout and stderr to the same pipe
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000208 p = subprocess.Popen([sys.executable, "-c",
209 'import sys;' \
210 'sys.stdout.write("apple");' \
211 'sys.stdout.flush();' \
212 'sys.stderr.write("orange")'],
213 stdout=subprocess.PIPE,
214 stderr=subprocess.STDOUT)
Tim Peters3761e8d2004-10-13 04:07:12 +0000215 output = p.stdout.read()
216 stripped = remove_stderr_debug_decorations(output)
217 self.assertEqual(stripped, "appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000218
219 def test_stdout_stderr_file(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000220 # capture stdout and stderr to the same open file
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000221 tf = tempfile.TemporaryFile()
222 p = subprocess.Popen([sys.executable, "-c",
223 'import sys;' \
224 'sys.stdout.write("apple");' \
225 'sys.stdout.flush();' \
226 'sys.stderr.write("orange")'],
227 stdout=tf,
228 stderr=tf)
229 p.wait()
230 tf.seek(0)
Tim Peters3761e8d2004-10-13 04:07:12 +0000231 output = tf.read()
232 stripped = remove_stderr_debug_decorations(output)
233 self.assertEqual(stripped, "appleorange")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000234
235 def test_cwd(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000236 tmpdir = os.getenv("TEMP", "/tmp")
Peter Astrand195404f2004-11-12 15:51:48 +0000237 # We cannot use os.path.realpath to canonicalize the path,
238 # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
239 cwd = os.getcwd()
240 os.chdir(tmpdir)
241 tmpdir = os.getcwd()
242 os.chdir(cwd)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000243 p = subprocess.Popen([sys.executable, "-c",
244 'import sys,os;' \
245 'sys.stdout.write(os.getcwd())'],
246 stdout=subprocess.PIPE,
247 cwd=tmpdir)
Fredrik Lundh59c05592004-10-13 06:55:40 +0000248 normcase = os.path.normcase
249 self.assertEqual(normcase(p.stdout.read()), normcase(tmpdir))
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000250
251 def test_env(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000252 newenv = os.environ.copy()
253 newenv["FRUIT"] = "orange"
254 p = subprocess.Popen([sys.executable, "-c",
255 'import sys,os;' \
256 'sys.stdout.write(os.getenv("FRUIT"))'],
257 stdout=subprocess.PIPE,
258 env=newenv)
259 self.assertEqual(p.stdout.read(), "orange")
260
Peter Astrandcbac93c2005-03-03 20:24:28 +0000261 def test_communicate_stdin(self):
262 p = subprocess.Popen([sys.executable, "-c",
263 'import sys; sys.exit(sys.stdin.read() == "pear")'],
264 stdin=subprocess.PIPE)
265 p.communicate("pear")
266 self.assertEqual(p.returncode, 1)
267
268 def test_communicate_stdout(self):
269 p = subprocess.Popen([sys.executable, "-c",
270 'import sys; sys.stdout.write("pineapple")'],
271 stdout=subprocess.PIPE)
272 (stdout, stderr) = p.communicate()
273 self.assertEqual(stdout, "pineapple")
274 self.assertEqual(stderr, None)
275
276 def test_communicate_stderr(self):
277 p = subprocess.Popen([sys.executable, "-c",
278 'import sys; sys.stderr.write("pineapple")'],
279 stderr=subprocess.PIPE)
280 (stdout, stderr) = p.communicate()
281 self.assertEqual(stdout, None)
Brett Cannon653a5ad2005-03-05 06:40:52 +0000282 # When running with a pydebug build, the # of references is outputted
283 # to stderr, so just check if stderr at least started with "pinapple"
284 self.assert_(stderr.startswith("pineapple"))
Peter Astrandcbac93c2005-03-03 20:24:28 +0000285
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000286 def test_communicate(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000287 p = subprocess.Popen([sys.executable, "-c",
288 'import sys,os;' \
289 'sys.stderr.write("pineapple");' \
290 'sys.stdout.write(sys.stdin.read())'],
Tim Peters3b01a702004-10-12 22:19:32 +0000291 stdin=subprocess.PIPE,
292 stdout=subprocess.PIPE,
293 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000294 (stdout, stderr) = p.communicate("banana")
295 self.assertEqual(stdout, "banana")
Tim Peters3761e8d2004-10-13 04:07:12 +0000296 self.assertEqual(remove_stderr_debug_decorations(stderr),
297 "pineapple")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000298
299 def test_communicate_returns(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000300 # communicate() should return None if no redirection is active
Tim Peters3b01a702004-10-12 22:19:32 +0000301 p = subprocess.Popen([sys.executable, "-c",
302 "import sys; sys.exit(47)"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000303 (stdout, stderr) = p.communicate()
304 self.assertEqual(stdout, None)
305 self.assertEqual(stderr, None)
306
307 def test_communicate_pipe_buf(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000308 # communicate() with writes larger than pipe_buf
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000309 # This test will probably deadlock rather than fail, if
Tim Peterse718f612004-10-12 21:51:32 +0000310 # communicate() does not work properly.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000311 x, y = os.pipe()
312 if mswindows:
313 pipe_buf = 512
314 else:
315 pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
316 os.close(x)
317 os.close(y)
318 p = subprocess.Popen([sys.executable, "-c",
Tim Peterse718f612004-10-12 21:51:32 +0000319 'import sys,os;'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000320 'sys.stdout.write(sys.stdin.read(47));' \
321 'sys.stderr.write("xyz"*%d);' \
322 'sys.stdout.write(sys.stdin.read())' % pipe_buf],
Tim Peters3b01a702004-10-12 22:19:32 +0000323 stdin=subprocess.PIPE,
324 stdout=subprocess.PIPE,
325 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000326 string_to_write = "abc"*pipe_buf
327 (stdout, stderr) = p.communicate(string_to_write)
328 self.assertEqual(stdout, string_to_write)
329
330 def test_writes_before_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000331 # stdin.write before communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000332 p = subprocess.Popen([sys.executable, "-c",
333 'import sys,os;' \
334 'sys.stdout.write(sys.stdin.read())'],
Tim Peters3b01a702004-10-12 22:19:32 +0000335 stdin=subprocess.PIPE,
336 stdout=subprocess.PIPE,
337 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000338 p.stdin.write("banana")
339 (stdout, stderr) = p.communicate("split")
340 self.assertEqual(stdout, "bananasplit")
Tim Peters3761e8d2004-10-13 04:07:12 +0000341 self.assertEqual(remove_stderr_debug_decorations(stderr), "")
Tim Peterse718f612004-10-12 21:51:32 +0000342
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000343 def test_universal_newlines(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000344 p = subprocess.Popen([sys.executable, "-c",
Tim Peters3b01a702004-10-12 22:19:32 +0000345 'import sys,os;' + SETBINARY +
346 'sys.stdout.write("line1\\n");'
347 'sys.stdout.flush();'
348 'sys.stdout.write("line2\\r");'
349 'sys.stdout.flush();'
350 'sys.stdout.write("line3\\r\\n");'
351 'sys.stdout.flush();'
352 'sys.stdout.write("line4\\r");'
353 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000354 'sys.stdout.write("\\nline5");'
Tim Peters3b01a702004-10-12 22:19:32 +0000355 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000356 'sys.stdout.write("\\nline6");'],
357 stdout=subprocess.PIPE,
358 universal_newlines=1)
359 stdout = p.stdout.read()
Neal Norwitza6d01ce2006-05-02 06:23:22 +0000360 if hasattr(file, 'newlines'):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000361 # Interpreter with universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000362 self.assertEqual(stdout,
363 "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000364 else:
365 # Interpreter without universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000366 self.assertEqual(stdout,
367 "line1\nline2\rline3\r\nline4\r\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000368
369 def test_universal_newlines_communicate(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000370 # universal newlines through communicate()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000371 p = subprocess.Popen([sys.executable, "-c",
Tim Peters3b01a702004-10-12 22:19:32 +0000372 'import sys,os;' + SETBINARY +
373 'sys.stdout.write("line1\\n");'
374 'sys.stdout.flush();'
375 'sys.stdout.write("line2\\r");'
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();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000381 'sys.stdout.write("\\nline5");'
Tim Peters3b01a702004-10-12 22:19:32 +0000382 'sys.stdout.flush();'
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000383 'sys.stdout.write("\\nline6");'],
384 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
385 universal_newlines=1)
386 (stdout, stderr) = p.communicate()
Neal Norwitza6d01ce2006-05-02 06:23:22 +0000387 if hasattr(file, 'newlines'):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000388 # Interpreter with universal newline support
Tim Peters3b01a702004-10-12 22:19:32 +0000389 self.assertEqual(stdout,
390 "line1\nline2\nline3\nline4\nline5\nline6")
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000391 else:
392 # Interpreter without universal newline support
393 self.assertEqual(stdout, "line1\nline2\rline3\r\nline4\r\nline5\nline6")
394
395 def test_no_leaking(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000396 # Make sure we leak no resources
Peter Astrandd6b24302006-06-22 20:06:46 +0000397 if not hasattr(test_support, "is_resource_enabled") \
398 or test_support.is_resource_enabled("subprocess") and not mswindows:
Peter Astrandf7f1bb72005-03-03 20:47:37 +0000399 max_handles = 1026 # too much for most UNIX systems
400 else:
Tim Peterseba28be2005-03-28 01:08:02 +0000401 max_handles = 65
Fredrik Lundh9e29fc52004-10-13 07:54:54 +0000402 for i in range(max_handles):
Tim Peters3b01a702004-10-12 22:19:32 +0000403 p = subprocess.Popen([sys.executable, "-c",
404 "import sys;sys.stdout.write(sys.stdin.read())"],
405 stdin=subprocess.PIPE,
406 stdout=subprocess.PIPE,
407 stderr=subprocess.PIPE)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000408 data = p.communicate("lime")[0]
409 self.assertEqual(data, "lime")
410
411
412 def test_list2cmdline(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000413 self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
414 '"a b c" d e')
415 self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
416 'ab\\"c \\ d')
417 self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
418 'a\\\\\\b "de fg" h')
419 self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
420 'a\\\\\\"b c d')
421 self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
422 '"a\\\\b c" d e')
423 self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
424 '"a\\\\b\\ c" d e')
425
426
427 def test_poll(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000428 p = subprocess.Popen([sys.executable,
Tim Peters29b6b4f2004-10-13 03:43:40 +0000429 "-c", "import time; time.sleep(1)"])
430 count = 0
431 while p.poll() is None:
432 time.sleep(0.1)
433 count += 1
434 # We expect that the poll loop probably went around about 10 times,
435 # but, based on system scheduling we can't control, it's possible
436 # poll() never returned None. It "should be" very rare that it
437 # didn't go around at least twice.
438 self.assert_(count >= 2)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000439 # Subsequent invocations should just return the returncode
440 self.assertEqual(p.poll(), 0)
441
442
443 def test_wait(self):
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000444 p = subprocess.Popen([sys.executable,
445 "-c", "import time; time.sleep(2)"])
446 self.assertEqual(p.wait(), 0)
447 # Subsequent invocations should just return the returncode
448 self.assertEqual(p.wait(), 0)
Tim Peterse718f612004-10-12 21:51:32 +0000449
Peter Astrand738131d2004-11-30 21:04:45 +0000450
451 def test_invalid_bufsize(self):
452 # an invalid type of the bufsize argument should raise
453 # TypeError.
454 try:
455 subprocess.Popen([sys.executable, "-c", "pass"], "orange")
456 except TypeError:
457 pass
458 else:
459 self.fail("Expected TypeError")
460
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000461 #
462 # POSIX tests
463 #
464 if not mswindows:
465 def test_exceptions(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000466 # catched & re-raised exceptions
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000467 try:
468 p = subprocess.Popen([sys.executable, "-c", ""],
469 cwd="/this/path/does/not/exist")
470 except OSError, e:
471 # The attribute child_traceback should contain "os.chdir"
472 # somewhere.
473 self.assertNotEqual(e.child_traceback.find("os.chdir"), -1)
474 else:
475 self.fail("Expected OSError")
Tim Peterse718f612004-10-12 21:51:32 +0000476
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000477 def test_run_abort(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000478 # returncode handles signal termination
Tim Peters3b01a702004-10-12 22:19:32 +0000479 p = subprocess.Popen([sys.executable,
480 "-c", "import os; os.abort()"])
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000481 p.wait()
482 self.assertEqual(-p.returncode, signal.SIGABRT)
483
484 def test_preexec(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000485 # preexec function
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000486 p = subprocess.Popen([sys.executable, "-c",
487 'import sys,os;' \
488 'sys.stdout.write(os.getenv("FRUIT"))'],
489 stdout=subprocess.PIPE,
490 preexec_fn=lambda: os.putenv("FRUIT", "apple"))
491 self.assertEqual(p.stdout.read(), "apple")
492
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000493 def test_args_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000494 # args is a string
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000495 f, fname = self.mkstemp()
496 os.write(f, "#!/bin/sh\n")
Tim Peters3b01a702004-10-12 22:19:32 +0000497 os.write(f, "exec %s -c 'import sys; sys.exit(47)'\n" %
498 sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000499 os.close(f)
500 os.chmod(fname, 0700)
501 p = subprocess.Popen(fname)
502 p.wait()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000503 os.remove(fname)
Peter Astrand2224be62004-11-17 20:06:35 +0000504 self.assertEqual(p.returncode, 47)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000505
506 def test_invalid_args(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000507 # invalid arguments should raise ValueError
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000508 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000509 [sys.executable,
510 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000511 startupinfo=47)
512 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000513 [sys.executable,
514 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000515 creationflags=47)
516
517 def test_shell_sequence(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000518 # Run command through the shell (sequence)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000519 newenv = os.environ.copy()
520 newenv["FRUIT"] = "apple"
521 p = subprocess.Popen(["echo $FRUIT"], shell=1,
522 stdout=subprocess.PIPE,
523 env=newenv)
524 self.assertEqual(p.stdout.read().strip(), "apple")
525
526 def test_shell_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000527 # Run command through the shell (string)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000528 newenv = os.environ.copy()
529 newenv["FRUIT"] = "apple"
530 p = subprocess.Popen("echo $FRUIT", shell=1,
531 stdout=subprocess.PIPE,
532 env=newenv)
533 self.assertEqual(p.stdout.read().strip(), "apple")
534
535 def test_call_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000536 # call() function with string argument on UNIX
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000537 f, fname = self.mkstemp()
538 os.write(f, "#!/bin/sh\n")
Tim Peters3b01a702004-10-12 22:19:32 +0000539 os.write(f, "exec %s -c 'import sys; sys.exit(47)'\n" %
540 sys.executable)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000541 os.close(f)
542 os.chmod(fname, 0700)
543 rc = subprocess.call(fname)
Peter Astrand2224be62004-11-17 20:06:35 +0000544 os.remove(fname)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000545 self.assertEqual(rc, 47)
546
Tim Peterse718f612004-10-12 21:51:32 +0000547
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000548 #
549 # Windows tests
550 #
551 if mswindows:
552 def test_startupinfo(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000553 # startupinfo argument
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000554 # We uses hardcoded constants, because we do not want to
Tim Peterse718f612004-10-12 21:51:32 +0000555 # depend on win32all.
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000556 STARTF_USESHOWWINDOW = 1
557 SW_MAXIMIZE = 3
558 startupinfo = subprocess.STARTUPINFO()
559 startupinfo.dwFlags = STARTF_USESHOWWINDOW
560 startupinfo.wShowWindow = SW_MAXIMIZE
561 # Since Python is a console process, it won't be affected
562 # by wShowWindow, but the argument should be silently
563 # ignored
564 subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
565 startupinfo=startupinfo)
566
567 def test_creationflags(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000568 # creationflags argument
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000569 CREATE_NEW_CONSOLE = 16
Tim Peters876c4322004-10-13 03:21:35 +0000570 sys.stderr.write(" a DOS box should flash briefly ...\n")
Tim Peters3b01a702004-10-12 22:19:32 +0000571 subprocess.call(sys.executable +
Tim Peters876c4322004-10-13 03:21:35 +0000572 ' -c "import time; time.sleep(0.25)"',
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000573 creationflags=CREATE_NEW_CONSOLE)
574
575 def test_invalid_args(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000576 # invalid arguments should raise ValueError
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000577 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000578 [sys.executable,
579 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000580 preexec_fn=lambda: 1)
581 self.assertRaises(ValueError, subprocess.call,
Tim Peters3b01a702004-10-12 22:19:32 +0000582 [sys.executable,
583 "-c", "import sys; sys.exit(47)"],
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000584 close_fds=True)
585
586 def test_shell_sequence(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000587 # Run command through the shell (sequence)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000588 newenv = os.environ.copy()
589 newenv["FRUIT"] = "physalis"
590 p = subprocess.Popen(["set"], shell=1,
Tim Peterse718f612004-10-12 21:51:32 +0000591 stdout=subprocess.PIPE,
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000592 env=newenv)
593 self.assertNotEqual(p.stdout.read().find("physalis"), -1)
594
595 def test_shell_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000596 # Run command through the shell (string)
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000597 newenv = os.environ.copy()
598 newenv["FRUIT"] = "physalis"
599 p = subprocess.Popen("set", shell=1,
Tim Peterse718f612004-10-12 21:51:32 +0000600 stdout=subprocess.PIPE,
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000601 env=newenv)
602 self.assertNotEqual(p.stdout.read().find("physalis"), -1)
603
604 def test_call_string(self):
Tim Peters7b759da2004-10-12 22:29:54 +0000605 # call() function with string argument on Windows
Tim Peters3b01a702004-10-12 22:19:32 +0000606 rc = subprocess.call(sys.executable +
607 ' -c "import sys; sys.exit(47)"')
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000608 self.assertEqual(rc, 47)
609
610
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000611def test_main():
612 test_support.run_unittest(ProcessTestCase)
Neal Norwitzb15ac312006-06-29 04:10:08 +0000613 test_support.reap_children()
Fredrik Lundh5b3687d2004-10-12 15:26:28 +0000614
615if __name__ == "__main__":
616 test_main()