PageRenderTime 615ms CodeModel.GetById 185ms app.highlight 309ms RepoModel.GetById 112ms app.codeStats 0ms

/Lib/test/test_subprocess.py

http://unladen-swallow.googlecode.com/
Python | 741 lines | 624 code | 60 blank | 57 comment | 10 complexity | 032ea369e99ee1069077519ba3c67619 MD5 | raw file
  1import unittest
  2from test import test_support
  3import subprocess
  4import sys
  5import signal
  6import os
  7import tempfile
  8import time
  9import re
 10
 11mswindows = (sys.platform == "win32")
 12
 13#
 14# Depends on the following external programs: Python
 15#
 16
 17if mswindows:
 18    SETBINARY = ('import msvcrt; msvcrt.setmode(sys.stdout.fileno(), '
 19                                                'os.O_BINARY);')
 20else:
 21    SETBINARY = ''
 22
 23# 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):
 27    return re.sub(r"\[\d+ refs\]\r?\n?$", "", stderr)
 28
 29class ProcessTestCase(unittest.TestCase):
 30    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        if hasattr(test_support, "reap_children"):
 34            test_support.reap_children()
 35
 36    def tearDown(self):
 37        # Try to minimize the number of children we have so this test
 38        # doesn't crash on some buildbots (Alphas in particular).
 39        if hasattr(test_support, "reap_children"):
 40            test_support.reap_children()
 41
 42    def mkstemp(self):
 43        """wrapper for mkstemp, calling mktemp if mkstemp is not available"""
 44        if hasattr(tempfile, "mkstemp"):
 45            return tempfile.mkstemp()
 46        else:
 47            fname = tempfile.mktemp()
 48            return os.open(fname, os.O_RDWR|os.O_CREAT), fname
 49
 50    #
 51    # Generic tests
 52    #
 53    def test_call_seq(self):
 54        # call() function with sequence argument
 55        rc = subprocess.call([sys.executable, "-c",
 56                              "import sys; sys.exit(47)"])
 57        self.assertEqual(rc, 47)
 58
 59    def test_check_call_zero(self):
 60        # check_call() function with zero return code
 61        rc = subprocess.check_call([sys.executable, "-c",
 62                                    "import sys; sys.exit(0)"])
 63        self.assertEqual(rc, 0)
 64
 65    def test_check_call_nonzero(self):
 66        # check_call() function with non-zero return code
 67        try:
 68            subprocess.check_call([sys.executable, "-c",
 69                                   "import sys; sys.exit(47)"])
 70        except subprocess.CalledProcessError, e:
 71            self.assertEqual(e.returncode, 47)
 72        else:
 73            self.fail("Expected CalledProcessError")
 74
 75    def test_call_kwargs(self):
 76        # call() function with keyword args
 77        newenv = os.environ.copy()
 78        newenv["FRUIT"] = "banana"
 79        rc = subprocess.call([sys.executable, "-c",
 80                          'import sys, os;' \
 81                          'sys.exit(os.getenv("FRUIT")=="banana")'],
 82                        env=newenv)
 83        self.assertEqual(rc, 1)
 84
 85    def test_stdin_none(self):
 86        # .stdin is None when not redirected
 87        p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
 88                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 89        p.wait()
 90        self.assertEqual(p.stdin, None)
 91
 92    def test_stdout_none(self):
 93        # .stdout is None when not redirected
 94        p = subprocess.Popen([sys.executable, "-c",
 95                             'print "    this bit of output is from a '
 96                             'test of stdout in a different '
 97                             'process ..."'],
 98                             stdin=subprocess.PIPE, stderr=subprocess.PIPE)
 99        p.wait()
100        self.assertEqual(p.stdout, None)
101
102    def test_stderr_none(self):
103        # .stderr is None when not redirected
104        p = subprocess.Popen([sys.executable, "-c", 'print "banana"'],
105                         stdin=subprocess.PIPE, stdout=subprocess.PIPE)
106        p.wait()
107        self.assertEqual(p.stderr, None)
108
109    def test_executable(self):
110        p = subprocess.Popen(["somethingyoudonthave",
111                              "-c", "import sys; sys.exit(47)"],
112                             executable=sys.executable)
113        p.wait()
114        self.assertEqual(p.returncode, 47)
115
116    def test_stdin_pipe(self):
117        # stdin redirection
118        p = subprocess.Popen([sys.executable, "-c",
119                         'import sys; sys.exit(sys.stdin.read() == "pear")'],
120                        stdin=subprocess.PIPE)
121        p.stdin.write("pear")
122        p.stdin.close()
123        p.wait()
124        self.assertEqual(p.returncode, 1)
125
126    def test_stdin_filedes(self):
127        # stdin is set to open file descriptor
128        tf = tempfile.TemporaryFile()
129        d = tf.fileno()
130        os.write(d, "pear")
131        os.lseek(d, 0, 0)
132        p = subprocess.Popen([sys.executable, "-c",
133                         'import sys; sys.exit(sys.stdin.read() == "pear")'],
134                         stdin=d)
135        p.wait()
136        self.assertEqual(p.returncode, 1)
137
138    def test_stdin_fileobj(self):
139        # stdin is set to open file object
140        tf = tempfile.TemporaryFile()
141        tf.write("pear")
142        tf.seek(0)
143        p = subprocess.Popen([sys.executable, "-c",
144                         'import sys; sys.exit(sys.stdin.read() == "pear")'],
145                         stdin=tf)
146        p.wait()
147        self.assertEqual(p.returncode, 1)
148
149    def test_stdout_pipe(self):
150        # stdout redirection
151        p = subprocess.Popen([sys.executable, "-c",
152                          'import sys; sys.stdout.write("orange")'],
153                         stdout=subprocess.PIPE)
154        self.assertEqual(p.stdout.read(), "orange")
155
156    def test_stdout_filedes(self):
157        # stdout is set to open file descriptor
158        tf = tempfile.TemporaryFile()
159        d = tf.fileno()
160        p = subprocess.Popen([sys.executable, "-c",
161                          'import sys; sys.stdout.write("orange")'],
162                         stdout=d)
163        p.wait()
164        os.lseek(d, 0, 0)
165        self.assertEqual(os.read(d, 1024), "orange")
166
167    def test_stdout_fileobj(self):
168        # stdout is set to open file object
169        tf = tempfile.TemporaryFile()
170        p = subprocess.Popen([sys.executable, "-c",
171                          'import sys; sys.stdout.write("orange")'],
172                         stdout=tf)
173        p.wait()
174        tf.seek(0)
175        self.assertEqual(tf.read(), "orange")
176
177    def test_stderr_pipe(self):
178        # stderr redirection
179        p = subprocess.Popen([sys.executable, "-c",
180                          'import sys; sys.stderr.write("strawberry")'],
181                         stderr=subprocess.PIPE)
182        self.assertEqual(remove_stderr_debug_decorations(p.stderr.read()),
183                         "strawberry")
184
185    def test_stderr_filedes(self):
186        # stderr is set to open file descriptor
187        tf = tempfile.TemporaryFile()
188        d = tf.fileno()
189        p = subprocess.Popen([sys.executable, "-c",
190                          'import sys; sys.stderr.write("strawberry")'],
191                         stderr=d)
192        p.wait()
193        os.lseek(d, 0, 0)
194        self.assertEqual(remove_stderr_debug_decorations(os.read(d, 1024)),
195                         "strawberry")
196
197    def test_stderr_fileobj(self):
198        # stderr is set to open file object
199        tf = tempfile.TemporaryFile()
200        p = subprocess.Popen([sys.executable, "-c",
201                          'import sys; sys.stderr.write("strawberry")'],
202                         stderr=tf)
203        p.wait()
204        tf.seek(0)
205        self.assertEqual(remove_stderr_debug_decorations(tf.read()),
206                         "strawberry")
207
208    def test_stdout_stderr_pipe(self):
209        # capture stdout and stderr to the same pipe
210        p = subprocess.Popen([sys.executable, "-c",
211                          'import sys;' \
212                          'sys.stdout.write("apple");' \
213                          'sys.stdout.flush();' \
214                          'sys.stderr.write("orange")'],
215                         stdout=subprocess.PIPE,
216                         stderr=subprocess.STDOUT)
217        output = p.stdout.read()
218        stripped = remove_stderr_debug_decorations(output)
219        self.assertEqual(stripped, "appleorange")
220
221    def test_stdout_stderr_file(self):
222        # capture stdout and stderr to the same open file
223        tf = tempfile.TemporaryFile()
224        p = subprocess.Popen([sys.executable, "-c",
225                          'import sys;' \
226                          'sys.stdout.write("apple");' \
227                          'sys.stdout.flush();' \
228                          'sys.stderr.write("orange")'],
229                         stdout=tf,
230                         stderr=tf)
231        p.wait()
232        tf.seek(0)
233        output = tf.read()
234        stripped = remove_stderr_debug_decorations(output)
235        self.assertEqual(stripped, "appleorange")
236
237    def test_stdout_filedes_of_stdout(self):
238        # stdout is set to 1 (#1531862).
239        cmd = r"import sys, os; sys.exit(os.write(sys.stdout.fileno(), '.\n'))"
240        rc = subprocess.call([sys.executable, "-c", cmd], stdout=1)
241        self.assertEquals(rc, 2)
242
243    def test_cwd(self):
244        tmpdir = tempfile.gettempdir()
245        # We cannot use os.path.realpath to canonicalize the path,
246        # since it doesn't expand Tru64 {memb} strings. See bug 1063571.
247        cwd = os.getcwd()
248        os.chdir(tmpdir)
249        tmpdir = os.getcwd()
250        os.chdir(cwd)
251        p = subprocess.Popen([sys.executable, "-c",
252                          'import sys,os;' \
253                          'sys.stdout.write(os.getcwd())'],
254                         stdout=subprocess.PIPE,
255                         cwd=tmpdir)
256        normcase = os.path.normcase
257        self.assertEqual(normcase(p.stdout.read()), normcase(tmpdir))
258
259    def test_env(self):
260        newenv = os.environ.copy()
261        newenv["FRUIT"] = "orange"
262        p = subprocess.Popen([sys.executable, "-c",
263                          'import sys,os;' \
264                          'sys.stdout.write(os.getenv("FRUIT"))'],
265                         stdout=subprocess.PIPE,
266                         env=newenv)
267        self.assertEqual(p.stdout.read(), "orange")
268
269    def test_communicate_stdin(self):
270        p = subprocess.Popen([sys.executable, "-c",
271                              'import sys; sys.exit(sys.stdin.read() == "pear")'],
272                             stdin=subprocess.PIPE)
273        p.communicate("pear")
274        self.assertEqual(p.returncode, 1)
275
276    def test_communicate_stdout(self):
277        p = subprocess.Popen([sys.executable, "-c",
278                              'import sys; sys.stdout.write("pineapple")'],
279                             stdout=subprocess.PIPE)
280        (stdout, stderr) = p.communicate()
281        self.assertEqual(stdout, "pineapple")
282        self.assertEqual(stderr, None)
283
284    def test_communicate_stderr(self):
285        p = subprocess.Popen([sys.executable, "-c",
286                              'import sys; sys.stderr.write("pineapple")'],
287                             stderr=subprocess.PIPE)
288        (stdout, stderr) = p.communicate()
289        self.assertEqual(stdout, None)
290        self.assertEqual(remove_stderr_debug_decorations(stderr), "pineapple")
291
292    def test_communicate(self):
293        p = subprocess.Popen([sys.executable, "-c",
294                          'import sys,os;'
295                          'sys.stderr.write("pineapple");'
296                          'sys.stdout.write(sys.stdin.read())'],
297                         stdin=subprocess.PIPE,
298                         stdout=subprocess.PIPE,
299                         stderr=subprocess.PIPE)
300        (stdout, stderr) = p.communicate("banana")
301        self.assertEqual(stdout, "banana")
302        self.assertEqual(remove_stderr_debug_decorations(stderr),
303                         "pineapple")
304
305    # This test is Linux specific for simplicity to at least have
306    # some coverage.  It is not a platform specific bug.
307    if os.path.isdir('/proc/%d/fd' % os.getpid()):
308        # Test for the fd leak reported in http://bugs.python.org/issue2791.
309        def test_communicate_pipe_fd_leak(self):
310            fd_directory = '/proc/%d/fd' % os.getpid()
311            num_fds_before_popen = len(os.listdir(fd_directory))
312            p = subprocess.Popen([sys.executable, '-c', 'print()'],
313                                 stdout=subprocess.PIPE)
314            p.communicate()
315            num_fds_after_communicate = len(os.listdir(fd_directory))
316            del p
317            num_fds_after_destruction = len(os.listdir(fd_directory))
318            self.assertEqual(num_fds_before_popen, num_fds_after_destruction)
319            self.assertEqual(num_fds_before_popen, num_fds_after_communicate)
320
321    def test_communicate_returns(self):
322        # communicate() should return None if no redirection is active
323        p = subprocess.Popen([sys.executable, "-c",
324                              "import sys; sys.exit(47)"])
325        (stdout, stderr) = p.communicate()
326        self.assertEqual(stdout, None)
327        self.assertEqual(stderr, None)
328
329    def test_communicate_pipe_buf(self):
330        # communicate() with writes larger than pipe_buf
331        # This test will probably deadlock rather than fail, if
332        # communicate() does not work properly.
333        x, y = os.pipe()
334        if mswindows:
335            pipe_buf = 512
336        else:
337            pipe_buf = os.fpathconf(x, "PC_PIPE_BUF")
338        os.close(x)
339        os.close(y)
340        p = subprocess.Popen([sys.executable, "-c",
341                          'import sys,os;'
342                          'sys.stdout.write(sys.stdin.read(47));' \
343                          'sys.stderr.write("xyz"*%d);' \
344                          'sys.stdout.write(sys.stdin.read())' % pipe_buf],
345                         stdin=subprocess.PIPE,
346                         stdout=subprocess.PIPE,
347                         stderr=subprocess.PIPE)
348        string_to_write = "abc"*pipe_buf
349        (stdout, stderr) = p.communicate(string_to_write)
350        self.assertEqual(stdout, string_to_write)
351
352    def test_writes_before_communicate(self):
353        # stdin.write before communicate()
354        p = subprocess.Popen([sys.executable, "-c",
355                          'import sys,os;' \
356                          'sys.stdout.write(sys.stdin.read())'],
357                         stdin=subprocess.PIPE,
358                         stdout=subprocess.PIPE,
359                         stderr=subprocess.PIPE)
360        p.stdin.write("banana")
361        (stdout, stderr) = p.communicate("split")
362        self.assertEqual(stdout, "bananasplit")
363        self.assertEqual(remove_stderr_debug_decorations(stderr), "")
364
365    def test_universal_newlines(self):
366        p = subprocess.Popen([sys.executable, "-c",
367                          'import sys,os;' + SETBINARY +
368                          'sys.stdout.write("line1\\n");'
369                          'sys.stdout.flush();'
370                          'sys.stdout.write("line2\\r");'
371                          'sys.stdout.flush();'
372                          'sys.stdout.write("line3\\r\\n");'
373                          'sys.stdout.flush();'
374                          'sys.stdout.write("line4\\r");'
375                          'sys.stdout.flush();'
376                          'sys.stdout.write("\\nline5");'
377                          'sys.stdout.flush();'
378                          'sys.stdout.write("\\nline6");'],
379                         stdout=subprocess.PIPE,
380                         universal_newlines=1)
381        stdout = p.stdout.read()
382        if hasattr(file, 'newlines'):
383            # Interpreter with universal newline support
384            self.assertEqual(stdout,
385                             "line1\nline2\nline3\nline4\nline5\nline6")
386        else:
387            # Interpreter without universal newline support
388            self.assertEqual(stdout,
389                             "line1\nline2\rline3\r\nline4\r\nline5\nline6")
390
391    def test_universal_newlines_communicate(self):
392        # universal newlines through communicate()
393        p = subprocess.Popen([sys.executable, "-c",
394                          'import sys,os;' + SETBINARY +
395                          'sys.stdout.write("line1\\n");'
396                          'sys.stdout.flush();'
397                          'sys.stdout.write("line2\\r");'
398                          'sys.stdout.flush();'
399                          'sys.stdout.write("line3\\r\\n");'
400                          'sys.stdout.flush();'
401                          'sys.stdout.write("line4\\r");'
402                          'sys.stdout.flush();'
403                          'sys.stdout.write("\\nline5");'
404                          'sys.stdout.flush();'
405                          'sys.stdout.write("\\nline6");'],
406                         stdout=subprocess.PIPE, stderr=subprocess.PIPE,
407                         universal_newlines=1)
408        (stdout, stderr) = p.communicate()
409        if hasattr(file, 'newlines'):
410            # Interpreter with universal newline support
411            self.assertEqual(stdout,
412                             "line1\nline2\nline3\nline4\nline5\nline6")
413        else:
414            # Interpreter without universal newline support
415            self.assertEqual(stdout, "line1\nline2\rline3\r\nline4\r\nline5\nline6")
416
417    def test_no_leaking(self):
418        # Make sure we leak no resources
419        if not hasattr(test_support, "is_resource_enabled") \
420               or test_support.is_resource_enabled("subprocess") and not mswindows:
421            max_handles = 1026 # too much for most UNIX systems
422        else:
423            max_handles = 65
424        for i in range(max_handles):
425            p = subprocess.Popen([sys.executable, "-c",
426                    "import sys;sys.stdout.write(sys.stdin.read())"],
427                    stdin=subprocess.PIPE,
428                    stdout=subprocess.PIPE,
429                    stderr=subprocess.PIPE)
430            data = p.communicate("lime")[0]
431            self.assertEqual(data, "lime")
432
433
434    def test_list2cmdline(self):
435        self.assertEqual(subprocess.list2cmdline(['a b c', 'd', 'e']),
436                         '"a b c" d e')
437        self.assertEqual(subprocess.list2cmdline(['ab"c', '\\', 'd']),
438                         'ab\\"c \\ d')
439        self.assertEqual(subprocess.list2cmdline(['ab"c', ' \\', 'd']),
440                         'ab\\"c " \\\\" d')
441        self.assertEqual(subprocess.list2cmdline(['a\\\\\\b', 'de fg', 'h']),
442                         'a\\\\\\b "de fg" h')
443        self.assertEqual(subprocess.list2cmdline(['a\\"b', 'c', 'd']),
444                         'a\\\\\\"b c d')
445        self.assertEqual(subprocess.list2cmdline(['a\\\\b c', 'd', 'e']),
446                         '"a\\\\b c" d e')
447        self.assertEqual(subprocess.list2cmdline(['a\\\\b\\ c', 'd', 'e']),
448                         '"a\\\\b\\ c" d e')
449        self.assertEqual(subprocess.list2cmdline(['ab', '']),
450                         'ab ""')
451        self.assertEqual(subprocess.list2cmdline(['echo', 'foo|bar']),
452                         'echo "foo|bar"')
453
454
455    def test_poll(self):
456        p = subprocess.Popen([sys.executable,
457                          "-c", "import time; time.sleep(1)"])
458        count = 0
459        while p.poll() is None:
460            time.sleep(0.1)
461            count += 1
462        # We expect that the poll loop probably went around about 10 times,
463        # but, based on system scheduling we can't control, it's possible
464        # poll() never returned None.  It "should be" very rare that it
465        # didn't go around at least twice.
466        self.assert_(count >= 2)
467        # Subsequent invocations should just return the returncode
468        self.assertEqual(p.poll(), 0)
469
470
471    def test_wait(self):
472        p = subprocess.Popen([sys.executable,
473                          "-c", "import time; time.sleep(2)"])
474        self.assertEqual(p.wait(), 0)
475        # Subsequent invocations should just return the returncode
476        self.assertEqual(p.wait(), 0)
477
478
479    def test_invalid_bufsize(self):
480        # an invalid type of the bufsize argument should raise
481        # TypeError.
482        try:
483            subprocess.Popen([sys.executable, "-c", "pass"], "orange")
484        except TypeError:
485            pass
486        else:
487            self.fail("Expected TypeError")
488
489    def test_leaking_fds_on_error(self):
490        # see bug #5179: Popen leaks file descriptors to PIPEs if
491        # the child fails to execute; this will eventually exhaust
492        # the maximum number of open fds. 1024 seems a very common
493        # value for that limit, but Windows has 2048, so we loop
494        # 1024 times (each call leaked two fds).
495        for i in range(1024):
496            try:
497                subprocess.Popen(['nonexisting_i_hope'],
498                                 stdout=subprocess.PIPE,
499                                 stderr=subprocess.PIPE)
500            # Windows raises IOError
501            except (IOError, OSError), err:
502                if err.errno != 2:  # ignore "no such file"
503                    raise
504
505    #
506    # POSIX tests
507    #
508    if not mswindows:
509        def test_exceptions(self):
510            # catched & re-raised exceptions
511            try:
512                p = subprocess.Popen([sys.executable, "-c", ""],
513                                 cwd="/this/path/does/not/exist")
514            except OSError, e:
515                # The attribute child_traceback should contain "os.chdir"
516                # somewhere.
517                self.assertNotEqual(e.child_traceback.find("os.chdir"), -1)
518            else:
519                self.fail("Expected OSError")
520
521        def _suppress_core_files(self):
522            """Try to prevent core files from being created.
523            Returns previous ulimit if successful, else None.
524            """
525            try:
526                import resource
527                old_limit = resource.getrlimit(resource.RLIMIT_CORE)
528                resource.setrlimit(resource.RLIMIT_CORE, (0,0))
529                return old_limit
530            except (ImportError, ValueError, resource.error):
531                return None
532
533        def _unsuppress_core_files(self, old_limit):
534            """Return core file behavior to default."""
535            if old_limit is None:
536                return
537            try:
538                import resource
539                resource.setrlimit(resource.RLIMIT_CORE, old_limit)
540            except (ImportError, ValueError, resource.error):
541                return
542
543        def test_run_abort(self):
544            # returncode handles signal termination
545            old_limit = self._suppress_core_files()
546            try:
547                p = subprocess.Popen([sys.executable,
548                                      "-c", "import os; os.abort()"])
549            finally:
550                self._unsuppress_core_files(old_limit)
551            p.wait()
552            self.assertEqual(-p.returncode, signal.SIGABRT)
553
554        def test_preexec(self):
555            # preexec function
556            p = subprocess.Popen([sys.executable, "-c",
557                              'import sys,os;' \
558                              'sys.stdout.write(os.getenv("FRUIT"))'],
559                             stdout=subprocess.PIPE,
560                             preexec_fn=lambda: os.putenv("FRUIT", "apple"))
561            self.assertEqual(p.stdout.read(), "apple")
562
563        def test_args_string(self):
564            # args is a string
565            f, fname = self.mkstemp()
566            os.write(f, "#!/bin/sh\n")
567            os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
568                        sys.executable)
569            os.close(f)
570            os.chmod(fname, 0700)
571            p = subprocess.Popen(fname)
572            p.wait()
573            os.remove(fname)
574            self.assertEqual(p.returncode, 47)
575
576        def test_invalid_args(self):
577            # invalid arguments should raise ValueError
578            self.assertRaises(ValueError, subprocess.call,
579                              [sys.executable,
580                               "-c", "import sys; sys.exit(47)"],
581                              startupinfo=47)
582            self.assertRaises(ValueError, subprocess.call,
583                              [sys.executable,
584                               "-c", "import sys; sys.exit(47)"],
585                              creationflags=47)
586
587        def test_shell_sequence(self):
588            # Run command through the shell (sequence)
589            newenv = os.environ.copy()
590            newenv["FRUIT"] = "apple"
591            p = subprocess.Popen(["echo $FRUIT"], shell=1,
592                                 stdout=subprocess.PIPE,
593                                 env=newenv)
594            self.assertEqual(p.stdout.read().strip(), "apple")
595
596        def test_shell_string(self):
597            # Run command through the shell (string)
598            newenv = os.environ.copy()
599            newenv["FRUIT"] = "apple"
600            p = subprocess.Popen("echo $FRUIT", shell=1,
601                                 stdout=subprocess.PIPE,
602                                 env=newenv)
603            self.assertEqual(p.stdout.read().strip(), "apple")
604
605        def test_call_string(self):
606            # call() function with string argument on UNIX
607            f, fname = self.mkstemp()
608            os.write(f, "#!/bin/sh\n")
609            os.write(f, "exec '%s' -c 'import sys; sys.exit(47)'\n" %
610                        sys.executable)
611            os.close(f)
612            os.chmod(fname, 0700)
613            rc = subprocess.call(fname)
614            os.remove(fname)
615            self.assertEqual(rc, 47)
616
617        def DISABLED_test_send_signal(self):
618            p = subprocess.Popen([sys.executable,
619                              "-c", "input()"])
620
621            self.assert_(p.poll() is None, p.poll())
622            p.send_signal(signal.SIGINT)
623            self.assertNotEqual(p.wait(), 0)
624
625        def DISABLED_test_kill(self):
626            p = subprocess.Popen([sys.executable,
627                            "-c", "input()"])
628
629            self.assert_(p.poll() is None, p.poll())
630            p.kill()
631            self.assertEqual(p.wait(), -signal.SIGKILL)
632
633        def DISABLED_test_terminate(self):
634            p = subprocess.Popen([sys.executable,
635                            "-c", "input()"])
636
637            self.assert_(p.poll() is None, p.poll())
638            p.terminate()
639            self.assertEqual(p.wait(), -signal.SIGTERM)
640
641    #
642    # Windows tests
643    #
644    if mswindows:
645        def test_startupinfo(self):
646            # startupinfo argument
647            # We uses hardcoded constants, because we do not want to
648            # depend on win32all.
649            STARTF_USESHOWWINDOW = 1
650            SW_MAXIMIZE = 3
651            startupinfo = subprocess.STARTUPINFO()
652            startupinfo.dwFlags = STARTF_USESHOWWINDOW
653            startupinfo.wShowWindow = SW_MAXIMIZE
654            # Since Python is a console process, it won't be affected
655            # by wShowWindow, but the argument should be silently
656            # ignored
657            subprocess.call([sys.executable, "-c", "import sys; sys.exit(0)"],
658                        startupinfo=startupinfo)
659
660        def test_creationflags(self):
661            # creationflags argument
662            CREATE_NEW_CONSOLE = 16
663            sys.stderr.write("    a DOS box should flash briefly ...\n")
664            subprocess.call(sys.executable +
665                                ' -c "import time; time.sleep(0.25)"',
666                            creationflags=CREATE_NEW_CONSOLE)
667
668        def test_invalid_args(self):
669            # invalid arguments should raise ValueError
670            self.assertRaises(ValueError, subprocess.call,
671                              [sys.executable,
672                               "-c", "import sys; sys.exit(47)"],
673                              preexec_fn=lambda: 1)
674            self.assertRaises(ValueError, subprocess.call,
675                              [sys.executable,
676                               "-c", "import sys; sys.exit(47)"],
677                              stdout=subprocess.PIPE,
678                              close_fds=True)
679
680        def test_close_fds(self):
681            # close file descriptors
682            rc = subprocess.call([sys.executable, "-c",
683                                  "import sys; sys.exit(47)"],
684                                  close_fds=True)
685            self.assertEqual(rc, 47)
686
687        def test_shell_sequence(self):
688            # Run command through the shell (sequence)
689            newenv = os.environ.copy()
690            newenv["FRUIT"] = "physalis"
691            p = subprocess.Popen(["set"], shell=1,
692                                 stdout=subprocess.PIPE,
693                                 env=newenv)
694            self.assertNotEqual(p.stdout.read().find("physalis"), -1)
695
696        def test_shell_string(self):
697            # Run command through the shell (string)
698            newenv = os.environ.copy()
699            newenv["FRUIT"] = "physalis"
700            p = subprocess.Popen("set", shell=1,
701                                 stdout=subprocess.PIPE,
702                                 env=newenv)
703            self.assertNotEqual(p.stdout.read().find("physalis"), -1)
704
705        def test_call_string(self):
706            # call() function with string argument on Windows
707            rc = subprocess.call(sys.executable +
708                                 ' -c "import sys; sys.exit(47)"')
709            self.assertEqual(rc, 47)
710
711        def DISABLED_test_send_signal(self):
712            p = subprocess.Popen([sys.executable,
713                              "-c", "input()"])
714
715            self.assert_(p.poll() is None, p.poll())
716            p.send_signal(signal.SIGTERM)
717            self.assertNotEqual(p.wait(), 0)
718
719        def DISABLED_test_kill(self):
720            p = subprocess.Popen([sys.executable,
721                            "-c", "input()"])
722
723            self.assert_(p.poll() is None, p.poll())
724            p.kill()
725            self.assertNotEqual(p.wait(), 0)
726
727        def DISABLED_test_terminate(self):
728            p = subprocess.Popen([sys.executable,
729                            "-c", "input()"])
730
731            self.assert_(p.poll() is None, p.poll())
732            p.terminate()
733            self.assertNotEqual(p.wait(), 0)
734
735def test_main():
736    test_support.run_unittest(ProcessTestCase)
737    if hasattr(test_support, "reap_children"):
738        test_support.reap_children()
739
740if __name__ == "__main__":
741    test_main()