Commit 85557a08 authored by Marco Georgaklis's avatar Marco Georgaklis Committed by LUCI CQ

Implemented suppport for getrelatedchanges endpoint in gerrit module


The endpoint documentation can be found here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#get-related-changes

This involved adding support for the command in gerrit_client and
gerrit_util and then incorporating functionality and testing into
the gerrit recipe module.

The reasoning for this is to be able to identify chained builds for
improved accuracy of the new test identification for the FLake
Endorser project.

Bug:1204163
Change-Id: Ic60c733540a9afd7ff159408b0ea9ad7aac078e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/2928016
Commit-Queue: Marco Georgaklis <mgeorgaklis@google.com>
Reviewed-by: 's avatarJosip Sokcevic <sokcevic@google.com>
parent c8f63d39
......@@ -153,6 +153,22 @@ def CMDchanges(parser, args):
write_result(result, opt)
@subcommand.usage('[args ...]')
def CMDrelatedchanges(parser, args):
parser.add_option('-c', '--change', type=str, help='change id')
parser.add_option('-r', '--revision', type=str, help='revision id')
(opt, args) = parser.parse_args(args)
result = gerrit_util.GetRelatedChanges(
urlparse.urlparse(opt.host).netloc,
change=opt.change,
revision=opt.revision,
)
logging.info(result)
write_result(result, opt)
@subcommand.usage('[args ...]')
def CMDcreatechange(parser, args):
parser.add_option('-s', '--subject', help='subject for change')
......
......@@ -703,6 +703,12 @@ def GetChangeRobotComments(host, change):
return ReadHttpJsonResponse(CreateHttpConn(host, path))
def GetRelatedChanges(host, change, revision='current'):
"""Gets the related changes for a given change and revision."""
path = 'changes/%s/revisions/%s/related' % (change, revision)
return ReadHttpJsonResponse(CreateHttpConn(host, path))
def AbandonChange(host, change, msg=''):
"""Abandons a Gerrit change."""
path = 'changes/%s/abandon' % change
......
......@@ -361,7 +361,7 @@ Module for interact with Gerrit endpoints
Wrapper for easy calling of gerrit_utils steps.
&mdash; **def [abandon\_change](/recipes/recipe_modules/gerrit/api.py#173)(self, host, change, message=None, name=None, step_test_data=None):**
&mdash; **def [abandon\_change](/recipes/recipe_modules/gerrit/api.py#209)(self, host, change, message=None, name=None, step_test_data=None):**
&mdash; **def [create\_gerrit\_branch](/recipes/recipe_modules/gerrit/api.py#32)(self, host, project, branch, commit, \*\*kwargs):**
......@@ -408,6 +408,25 @@ Gets a branch from given project and commit
Returns:
The revision of the branch
&mdash; **def [get\_related\_changes](/recipes/recipe_modules/gerrit/api.py#173)(self, host, change, revision='current', step_test_data=None):**
Queries related changes for a given host, change, and revision.
Args:
* host: URL of Gerrit host to query.
* change: The change-id of the change to get related changes for as
documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
* revision: The revision-id of the revision to get related changes for as
documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#revision-id
This defaults to current, which names the most recent patch set.
* step_test_data: Optional mock test data for the underlying gerrit client.
Returns:
A related changes dictionary as documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#related-changes-info
&mdash; **def [get\_revision\_info](/recipes/recipe_modules/gerrit/api.py#90)(self, host, change, patchset, timeout=None, step_test_data=None):**
Returns the info for a given patchset of a given change.
......@@ -421,7 +440,7 @@ Returns:
A dict for the target revision as documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#list-changes
&mdash; **def [move\_changes](/recipes/recipe_modules/gerrit/api.py#193)(self, host, project, from_branch, to_branch, step_test_data=None):**
&mdash; **def [move\_changes](/recipes/recipe_modules/gerrit/api.py#229)(self, host, project, from_branch, to_branch, step_test_data=None):**
### *recipe_modules* / [git](/recipes/recipe_modules/git)
[DEPS](/recipes/recipe_modules/git/__init__.py#1): [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/runtime][recipe_engine/recipe_modules/runtime], [recipe\_engine/step][recipe_engine/recipe_modules/step]
......
......@@ -170,6 +170,42 @@ class GerritApi(recipe_api.RecipeApi):
**kwargs
).json.output
def get_related_changes(self, host, change, revision='current', step_test_data=None):
"""Queries related changes for a given host, change, and revision.
Args:
* host: URL of Gerrit host to query.
* change: The change-id of the change to get related changes for as
documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#change-id
* revision: The revision-id of the revision to get related changes for as
documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#revision-id
This defaults to current, which names the most recent patch set.
* step_test_data: Optional mock test data for the underlying gerrit client.
Returns:
A related changes dictionary as documented here:
https://gerrit-review.googlesource.com/Documentation/rest-api-changes.html#related-changes-info
"""
args = [
'relatedchanges',
'--host',
host,
'--change',
change,
'--revision',
revision,
'--json_file',
self.m.json.output(),
]
if not step_test_data:
step_test_data = lambda: self.test_api.get_related_changes_response_data()
return self('relatedchanges', args,
step_test_data=step_test_data).json.output
def abandon_change(self, host, change, message=None, name=None,
step_test_data=None):
args = [
......
......@@ -156,6 +156,57 @@
"@@@STEP_LOG_END@json.output@@@"
]
},
{
"cmd": [
"vpython",
"-u",
"RECIPE_REPO[depot_tools]/gerrit_client.py",
"relatedchanges",
"--host",
"https://chromium-review.googlesource.com",
"--change",
"58478",
"--revision",
"2",
"--json_file",
"/path/to/tmp/json"
],
"env": {
"PATH": "<PATH>:RECIPE_REPO[depot_tools]"
},
"infra_step": true,
"name": "gerrit relatedchanges",
"~followup_annotations": [
"@@@STEP_LOG_LINE@json.output@{@@@",
"@@@STEP_LOG_LINE@json.output@ \"changes\": [@@@",
"@@@STEP_LOG_LINE@json.output@ {@@@",
"@@@STEP_LOG_LINE@json.output@ \"_change_number\": 58478, @@@",
"@@@STEP_LOG_LINE@json.output@ \"_current_revision_number\": 2, @@@",
"@@@STEP_LOG_LINE@json.output@ \"_revision_number\": 2, @@@",
"@@@STEP_LOG_LINE@json.output@ \"change_id\": \"Ic62ae3103fca2214904dbf2faf4c861b5f0ae9b5\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"commit\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"author\": {@@@",
"@@@STEP_LOG_LINE@json.output@ \"date\": \"2014-07-12 15:04:24.000000000\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"email\": \"example@example.com\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"name\": \"Example Name\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"tz\": 120@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"commit\": \"78847477532e386f5a2185a4e8c90b2509e354e3\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"parents\": [@@@",
"@@@STEP_LOG_LINE@json.output@ {@@@",
"@@@STEP_LOG_LINE@json.output@ \"commit\": \"bb499510bbcdbc9164d96b0dbabb4aa45f59a87e\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ ], @@@",
"@@@STEP_LOG_LINE@json.output@ \"subject\": \"Remove Solr\"@@@",
"@@@STEP_LOG_LINE@json.output@ }, @@@",
"@@@STEP_LOG_LINE@json.output@ \"project\": \"gerrit\", @@@",
"@@@STEP_LOG_LINE@json.output@ \"status\": \"NEW\"@@@",
"@@@STEP_LOG_LINE@json.output@ }@@@",
"@@@STEP_LOG_LINE@json.output@ ]@@@",
"@@@STEP_LOG_LINE@json.output@}@@@",
"@@@STEP_LOG_END@json.output@@@"
]
},
{
"cmd": [
"vpython",
......
......@@ -34,6 +34,10 @@ def RunSteps(api):
start=1,
limit=1,
)
related_changes = api.gerrit.get_related_changes(host,
change='58478',
revision='2')
assert len(related_changes["changes"]) == 1
# Query which returns no changes is still successful query.
empty_list = api.gerrit.get_changes(
......@@ -69,5 +73,7 @@ def GenTests(api):
api.gerrit.make_gerrit_get_branch_response_data()) +
api.step_data('gerrit move changes',
api.gerrit.get_move_change_response_data(branch='main')) +
api.step_data('gerrit relatedchanges',
api.gerrit.get_related_changes_response_data()) +
api.step_data('gerrit changes empty query',
api.gerrit.get_empty_changes_response_data()))
......@@ -32,6 +32,34 @@ class GerritTestApi(recipe_test_api.RecipeTestApi):
data.update(kwargs)
return data
@staticmethod
def _related_changes_data(**kwargs):
data = {
"changes": [{
"project": "gerrit",
"change_id": "Ic62ae3103fca2214904dbf2faf4c861b5f0ae9b5",
"commit": {
"commit": "78847477532e386f5a2185a4e8c90b2509e354e3",
"parents": [{
"commit": "bb499510bbcdbc9164d96b0dbabb4aa45f59a87e"
}],
"author": {
"name": "Example Name",
"email": "example@example.com",
"date": "2014-07-12 15:04:24.000000000",
"tz": 120
},
"subject": "Remove Solr"
},
"_change_number": 58478,
"_revision_number": 2,
"_current_revision_number": 2,
"status": "NEW"
}]
}
data.update(kwargs)
return data
def _make_gerrit_response_json(self, data):
return self.m.json.output(data)
......@@ -56,3 +84,6 @@ class GerritTestApi(recipe_test_api.RecipeTestApi):
def get_move_change_response_data(self, **kwargs):
return self._make_gerrit_response_json([self._gerrit_change_data(**kwargs)])
def get_related_changes_response_data(self, **kwargs):
return self._make_gerrit_response_json(self._related_changes_data(**kwargs))
......@@ -56,6 +56,16 @@ class TestGerritClient(unittest.TestCase):
start=20,
o_params=['op1', 'op2'])
@mock.patch('gerrit_util.GetRelatedChanges', return_value='')
def test_relatedchanges(self, util_mock):
gerrit_client.main([
'relatedchanges', '--host', 'https://example.org/foo', '--change',
'foo-change-id', '--revision', 'foo-revision-id'
])
util_mock.assert_called_once_with('example.org',
change='foo-change-id',
revision='foo-revision-id')
@mock.patch('gerrit_util.CreateChange', return_value={})
def test_createchange(self, util_mock):
gerrit_client.main([
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment