def test_mail(mock_config, mock_issues, mock_phabricator): ''' Test mail sending through Taskcluster ''' from static_analysis_bot.report.mail import MailReporter from static_analysis_bot.revisions import PhabricatorRevision, ImprovementPatch def _check_email(request): payload = json.loads(request.body) assert payload['subject'] in ( '[test] New Static Analysis Phabricator #42 - PHID-DIFF-test', ) assert payload['address'] == '*****@*****.**' assert payload['template'] == 'fullscreen' assert payload['content'] == MAIL_CONTENT.format( results=mock_config.taskcluster.results_dir) return (200, {}, '') # ack # Add mock taskcluster email to check output responses.add_callback( responses.POST, 'https://notify.taskcluster.net/v1/email', callback=_check_email, ) # Publish email conf = { 'emails': [ '*****@*****.**', ], } r = MailReporter(conf, 'test_tc', 'token_tc') with mock_phabricator as api: prev = PhabricatorRevision(api, 'PHID-DIFF-test') prev.improvement_patches = [ ImprovementPatch('clang-tidy', repr(prev), 'Some code fixes'), ImprovementPatch('clang-format', repr(prev), 'Some lint fixes'), ] list(map(lambda p: p.write(), prev.improvement_patches)) # trigger local write r.publish(mock_issues, prev) # Check stats mock_cls = mock_issues[0].__class__ assert r.calc_stats(mock_issues) == { mock_cls: { 'total': 5, 'publishable': 3, 'publishable_paths': ['/path/to/file'] } }
def _test_reporter(api, analyzers): # Always use the same setup, only varies the analyzers revision = Revision(api, mock_try_task) revision.lines = { 'test.cpp': [0, 41, 42, 43], 'dom/test.cpp': [ 42, ], } reporter = PhabricatorReporter({'analyzers': analyzers}, api=api) issues = [ ClangFormatIssue('dom/test.cpp', 42, 1, revision), ClangTidyIssue(revision, 'test.cpp', '42', '51', 'modernize-use-nullptr', 'dummy message', 'error'), InferIssue( { 'file': 'test.cpp', 'line': 42, 'column': 1, 'bug_type': 'dummy', 'kind': 'whatever', 'qualifier': 'dummy message.', }, revision), MozLintIssue('test.cpp', 1, 'danger', 42, 'flake8', 'Python error', 'EXXX', revision), CoverageIssue('test.cpp', 0, 'This file is uncovered', revision), ] assert all(i.is_publishable() for i in issues) revision.improvement_patches = [ ImprovementPatch('dummy', repr(revision), 'Whatever'), ImprovementPatch('clang-tidy', repr(revision), 'Some C fixes'), ImprovementPatch('clang-format', repr(revision), 'Some lint fixes'), ImprovementPatch('infer', repr(revision), 'Some java fixes'), ImprovementPatch('mozlint', repr(revision), 'Some js fixes'), ] list(map(lambda p: p.write(), revision.improvement_patches)) # trigger local write return reporter.publish(issues, revision)
def test_phabricator_clang_format(mock_config, mock_phabricator): ''' Test Phabricator reporter publication on a mock clang-format issue ''' from static_analysis_bot.report.phabricator import PhabricatorReporter from static_analysis_bot.revisions import PhabricatorRevision, ImprovementPatch from static_analysis_bot.tasks.clang_format import ClangFormatIssue 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['message'] == VALID_CLANG_FORMAT_MESSAGE.format(results=mock_config.taskcluster.results_dir) # Outputs dummy empty response resp = { 'error_code': None, 'result': None, } return 201, {'Content-Type': 'application/json', 'unittest': 'clang-format'}, 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], 'dom/test.cpp': [42, ], } reporter = PhabricatorReporter({'analyzers': ['clang-format']}, api=api) issue = ClangFormatIssue('dom/test.cpp', 42, 1, revision) assert issue.is_publishable() revision.improvement_patches = [ ImprovementPatch('clang-format', repr(revision), 'Some lint fixes'), ] list(map(lambda p: p.write(), revision.improvement_patches)) # trigger local write issues, patches = reporter.publish([issue, ], revision) assert len(issues) == 1 assert len(patches) == 1 # 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-format'