OLD | NEW |
1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 """Generic presubmit checks that can be reused by other presubmit checks.""" | 5 """Generic presubmit checks that can be reused by other presubmit checks.""" |
6 | 6 |
7 | 7 |
8 ### Description checks | 8 ### Description checks |
9 | 9 |
10 def CheckChangeHasTestField(input_api, output_api): | 10 def CheckChangeHasTestField(input_api, output_api): |
(...skipping 430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 """Runs all unit tests in a directory. | 441 """Runs all unit tests in a directory. |
442 | 442 |
443 On Windows, sys.executable is used for unit tests ending with ".py". | 443 On Windows, sys.executable is used for unit tests ending with ".py". |
444 """ | 444 """ |
445 # We don't want to hinder users from uploading incomplete patches. | 445 # We don't want to hinder users from uploading incomplete patches. |
446 if input_api.is_committing: | 446 if input_api.is_committing: |
447 message_type = output_api.PresubmitError | 447 message_type = output_api.PresubmitError |
448 else: | 448 else: |
449 message_type = output_api.PresubmitPromptWarning | 449 message_type = output_api.PresubmitPromptWarning |
450 | 450 |
451 if verbose: | |
452 pipe = None | |
453 else: | |
454 pipe = input_api.subprocess.PIPE | |
455 | |
456 results = [] | 451 results = [] |
457 for unit_test in unit_tests: | 452 for unit_test in unit_tests: |
458 cmd = [] | 453 cmd = [] |
459 if input_api.platform == 'win32' and unit_test.endswith('.py'): | 454 if input_api.platform == 'win32' and unit_test.endswith('.py'): |
460 # Windows needs some help. | 455 # Windows needs some help. |
461 cmd = [input_api.python_executable] | 456 cmd = [input_api.python_executable] |
462 cmd.append(unit_test) | 457 cmd.append(unit_test) |
463 if verbose: | 458 if verbose: |
464 print('Running %s' % unit_test) | 459 print('Running %s' % unit_test) |
465 try: | 460 try: |
466 proc = input_api.subprocess.Popen( | 461 if verbose: |
467 cmd, cwd=input_api.PresubmitLocalPath(), stdout=pipe, stderr=pipe) | 462 input_api.subprocess.check_call(cmd, cwd=input_api.PresubmitLocalPath()) |
468 out = '\n'.join(filter(None, proc.communicate())) | 463 else: |
469 if proc.returncode: | 464 input_api.subprocess.check_output( |
470 results.append(message_type( | 465 cmd, cwd=input_api.PresubmitLocalPath()) |
471 '%s failed with return code %d\n%s' % ( | 466 except (OSError, input_api.subprocess.CalledProcessError), e: |
472 unit_test, proc.returncode, out))) | 467 results.append(message_type('%s failed!\n%s' % (unit_test, e))) |
473 except (OSError, input_api.subprocess.CalledProcessError): | |
474 results.append(message_type('%s failed' % unit_test)) | |
475 return results | 468 return results |
476 | 469 |
477 | 470 |
478 def RunPythonUnitTests(input_api, output_api, unit_tests): | 471 def RunPythonUnitTests(input_api, output_api, unit_tests): |
479 """Run the unit tests out of process, capture the output and use the result | 472 """Run the unit tests out of process, capture the output and use the result |
480 code to determine success. | 473 code to determine success. |
481 | 474 |
482 DEPRECATED. | 475 DEPRECATED. |
483 """ | 476 """ |
484 # We don't want to hinder users from uploading incomplete patches. | 477 # We don't want to hinder users from uploading incomplete patches. |
485 if input_api.is_committing: | 478 if input_api.is_committing: |
486 message_type = output_api.PresubmitError | 479 message_type = output_api.PresubmitError |
487 else: | 480 else: |
488 message_type = output_api.PresubmitNotifyResult | 481 message_type = output_api.PresubmitNotifyResult |
489 outputs = [] | 482 results = [] |
490 for unit_test in unit_tests: | 483 for unit_test in unit_tests: |
491 # Run the unit tests out of process. This is because some unit tests | 484 # Run the unit tests out of process. This is because some unit tests |
492 # stub out base libraries and don't clean up their mess. It's too easy to | 485 # stub out base libraries and don't clean up their mess. It's too easy to |
493 # get subtle bugs. | 486 # get subtle bugs. |
494 cwd = None | 487 cwd = None |
495 env = None | 488 env = None |
496 unit_test_name = unit_test | 489 unit_test_name = unit_test |
497 # 'python -m test.unit_test' doesn't work. We need to change to the right | 490 # 'python -m test.unit_test' doesn't work. We need to change to the right |
498 # directory instead. | 491 # directory instead. |
499 if '.' in unit_test: | 492 if '.' in unit_test: |
500 # Tests imported in submodules (subdirectories) assume that the current | 493 # Tests imported in submodules (subdirectories) assume that the current |
501 # directory is in the PYTHONPATH. Manually fix that. | 494 # directory is in the PYTHONPATH. Manually fix that. |
502 unit_test = unit_test.replace('.', '/') | 495 unit_test = unit_test.replace('.', '/') |
503 cwd = input_api.os_path.dirname(unit_test) | 496 cwd = input_api.os_path.dirname(unit_test) |
504 unit_test = input_api.os_path.basename(unit_test) | 497 unit_test = input_api.os_path.basename(unit_test) |
505 env = input_api.environ.copy() | 498 env = input_api.environ.copy() |
506 # At least on Windows, it seems '.' must explicitly be in PYTHONPATH | 499 # At least on Windows, it seems '.' must explicitly be in PYTHONPATH |
507 backpath = [ | 500 backpath = [ |
508 '.', input_api.os_path.pathsep.join(['..'] * (cwd.count('/') + 1)) | 501 '.', input_api.os_path.pathsep.join(['..'] * (cwd.count('/') + 1)) |
509 ] | 502 ] |
510 if env.get('PYTHONPATH'): | 503 if env.get('PYTHONPATH'): |
511 backpath.append(env.get('PYTHONPATH')) | 504 backpath.append(env.get('PYTHONPATH')) |
512 env['PYTHONPATH'] = input_api.os_path.pathsep.join((backpath)) | 505 env['PYTHONPATH'] = input_api.os_path.pathsep.join((backpath)) |
513 subproc = input_api.subprocess.Popen( | 506 cmd = [input_api.python_executable, '-m', '%s' % unit_test] |
514 [ | 507 try: |
515 input_api.python_executable, | 508 input_api.subprocess.check_output(cmd, cwd=cwd, env=env) |
516 '-m', | 509 except (OSError, input_api.subprocess.CalledProcessError), e: |
517 '%s' % unit_test | 510 results.append(message_type('%s failed!\n%s' % (unit_test_name, e))) |
518 ], | 511 return results |
519 cwd=cwd, | |
520 env=env, | |
521 stdin=input_api.subprocess.PIPE, | |
522 stdout=input_api.subprocess.PIPE, | |
523 stderr=input_api.subprocess.PIPE) | |
524 stdoutdata, stderrdata = subproc.communicate() | |
525 # Discard the output if returncode == 0 | |
526 if subproc.returncode: | |
527 outputs.append('Test \'%s\' failed with code %d\n%s\n%s\n' % ( | |
528 unit_test_name, subproc.returncode, stdoutdata, stderrdata)) | |
529 if outputs: | |
530 return [message_type('%d unit tests failed.' % len(outputs), | |
531 long_text='\n'.join(outputs))] | |
532 return [] | |
533 | 512 |
534 | 513 |
535 def _FetchAllFiles(input_api, white_list, black_list): | 514 def _FetchAllFiles(input_api, white_list, black_list): |
536 """Hack to fetch all files.""" | 515 """Hack to fetch all files.""" |
537 # We cannot use AffectedFiles here because we want to test every python | 516 # We cannot use AffectedFiles here because we want to test every python |
538 # file on each single python change. It's because a change in a python file | 517 # file on each single python change. It's because a change in a python file |
539 # can break another unmodified file. | 518 # can break another unmodified file. |
540 # Use code similar to InputApi.FilterSourceFile() | 519 # Use code similar to InputApi.FilterSourceFile() |
541 def Find(filepath, filters): | 520 def Find(filepath, filters): |
542 for item in filters: | 521 for item in filters: |
(...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
900 input_api, output_api, source_file_filter=text_files)) | 879 input_api, output_api, source_file_filter=text_files)) |
901 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( | 880 results.extend(input_api.canned_checks.CheckSvnForCommonMimeTypes( |
902 input_api, output_api)) | 881 input_api, output_api)) |
903 results.extend(input_api.canned_checks.CheckLicense( | 882 results.extend(input_api.canned_checks.CheckLicense( |
904 input_api, output_api, license_header, source_file_filter=sources)) | 883 input_api, output_api, license_header, source_file_filter=sources)) |
905 results.extend(_CheckConstNSObject( | 884 results.extend(_CheckConstNSObject( |
906 input_api, output_api, source_file_filter=sources)) | 885 input_api, output_api, source_file_filter=sources)) |
907 results.extend(_CheckSingletonInHeaders( | 886 results.extend(_CheckSingletonInHeaders( |
908 input_api, output_api, source_file_filter=sources)) | 887 input_api, output_api, source_file_filter=sources)) |
909 return results | 888 return results |
OLD | NEW |