def test_pr_for_chromium_commit_falls_back_to_commit_position(self): self.wpt_github.all_pull_requests = lambda: [ PullRequest('PR1', 1, 'body\nChange-Id: I00c0ffee\nCr-Commit-Position: refs/heads/master@{#10}', 'open', []), PullRequest('PR2', 2, 'body\nChange-Id: I00decade\nCr-Commit-Position: refs/heads/master@{#33}', 'open', []), ] chromium_commit = MockChromiumCommit( MockHost(), position='refs/heads/master@{#10}') pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit) self.assertEqual(pull_request.number, 1)
def test_pr_for_chromium_commit_change_id_only(self): self.wpt_github.all_pull_requests = lambda: [ PullRequest('PR1', 1, 'body\nChange-Id: I00c0ffee', 'open', []), PullRequest('PR2', 2, 'body\nChange-Id: I00decade', 'open', []), ] chromium_commit = MockChromiumCommit( MockHost(), change_id='I00decade', position='refs/heads/master@{#10}') pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit) self.assertEqual(pull_request.number, 2)
def test_commit_that_has_open_pr_is_exportable(self): commit = MockChromiumCommit(MockHost(), change_id='I00decade') github = MockWPTGitHub(pull_requests=[ PullRequest('PR2', 2, 'body\nChange-Id: I00decade', 'open', []), ]) self.assertEqual(get_commit_export_state(commit, MockLocalWPT(test_patch=[(True, '')]), github), (CommitExportState.EXPORTABLE_CLEAN, ''))
def test_gerrit_cl_no_update_if_pr_with_same_revision(self): test_exporter = TestExporter(self.host) test_exporter.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest(title='title1', number=1234, body='description\nWPT-Export-Revision: 1', state='open', labels=[]), ]) test_exporter.get_exportable_commits = lambda: ([], []) test_exporter.gerrit = MockGerritAPI() test_exporter.gerrit.exportable_open_cls = [MockGerritCL( data={ 'change_id': '1', 'subject': 'subject', '_number': 1, 'current_revision': '1', 'has_review_started': True, 'revisions': { '1': {'commit_with_footers': 'a commit with footers'} }, 'owner': {'email': '*****@*****.**'}, }, api=test_exporter.gerrit, chromium_commit=MockChromiumCommit(self.host) )] success = test_exporter.main(['--credentials-json', '/tmp/credentials.json']) self.assertTrue(success) self.assertEqual(test_exporter.wpt_github.calls, [ 'pr_with_change_id', ]) self.assertEqual(test_exporter.wpt_github.pull_requests_created, []) self.assertEqual(test_exporter.wpt_github.pull_requests_merged, [])
def test_main_successful_close_abandoned_cl(self): pr_cleanup = PrCleanupTool(self.host) pr_cleanup.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest(title='title1', number=1234, body='Change-Id: 88', state='open', labels=[]), ]) pr_cleanup.gerrit = MockGerritAPI() pr_cleanup.gerrit.cl = MockGerritCL(data={ 'change_id': 'I001', 'subject': 'subject', '_number': 1234, 'status': 'ABANDONED', 'current_revision': '1', 'has_review_started': True, 'revisions': { '1': { 'commit_with_footers': 'a commit with footers' } }, 'owner': { 'email': '*****@*****.**' }, }, api=pr_cleanup.gerrit) pr_cleanup.main(['--credentials-json', '/tmp/credentials.json']) self.assertEqual(pr_cleanup.gerrit.cls_queried, ['88']) self.assertEqual(pr_cleanup.wpt_github.calls, [ 'all_pull_requests', 'add_comment "Close this PR because the Chromium CL has been abandoned."', 'update_pr', 'get_pr_branch', 'delete_remote_branch' ])
def test_merges_non_provisional_pr(self): test_exporter = TestExporter(self.host) test_exporter.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest( title='title1', number=1234, body='description\nWPT-Export-Revision: 9\nChange-Id: decafbad', state='open', labels=['']), ]) test_exporter.get_exportable_commits = lambda: ([ MockChromiumCommit(self.host, change_id='decafbad'), ], []) test_exporter.gerrit = MockGerritAPI() success = test_exporter.main( ['--credentials-json', '/tmp/credentials.json']) self.assertTrue(success) self.assertEqual(test_exporter.wpt_github.calls, [ 'pr_for_chromium_commit', 'get_pr_branch', 'merge_pr', ]) self.assertEqual(test_exporter.wpt_github.pull_requests_created, []) self.assertEqual(test_exporter.wpt_github.pull_requests_merged, [1234])
def test_query_cl_raise_exception(self): pr_cleanup = PrCleanupTool(self.host) pr_cleanup.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest( title='title1', number=1234, body='Change-Id: 88', state='open', labels=[]), ]) pr_cleanup.gerrit = MockGerritAPI(raise_error=True) pr_cleanup.gerrit.cl = MockGerritCL( data={ 'change_id': 'I001', 'subject': 'subject', '_number': 1234, 'status': 'ABANDONED', 'current_revision': '1', 'has_review_started': True, 'revisions': { '1': { 'commit_with_footers': 'a commit with footers' } }, 'owner': { 'email': '*****@*****.**' }, }, api=pr_cleanup.gerrit) pr_cleanup.main(['--credentials-json', '/tmp/credentials.json']) self.assertEqual(pr_cleanup.gerrit.cls_queried, ['88']) self.assertEqual(pr_cleanup.wpt_github.calls, ['all_pull_requests'])
def test_commit_that_has_merged_pr_and_found_locally(self): commit = MockChromiumCommit(MockHost(), change_id='I00decade') github = MockWPTGitHub(pull_requests=[ PullRequest('PR2', 2, 'body\nChange-Id: I00decade', 'closed', []), ], merged_index=0) self.assertEqual(get_commit_export_state(commit, MockLocalWPT(change_ids=['I00decade']), github, verify_merged_pr=False), (CommitExportState.EXPORTED, '')) self.assertEqual(get_commit_export_state(commit, MockLocalWPT(change_ids=['I00decade']), github, verify_merged_pr=True), (CommitExportState.EXPORTED, ''))
def test_commit_that_has_closed_but_not_merged_pr(self): commit = MockChromiumCommit(MockHost(), change_id='I00decade') github = MockWPTGitHub(pull_requests=[ PullRequest('PR2', 2, 'body\nChange-Id: I00decade', 'closed', []), ]) # Regardless of verify_merged_pr, abandoned PRs are always exported. self.assertEqual(get_commit_export_state(commit, MockLocalWPT(), github, verify_merged_pr=False), (CommitExportState.EXPORTED, '')) self.assertEqual(get_commit_export_state(commit, MockLocalWPT(), github, verify_merged_pr=True), (CommitExportState.EXPORTED, ''))
def test_commit_that_has_merged_pr_but_not_found_locally(self): commit = MockChromiumCommit(MockHost(), change_id='I00decade') github = MockWPTGitHub(pull_requests=[ PullRequest('PR2', 2, 'body\nChange-Id: I00decade', 'closed', []), ], merged_index=0) # verify_merged_pr should be False by default. self.assertEqual(get_commit_export_state(commit, MockLocalWPT(), github), (CommitExportState.EXPORTED, '')) self.assertEqual(get_commit_export_state(commit, MockLocalWPT(test_patch=[(True, '')]), github, verify_merged_pr=True), (CommitExportState.EXPORTABLE_CLEAN, ''))
def test_pr_for_chromium_commit_multiple_commit_positions(self): self.wpt_github.all_pull_requests = lambda: [ PullRequest('PR1', 1, 'body\nCr-Commit-Position: refs/heads/master@{#10}\n' 'Cr-Commit-Position: refs/heads/master@{#33}', 'open', []), ] chromium_commit = MockChromiumCommit( MockHost(), position='refs/heads/master@{#10}') pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit) self.assertEqual(pull_request.number, 1) chromium_commit = MockChromiumCommit( MockHost(), position='refs/heads/master@{#33}') pull_request = self.wpt_github.pr_for_chromium_commit(chromium_commit) self.assertEqual(pull_request.number, 1)
def test_get_taskcluster_statuses_success(self): self.notifier.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest(title='title1', number=1234, body='description\nWPT-Export-Revision: 1', state='open', labels=[]), ]) status = [{"description": "foo"}] self.notifier.wpt_github.status = status actual = self.notifier.get_taskcluster_statuses(123) self.assertEqual(actual, status) self.assertEqual(self.notifier.wpt_github.calls, [ 'get_pr_branch', 'get_branch_statuses', ])
def test_dry_run_stops_before_creating_pr(self): test_exporter = TestExporter(self.host) test_exporter.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest( title='title1', number=1234, body='', state='open', labels=[]), ]) test_exporter.gerrit = MockGerritAPI() test_exporter.gerrit.exportable_open_cls = [ MockGerritCL(data={ 'change_id': 'I001', 'subject': 'subject', '_number': 1234, 'current_revision': '1', 'has_review_started': True, 'revisions': { '1': { 'commit_with_footers': 'a commit with footers' } }, 'owner': { 'email': '*****@*****.**' }, }, api=test_exporter.gerrit, chromium_commit=MockChromiumCommit(self.host, subject='subject', body='fake body', change_id='I001')) ] test_exporter.get_exportable_commits = lambda: ([ MockChromiumCommit(self.host, position='refs/heads/master@{#458475}'), MockChromiumCommit(self.host, position='refs/heads/master@{#458476}'), ], []) success = test_exporter.main( ['--credentials-json', '/tmp/credentials.json', '--dry-run']) self.assertTrue(success) self.assertEqual(test_exporter.wpt_github.calls, [ 'pr_with_change_id', 'pr_for_chromium_commit', 'pr_for_chromium_commit', ]) self.assertEqual(len(test_exporter.gerrit.request_posted), 0)
def test_dry_run_stops_before_creating_pr(self): test_exporter = TestExporter(self.host) test_exporter.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest(title='title1', number=1234, body='', state='open', labels=[]), ]) test_exporter.gerrit = MockGerritAPI() test_exporter.get_exportable_commits = lambda: ([ MockChromiumCommit(self.host, position='refs/heads/master@{#458475}'), MockChromiumCommit(self.host, position='refs/heads/master@{#458476}'), MockChromiumCommit(self.host, position='refs/heads/master@{#458477}'), ], []) success = test_exporter.main(['--credentials-json', '/tmp/credentials.json', '--dry-run']) self.assertTrue(success) self.assertEqual(test_exporter.wpt_github.calls, [ 'pr_for_chromium_commit', 'pr_for_chromium_commit', 'pr_for_chromium_commit', ])
def test_main_successful_close_no_exportable_changes(self): pr_cleanup = PrCleanupTool(self.host) pr_cleanup.wpt_github = MockWPTGitHub(pull_requests=[ PullRequest( title='title1', number=1234, body='Change-Id: 99', state='open', labels=[]), ]) pr_cleanup.gerrit = MockGerritAPI() pr_cleanup.gerrit.cl = MockGerritCL( data={ 'change_id': 'I001', 'subject': 'subject', '_number': 1234, 'status': 'MERGED', 'current_revision': '1', 'has_review_started': True, 'revisions': { '1': { 'commit_with_footers': 'a commit with footers', 'files': { RELATIVE_WEB_TESTS + 'foo/bar.html': '', } } }, 'owner': { 'email': '*****@*****.**' }, }, api=pr_cleanup.gerrit) pr_cleanup.main(['--credentials-json', '/tmp/credentials.json']) self.assertEqual(pr_cleanup.gerrit.cls_queried, ['99']) self.assertEqual(pr_cleanup.wpt_github.calls, [ 'all_pull_requests', 'add_comment "Close this PR because the Chromium' ' CL does not have exportable changes."', 'update_pr', 'get_pr_branch', 'delete_remote_branch' ])
def test_export_notifier_success(self): self.notifier.wpt_github = MockWPTGitHub(pull_requests=[]) self.notifier.wpt_github.recent_failing_pull_requests = [ PullRequest( title='title1', number=1234, body= 'description\nWPT-Export-Revision: hash\nChange-Id: decafbad', state='open', labels=['']) ] self.notifier.wpt_github.check_runs = [ { "id": "123", "conclusion": "failure", "name": "wpt-chrome-dev-stability" }, { "id": "456", "conclusion": "success", "name": "firefox" }, ] checks_results_comment = ('\nwpt-chrome-dev-stability (' 'https://github.com/web-platform-tests/wpt' '/pull/1234/checks?check_run_id=123)') self.notifier.dry_run = False self.notifier.gerrit = MockGerritAPI() self.notifier.gerrit.cl = MockGerritCL(data={ 'change_id': 'decafbad', 'messages': [ { "date": "2019-08-20 17:42:05.000000000", "message": "Uploaded patch set 1.\nInitial upload", "_revision_number": 1 }, { "date": "2019-08-21 17:41:05.000000000", "message": self.generate_notifier_comment(1234, 'notbar', 'notnum', 3), "_revision_number": 2 }, ], 'revisions': { 'hash': { '_number': 2 } } }, api=self.notifier.gerrit) expected = self.generate_notifier_comment(1234, checks_results_comment, 'hash', 2) exit_code = self.notifier.main() self.assertFalse(exit_code) self.assertEqual(self.notifier.wpt_github.calls, [ 'recent_failing_chromium_exports', 'get_pr_branch', 'get_branch_check_runs', ]) self.assertEqual(self.notifier.gerrit.cls_queried, ['decafbad']) self.assertEqual(self.notifier.gerrit.request_posted, [('/a/changes/decafbad/revisions/current/review', { 'message': expected })])
def test_export_notifier_success(self): self.notifier.wpt_github = MockWPTGitHub(pull_requests=[]) self.notifier.wpt_github.recent_failing_pull_requests = [ PullRequest( title='title1', number=1234, body= 'description\nWPT-Export-Revision: hash\nChange-Id: decafbad', state='open', labels=['']) ] status = [{ "state": "failure", "context": "Community-TC (pull_request)", "node_id": "foo", "target_url": "bar" }] self.notifier.wpt_github.status = status self.notifier.dry_run = False self.notifier.gerrit = MockGerritAPI() self.notifier.gerrit.cl = MockGerritCL(data={ 'change_id': 'decafbad', 'messages': [ { "date": "2019-08-20 17:42:05.000000000", "message": "Uploaded patch set 1.\nInitial upload", "_revision_number": 1 }, { "date": "2019-08-21 17:41:05.000000000", "message": ('The exported PR for the current patch failed Taskcluster check(s) ' 'on GitHub, which could indict cross-broswer failures on the ' 'exportable changes. Please contact ecosystem-infra@ team for ' 'more information.\n\n' 'Taskcluster Link: notbar\n' 'Gerrit CL SHA: notnum\n' 'Patchset Number: 3'), "_revision_number": 2 }, ], 'revisions': { 'hash': { '_number': 2 } } }, api=self.notifier.gerrit) expected = ( 'The exported PR for the current patch failed Taskcluster check(s) ' 'on GitHub, which could indict cross-broswer failures on the ' 'exportable changes. Please contact ecosystem-infra@ team for ' 'more information.\n\n' 'Taskcluster Link: bar\n' 'Gerrit CL SHA: hash\n' 'Patchset Number: 2') exit_code = self.notifier.main() self.assertFalse(exit_code) self.assertEqual(self.notifier.wpt_github.calls, [ 'recent_failing_chromium_exports', 'get_pr_branch', 'get_branch_statuses', ]) self.assertEqual(self.notifier.gerrit.cls_queried, ['decafbad']) self.assertEqual(self.notifier.gerrit.request_posted, [('/a/changes/decafbad/revisions/current/review', { 'message': expected })])
def test_export_notifier_success(self): self.notifier.wpt_github = MockWPTGitHub(pull_requests=[]) self.notifier.wpt_github.recent_failing_pull_requests = [ PullRequest( title='title1', number=1234, body= 'description\nWPT-Export-Revision: hash\nChange-Id: decafbad', state='open', labels=['']) ] status = [{ "state": "failure", "context": "Community-TC (pull_request)", "node_id": "foo", "target_url": "bar" }] self.notifier.wpt_github.status = status self.notifier.dry_run = False self.notifier.gerrit = MockGerritAPI() self.notifier.gerrit.cl = MockGerritCL(data={ 'change_id': 'decafbad', 'messages': [ { "date": "2019-08-20 17:42:05.000000000", "message": "Uploaded patch set 1.\nInitial upload", "_revision_number": 1 }, { "date": "2019-08-21 17:41:05.000000000", "message": self.generate_notifier_comment(1234, 'notbar', 'notnum', 3), "_revision_number": 2 }, ], 'revisions': { 'hash': { '_number': 2 } } }, api=self.notifier.gerrit) expected = self.generate_notifier_comment(1234, 'bar', 'hash', 2) exit_code = self.notifier.main() self.assertFalse(exit_code) self.assertEqual(self.notifier.wpt_github.calls, [ 'recent_failing_chromium_exports', 'get_pr_branch', 'get_branch_statuses', ]) self.assertEqual(self.notifier.gerrit.cls_queried, ['decafbad']) self.assertEqual(self.notifier.gerrit.request_posted, [('/a/changes/decafbad/revisions/current/review', { 'message': expected })])
def test_creates_and_merges_pull_requests(self): # This tests 4 exportable commits: # 1. #458475 has a provisional in-flight PR associated with it. The PR needs to be updated but not merged. # 2. #458476 has no PR associated with it and should have one created. # 3. #458477 has a closed PR associated with it and should be skipped. # 4. #458478 has an in-flight PR associated with it and should be merged successfully. # 5. #458479 has an in-flight PR associated with it but can not be merged. test_exporter = TestExporter(self.host) test_exporter.wpt_github = MockWPTGitHub( pull_requests=[ PullRequest( title='Open PR', number=1234, body= 'rutabaga\nCr-Commit-Position: refs/heads/master@{#458475}\nChange-Id: I0005', state='open', labels=['do not merge yet']), PullRequest( title='Merged PR', number=2345, body= 'rutabaga\nCr-Commit-Position: refs/heads/master@{#458477}\nChange-Id: Idead', state='closed', labels=[]), PullRequest( title='Open PR', number=3456, body= 'rutabaga\nCr-Commit-Position: refs/heads/master@{#458478}\nChange-Id: I0118', state='open', labels=[] # It's important that this is empty. ), PullRequest( title='Open PR', number=4747, body= 'rutabaga\nCr-Commit-Position: refs/heads/master@{#458479}\nChange-Id: I0147', state='open', labels=[] # It's important that this is empty. ), ], unsuccessful_merge_index=3) # Mark the last PR as unmergable. test_exporter.gerrit = MockGerritAPI() test_exporter.get_exportable_commits = lambda: ([ MockChromiumCommit(self.host, position='refs/heads/master@{#458475}', change_id='I0005'), MockChromiumCommit(self.host, position='refs/heads/master@{#458476}', change_id='I0476'), MockChromiumCommit(self.host, position='refs/heads/master@{#458477}', change_id='Idead'), MockChromiumCommit(self.host, position='refs/heads/master@{#458478}', change_id='I0118'), MockChromiumCommit(self.host, position='refs/heads/master@{#458479}', change_id='I0147'), ], []) success = test_exporter.main( ['--credentials-json', '/tmp/credentials.json']) self.assertTrue(success) self.assertEqual( test_exporter.wpt_github.calls, [ # 1. #458475 'pr_for_chromium_commit', 'get_pr_branch', 'update_pr', 'remove_label "do not merge yet"', # 2. #458476 'pr_for_chromium_commit', 'create_pr', 'add_label "chromium-export"', # 3. #458477 'pr_for_chromium_commit', # 4. #458478 'pr_for_chromium_commit', # Testing the lack of remove_label here. The exporter should not # try to remove the provisional label from PRs it has already # removed it from. 'get_pr_branch', 'merge_pr', # 5. #458479 'pr_for_chromium_commit', 'get_pr_branch', 'merge_pr', ]) self.assertEqual(test_exporter.wpt_github.pull_requests_created, [ ('chromium-export-52c3178508', 'Fake subject', 'Fake body\n\nChange-Id: I0476\n'), ]) self.assertEqual(test_exporter.wpt_github.pull_requests_merged, [3456])