def test_phabricator_clang_tidy(mock_repository, mock_phabricator): ''' Test Phabricator reporter publication on a mock clang-tidy issue ''' from static_analysis_bot.report.phabricator import PhabricatorReporter from static_analysis_bot.revisions import PhabricatorRevision from static_analysis_bot.clang.tidy import ClangTidyIssue def _check_comment(request): # Check the Phabricator main comment is well formed payload = urllib.parse.parse_qs(request.body) assert payload['output'] == ['json'] assert len(payload['params']) == 1 details = json.loads(payload['params'][0]) assert details == { 'revision_id': 51, 'message': VALID_CLANG_TIDY_MESSAGE, 'attach_inlines': 1, '__conduit__': {'token': 'deadbeef'}, } # Outputs dummy empty response resp = { 'error_code': None, 'result': None, } return 201, {'Content-Type': 'application/json', 'unittest': 'clang-tidy'}, json.dumps(resp) responses.add_callback( responses.POST, 'http://phabricator.test/api/differential.createcomment', callback=_check_comment, ) with mock_phabricator as api: revision = PhabricatorRevision('PHID-DIFF-abcdef', api) revision.lines = { # Add dummy lines diff 'test.cpp': [41, 42, 43], } reporter = PhabricatorReporter({'analyzers': ['clang-tidy']}, api=api) issue_parts = ('test.cpp', '42', '51', 'error', 'dummy message', 'modernize-use-nullptr') issue = ClangTidyIssue(issue_parts, revision) assert issue.is_publishable() issues, patches = reporter.publish([issue, ], revision) assert len(issues) == 1 assert len(patches) == 0 # Check the callback has been used assert len(responses.calls) > 0 call = responses.calls[-1] assert call.request.url == 'http://phabricator.test/api/differential.createcomment' assert call.response.headers.get('unittest') == 'clang-tidy'
def test_phabricator_clang_tidy(mock_repository, mock_phabricator): ''' Test Phabricator reporter publication on a mock clang-tidy issue ''' from static_analysis_bot.report.phabricator import PhabricatorReporter from static_analysis_bot.revisions import PhabricatorRevision from static_analysis_bot.clang.tidy import ClangTidyIssue def _check_comment(request): # Check the Phabricator main comment is well formed payload = urllib.parse.parse_qs(request.body) assert payload['output'] == ['json'] assert len(payload['params']) == 1 details = json.loads(payload['params'][0]) assert details == { 'revision_id': 51, 'message': VALID_CLANG_TIDY_MESSAGE, 'attach_inlines': 1, '__conduit__': {'token': 'deadbeef'}, } # Outputs dummy empty response resp = { 'error_code': None, 'result': None, } return 201, {'Content-Type': 'application/json', 'unittest': 'clang-tidy'}, json.dumps(resp) responses.add_callback( responses.POST, 'http://phabricator.test/api/differential.createcomment', callback=_check_comment, ) with mock_phabricator as api: revision = PhabricatorRevision(api, 'PHID-DIFF-abcdef') revision.lines = { # Add dummy lines diff 'test.cpp': [41, 42, 43], } reporter = PhabricatorReporter({'analyzers': ['clang-tidy'], 'modes': ('comment')}, api=api) issue = ClangTidyIssue(revision, 'test.cpp', '42', '51', 'modernize-use-nullptr', 'dummy message', 'error') assert issue.is_publishable() issues, patches = reporter.publish([issue, ], revision) assert len(issues) == 1 assert len(patches) == 0 # Check the callback has been used assert len(responses.calls) > 0 call = responses.calls[-1] assert call.request.url == 'http://phabricator.test/api/differential.createcomment' assert call.response.headers.get('unittest') == 'clang-tidy'
def test_phabricator_harbormaster(mock_repository, mock_phabricator): ''' Test Phabricator reporter publication on a mock clang-tidy issue using harbormaster ''' from static_analysis_bot.report.phabricator import PhabricatorReporter from static_analysis_bot.revisions import PhabricatorRevision from static_analysis_bot.clang.tidy import ClangTidyIssue def _check_message(request): # Check the Phabricator main comment is well formed payload = urllib.parse.parse_qs(request.body) assert payload['output'] == ['json'] assert len(payload['params']) == 1 details = json.loads(payload['params'][0]) assert details == { 'buildTargetPHID': 'PHID-HMBD-deadbeef12456', 'lint': [ { 'char': 51, 'code': 'clang-tidy.modernize-use-nullptr', 'name': 'Clang-Tidy - modernize-use-nullptr', 'line': 42, 'path': 'test.cpp', 'severity': 'warning', 'description': 'dummy message' } ], 'unit': [], 'type': 'work', '__conduit__': {'token': 'deadbeef'}, } # Outputs dummy empty response resp = { 'error_code': None, 'result': None, } return 201, {'Content-Type': 'application/json', 'unittest': 'clang-tidy'}, json.dumps(resp) responses.add_callback( responses.POST, 'http://phabricator.test/api/harbormaster.sendmessage', callback=_check_message, ) with mock_phabricator as api: revision = PhabricatorRevision(api, 'PHID-DIFF-abcdef') revision.lines = { # Add dummy lines diff 'test.cpp': [41, 42, 43], } revision.build_target_phid = 'PHID-HMBD-deadbeef12456' reporter = PhabricatorReporter({'analyzers': ['clang-tidy'], 'mode': 'harbormaster'}, api=api) issue = ClangTidyIssue(revision, 'test.cpp', '42', '51', 'modernize-use-nullptr', 'dummy message', 'error') assert issue.is_publishable() issues, patches = reporter.publish([issue, ], revision) assert len(issues) == 1 assert len(patches) == 0 # Check the callback has been used assert len(responses.calls) > 0 call = responses.calls[-1] assert call.request.url == 'http://phabricator.test/api/harbormaster.sendmessage' assert call.response.headers.get('unittest') == 'clang-tidy'
def test_comment(mock_mozreview, test_cpp, mock_revision): ''' Test comment creation for specific issues ''' from static_analysis_bot.clang.tidy import ClangTidyIssue from static_analysis_bot.clang.format import ClangFormatIssue from static_analysis_bot.lint import MozLintIssue from static_analysis_bot.report.base import Reporter # Init dummy reporter class TestReporter(Reporter): def __init__(self): pass reporter = TestReporter() # Build clang tidy fake issue, while forcing publication status header = ('test.cpp', 1, 1, 'error', 'Dummy message', 'test-check') clang_tidy_publishable = ClangTidyIssue(header, mock_revision) clang_tidy_publishable.is_publishable = lambda: True assert clang_tidy_publishable.is_publishable() issues = [ clang_tidy_publishable, ] assert reporter.build_comment(issues, 'https://report.example.com') == ''' Code analysis found 1 defect in this patch: - 1 defect found by clang-tidy You can run this analysis locally with: - `./mach static-analysis check path/to/file.cpp` (C/C++) If you see a problem in this automated review, please report it here: https://report.example.com ''' # Now add a clang-format issue clang_format_publishable = ClangFormatIssue('test.cpp', '', '', ('delete', 1, 2, 3, 4), mock_revision) clang_format_publishable.is_publishable = lambda: True assert clang_tidy_publishable.is_publishable() issues.append(clang_format_publishable) assert reporter.build_comment(issues, 'https://report.example.com') == ''' Code analysis found 2 defects in this patch: - 1 defect found by clang-format - 1 defect found by clang-tidy You can run this analysis locally with: - `./mach clang-format -p path/to/file.cpp` (C/C++) - `./mach static-analysis check path/to/file.cpp` (C/C++) If you see a problem in this automated review, please report it here: https://report.example.com ''' # Now add a mozlint issue mozlint_publishable = MozLintIssue('test.cpp', 1, 'error', 1, 'test', 'Dummy test', 'dummy rule', mock_revision) mozlint_publishable.is_publishable = lambda: True assert mozlint_publishable.is_publishable() issues.append(mozlint_publishable) assert reporter.build_comment(issues, 'https://report.example.com') == '''
def test_phabricator_harbormaster(mock_repository, mock_phabricator): ''' Test Phabricator reporter publication on a mock clang-tidy issue using harbormaster ''' from static_analysis_bot.report.phabricator import PhabricatorReporter from static_analysis_bot.revisions import PhabricatorRevision from static_analysis_bot.clang.tidy import ClangTidyIssue def _check_message(request): # Check the Phabricator main comment is well formed payload = urllib.parse.parse_qs(request.body) assert payload['output'] == ['json'] assert len(payload['params']) == 1 details = json.loads(payload['params'][0]) assert details == { 'buildTargetPHID': 'PHID-HMBD-deadbeef12456', 'lint': [{ 'char': 51, 'code': 'clang-tidy.modernize-use-nullptr', 'name': 'Clang-Tidy - modernize-use-nullptr', 'line': 42, 'path': 'test.cpp', 'severity': 'warning', 'description': 'dummy message' }], 'unit': [], 'type': 'work', '__conduit__': { 'token': 'deadbeef' }, } # Outputs dummy empty response resp = { 'error_code': None, 'result': None, } return 201, { 'Content-Type': 'application/json', 'unittest': 'clang-tidy' }, json.dumps(resp) responses.add_callback( responses.POST, 'http://phabricator.test/api/harbormaster.sendmessage', callback=_check_message, ) with mock_phabricator as api: revision = PhabricatorRevision(api, 'PHID-DIFF-abcdef') revision.lines = { # Add dummy lines diff 'test.cpp': [41, 42, 43], } revision.build_target_phid = 'PHID-HMBD-deadbeef12456' reporter = PhabricatorReporter( { 'analyzers': ['clang-tidy'], 'mode': 'harbormaster' }, api=api) issue = ClangTidyIssue(revision, 'test.cpp', '42', '51', 'modernize-use-nullptr', 'dummy message', 'error') assert issue.is_publishable() issues, patches = reporter.publish([ issue, ], revision) assert len(issues) == 1 assert len(patches) == 0 # Check the callback has been used assert len(responses.calls) > 0 call = responses.calls[-1] assert call.request.url == 'http://phabricator.test/api/harbormaster.sendmessage' assert call.response.headers.get('unittest') == 'clang-tidy'