OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Unit tests for subprocess2.py.""" | 6 """Unit tests for subprocess2.py.""" |
7 | 7 |
| 8 import logging |
8 import optparse | 9 import optparse |
9 import os | 10 import os |
10 import sys | 11 import sys |
11 import time | 12 import time |
12 import unittest | 13 import unittest |
13 | 14 |
14 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | 15 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) |
15 sys.path.insert(0, ROOT_DIR) | 16 sys.path.insert(0, ROOT_DIR) |
16 | 17 |
17 import subprocess2 | 18 import subprocess2 |
18 | 19 |
19 # Method could be a function | 20 # Method could be a function |
20 # pylint: disable=R0201 | 21 # pylint: disable=R0201 |
21 | 22 |
| 23 |
| 24 def convert(string): |
| 25 """Converts string to CRLF on Windows.""" |
| 26 if sys.platform == 'win32': |
| 27 return string.replace('\n', '\r\n') |
| 28 return string |
| 29 |
| 30 |
22 class Subprocess2Test(unittest.TestCase): | 31 class Subprocess2Test(unittest.TestCase): |
23 # Can be mocked in a test. | 32 # Can be mocked in a test. |
24 TO_SAVE = { | 33 TO_SAVE = { |
25 subprocess2: [ | 34 subprocess2: [ |
26 'Popen', 'communicate', 'call', 'check_call', 'capture', 'check_output'], | 35 'Popen', 'communicate', 'call', 'check_call', 'capture', 'check_output'], |
27 subprocess2.subprocess: ['Popen'], | 36 subprocess2.subprocess: ['Popen'], |
28 } | 37 } |
29 | 38 |
30 def setUp(self): | 39 def setUp(self): |
31 self.exe_path = __file__ | 40 self.exe_path = __file__ |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
140 self.assertEquals('stdout', subprocess2.check_output(['foo'], a=True)) | 149 self.assertEquals('stdout', subprocess2.check_output(['foo'], a=True)) |
141 expected = { | 150 expected = { |
142 'args': ['foo'], | 151 'args': ['foo'], |
143 'a':True, | 152 'a':True, |
144 'stdin': subprocess2.VOID, | 153 'stdin': subprocess2.VOID, |
145 'stdout': subprocess2.PIPE, | 154 'stdout': subprocess2.PIPE, |
146 } | 155 } |
147 self.assertEquals(expected, results) | 156 self.assertEquals(expected, results) |
148 | 157 |
149 def test_timeout(self): | 158 def test_timeout(self): |
150 # It'd be better to not discard stdout. | |
151 out, returncode = subprocess2.communicate( | 159 out, returncode = subprocess2.communicate( |
152 self.exe + ['--sleep', '--stdout'], | 160 self.exe + ['--sleep', '--stdout'], |
153 timeout=0.01, | 161 timeout=0.01, |
154 stdout=subprocess2.PIPE) | 162 stdout=subprocess2.PIPE, |
| 163 shell=False) |
155 self.assertEquals(subprocess2.TIMED_OUT, returncode) | 164 self.assertEquals(subprocess2.TIMED_OUT, returncode) |
156 self.assertEquals(['', None], out) | 165 self.assertEquals(('', None), out) |
| 166 |
| 167 def test_timeout_shell_throws(self): |
| 168 try: |
| 169 subprocess2.communicate( |
| 170 self.exe + ['--sleep', '--stdout'], |
| 171 timeout=0.01, |
| 172 stdout=subprocess2.PIPE, |
| 173 shell=True) |
| 174 self.fail() |
| 175 except TypeError: |
| 176 pass |
157 | 177 |
158 def test_check_output_no_stdout(self): | 178 def test_check_output_no_stdout(self): |
159 try: | 179 try: |
160 subprocess2.check_output(self.exe, stdout=subprocess2.PIPE) | 180 subprocess2.check_output(self.exe, stdout=subprocess2.PIPE) |
161 self.fail() | 181 self.fail() |
162 except TypeError: | 182 except TypeError: |
163 pass | 183 pass |
164 | 184 |
165 def test_stdout_void(self): | 185 def test_stdout_void(self): |
166 (out, err), code = subprocess2.communicate( | 186 (out, err), code = subprocess2.communicate( |
167 self.exe + ['--stdout', '--stderr'], | 187 self.exe + ['--stdout', '--stderr'], |
168 stdout=subprocess2.VOID, | 188 stdout=subprocess2.VOID, |
169 stderr=subprocess2.PIPE) | 189 stderr=subprocess2.PIPE) |
170 self.assertEquals(None, out) | 190 self.assertEquals(None, out) |
171 expected = 'a\nbb\nccc\n' | 191 self.assertEquals(convert('a\nbb\nccc\n'), err) |
172 if sys.platform == 'win32': | |
173 expected = expected.replace('\n', '\r\n') | |
174 self.assertEquals(expected, err) | |
175 self.assertEquals(0, code) | 192 self.assertEquals(0, code) |
176 | 193 |
177 def test_stderr_void(self): | 194 def test_stderr_void(self): |
178 (out, err), code = subprocess2.communicate( | 195 (out, err), code = subprocess2.communicate( |
179 self.exe + ['--stdout', '--stderr'], | 196 self.exe + ['--stdout', '--stderr'], |
180 universal_newlines=True, | 197 universal_newlines=True, |
181 stdout=subprocess2.PIPE, | 198 stdout=subprocess2.PIPE, |
182 stderr=subprocess2.VOID) | 199 stderr=subprocess2.VOID) |
183 self.assertEquals('A\nBB\nCCC\n', out) | 200 self.assertEquals('A\nBB\nCCC\n', out) |
184 self.assertEquals(None, err) | 201 self.assertEquals(None, err) |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
228 | 245 |
229 def test_check_call_throw(self): | 246 def test_check_call_throw(self): |
230 try: | 247 try: |
231 subprocess2.check_call(self.exe + ['--fail', '--stderr']) | 248 subprocess2.check_call(self.exe + ['--fail', '--stderr']) |
232 self.fail() | 249 self.fail() |
233 except subprocess2.CalledProcessError, e: | 250 except subprocess2.CalledProcessError, e: |
234 self.assertEquals(None, e.stdout) | 251 self.assertEquals(None, e.stdout) |
235 self.assertEquals(None, e.stderr) | 252 self.assertEquals(None, e.stderr) |
236 self.assertEquals(64, e.returncode) | 253 self.assertEquals(64, e.returncode) |
237 | 254 |
| 255 def test_check_output_tee_stderr(self): |
| 256 stderr = [] |
| 257 out, returncode = subprocess2.communicate( |
| 258 self.exe + ['--stderr'], stderr=stderr.append) |
| 259 self.assertEquals(convert('a\nbb\nccc\n'), ''.join(stderr)) |
| 260 self.assertEquals((None, None), out) |
| 261 self.assertEquals(0, returncode) |
| 262 |
| 263 def test_check_output_tee_stdout_stderr(self): |
| 264 stdout = [] |
| 265 stderr = [] |
| 266 out, returncode = subprocess2.communicate( |
| 267 self.exe + ['--stdout', '--stderr'], |
| 268 stdout=stdout.append, |
| 269 stderr=stderr.append) |
| 270 self.assertEquals(convert('A\nBB\nCCC\n'), ''.join(stdout)) |
| 271 self.assertEquals(convert('a\nbb\nccc\n'), ''.join(stderr)) |
| 272 self.assertEquals((None, None), out) |
| 273 self.assertEquals(0, returncode) |
| 274 |
| 275 def test_check_output_tee_stdin(self): |
| 276 stdout = [] |
| 277 stdin = '0123456789' |
| 278 out, returncode = subprocess2.communicate( |
| 279 self.exe + ['--stdout', '--read'], stdin=stdin, stdout=stdout.append) |
| 280 self.assertEquals(convert('A\nBB\nCCC\n'), ''.join(stdout)) |
| 281 self.assertEquals((None, None), out) |
| 282 self.assertEquals(0, returncode) |
| 283 |
| 284 def test_check_output_tee_throw(self): |
| 285 stderr = [] |
| 286 try: |
| 287 subprocess2.check_output( |
| 288 self.exe + ['--stderr', '--fail'], stderr=stderr.append) |
| 289 self.fail() |
| 290 except subprocess2.CalledProcessError, e: |
| 291 self.assertEquals(convert('a\nbb\nccc\n'), ''.join(stderr)) |
| 292 self.assertEquals('', e.stdout) |
| 293 self.assertEquals(None, e.stderr) |
| 294 self.assertEquals(64, e.returncode) |
| 295 |
| 296 def test_check_output_tee_large(self): |
| 297 stdout = [] |
| 298 # Read 128kb. On my workstation it takes >2s. Welcome to 2011. |
| 299 out, returncode = subprocess2.communicate( |
| 300 self.exe + ['--large'], stdout=stdout.append) |
| 301 self.assertEquals(128*1024, len(''.join(stdout))) |
| 302 self.assertEquals((None, None), out) |
| 303 self.assertEquals(0, returncode) |
| 304 |
| 305 def test_check_output_tee_large_stdin(self): |
| 306 stdout = [] |
| 307 # Write 128kb. |
| 308 stdin = '0123456789abcdef' * (8*1024) |
| 309 out, returncode = subprocess2.communicate( |
| 310 self.exe + ['--large', '--read'], stdin=stdin, stdout=stdout.append) |
| 311 self.assertEquals(128*1024, len(''.join(stdout))) |
| 312 self.assertEquals((None, None), out) |
| 313 self.assertEquals(0, returncode) |
| 314 |
238 | 315 |
239 def child_main(args): | 316 def child_main(args): |
240 parser = optparse.OptionParser() | 317 parser = optparse.OptionParser() |
241 parser.add_option( | 318 parser.add_option( |
242 '--fail', | 319 '--fail', |
243 dest='return_value', | 320 dest='return_value', |
244 action='store_const', | 321 action='store_const', |
245 default=0, | 322 default=0, |
246 const=64) | 323 const=64) |
247 parser.add_option('--stdout', action='store_true') | 324 parser.add_option('--stdout', action='store_true') |
248 parser.add_option('--stderr', action='store_true') | 325 parser.add_option('--stderr', action='store_true') |
249 parser.add_option('--sleep', action='store_true') | 326 parser.add_option('--sleep', action='store_true') |
| 327 parser.add_option('--large', action='store_true') |
| 328 parser.add_option('--read', action='store_true') |
250 options, args = parser.parse_args(args) | 329 options, args = parser.parse_args(args) |
251 if args: | 330 if args: |
252 parser.error('Internal error') | 331 parser.error('Internal error') |
| 332 if options.sleep: |
| 333 time.sleep(10) |
253 | 334 |
254 def do(string): | 335 def do(string): |
255 if options.stdout: | 336 if options.stdout: |
256 print >> sys.stdout, string.upper() | 337 print >> sys.stdout, string.upper() |
257 if options.stderr: | 338 if options.stderr: |
258 print >> sys.stderr, string.lower() | 339 print >> sys.stderr, string.lower() |
259 | 340 |
260 do('A') | 341 do('A') |
261 do('BB') | 342 do('BB') |
262 do('CCC') | 343 do('CCC') |
263 if options.sleep: | 344 if options.large: |
264 time.sleep(10) | 345 # Print 128kb. |
| 346 string = '0123456789abcdef' * (8*1024) |
| 347 sys.stdout.write(string) |
| 348 if options.read: |
| 349 try: |
| 350 while sys.stdin.read(): |
| 351 pass |
| 352 except OSError: |
| 353 pass |
265 return options.return_value | 354 return options.return_value |
266 | 355 |
267 | 356 |
268 if __name__ == '__main__': | 357 if __name__ == '__main__': |
| 358 logging.basicConfig(level= |
| 359 [logging.WARNING, logging.INFO, logging.DEBUG][ |
| 360 min(2, sys.argv.count('-v'))]) |
269 if len(sys.argv) > 1 and sys.argv[1] == '--child': | 361 if len(sys.argv) > 1 and sys.argv[1] == '--child': |
270 sys.exit(child_main(sys.argv[2:])) | 362 sys.exit(child_main(sys.argv[2:])) |
271 unittest.main() | 363 unittest.main() |
OLD | NEW |