blob: e7ddf90947cf5f10f21f200bb42c7acb7ac34bf9 [file] [log] [blame]
[email protected]eba40222011-04-05 14:52:481#!/usr/bin/env python
[email protected]0e023172012-01-10 18:06:452# Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]eba40222011-04-05 14:52:483# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
6"""Unit tests for subprocess2.py."""
7
[email protected]4942e4a2011-11-15 15:50:508import logging
[email protected]eba40222011-04-05 14:52:489import optparse
10import os
11import sys
12import time
13import unittest
14
[email protected]4942e4a2011-11-15 15:50:5015try:
[email protected]97170132013-05-08 14:58:3416 import fcntl # pylint: disable=F0401
[email protected]4942e4a2011-11-15 15:50:5017except ImportError:
18 fcntl = None
19
[email protected]428342a2011-11-10 15:46:3320sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
[email protected]eba40222011-04-05 14:52:4821
[email protected]db59bfc2011-11-30 14:03:1422import subprocess
[email protected]eba40222011-04-05 14:52:4823import subprocess2
24
[email protected]7bb06bb2011-11-29 15:22:0625from testing_support import auto_stub
26
[email protected]4942e4a2011-11-15 15:50:5027# Method could be a function
28# pylint: disable=R0201
29
30
[email protected]a8e81632011-12-01 00:35:2431# Create aliases for subprocess2 specific tests. They shouldn't be used for
32# regression tests.
33TIMED_OUT = subprocess2.TIMED_OUT
34VOID = subprocess2.VOID
35PIPE = subprocess2.PIPE
36STDOUT = subprocess2.STDOUT
37
38
[email protected]4942e4a2011-11-15 15:50:5039def convert_to_crlf(string):
40 """Unconditionally convert LF to CRLF."""
41 return string.replace('\n', '\r\n')
42
43
44def convert_to_cr(string):
45 """Unconditionally convert LF to CR."""
46 return string.replace('\n', '\r')
47
48
49def convert_win(string):
50 """Converts string to CRLF on Windows only."""
51 if sys.platform == 'win32':
52 return string.replace('\n', '\r\n')
53 return string
54
55
[email protected]7bb06bb2011-11-29 15:22:0656class DefaultsTest(auto_stub.TestCase):
57 # TODO(maruel): Do a reopen() on sys.__stdout__ and sys.__stderr__ so they
58 # can be trapped in the child process for better coverage.
59 def _fake_communicate(self):
[email protected]ef77f9e2011-11-24 15:24:0260 """Mocks subprocess2.communicate()."""
[email protected]eba40222011-04-05 14:52:4861 results = {}
[email protected]1f063db2011-04-18 19:04:5262 def fake_communicate(args, **kwargs):
[email protected]f08b09c2011-04-06 13:14:2763 assert not results
[email protected]eba40222011-04-05 14:52:4864 results.update(kwargs)
65 results['args'] = args
[email protected]ef77f9e2011-11-24 15:24:0266 return ('stdout', 'stderr'), 0
[email protected]7bb06bb2011-11-29 15:22:0667 self.mock(subprocess2, 'communicate', fake_communicate)
[email protected]eba40222011-04-05 14:52:4868 return results
69
[email protected]7bb06bb2011-11-29 15:22:0670 def _fake_Popen(self):
[email protected]ef77f9e2011-11-24 15:24:0271 """Mocks the whole subprocess2.Popen class."""
[email protected]f08b09c2011-04-06 13:14:2772 results = {}
73 class fake_Popen(object):
74 returncode = -8
75 def __init__(self, args, **kwargs):
76 assert not results
77 results.update(kwargs)
78 results['args'] = args
[email protected]428342a2011-11-10 15:46:3379 @staticmethod
[email protected]e0558e62013-05-02 02:48:5180 # pylint: disable=W0622
[email protected]12b07e72013-05-03 22:06:3481 def communicate(input=None, timeout=None, nag_max=None, nag_timer=None):
[email protected]f08b09c2011-04-06 13:14:2782 return None, None
[email protected]7bb06bb2011-11-29 15:22:0683 self.mock(subprocess2, 'Popen', fake_Popen)
[email protected]f08b09c2011-04-06 13:14:2784 return results
85
[email protected]7bb06bb2011-11-29 15:22:0686 def _fake_subprocess_Popen(self):
[email protected]ef77f9e2011-11-24 15:24:0287 """Mocks the base class subprocess.Popen only."""
[email protected]f08b09c2011-04-06 13:14:2788 results = {}
[email protected]ef77f9e2011-11-24 15:24:0289 def __init__(self, args, **kwargs):
90 assert not results
91 results.update(kwargs)
92 results['args'] = args
93 def communicate():
94 return None, None
[email protected]db59bfc2011-11-30 14:03:1495 self.mock(subprocess.Popen, '__init__', __init__)
96 self.mock(subprocess.Popen, 'communicate', communicate)
[email protected]f08b09c2011-04-06 13:14:2797 return results
98
[email protected]eba40222011-04-05 14:52:4899 def test_check_call_defaults(self):
[email protected]1f063db2011-04-18 19:04:52100 results = self._fake_communicate()
[email protected]eba40222011-04-05 14:52:48101 self.assertEquals(
[email protected]ef77f9e2011-11-24 15:24:02102 ('stdout', 'stderr'), subprocess2.check_call_out(['foo'], a=True))
[email protected]eba40222011-04-05 14:52:48103 expected = {
104 'args': ['foo'],
105 'a':True,
106 }
107 self.assertEquals(expected, results)
108
[email protected]87e6d332011-09-09 19:01:28109 def test_capture_defaults(self):
110 results = self._fake_communicate()
111 self.assertEquals(
112 'stdout', subprocess2.capture(['foo'], a=True))
113 expected = {
114 'args': ['foo'],
115 'a':True,
116 'stdin': subprocess2.VOID,
117 'stdout': subprocess2.PIPE,
118 }
119 self.assertEquals(expected, results)
120
[email protected]1f063db2011-04-18 19:04:52121 def test_communicate_defaults(self):
[email protected]f08b09c2011-04-06 13:14:27122 results = self._fake_Popen()
[email protected]1f063db2011-04-18 19:04:52123 self.assertEquals(
124 ((None, None), -8), subprocess2.communicate(['foo'], a=True))
[email protected]f08b09c2011-04-06 13:14:27125 expected = {
126 'args': ['foo'],
127 'a': True,
128 }
129 self.assertEquals(expected, results)
130
131 def test_Popen_defaults(self):
132 results = self._fake_subprocess_Popen()
133 proc = subprocess2.Popen(['foo'], a=True)
[email protected]ef77f9e2011-11-24 15:24:02134 # Cleanup code in subprocess.py needs this member to be set.
135 # pylint: disable=W0201
136 proc._child_created = None
[email protected]f08b09c2011-04-06 13:14:27137 expected = {
138 'args': ['foo'],
139 'a': True,
140 'shell': bool(sys.platform=='win32'),
[email protected]f08b09c2011-04-06 13:14:27141 }
[email protected]c98c0c52011-04-06 13:39:43142 if sys.platform != 'win32':
143 env = os.environ.copy()
144 is_english = lambda name: env.get(name, 'en').startswith('en')
145 if not is_english('LANG'):
146 env['LANG'] = 'en_US.UTF-8'
147 expected['env'] = env
148 if not is_english('LANGUAGE'):
149 env['LANGUAGE'] = 'en_US.UTF-8'
150 expected['env'] = env
[email protected]f08b09c2011-04-06 13:14:27151 self.assertEquals(expected, results)
[email protected]dd9837f2011-11-30 01:55:22152 self.assertTrue(time.time() >= proc.start)
[email protected]f08b09c2011-04-06 13:14:27153
[email protected]eba40222011-04-05 14:52:48154 def test_check_output_defaults(self):
[email protected]1f063db2011-04-18 19:04:52155 results = self._fake_communicate()
[email protected]eba40222011-04-05 14:52:48156 # It's discarding 'stderr' because it assumes stderr=subprocess2.STDOUT but
[email protected]1f063db2011-04-18 19:04:52157 # fake_communicate() doesn't 'implement' that.
[email protected]eba40222011-04-05 14:52:48158 self.assertEquals('stdout', subprocess2.check_output(['foo'], a=True))
159 expected = {
160 'args': ['foo'],
161 'a':True,
[email protected]4a982272011-04-12 20:49:37162 'stdin': subprocess2.VOID,
[email protected]eba40222011-04-05 14:52:48163 'stdout': subprocess2.PIPE,
[email protected]eba40222011-04-05 14:52:48164 }
165 self.assertEquals(expected, results)
166
[email protected]4942e4a2011-11-15 15:50:50167
[email protected]db59bfc2011-11-30 14:03:14168class BaseTestCase(unittest.TestCase):
[email protected]4942e4a2011-11-15 15:50:50169 def setUp(self):
[email protected]db59bfc2011-11-30 14:03:14170 super(BaseTestCase, self).setUp()
[email protected]4942e4a2011-11-15 15:50:50171 self.exe_path = __file__
172 self.exe = [sys.executable, self.exe_path, '--child']
173 self.states = {}
174 if fcntl:
175 for v in (sys.stdin, sys.stdout, sys.stderr):
176 fileno = v.fileno()
177 self.states[fileno] = fcntl.fcntl(fileno, fcntl.F_GETFL)
178
179 def tearDown(self):
180 for fileno, fl in self.states.iteritems():
181 self.assertEquals(fl, fcntl.fcntl(fileno, fcntl.F_GETFL))
[email protected]db59bfc2011-11-30 14:03:14182 super(BaseTestCase, self).tearDown()
[email protected]4942e4a2011-11-15 15:50:50183
[email protected]94c712f2011-12-01 15:04:57184 def _check_res(self, res, stdout, stderr, returncode):
185 (out, err), code = res
186 self.assertEquals(stdout, out)
187 self.assertEquals(stderr, err)
188 self.assertEquals(returncode, code)
189
[email protected]db59bfc2011-11-30 14:03:14190
191class RegressionTest(BaseTestCase):
192 # Regression tests to ensure that subprocess and subprocess2 have the same
193 # behavior.
194 def _run_test(self, function):
195 """Runs tests in 12 combinations:
196 - LF output with universal_newlines=False
197 - CR output with universal_newlines=False
198 - CRLF output with universal_newlines=False
199 - LF output with universal_newlines=True
200 - CR output with universal_newlines=True
201 - CRLF output with universal_newlines=True
202
203 Once with subprocess, once with subprocess2.
204
205 First |function| argument is the conversion for the original expected LF
206 string to the right EOL.
207 Second |function| argument is the executable and initial flag to run, to
208 control what EOL is used by the child process.
209 Third |function| argument is universal_newlines value.
210 """
211 noop = lambda x: x
212 for subp in (subprocess, subprocess2):
213 function(noop, self.exe, False, subp)
214 function(convert_to_cr, self.exe + ['--cr'], False, subp)
215 function(convert_to_crlf, self.exe + ['--crlf'], False, subp)
216 function(noop, self.exe, True, subp)
217 function(noop, self.exe + ['--cr'], True, subp)
218 function(noop, self.exe + ['--crlf'], True, subp)
219
[email protected]a8e81632011-12-01 00:35:24220 def _check_exception(self, subp, e, stdout, stderr, returncode):
[email protected]db59bfc2011-11-30 14:03:14221 """On exception, look if the exception members are set correctly."""
[email protected]a8e81632011-12-01 00:35:24222 self.assertEquals(returncode, e.returncode)
[email protected]db59bfc2011-11-30 14:03:14223 if subp is subprocess:
224 # subprocess never save the output.
225 self.assertFalse(hasattr(e, 'stdout'))
226 self.assertFalse(hasattr(e, 'stderr'))
227 elif subp is subprocess2:
228 self.assertEquals(stdout, e.stdout)
229 self.assertEquals(stderr, e.stderr)
230 else:
231 self.fail()
232
233 def test_check_output_no_stdout(self):
234 try:
235 subprocess2.check_output(self.exe, stdout=subprocess2.PIPE)
236 self.fail()
237 except ValueError:
238 pass
239
240 if (sys.version_info[0] * 10 + sys.version_info[1]) >= 27:
241 # python 2.7+
242 try:
243 # pylint: disable=E1101
244 subprocess.check_output(self.exe, stdout=subprocess.PIPE)
245 self.fail()
246 except ValueError:
247 pass
248
249 def test_check_output_throw_stdout(self):
250 def fn(c, e, un, subp):
251 if not hasattr(subp, 'check_output'):
252 return
253 try:
254 subp.check_output(
255 e + ['--fail', '--stdout'], universal_newlines=un)
256 self.fail()
[email protected]0e023172012-01-10 18:06:45257 except subp.CalledProcessError, exception:
258 self._check_exception(subp, exception, c('A\nBB\nCCC\n'), None, 64)
[email protected]db59bfc2011-11-30 14:03:14259 self._run_test(fn)
260
261 def test_check_output_throw_no_stderr(self):
262 def fn(c, e, un, subp):
263 if not hasattr(subp, 'check_output'):
264 return
265 try:
266 subp.check_output(
267 e + ['--fail', '--stderr'], universal_newlines=un)
268 self.fail()
[email protected]0e023172012-01-10 18:06:45269 except subp.CalledProcessError, exception:
270 self._check_exception(subp, exception, c(''), None, 64)
[email protected]db59bfc2011-11-30 14:03:14271 self._run_test(fn)
272
273 def test_check_output_throw_stderr(self):
274 def fn(c, e, un, subp):
275 if not hasattr(subp, 'check_output'):
276 return
277 try:
278 subp.check_output(
279 e + ['--fail', '--stderr'],
280 stderr=subp.PIPE,
281 universal_newlines=un)
282 self.fail()
[email protected]0e023172012-01-10 18:06:45283 except subp.CalledProcessError, exception:
284 self._check_exception(subp, exception, '', c('a\nbb\nccc\n'), 64)
[email protected]db59bfc2011-11-30 14:03:14285 self._run_test(fn)
286
287 def test_check_output_throw_stderr_stdout(self):
288 def fn(c, e, un, subp):
289 if not hasattr(subp, 'check_output'):
290 return
291 try:
292 subp.check_output(
293 e + ['--fail', '--stderr'],
294 stderr=subp.STDOUT,
295 universal_newlines=un)
296 self.fail()
[email protected]0e023172012-01-10 18:06:45297 except subp.CalledProcessError, exception:
298 self._check_exception(subp, exception, c('a\nbb\nccc\n'), None, 64)
[email protected]db59bfc2011-11-30 14:03:14299 self._run_test(fn)
300
301 def test_check_call_throw(self):
302 for subp in (subprocess, subprocess2):
303 try:
304 subp.check_call(self.exe + ['--fail', '--stderr'])
305 self.fail()
[email protected]0e023172012-01-10 18:06:45306 except subp.CalledProcessError, exception:
307 self._check_exception(subp, exception, None, None, 64)
[email protected]db59bfc2011-11-30 14:03:14308
[email protected]94c712f2011-12-01 15:04:57309 def test_redirect_stderr_to_stdout_pipe(self):
310 def fn(c, e, un, subp):
311 # stderr output into stdout.
312 proc = subp.Popen(
313 e + ['--stderr'],
314 stdout=subp.PIPE,
315 stderr=subp.STDOUT,
316 universal_newlines=un)
317 res = proc.communicate(), proc.returncode
318 self._check_res(res, c('a\nbb\nccc\n'), None, 0)
319 self._run_test(fn)
320
321 def test_redirect_stderr_to_stdout(self):
322 def fn(c, e, un, subp):
323 # stderr output into stdout but stdout is not piped.
324 proc = subp.Popen(
325 e + ['--stderr'], stderr=STDOUT, universal_newlines=un)
326 res = proc.communicate(), proc.returncode
327 self._check_res(res, None, None, 0)
328 self._run_test(fn)
329
[email protected]b054ebc2013-04-30 19:10:52330 def test_stderr(self):
331 cmd = ['expr', '1', '/', '0']
[email protected]97170132013-05-08 14:58:34332 if sys.platform == 'win32':
333 cmd = ['cmd.exe', '/c', 'exit', '1']
334 p1 = subprocess.Popen(cmd, stderr=subprocess.PIPE, shell=False)
335 p2 = subprocess2.Popen(cmd, stderr=subprocess.PIPE, shell=False)
[email protected]b054ebc2013-04-30 19:10:52336 r1 = p1.communicate()
337 r2 = p2.communicate(timeout=100)
338 self.assertEquals(r1, r2)
339
[email protected]db59bfc2011-11-30 14:03:14340
341class S2Test(BaseTestCase):
342 # Tests that can only run in subprocess2, e.g. new functionalities.
343 # In particular, subprocess2.communicate() doesn't exist in subprocess.
[email protected]4942e4a2011-11-15 15:50:50344 def _run_test(self, function):
345 """Runs tests in 6 combinations:
346 - LF output with universal_newlines=False
347 - CR output with universal_newlines=False
348 - CRLF output with universal_newlines=False
349 - LF output with universal_newlines=True
350 - CR output with universal_newlines=True
351 - CRLF output with universal_newlines=True
352
353 First |function| argument is the convertion for the origianl expected LF
354 string to the right EOL.
355 Second |function| argument is the executable and initial flag to run, to
356 control what EOL is used by the child process.
357 Third |function| argument is universal_newlines value.
358 """
359 noop = lambda x: x
360 function(noop, self.exe, False)
361 function(convert_to_cr, self.exe + ['--cr'], False)
362 function(convert_to_crlf, self.exe + ['--crlf'], False)
363 function(noop, self.exe, True)
364 function(noop, self.exe + ['--cr'], True)
365 function(noop, self.exe + ['--crlf'], True)
366
[email protected]94c712f2011-12-01 15:04:57367 def _check_exception(self, e, stdout, stderr, returncode):
368 """On exception, look if the exception members are set correctly."""
369 self.assertEquals(returncode, e.returncode)
370 self.assertEquals(stdout, e.stdout)
371 self.assertEquals(stderr, e.stderr)
[email protected]a8e81632011-12-01 00:35:24372
[email protected]f2dca4e2011-11-09 19:24:48373 def test_timeout(self):
[email protected]db59bfc2011-11-30 14:03:14374 # timeout doesn't exist in subprocess.
375 def fn(c, e, un):
[email protected]a8e81632011-12-01 00:35:24376 res = subprocess2.communicate(
[email protected]db59bfc2011-11-30 14:03:14377 self.exe + ['--sleep_first', '--stdout'],
378 timeout=0.01,
[email protected]a8e81632011-12-01 00:35:24379 stdout=PIPE,
[email protected]db59bfc2011-11-30 14:03:14380 shell=False)
[email protected]a8e81632011-12-01 00:35:24381 self._check_res(res, '', None, TIMED_OUT)
382 self._run_test(fn)
383
384 def test_timeout_shell_throws(self):
385 def fn(c, e, un):
386 try:
387 # With shell=True, it needs a string.
388 subprocess2.communicate(' '.join(self.exe), timeout=0.01, shell=True)
389 self.fail()
390 except TypeError:
391 pass
[email protected]db59bfc2011-11-30 14:03:14392 self._run_test(fn)
[email protected]87e6d332011-09-09 19:01:28393
[email protected]bc3a53c2011-12-05 23:38:19394 def test_stdin(self):
395 def fn(c, e, un):
396 stdin = '0123456789'
397 res = subprocess2.communicate(
398 e + ['--read'],
399 stdin=stdin,
400 universal_newlines=un)
401 self._check_res(res, None, None, 10)
402 self._run_test(fn)
403
404 def test_stdin_unicode(self):
405 def fn(c, e, un):
406 stdin = u'0123456789'
407 res = subprocess2.communicate(
408 e + ['--read'],
409 stdin=stdin,
410 universal_newlines=un)
411 self._check_res(res, None, None, 10)
412 self._run_test(fn)
413
[email protected]740a6c02011-12-05 23:46:44414 def test_stdin_empty(self):
415 def fn(c, e, un):
416 stdin = ''
417 res = subprocess2.communicate(
418 e + ['--read'],
419 stdin=stdin,
420 universal_newlines=un)
421 self._check_res(res, None, None, 0)
422 self._run_test(fn)
423
[email protected]bc3a53c2011-12-05 23:38:19424 def test_stdin_void(self):
425 res = subprocess2.communicate(self.exe + ['--read'], stdin=VOID)
426 self._check_res(res, None, None, 0)
427
428 def test_stdin_void_stdout_timeout(self):
429 # Make sure a mix of VOID, PIPE and timeout works.
430 def fn(c, e, un):
431 res = subprocess2.communicate(
432 e + ['--stdout', '--read'],
433 stdin=VOID,
434 stdout=PIPE,
435 timeout=10,
[email protected]97170132013-05-08 14:58:34436 universal_newlines=un,
437 shell=False)
[email protected]bc3a53c2011-12-05 23:38:19438 self._check_res(res, c('A\nBB\nCCC\n'), None, 0)
439 self._run_test(fn)
440
[email protected]87e6d332011-09-09 19:01:28441 def test_stdout_void(self):
[email protected]4942e4a2011-11-15 15:50:50442 def fn(c, e, un):
[email protected]a8e81632011-12-01 00:35:24443 res = subprocess2.communicate(
[email protected]4942e4a2011-11-15 15:50:50444 e + ['--stdout', '--stderr'],
[email protected]a8e81632011-12-01 00:35:24445 stdout=VOID,
446 stderr=PIPE,
[email protected]4942e4a2011-11-15 15:50:50447 universal_newlines=un)
[email protected]a8e81632011-12-01 00:35:24448 self._check_res(res, None, c('a\nbb\nccc\n'), 0)
[email protected]4942e4a2011-11-15 15:50:50449 self._run_test(fn)
[email protected]87e6d332011-09-09 19:01:28450
451 def test_stderr_void(self):
[email protected]4942e4a2011-11-15 15:50:50452 def fn(c, e, un):
[email protected]a8e81632011-12-01 00:35:24453 res = subprocess2.communicate(
[email protected]4942e4a2011-11-15 15:50:50454 e + ['--stdout', '--stderr'],
[email protected]a8e81632011-12-01 00:35:24455 stdout=PIPE,
456 stderr=VOID,
[email protected]4942e4a2011-11-15 15:50:50457 universal_newlines=un)
[email protected]a8e81632011-12-01 00:35:24458 self._check_res(res, c('A\nBB\nCCC\n'), None, 0)
459 self._run_test(fn)
460
461 def test_stdout_void_stderr_redirect(self):
462 def fn(c, e, un):
463 res = subprocess2.communicate(
464 e + ['--stdout', '--stderr'],
465 stdout=VOID,
466 stderr=STDOUT,
467 universal_newlines=un)
468 self._check_res(res, None, None, 0)
[email protected]4942e4a2011-11-15 15:50:50469 self._run_test(fn)
[email protected]eba40222011-04-05 14:52:48470
[email protected]94c712f2011-12-01 15:04:57471 def test_tee_stderr(self):
[email protected]93e21372011-11-24 15:57:19472 def fn(c, e, un):
[email protected]94c712f2011-12-01 15:04:57473 stderr = []
[email protected]a8e81632011-12-01 00:35:24474 res = subprocess2.communicate(
[email protected]94c712f2011-12-01 15:04:57475 e + ['--stderr'], stderr=stderr.append, universal_newlines=un)
476 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
[email protected]a8e81632011-12-01 00:35:24477 self._check_res(res, None, None, 0)
[email protected]93e21372011-11-24 15:57:19478 self._run_test(fn)
479
[email protected]94c712f2011-12-01 15:04:57480 def test_tee_stdout_stderr(self):
481 def fn(c, e, un):
482 stdout = []
483 stderr = []
484 res = subprocess2.communicate(
485 e + ['--stdout', '--stderr'],
486 stdout=stdout.append,
487 stderr=stderr.append,
488 universal_newlines=un)
489 self.assertEquals(c('A\nBB\nCCC\n'), ''.join(stdout))
490 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
491 self._check_res(res, None, None, 0)
492 self._run_test(fn)
493
494 def test_tee_stdin(self):
495 def fn(c, e, un):
[email protected]bc3a53c2011-12-05 23:38:19496 # Mix of stdin input and stdout callback.
[email protected]94c712f2011-12-01 15:04:57497 stdout = []
498 stdin = '0123456789'
499 res = subprocess2.communicate(
[email protected]bc3a53c2011-12-05 23:38:19500 e + ['--stdout', '--read'],
501 stdin=stdin,
502 stdout=stdout.append,
[email protected]94c712f2011-12-01 15:04:57503 universal_newlines=un)
504 self.assertEquals(c('A\nBB\nCCC\n'), ''.join(stdout))
[email protected]bc3a53c2011-12-05 23:38:19505 self._check_res(res, None, None, 10)
[email protected]94c712f2011-12-01 15:04:57506 self._run_test(fn)
507
508 def test_tee_throw(self):
509 def fn(c, e, un):
[email protected]bc3a53c2011-12-05 23:38:19510 # Make sure failure still returns stderr completely.
[email protected]94c712f2011-12-01 15:04:57511 stderr = []
512 try:
513 subprocess2.check_output(
[email protected]bc3a53c2011-12-05 23:38:19514 e + ['--stderr', '--fail'],
515 stderr=stderr.append,
[email protected]94c712f2011-12-01 15:04:57516 universal_newlines=un)
517 self.fail()
[email protected]0e023172012-01-10 18:06:45518 except subprocess2.CalledProcessError, exception:
519 self._check_exception(exception, '', None, 64)
[email protected]94c712f2011-12-01 15:04:57520 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
521 self._run_test(fn)
522
523 def test_tee_timeout_stdout_void(self):
524 def fn(c, e, un):
525 stderr = []
526 res = subprocess2.communicate(
527 e + ['--stdout', '--stderr', '--fail'],
528 stdout=VOID,
529 stderr=stderr.append,
530 shell=False,
531 timeout=10,
532 universal_newlines=un)
533 self._check_res(res, None, None, 64)
534 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
535 self._run_test(fn)
536
537 def test_tee_timeout_stderr_void(self):
538 def fn(c, e, un):
539 stdout = []
540 res = subprocess2.communicate(
541 e + ['--stdout', '--stderr', '--fail'],
542 stdout=stdout.append,
543 stderr=VOID,
544 shell=False,
545 timeout=10,
546 universal_newlines=un)
547 self._check_res(res, None, None, 64)
548 self.assertEquals(c('A\nBB\nCCC\n'), ''.join(stdout))
549 self._run_test(fn)
550
551 def test_tee_timeout_stderr_stdout(self):
552 def fn(c, e, un):
553 stdout = []
554 res = subprocess2.communicate(
555 e + ['--stdout', '--stderr', '--fail'],
556 stdout=stdout.append,
557 stderr=STDOUT,
558 shell=False,
559 timeout=10,
560 universal_newlines=un)
561 self._check_res(res, None, None, 64)
562 # Ordering is random due to buffering.
563 self.assertEquals(
564 set(c('a\nbb\nccc\nA\nBB\nCCC\n').splitlines(True)),
565 set(''.join(stdout).splitlines(True)))
566 self._run_test(fn)
567
568 def test_tee_large(self):
569 stdout = []
570 # Read 128kb. On my workstation it takes >2s. Welcome to 2011.
571 res = subprocess2.communicate(self.exe + ['--large'], stdout=stdout.append)
572 self.assertEquals(128*1024, len(''.join(stdout)))
573 self._check_res(res, None, None, 0)
574
575 def test_tee_large_stdin(self):
576 stdout = []
577 # Write 128kb.
578 stdin = '0123456789abcdef' * (8*1024)
579 res = subprocess2.communicate(
580 self.exe + ['--large', '--read'], stdin=stdin, stdout=stdout.append)
581 self.assertEquals(128*1024, len(''.join(stdout)))
[email protected]97170132013-05-08 14:58:34582 # Windows return code is > 8 bits.
583 returncode = len(stdin) if sys.platform == 'win32' else 0
584 self._check_res(res, None, None, returncode)
[email protected]94c712f2011-12-01 15:04:57585
586 def test_tee_cb_throw(self):
587 # Having a callback throwing up should not cause side-effects. It's a bit
588 # hard to measure.
589 class Blow(Exception):
590 pass
591 def blow(_):
592 raise Blow()
593 proc = subprocess2.Popen(self.exe + ['--stdout'], stdout=blow)
594 try:
595 proc.communicate()
596 self.fail()
597 except Blow:
598 self.assertNotEquals(0, proc.returncode)
599
[email protected]e0558e62013-05-02 02:48:51600 def test_nag_timer(self):
601 w = []
602 l = logging.getLogger()
603 class _Filter(logging.Filter):
604 def filter(self, record):
605 if record.levelno == logging.WARNING:
606 w.append(record.getMessage().lstrip())
607 return 0
608 f = _Filter()
609 l.addFilter(f)
610 proc = subprocess2.Popen(
611 self.exe + ['--stdout', '--sleep_first'], stdout=PIPE)
612 res = proc.communicate(nag_timer=3), proc.returncode
613 l.removeFilter(f)
614 self._check_res(res, 'A\nBB\nCCC\n', None, 0)
615 expected = ['No output for 3 seconds from command:', proc.cmd_str,
616 'No output for 6 seconds from command:', proc.cmd_str,
617 'No output for 9 seconds from command:', proc.cmd_str]
618 self.assertEquals(w, expected)
[email protected]eba40222011-04-05 14:52:48619
[email protected]e0558e62013-05-02 02:48:51620
[email protected]eba40222011-04-05 14:52:48621def child_main(args):
[email protected]4942e4a2011-11-15 15:50:50622 if sys.platform == 'win32':
623 # Annoying, make sure the output is not translated on Windows.
624 # pylint: disable=E1101,F0401
625 import msvcrt
626 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
627 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
628
[email protected]eba40222011-04-05 14:52:48629 parser = optparse.OptionParser()
630 parser.add_option(
631 '--fail',
632 dest='return_value',
633 action='store_const',
634 default=0,
635 const=64)
[email protected]4942e4a2011-11-15 15:50:50636 parser.add_option(
637 '--crlf', action='store_const', const='\r\n', dest='eol', default='\n')
638 parser.add_option(
639 '--cr', action='store_const', const='\r', dest='eol')
[email protected]eba40222011-04-05 14:52:48640 parser.add_option('--stdout', action='store_true')
641 parser.add_option('--stderr', action='store_true')
[email protected]4942e4a2011-11-15 15:50:50642 parser.add_option('--sleep_first', action='store_true')
643 parser.add_option('--sleep_last', action='store_true')
644 parser.add_option('--large', action='store_true')
645 parser.add_option('--read', action='store_true')
[email protected]eba40222011-04-05 14:52:48646 options, args = parser.parse_args(args)
647 if args:
648 parser.error('Internal error')
[email protected]4942e4a2011-11-15 15:50:50649 if options.sleep_first:
650 time.sleep(10)
[email protected]eba40222011-04-05 14:52:48651
652 def do(string):
653 if options.stdout:
[email protected]4942e4a2011-11-15 15:50:50654 sys.stdout.write(string.upper())
655 sys.stdout.write(options.eol)
[email protected]eba40222011-04-05 14:52:48656 if options.stderr:
[email protected]4942e4a2011-11-15 15:50:50657 sys.stderr.write(string.lower())
658 sys.stderr.write(options.eol)
[email protected]eba40222011-04-05 14:52:48659
660 do('A')
661 do('BB')
662 do('CCC')
[email protected]4942e4a2011-11-15 15:50:50663 if options.large:
664 # Print 128kb.
665 string = '0123456789abcdef' * (8*1024)
666 sys.stdout.write(string)
667 if options.read:
[email protected]bc3a53c2011-12-05 23:38:19668 assert options.return_value is 0
[email protected]4942e4a2011-11-15 15:50:50669 try:
[email protected]bc3a53c2011-12-05 23:38:19670 while sys.stdin.read(1):
671 options.return_value += 1
[email protected]4942e4a2011-11-15 15:50:50672 except OSError:
673 pass
674 if options.sleep_last:
[email protected]f2dca4e2011-11-09 19:24:48675 time.sleep(10)
[email protected]eba40222011-04-05 14:52:48676 return options.return_value
677
678
679if __name__ == '__main__':
[email protected]4942e4a2011-11-15 15:50:50680 logging.basicConfig(level=
681 [logging.WARNING, logging.INFO, logging.DEBUG][
682 min(2, sys.argv.count('-v'))])
[email protected]eba40222011-04-05 14:52:48683 if len(sys.argv) > 1 and sys.argv[1] == '--child':
684 sys.exit(child_main(sys.argv[2:]))
685 unittest.main()