blob: 62034adf5c233b9bb3612ebc342aba8dbb78def0 [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:
16 import fcntl
17except 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
81 def communicate(input=None, timeout=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']
332 p1 = subprocess.Popen(cmd, stderr=subprocess.PIPE)
333 p2 = subprocess2.Popen(cmd, stderr=subprocess.PIPE)
334 r1 = p1.communicate()
335 r2 = p2.communicate(timeout=100)
336 self.assertEquals(r1, r2)
337
[email protected]db59bfc2011-11-30 14:03:14338
339class S2Test(BaseTestCase):
340 # Tests that can only run in subprocess2, e.g. new functionalities.
341 # In particular, subprocess2.communicate() doesn't exist in subprocess.
[email protected]4942e4a2011-11-15 15:50:50342 def _run_test(self, function):
343 """Runs tests in 6 combinations:
344 - LF output with universal_newlines=False
345 - CR output with universal_newlines=False
346 - CRLF output with universal_newlines=False
347 - LF output with universal_newlines=True
348 - CR output with universal_newlines=True
349 - CRLF output with universal_newlines=True
350
351 First |function| argument is the convertion for the origianl expected LF
352 string to the right EOL.
353 Second |function| argument is the executable and initial flag to run, to
354 control what EOL is used by the child process.
355 Third |function| argument is universal_newlines value.
356 """
357 noop = lambda x: x
358 function(noop, self.exe, False)
359 function(convert_to_cr, self.exe + ['--cr'], False)
360 function(convert_to_crlf, self.exe + ['--crlf'], False)
361 function(noop, self.exe, True)
362 function(noop, self.exe + ['--cr'], True)
363 function(noop, self.exe + ['--crlf'], True)
364
[email protected]94c712f2011-12-01 15:04:57365 def _check_exception(self, e, stdout, stderr, returncode):
366 """On exception, look if the exception members are set correctly."""
367 self.assertEquals(returncode, e.returncode)
368 self.assertEquals(stdout, e.stdout)
369 self.assertEquals(stderr, e.stderr)
[email protected]a8e81632011-12-01 00:35:24370
[email protected]f2dca4e2011-11-09 19:24:48371 def test_timeout(self):
[email protected]db59bfc2011-11-30 14:03:14372 # timeout doesn't exist in subprocess.
373 def fn(c, e, un):
[email protected]a8e81632011-12-01 00:35:24374 res = subprocess2.communicate(
[email protected]db59bfc2011-11-30 14:03:14375 self.exe + ['--sleep_first', '--stdout'],
376 timeout=0.01,
[email protected]a8e81632011-12-01 00:35:24377 stdout=PIPE,
[email protected]db59bfc2011-11-30 14:03:14378 shell=False)
[email protected]a8e81632011-12-01 00:35:24379 self._check_res(res, '', None, TIMED_OUT)
380 self._run_test(fn)
381
382 def test_timeout_shell_throws(self):
383 def fn(c, e, un):
384 try:
385 # With shell=True, it needs a string.
386 subprocess2.communicate(' '.join(self.exe), timeout=0.01, shell=True)
387 self.fail()
388 except TypeError:
389 pass
[email protected]db59bfc2011-11-30 14:03:14390 self._run_test(fn)
[email protected]87e6d332011-09-09 19:01:28391
[email protected]bc3a53c2011-12-05 23:38:19392 def test_stdin(self):
393 def fn(c, e, un):
394 stdin = '0123456789'
395 res = subprocess2.communicate(
396 e + ['--read'],
397 stdin=stdin,
398 universal_newlines=un)
399 self._check_res(res, None, None, 10)
400 self._run_test(fn)
401
402 def test_stdin_unicode(self):
403 def fn(c, e, un):
404 stdin = u'0123456789'
405 res = subprocess2.communicate(
406 e + ['--read'],
407 stdin=stdin,
408 universal_newlines=un)
409 self._check_res(res, None, None, 10)
410 self._run_test(fn)
411
[email protected]740a6c02011-12-05 23:46:44412 def test_stdin_empty(self):
413 def fn(c, e, un):
414 stdin = ''
415 res = subprocess2.communicate(
416 e + ['--read'],
417 stdin=stdin,
418 universal_newlines=un)
419 self._check_res(res, None, None, 0)
420 self._run_test(fn)
421
[email protected]bc3a53c2011-12-05 23:38:19422 def test_stdin_void(self):
423 res = subprocess2.communicate(self.exe + ['--read'], stdin=VOID)
424 self._check_res(res, None, None, 0)
425
426 def test_stdin_void_stdout_timeout(self):
427 # Make sure a mix of VOID, PIPE and timeout works.
428 def fn(c, e, un):
429 res = subprocess2.communicate(
430 e + ['--stdout', '--read'],
431 stdin=VOID,
432 stdout=PIPE,
433 timeout=10,
434 universal_newlines=un)
435 self._check_res(res, c('A\nBB\nCCC\n'), None, 0)
436 self._run_test(fn)
437
[email protected]87e6d332011-09-09 19:01:28438 def test_stdout_void(self):
[email protected]4942e4a2011-11-15 15:50:50439 def fn(c, e, un):
[email protected]a8e81632011-12-01 00:35:24440 res = subprocess2.communicate(
[email protected]4942e4a2011-11-15 15:50:50441 e + ['--stdout', '--stderr'],
[email protected]a8e81632011-12-01 00:35:24442 stdout=VOID,
443 stderr=PIPE,
[email protected]4942e4a2011-11-15 15:50:50444 universal_newlines=un)
[email protected]a8e81632011-12-01 00:35:24445 self._check_res(res, None, c('a\nbb\nccc\n'), 0)
[email protected]4942e4a2011-11-15 15:50:50446 self._run_test(fn)
[email protected]87e6d332011-09-09 19:01:28447
448 def test_stderr_void(self):
[email protected]4942e4a2011-11-15 15:50:50449 def fn(c, e, un):
[email protected]a8e81632011-12-01 00:35:24450 res = subprocess2.communicate(
[email protected]4942e4a2011-11-15 15:50:50451 e + ['--stdout', '--stderr'],
[email protected]a8e81632011-12-01 00:35:24452 stdout=PIPE,
453 stderr=VOID,
[email protected]4942e4a2011-11-15 15:50:50454 universal_newlines=un)
[email protected]a8e81632011-12-01 00:35:24455 self._check_res(res, c('A\nBB\nCCC\n'), None, 0)
456 self._run_test(fn)
457
458 def test_stdout_void_stderr_redirect(self):
459 def fn(c, e, un):
460 res = subprocess2.communicate(
461 e + ['--stdout', '--stderr'],
462 stdout=VOID,
463 stderr=STDOUT,
464 universal_newlines=un)
465 self._check_res(res, None, None, 0)
[email protected]4942e4a2011-11-15 15:50:50466 self._run_test(fn)
[email protected]eba40222011-04-05 14:52:48467
[email protected]94c712f2011-12-01 15:04:57468 def test_tee_stderr(self):
[email protected]93e21372011-11-24 15:57:19469 def fn(c, e, un):
[email protected]94c712f2011-12-01 15:04:57470 stderr = []
[email protected]a8e81632011-12-01 00:35:24471 res = subprocess2.communicate(
[email protected]94c712f2011-12-01 15:04:57472 e + ['--stderr'], stderr=stderr.append, universal_newlines=un)
473 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
[email protected]a8e81632011-12-01 00:35:24474 self._check_res(res, None, None, 0)
[email protected]93e21372011-11-24 15:57:19475 self._run_test(fn)
476
[email protected]94c712f2011-12-01 15:04:57477 def test_tee_stdout_stderr(self):
478 def fn(c, e, un):
479 stdout = []
480 stderr = []
481 res = subprocess2.communicate(
482 e + ['--stdout', '--stderr'],
483 stdout=stdout.append,
484 stderr=stderr.append,
485 universal_newlines=un)
486 self.assertEquals(c('A\nBB\nCCC\n'), ''.join(stdout))
487 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
488 self._check_res(res, None, None, 0)
489 self._run_test(fn)
490
491 def test_tee_stdin(self):
492 def fn(c, e, un):
[email protected]bc3a53c2011-12-05 23:38:19493 # Mix of stdin input and stdout callback.
[email protected]94c712f2011-12-01 15:04:57494 stdout = []
495 stdin = '0123456789'
496 res = subprocess2.communicate(
[email protected]bc3a53c2011-12-05 23:38:19497 e + ['--stdout', '--read'],
498 stdin=stdin,
499 stdout=stdout.append,
[email protected]94c712f2011-12-01 15:04:57500 universal_newlines=un)
501 self.assertEquals(c('A\nBB\nCCC\n'), ''.join(stdout))
[email protected]bc3a53c2011-12-05 23:38:19502 self._check_res(res, None, None, 10)
[email protected]94c712f2011-12-01 15:04:57503 self._run_test(fn)
504
505 def test_tee_throw(self):
506 def fn(c, e, un):
[email protected]bc3a53c2011-12-05 23:38:19507 # Make sure failure still returns stderr completely.
[email protected]94c712f2011-12-01 15:04:57508 stderr = []
509 try:
510 subprocess2.check_output(
[email protected]bc3a53c2011-12-05 23:38:19511 e + ['--stderr', '--fail'],
512 stderr=stderr.append,
[email protected]94c712f2011-12-01 15:04:57513 universal_newlines=un)
514 self.fail()
[email protected]0e023172012-01-10 18:06:45515 except subprocess2.CalledProcessError, exception:
516 self._check_exception(exception, '', None, 64)
[email protected]94c712f2011-12-01 15:04:57517 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
518 self._run_test(fn)
519
520 def test_tee_timeout_stdout_void(self):
521 def fn(c, e, un):
522 stderr = []
523 res = subprocess2.communicate(
524 e + ['--stdout', '--stderr', '--fail'],
525 stdout=VOID,
526 stderr=stderr.append,
527 shell=False,
528 timeout=10,
529 universal_newlines=un)
530 self._check_res(res, None, None, 64)
531 self.assertEquals(c('a\nbb\nccc\n'), ''.join(stderr))
532 self._run_test(fn)
533
534 def test_tee_timeout_stderr_void(self):
535 def fn(c, e, un):
536 stdout = []
537 res = subprocess2.communicate(
538 e + ['--stdout', '--stderr', '--fail'],
539 stdout=stdout.append,
540 stderr=VOID,
541 shell=False,
542 timeout=10,
543 universal_newlines=un)
544 self._check_res(res, None, None, 64)
545 self.assertEquals(c('A\nBB\nCCC\n'), ''.join(stdout))
546 self._run_test(fn)
547
548 def test_tee_timeout_stderr_stdout(self):
549 def fn(c, e, un):
550 stdout = []
551 res = subprocess2.communicate(
552 e + ['--stdout', '--stderr', '--fail'],
553 stdout=stdout.append,
554 stderr=STDOUT,
555 shell=False,
556 timeout=10,
557 universal_newlines=un)
558 self._check_res(res, None, None, 64)
559 # Ordering is random due to buffering.
560 self.assertEquals(
561 set(c('a\nbb\nccc\nA\nBB\nCCC\n').splitlines(True)),
562 set(''.join(stdout).splitlines(True)))
563 self._run_test(fn)
564
565 def test_tee_large(self):
566 stdout = []
567 # Read 128kb. On my workstation it takes >2s. Welcome to 2011.
568 res = subprocess2.communicate(self.exe + ['--large'], stdout=stdout.append)
569 self.assertEquals(128*1024, len(''.join(stdout)))
570 self._check_res(res, None, None, 0)
571
572 def test_tee_large_stdin(self):
573 stdout = []
574 # Write 128kb.
575 stdin = '0123456789abcdef' * (8*1024)
576 res = subprocess2.communicate(
577 self.exe + ['--large', '--read'], stdin=stdin, stdout=stdout.append)
578 self.assertEquals(128*1024, len(''.join(stdout)))
579 self._check_res(res, None, None, 0)
580
581 def test_tee_cb_throw(self):
582 # Having a callback throwing up should not cause side-effects. It's a bit
583 # hard to measure.
584 class Blow(Exception):
585 pass
586 def blow(_):
587 raise Blow()
588 proc = subprocess2.Popen(self.exe + ['--stdout'], stdout=blow)
589 try:
590 proc.communicate()
591 self.fail()
592 except Blow:
593 self.assertNotEquals(0, proc.returncode)
594
[email protected]e0558e62013-05-02 02:48:51595 def test_nag_timer(self):
596 w = []
597 l = logging.getLogger()
598 class _Filter(logging.Filter):
599 def filter(self, record):
600 if record.levelno == logging.WARNING:
601 w.append(record.getMessage().lstrip())
602 return 0
603 f = _Filter()
604 l.addFilter(f)
605 proc = subprocess2.Popen(
606 self.exe + ['--stdout', '--sleep_first'], stdout=PIPE)
607 res = proc.communicate(nag_timer=3), proc.returncode
608 l.removeFilter(f)
609 self._check_res(res, 'A\nBB\nCCC\n', None, 0)
610 expected = ['No output for 3 seconds from command:', proc.cmd_str,
611 'No output for 6 seconds from command:', proc.cmd_str,
612 'No output for 9 seconds from command:', proc.cmd_str]
613 self.assertEquals(w, expected)
[email protected]eba40222011-04-05 14:52:48614
[email protected]e0558e62013-05-02 02:48:51615
[email protected]eba40222011-04-05 14:52:48616def child_main(args):
[email protected]4942e4a2011-11-15 15:50:50617 if sys.platform == 'win32':
618 # Annoying, make sure the output is not translated on Windows.
619 # pylint: disable=E1101,F0401
620 import msvcrt
621 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
622 msvcrt.setmode(sys.stderr.fileno(), os.O_BINARY)
623
[email protected]eba40222011-04-05 14:52:48624 parser = optparse.OptionParser()
625 parser.add_option(
626 '--fail',
627 dest='return_value',
628 action='store_const',
629 default=0,
630 const=64)
[email protected]4942e4a2011-11-15 15:50:50631 parser.add_option(
632 '--crlf', action='store_const', const='\r\n', dest='eol', default='\n')
633 parser.add_option(
634 '--cr', action='store_const', const='\r', dest='eol')
[email protected]eba40222011-04-05 14:52:48635 parser.add_option('--stdout', action='store_true')
636 parser.add_option('--stderr', action='store_true')
[email protected]4942e4a2011-11-15 15:50:50637 parser.add_option('--sleep_first', action='store_true')
638 parser.add_option('--sleep_last', action='store_true')
639 parser.add_option('--large', action='store_true')
640 parser.add_option('--read', action='store_true')
[email protected]eba40222011-04-05 14:52:48641 options, args = parser.parse_args(args)
642 if args:
643 parser.error('Internal error')
[email protected]4942e4a2011-11-15 15:50:50644 if options.sleep_first:
645 time.sleep(10)
[email protected]eba40222011-04-05 14:52:48646
647 def do(string):
648 if options.stdout:
[email protected]4942e4a2011-11-15 15:50:50649 sys.stdout.write(string.upper())
650 sys.stdout.write(options.eol)
[email protected]eba40222011-04-05 14:52:48651 if options.stderr:
[email protected]4942e4a2011-11-15 15:50:50652 sys.stderr.write(string.lower())
653 sys.stderr.write(options.eol)
[email protected]eba40222011-04-05 14:52:48654
655 do('A')
656 do('BB')
657 do('CCC')
[email protected]4942e4a2011-11-15 15:50:50658 if options.large:
659 # Print 128kb.
660 string = '0123456789abcdef' * (8*1024)
661 sys.stdout.write(string)
662 if options.read:
[email protected]bc3a53c2011-12-05 23:38:19663 assert options.return_value is 0
[email protected]4942e4a2011-11-15 15:50:50664 try:
[email protected]bc3a53c2011-12-05 23:38:19665 while sys.stdin.read(1):
666 options.return_value += 1
[email protected]4942e4a2011-11-15 15:50:50667 except OSError:
668 pass
669 if options.sleep_last:
[email protected]f2dca4e2011-11-09 19:24:48670 time.sleep(10)
[email protected]eba40222011-04-05 14:52:48671 return options.return_value
672
673
674if __name__ == '__main__':
[email protected]4942e4a2011-11-15 15:50:50675 logging.basicConfig(level=
676 [logging.WARNING, logging.INFO, logging.DEBUG][
677 min(2, sys.argv.count('-v'))])
[email protected]eba40222011-04-05 14:52:48678 if len(sys.argv) > 1 and sys.argv[1] == '--child':
679 sys.exit(child_main(sys.argv[2:]))
680 unittest.main()