Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(99)

Side by Side Diff: appengine/cr-buildbucket/test/api_test.py

Issue 1082303002: buildbucket: put_batch endpoint (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@master
Patch Set: removed memcache import Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « appengine/cr-buildbucket/service.py ('k') | appengine/cr-buildbucket/test/service_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import datetime 5 import datetime
6 import httplib 6 import httplib
7 import json 7 import json
8 import mock 8 import mock
9 9
10 from components import auth 10 from components import auth
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 self.assertEqual( 71 self.assertEqual(
72 resp['build']['parameters_json'], '{"buildername": "linux_rel"}') 72 resp['build']['parameters_json'], '{"buildername": "linux_rel"}')
73 73
74 def test_get_nonexistent_build(self): 74 def test_get_nonexistent_build(self):
75 self.service.get.return_value = None 75 self.service.get.return_value = None
76 self.expect_error('get', {'id': 1}, 'BUILD_NOT_FOUND') 76 self.expect_error('get', {'id': 1}, 'BUILD_NOT_FOUND')
77 77
78 ##################################### PUT #################################### 78 ##################################### PUT ####################################
79 79
80 def test_put(self): 80 def test_put(self):
81 self.test_build.tags = ['owner=ivan'] 81 self.test_build.tags = ['owner:ivan']
82 self.service.add.return_value = self.test_build 82 self.service.add.return_value = self.test_build
83 req = { 83 req = {
84 'bucket': self.test_build.bucket, 84 'bucket': self.test_build.bucket,
85 'tags': self.test_build.tags, 85 'tags': self.test_build.tags,
86 } 86 }
87 resp = self.call_api('put', req).json_body 87 resp = self.call_api('put', req).json_body
88 self.service.add.assert_called_once_with( 88 self.service.add.assert_called_once_with(
89 bucket=self.test_build.bucket, 89 bucket=self.test_build.bucket,
90 tags=req['tags'], 90 tags=req['tags'],
91 parameters=None, 91 parameters=None,
92 lease_expiration_date=None, 92 lease_expiration_date=None,
93 client_operation_id=None,
93 ) 94 )
94 self.assertEqual(resp['build']['id'], str(self.test_build.key.id())) 95 self.assertEqual(resp['build']['id'], str(self.test_build.key.id()))
95 self.assertEqual(resp['build']['bucket'], req['bucket']) 96 self.assertEqual(resp['build']['bucket'], req['bucket'])
96 self.assertEqual(resp['build']['tags'], req['tags']) 97 self.assertEqual(resp['build']['tags'], req['tags'])
97 98
98 def test_put_with_parameters(self): 99 def test_put_with_parameters(self):
99 self.service.add.return_value = self.test_build 100 self.service.add.return_value = self.test_build
100 req = { 101 req = {
101 'bucket': self.test_build.bucket, 102 'bucket': self.test_build.bucket,
102 'parameters_json': json.dumps(self.test_build.parameters), 103 'parameters_json': json.dumps(self.test_build.parameters),
103 } 104 }
104 resp = self.call_api('put', req).json_body 105 resp = self.call_api('put', req).json_body
105 self.assertEqual(resp['build']['parameters_json'], req['parameters_json']) 106 self.assertEqual(resp['build']['parameters_json'], req['parameters_json'])
106 107
107 def test_put_with_leasing(self): 108 def test_put_with_leasing(self):
108 self.test_build.lease_expiration_date = self.future_date 109 self.test_build.lease_expiration_date = self.future_date
109 self.service.add.return_value = self.test_build 110 self.service.add.return_value = self.test_build
110 req = { 111 req = {
111 'bucket': self.test_build.bucket, 112 'bucket': self.test_build.bucket,
112 'lease_expiration_ts': self.future_ts, 113 'lease_expiration_ts': self.future_ts,
113 } 114 }
114 resp = self.call_api('put', req).json_body 115 resp = self.call_api('put', req).json_body
115 self.service.add.assert_called_once_with( 116 self.service.add.assert_called_once_with(
116 bucket=self.test_build.bucket, 117 bucket=self.test_build.bucket,
117 tags=[], 118 tags=[],
118 parameters=None, 119 parameters=None,
119 lease_expiration_date=self.future_date, 120 lease_expiration_date=self.future_date,
121 client_operation_id=None,
120 ) 122 )
121 self.assertEqual( 123 self.assertEqual(
122 resp['build']['lease_expiration_ts'], req['lease_expiration_ts']) 124 resp['build']['lease_expiration_ts'], req['lease_expiration_ts'])
123 125
124 def test_put_with_empty_bucket(self):
125 self.expect_error('put', {'bucket': ''}, 'INVALID_INPUT')
126
127 def test_put_with_malformed_parameters_json(self): 126 def test_put_with_malformed_parameters_json(self):
128 req = { 127 req = {
129 'bucket':'chromium', 128 'bucket':'chromium',
130 'parameters_json': '}non-json', 129 'parameters_json': '}non-json',
131 } 130 }
132 self.expect_error('put', req, 'INVALID_INPUT') 131 self.expect_error('put', req, 'INVALID_INPUT')
133 132
133 ################################## PUT_BATCH #################################
134
135 def test_put_batch(self):
136 self.test_build.tags = ['owner:ivan']
137 build1_future = ndb.Future()
138 build1_future.set_result(self.test_build)
139
140 build2 = model.Build(id=2, bucket='v8')
141 build2_future = ndb.Future()
142 build2_future.set_result(build2)
143
144 bad_build_future = ndb.Future()
145 bad_build_future.set_exception(errors.InvalidInputError('Just bad'))
146
147 self.service.add_async.side_effect = [
148 build1_future, build2_future, bad_build_future]
149 req = {
150 'builds': [
151 {
152 'bucket': self.test_build.bucket,
153 'tags': self.test_build.tags,
154 'client_operation_id': '0',
155 },
156 {
157 'bucket': build2.bucket,
158 'client_operation_id': '1',
159 },
160 {
161 'bucket': 'bad name',
162 'client_operation_id': '2',
163 },
164 ],
165 }
166 resp = self.call_api('put_batch', req).json_body
167 self.service.add_async.assert_any_call(
168 bucket=self.test_build.bucket,
169 tags=self.test_build.tags,
170 parameters=None,
171 lease_expiration_date=None,
172 client_operation_id='0',
173 )
174 self.service.add_async.assert_any_call(
175 bucket=build2.bucket,
176 tags=[],
177 parameters=None,
178 lease_expiration_date=None,
179 client_operation_id='1',
180 )
181
182 res0 = resp['results'][0]
183 self.assertEqual(res0['client_operation_id'], '0')
184 self.assertEqual(res0['build']['id'], str(self.test_build.key.id()))
185 self.assertEqual(res0['build']['bucket'], self.test_build.bucket)
186 self.assertEqual(res0['build']['tags'], self.test_build.tags)
187
188 res1 = resp['results'][1]
189 self.assertEqual(res1['client_operation_id'], '1')
190 self.assertEqual(res1['build']['id'], str(build2.key.id()))
191 self.assertEqual(res1['build']['bucket'], build2.bucket)
192
193 res2 = resp['results'][2]
194 self.assertEqual(res2, {
195 'client_operation_id': '2',
196 'error': {'reason': 'INVALID_INPUT', 'message': 'Just bad'},
197 })
198
134 #################################### SEARCH ################################## 199 #################################### SEARCH ##################################
135 200
136 def test_search(self): 201 def test_search(self):
137 self.test_build.put() 202 self.test_build.put()
138 self.service.search.return_value = ([self.test_build], 'the cursor') 203 self.service.search.return_value = ([self.test_build], 'the cursor')
139 req = { 204 req = {
140 'bucket': ['chromium'], 205 'bucket': ['chromium'],
141 'cancelation_reason': 'CANCELED_EXPLICITLY', 206 'cancelation_reason': 'CANCELED_EXPLICITLY',
142 'created_by': 'user:x@chromium.org', 207 'created_by': 'user:x@chromium.org',
143 'result': 'CANCELED', 208 'result': 'CANCELED',
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
240 'lease_key': 42, 305 'lease_key': 42,
241 'url': self.test_build.url, 306 'url': self.test_build.url,
242 } 307 }
243 res = self.call_api('start', req).json_body 308 res = self.call_api('start', req).json_body
244 self.service.start.assert_called_once_with( 309 self.service.start.assert_called_once_with(
245 req['id'], req['lease_key'], url=req['url']) 310 req['id'], req['lease_key'], url=req['url'])
246 self.assertEqual(int(res['build']['id']), req['id']) 311 self.assertEqual(int(res['build']['id']), req['id'])
247 self.assertEqual(res['build']['url'], req['url']) 312 self.assertEqual(res['build']['url'], req['url'])
248 313
249 def test_start_completed_build(self): 314 def test_start_completed_build(self):
250 def raise_completed(*_, **__): 315 self.service.start.side_effect = errors.BuildIsCompletedError
251 raise errors.BuildIsCompletedError()
252 self.service.start.side_effect = raise_completed
253 req = { 316 req = {
254 'id': self.test_build.key.id(), 317 'id': self.test_build.key.id(),
255 'lease_key': 42, 318 'lease_key': 42,
256 } 319 }
257 res = self.call_api('start', req).json_body 320 res = self.call_api('start', req).json_body
258 self.assertEqual(res['error']['reason'], 'BUILD_IS_COMPLETED') 321 self.assertEqual(res['error']['reason'], 'BUILD_IS_COMPLETED')
259 322
260 #################################### HEATBEAT ################################ 323 #################################### HEATBEAT ################################
261 324
262 def test_heartbeat(self): 325 def test_heartbeat(self):
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
471 self.assertTrue('error' in res) 534 self.assertTrue('error' in res)
472 self.assertEqual(res['error']['reason'], 'INVALID_INPUT') 535 self.assertEqual(res['error']['reason'], 'INVALID_INPUT')
473 536
474 expect_invalid_input_error( 537 expect_invalid_input_error(
475 {'role': 'READER', 'group': 'good group'}, bucket='bad bucket') 538 {'role': 'READER', 'group': 'good group'}, bucket='bad bucket')
476 expect_invalid_input_error({'role': 'READER', 'group': 'bad/ group'}) 539 expect_invalid_input_error({'role': 'READER', 'group': 'bad/ group'})
477 540
478 #################################### ERRORS ################################## 541 #################################### ERRORS ##################################
479 542
480 def error_test(self, error_class, reason): 543 def error_test(self, error_class, reason):
481 def raise_service_error(*_, **__): 544 self.service.get.side_effect = error_class
482 raise error_class()
483 self.service.get.side_effect = raise_service_error
484 self.expect_error('get', {'id': 123}, reason) 545 self.expect_error('get', {'id': 123}, reason)
485 546
486 def test_build_not_found_error(self): 547 def test_build_not_found_error(self):
487 self.error_test(errors.BuildNotFoundError, 'BUILD_NOT_FOUND') 548 self.error_test(errors.BuildNotFoundError, 'BUILD_NOT_FOUND')
488 549
489 def test_invalid_input_error(self): 550 def test_invalid_input_error(self):
490 self.error_test(errors.InvalidInputError, 'INVALID_INPUT') 551 self.error_test(errors.InvalidInputError, 'INVALID_INPUT')
491 552
492 def test_invalid_build_state_error(self): 553 def test_invalid_build_state_error(self):
493 self.error_test(errors.InvalidBuildStateError, 'INVALID_BUILD_STATE') 554 self.error_test(errors.InvalidBuildStateError, 'INVALID_BUILD_STATE')
494 555
495 def test_lease_expired_error(self): 556 def test_lease_expired_error(self):
496 self.error_test(errors.LeaseExpiredError, 'LEASE_EXPIRED') 557 self.error_test(errors.LeaseExpiredError, 'LEASE_EXPIRED')
OLDNEW
« no previous file with comments | « appengine/cr-buildbucket/service.py ('k') | appengine/cr-buildbucket/test/service_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698