diff --git a/contrib/buildbot/server.py b/contrib/buildbot/server.py --- a/contrib/buildbot/server.py +++ b/contrib/buildbot/server.py @@ -254,28 +254,30 @@ def land(): data = get_json_request_data(request) - revision = data['revision'] - if not revision: + revision = data.get('revision', None) + diff = data.get('diff', None) + if not revision and not diff: + return FAILURE, 400 + + commitMessage = data.get('commitMessage', None) + if diff and not commitMessage: return FAILURE, 400 # conduitToken is expected to be encrypted and will be decrypted by the # land bot. - conduitToken = data['conduitToken'] + conduitToken = data.get('conduitToken', None) if not conduitToken: return FAILURE, 400 - committerName = data['committerName'] + committerName = data.get('committerName', None) if not committerName: return FAILURE, 400 - committerEmail = data['committerEmail'] + committerEmail = data.get('committerEmail', None) if not committerEmail: return FAILURE, 400 properties = [{ - 'name': 'env.ABC_REVISION', - 'value': revision, - }, { 'name': 'env.ABC_CONDUIT_TOKEN', 'value': conduitToken, }, { @@ -285,6 +287,22 @@ 'name': 'env.ABC_COMMITTER_EMAIL', 'value': committerEmail, }] + + if revision: + properties += [{ + 'name': 'env.ABC_REVISION', + 'value': revision, + }] + + if diff: + properties += [{ + 'name': 'env.ABC_DIFF', + 'value': diff, + }, { + 'name': 'env.ABC_COMMIT_MESSAGE', + 'value': commitMessage, + }] + output = tc.trigger_build( LANDBOT_BUILD_TYPE, 'master', diff --git a/contrib/buildbot/test/test_endpoint_land.py b/contrib/buildbot/test/test_endpoint_land.py --- a/contrib/buildbot/test/test_endpoint_land.py +++ b/contrib/buildbot/test/test_endpoint_land.py @@ -14,7 +14,7 @@ from testutil import AnyWith -class landRequestData(test.mocks.fixture.MockData): +class landRevisionRequestData(test.mocks.fixture.MockData): def __init__(self): self.revision = 'D1234' self.conduitToken = 'U2FsdGVkX1/RI0AAAAAAAF46wjo3lSAxj1d1iqqkxks=' @@ -22,9 +22,18 @@ self.committerEmail = 'user@bitcoinabc.org' +class landDiffRequestData(test.mocks.fixture.MockData): + def __init__(self): + self.diff = '12345' + self.commitMessage = '[Test] Commit message' + self.conduitToken = 'U2FsdGVkX1/RI0AAAAAAAF46wjo3lSAxj1d1iqqkxks=' + self.committerName = 'User Name' + self.committerEmail = 'user@bitcoinabc.org' + + class EndpointLandTestCase(ABCBotFixture): - def test_land_happyPath(self): - data = landRequestData() + def test_land_revision(self): + data = landRevisionRequestData() triggerBuildResponse = test.mocks.teamcity.buildInfo( test.mocks.teamcity.buildInfo_changes(['test-change'])) self.teamcity.session.send.return_value = triggerBuildResponse @@ -38,9 +47,42 @@ }, 'properties': { 'property': [{ + 'name': 'env.ABC_CONDUIT_TOKEN', + 'value': 'U2FsdGVkX1/RI0AAAAAAAF46wjo3lSAxj1d1iqqkxks=', + }, { + 'name': 'env.ABC_COMMITTER_NAME', + 'value': 'User Name', + }, { + 'name': 'env.ABC_COMMITTER_EMAIL', + 'value': 'user@bitcoinabc.org', + }, { 'name': 'env.ABC_REVISION', 'value': 'D1234', }, { + 'name': 'env.harborMasterTargetPHID', + 'value': 'UNRESOLVED', + }], + }, + }), + })) + assert response.status_code == 200 + assert response.get_json() == json.loads(triggerBuildResponse.content) + + def test_land_diff(self): + data = landDiffRequestData() + triggerBuildResponse = test.mocks.teamcity.buildInfo( + test.mocks.teamcity.buildInfo_changes(['test-change'])) + self.teamcity.session.send.return_value = triggerBuildResponse + response = self.app.post('/land', headers=self.headers, json=data) + self.teamcity.session.send.assert_called_with(AnyWith(requests.PreparedRequest, { + 'url': 'https://teamcity.test/app/rest/buildQueue', + 'body': json.dumps({ + 'branchName': 'master', + 'buildType': { + 'id': 'BitcoinAbcLandBot', + }, + 'properties': { + 'property': [{ 'name': 'env.ABC_CONDUIT_TOKEN', 'value': 'U2FsdGVkX1/RI0AAAAAAAF46wjo3lSAxj1d1iqqkxks=', }, { @@ -49,6 +91,12 @@ }, { 'name': 'env.ABC_COMMITTER_EMAIL', 'value': 'user@bitcoinabc.org', + }, { + 'name': 'env.ABC_DIFF', + 'value': '12345', + }, { + 'name': 'env.ABC_COMMIT_MESSAGE', + 'value': '[Test] Commit message', }, { 'name': 'env.harborMasterTargetPHID', 'value': 'UNRESOLVED', @@ -67,14 +115,27 @@ def test_land_missingArguments(self): # Test otherwise valid requests with each required argument missing. # All of them should fail with status code 400. - requiredArgs = [ + requiredRevisionArgs = [ 'revision', 'conduitToken', 'committerName', 'committerEmail', ] - for arg in requiredArgs: - data = landRequestData() + for arg in requiredRevisionArgs: + data = landRevisionRequestData() + setattr(data, arg, '') + response = self.app.post('/land', headers=self.headers, json=data) + assert response.status_code == 400 + + requiredDiffArgs = [ + 'diff', + 'commitMessage', + 'conduitToken', + 'committerName', + 'committerEmail', + ] + for arg in requiredDiffArgs: + data = landDiffRequestData() setattr(data, arg, '') response = self.app.post('/land', headers=self.headers, json=data) assert response.status_code == 400