Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions jf_agent/git/bitbucket_cloud_adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -514,16 +514,20 @@ def _standardize_pr(
and api_pr['merge_commit']
and api_pr['merge_commit'].get('hash')
):
api_merge_commit = client.get_commit(
repo.project.id, repo_slug, api_pr['merge_commit']['hash']
)
merge_commit = _standardize_commit(
api_merge_commit,
repo,
api_pr['destination']['branch']['name'],
strip_text_content,
redact_names_and_urls,
)
merge_commit_hash = api_pr['merge_commit']['hash']
try:
api_merge_commit = client.get_commit(repo.project.id, repo_slug, merge_commit_hash)
merge_commit = _standardize_commit(
api_merge_commit,
repo,
api_pr['destination']['branch']['name'],
strip_text_content,
redact_names_and_urls,
)
except requests.exceptions.HTTPError as e:
logger.info(
f'For merge commit {merge_commit_hash} received a {e.response.status_code} while retrieving PR commits'
Comment on lines +528 to +529

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a regression test in commit 08c794a: test_get_prs_merge_commit_404_does_not_skip_pr stubs client.get_commit to raise HTTPError(404) and asserts the PR is still returned with merge_commit=None.

)

# Repo links
base_repo = _standardize_short_form_repo(
Expand Down
104 changes: 100 additions & 4 deletions tests/test_bitbucket_cloud_adapter.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import json
import unittest

from dateutil import parser
from unittest import TestCase
from unittest.mock import MagicMock

import requests
from dateutil import parser

from jf_agent.git import StandardizedShortRepository
from jf_agent.git.bitbucket_cloud_adapter import BitbucketCloudAdapter

Expand Down Expand Up @@ -310,7 +311,11 @@ def test_get_prs_merge_commit_uses_destination_repo(self):
'name': 'fork_repo',
'type': 'repository',
'uuid': source_uuid,
'links': {'self': {'href': 'https://api.bitbucket.org/2.0/repositories/some-fork/fork'}},
'links': {
'self': {
'href': 'https://api.bitbucket.org/2.0/repositories/some-fork/fork'
}
},
},
},
'destination': {
Expand All @@ -320,7 +325,11 @@ def test_get_prs_merge_commit_uses_destination_repo(self):
'name': dest_slug,
'type': 'repository',
'uuid': '{cccccccc-0000-0000-0000-dddddddddddd}',
'links': {'self': {'href': f'https://api.bitbucket.org/2.0/repositories/test_project/{dest_slug}'}},
'links': {
'self': {
'href': f'https://api.bitbucket.org/2.0/repositories/test_project/{dest_slug}'
}
},
},
},
'links': {'html': {'href': 'https://bitbucket.org/test_project/pull-requests/99'}},
Expand Down Expand Up @@ -349,6 +358,93 @@ def test_get_prs_merge_commit_uses_destination_repo(self):
'test_project', dest_slug, 'abc123merge'
)

def test_get_prs_merge_commit_404_does_not_skip_pr(self) -> None:
# Regression test for OJ-54730: when Bitbucket Cloud has garbage-collected a PR's
# merge commit, get_commit raises HTTPError(404). The PR must still be returned,
# just with merge_commit left unset.
test_commits = _get_test_data('test_commits.json')
dest_slug = 'destination_repo_slug'

merged_pr = {
'id': 2394,
'title': 'Merged PR with stale merge commit',
'description': '',
'state': 'MERGED',
'merge_commit': {'hash': 'stalemergehash'},
'created_on': '2020-01-01T00:00:00+00:00',
'updated_on': '2020-01-02T00:00:00+00:00',
'author': {
'display_name': 'test_user',
'uuid': '{1cd06601-cd0e-4fce-be03-e9ac226978b7}',
'links': {'html': {'href': 'https://bitbucket.org/test_user/'}},
},
'source': {
'branch': {'name': 'feature'},
'repository': {
'full_name': f'test_project/{dest_slug}',
'name': dest_slug,
'type': 'repository',
'uuid': '{cccccccc-0000-0000-0000-dddddddddddd}',
'links': {
'self': {
'href': f'https://api.bitbucket.org/2.0/repositories/test_project/{dest_slug}'
}
},
},
},
'destination': {
'branch': {'name': 'master'},
'repository': {
'full_name': f'test_project/{dest_slug}',
'name': dest_slug,
'type': 'repository',
'uuid': '{cccccccc-0000-0000-0000-dddddddddddd}',
'links': {
'self': {
'href': f'https://api.bitbucket.org/2.0/repositories/test_project/{dest_slug}'
}
},
},
},
'links': {'html': {'href': 'https://bitbucket.org/test_project/pull-requests/2394'}},
}

mock_standardized_repo = MagicMock()
mock_standardized_repo.id = '{cccccccc-0000-0000-0000-dddddddddddd}'
mock_standardized_repo.full_name = f'test_project/{dest_slug}'
mock_standardized_repo.project.id = 'test_project'
mock_standardized_repos = [mock_standardized_repo]

mock_response = MagicMock()
mock_response.status_code = 404
http_error = requests.exceptions.HTTPError(
'404 Client Error: Not Found', response=mock_response
)

self.mock_client.get_pullrequests.return_value = [merged_pr]
self.mock_client.pr_diff.return_value = ""
self.mock_client.pr_comments.return_value = []
self.mock_client.pr_activity.return_value = []
self.mock_client.pr_commits.return_value = test_commits
self.mock_client.get_commit.side_effect = http_error

test_git_instance_info = {'pull_from': '1900-07-23', 'repos_dict_v2': {}}

resulting_prs = list(
self.adapter.get_pull_requests(mock_standardized_repos, test_git_instance_info)
)

self.assertEqual(
len(resulting_prs), 1, "PR must still be ingested despite 404 on merge commit"
)
resulting_pr = resulting_prs[0]
self.assertEqual(resulting_pr.id, 2394)
self.assertTrue(resulting_pr.is_merged)
self.assertIsNone(
resulting_pr.merge_commit,
"merge_commit should be None when Bitbucket returns 404 for the merge commit hash",
)


def _get_test_data(file_name):
with open(f'{TEST_INPUT_FILE_PATH}{file_name}', 'r') as f:
Expand Down
Loading