diff options
author | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-10 15:17:19 +0000 |
---|---|---|
committer | joi@chromium.org <joi@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-10 15:17:19 +0000 |
commit | 5545985efb8ffde196a5891b873bcd77d45e8a37 (patch) | |
tree | 3399662882a764a90c4fc22badf3d62e2a975925 /PRESUBMIT.py | |
parent | 2d77e523a6418807825268b0b43e5e649a7deb39 (diff) | |
download | chromium_src-5545985efb8ffde196a5891b873bcd77d45e8a37.zip chromium_src-5545985efb8ffde196a5891b873bcd77d45e8a37.tar.gz chromium_src-5545985efb8ffde196a5891b873bcd77d45e8a37.tar.bz2 |
Add check to help prevent test-only function usage in production code.
BUG=none
TEST=Manual testing was performed. Warning message from presubmit test includes note to report issues to joi@chromium.org
Review URL: http://codereview.chromium.org/7582002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96184 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'PRESUBMIT.py')
-rw-r--r-- | PRESUBMIT.py | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/PRESUBMIT.py b/PRESUBMIT.py index b11ed8d..515f3d0 100644 --- a/PRESUBMIT.py +++ b/PRESUBMIT.py @@ -38,6 +38,56 @@ def _CheckNoInterfacesInBase(input_api, output_api): return [] +def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api): + """Attempts to prevent use of functions intended only for testing in + non-testing code. For now this is just a best-effort implementation + that ignores header files and may have some false positives. A + better implementation would probably need a proper C++ parser. + """ + # We only scan .cc files and the like, as the declaration of + # for-testing functions in header files are hard to distinguish from + # calls to such functions without a proper C++ parser. + source_extensions = r'\.(cc|cpp|cxx|mm)$' + file_inclusion_pattern = r'.+%s' % source_extensions + file_exclusion_pattern = (r'.+(_test_support|_(unit|browser|ui|perf)test)%s' % + source_extensions) + + base_function_pattern = r'ForTest(ing)?|for_test(ing)?' + inclusion_pattern = input_api.re.compile(r'(%s)\s*\(' % base_function_pattern) + exclusion_pattern = input_api.re.compile( + r'::[A-Za-z0-9_]+(%s)|(%s)[^;]+\{' % ( + base_function_pattern, base_function_pattern)) + + def FilterFile(affected_file): + black_list = ((file_exclusion_pattern, ) + _EXCLUDED_PATHS + + input_api.DEFAULT_BLACK_LIST) + return input_api.FilterSourceFile( + affected_file, + white_list=(file_inclusion_pattern, ), + black_list=black_list) + + problems = [] + for f in input_api.AffectedSourceFiles(FilterFile): + local_path = f.LocalPath() + lines = input_api.ReadFile(f).splitlines() + line_number = 0 + for line in lines: + if (inclusion_pattern.search(line) and + not exclusion_pattern.search(line)): + problems.append( + '%s:%d\n %s' % (local_path, line_number, line.strip())) + line_number += 1 + + if problems: + return [output_api.PresubmitPromptWarning( + 'You might be calling functions intended only for testing from\n' + 'production code. Please verify that the following usages are OK,\n' + 'and email joi@chromium.org if you are seeing false positives:', + problems)] + else: + return [] + + def _CommonChecks(input_api, output_api): """Checks common to both upload and commit.""" results = [] @@ -45,6 +95,8 @@ def _CommonChecks(input_api, output_api): input_api, output_api, excluded_paths=_EXCLUDED_PATHS)) results.extend(_CheckNoInterfacesInBase(input_api, output_api)) results.extend(_CheckAuthorizedAuthor(input_api, output_api)) + results.extend( + _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api)) return results |