def CancelBuilds(buildbucket_ids, buildbucket_client, debug=True, config=None): """Cancel Buildbucket builds in a set. Args: buildbucket_ids: A list of build_ids (strings). buildbucket_client: Instance of buildbucket_lib.buildbucket_client. debug: Boolean indicating whether it's a dry run. Default to True. config: Instance of config_lib.BuildConfig. Config dict for the master build initiating the cancel. Optional. """ if buildbucket_ids: logging.info('Canceling buildbucket_ids: %s', buildbucket_ids) if (not debug) and config: fields = {'build_type': config.build_type, 'build_name': config.name} metrics.Counter(constants.MON_BB_CANCEL_BATCH_BUILDS_COUNT).increment( fields=fields) cancel_results = buildbucket_client.CancelBatchBuildsRequest( buildbucket_ids, dryrun=debug) result_map = buildbucket_lib.GetResultMap(cancel_results) for buildbucket_id, result in result_map.items(): # Check for error messages if buildbucket_lib.GetNestedAttr(result, ['error']): # TODO(nxia): Get build url and log url in the warnings. logging.warning('Error cancelling build %s with reason: %s. ' 'Please check the status of the build.', buildbucket_id, buildbucket_lib.GetErrorReason(result))
def _PutConfigToBuildBucket(self, buildbucket_client, dryrun): """Put the tryjob request to buildbucket. Args: buildbucket_client: The buildbucket client instance. dryrun: bool controlling dryrun behavior. Returns: ScheduledBuild describing the scheduled build. Raises: RemoteRequestFailure. """ request_body = self._GetRequestBody() content = buildbucket_client.PutBuildRequest( json.dumps(request_body), dryrun) if buildbucket_lib.GetNestedAttr(content, ['error']): raise RemoteRequestFailure( 'buildbucket error.\nReason: %s\n Message: %s' % (buildbucket_lib.GetErrorReason(content), buildbucket_lib.GetErrorMessage(content))) buildbucket_id = buildbucket_lib.GetBuildId(content) url = TryJobUrl(buildbucket_id) created_ts = buildbucket_lib.GetBuildCreated_ts(content) result = ScheduledBuild(buildbucket_id, self.build_config, url, created_ts) logging.info(self.BUILDBUCKET_PUT_RESP_FORMAT, result) return result
def testCancelBatchBuildsRequest(self): """Test CancelBatchBuilds.""" buildbucket_id_1 = 'test_buildbucket_id_1' buildbucket_id_2 = 'test_buildbucket_id_2' status = 'COMPLETED' result = 'CANCELED' error_reason = 'BUILD_IS_COMPLETED' content = json.dumps({ 'results': [{ 'build_id': buildbucket_id_1, 'build': { 'status': status, 'result': result, } }, { 'build_id': buildbucket_id_2, 'error': { 'message': 'Cannot cancel a completed build', 'reason': error_reason, } }] }) self.mock_http.request.return_value = (self.success_response, content) result_content = self.client.CancelBatchBuildsRequest( [buildbucket_id_1, buildbucket_id_2], False) result_map = buildbucket_lib.GetResultMap(result_content) self.assertIsNotNone( buildbucket_lib.GetNestedAttr(result_map[buildbucket_id_1], ['build'])) self.assertIsNotNone( buildbucket_lib.GetNestedAttr(result_map[buildbucket_id_2], ['error'])) self.assertEqual( buildbucket_lib.GetBuildStatus(result_map[buildbucket_id_1]), status) self.assertEqual( buildbucket_lib.GetErrorReason(result_map[buildbucket_id_2]), error_reason) # Test dryrun result_content_2 = self.client.CancelBatchBuildsRequest( [buildbucket_id_1, buildbucket_id_2], True) self.assertIsNone(result_content_2)
def testGetNestedAttr(self): """Test GetNestedAttr.""" buildbucket_id_1 = 'test_buildbucket_id_1' buildbucket_id_2 = 'test_buildbucket_id_2' content = { 'kind': 'kind', 'etag': 'etag', 'builds': [{ 'bucket': 'master.chromiumios.tryserver', 'status': 'COMPLETED', 'id': buildbucket_id_1, }, { 'bucket': 'master.chromiumios.tryserver', 'status': 'COMPLETED', 'id': buildbucket_id_2, }], 'result': { 'status': 'COMPLETED' } } etag = buildbucket_lib.GetNestedAttr(content, ['etag'], default='default_etag') self.assertEqual(etag, 'etag') status = buildbucket_lib.GetNestedAttr(content, ['result', 'status']) self.assertEqual('COMPLETED', status) test_attr = buildbucket_lib.GetNestedAttr(content, ['test_attr'], default='default_test_attr') self.assertEqual(test_attr, 'default_test_attr') test_etag_attr = buildbucket_lib.GetNestedAttr( content, ['etag', 'test_attr'], default='default_etag_test_attr') self.assertEqual(test_etag_attr, 'default_etag_test_attr') build_ids = buildbucket_lib.ExtractBuildIds( buildbucket_lib.GetNestedAttr(content, ['builds'], default=[])) self.assertTrue(buildbucket_id_1 in build_ids and buildbucket_id_2 in build_ids) build_ids = buildbucket_lib.GetBuildIds(content) self.assertTrue(buildbucket_id_1 in build_ids and buildbucket_id_2 in build_ids) content = { 'results': [{ 'build_id': buildbucket_id_1, 'error': { 'message': 'Cannot cancel a completed build', 'reason': 'error_reason', } }] } results = buildbucket_lib.GetNestedAttr(content, ['results'], default=[]) for r in results: reason = buildbucket_lib.GetErrorReason(r) self.assertEqual(reason, 'error_reason')