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

Side by Side Diff: recipe_engine/unittests/fetch_test.py

Issue 2835593002: Revert of [autoroller] All commits in updates(), only roll interesting ones. (Closed)
Patch Set: Created 3 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 | « recipe_engine/package.py ('k') | unittests/autoroll_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 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2016 The LUCI Authors. All rights reserved. 2 # Copyright 2016 The LUCI Authors. All rights reserved.
3 # Use of this source code is governed under the Apache License, Version 2.0 3 # Use of this source code is governed under the Apache License, Version 2.0
4 # that can be found in the LICENSE file. 4 # that can be found in the LICENSE file.
5 5
6 import base64 6 import base64
7 import itertools 7 import itertools
8 import json 8 import json
9 import unittest 9 import unittest
10 10
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
63 self.assertListEqual(list(real_args), full_args) 63 self.assertListEqual(list(real_args), full_args)
64 raise data_or_exception 64 raise data_or_exception
65 else: 65 else:
66 def _inner(*real_args): 66 def _inner(*real_args):
67 self.assertListEqual(list(real_args), full_args) 67 self.assertListEqual(list(real_args), full_args)
68 return data_or_exception 68 return data_or_exception
69 return _inner 69 return _inner
70 70
71 def g_metadata_calls(self, dirname='dir', commit='a'*40, 71 def g_metadata_calls(self, dirname='dir', commit='a'*40,
72 email='foo@example.com', msg='hello\nworld', 72 email='foo@example.com', msg='hello\nworld',
73 commit_timestamp=1492131405, config=None, 73 commit_timestamp=1492131405, config=None):
74 diff=('foo', 'bar')):
75 config = config or {'api_version': 2} 74 config = config or {'api_version': 2}
76 75
77 return [ 76 return [
78 self.g([ 77 self.g([
79 '-C', dirname, 'show', '-s', '--format=%aE%n%ct%n%B', commit 78 '-C', dirname, 'show', '-s', '--format=%aE%n%ct%n%B', commit
80 ], '%s\n%d\n%s\n' % (email, commit_timestamp, msg)), 79 ], '%s\n%d\n%s\n' % (email, commit_timestamp, msg)),
81 self.g([ 80 self.g([
82 '-C', dirname, 'cat-file', 'blob', commit+':infra/config/recipes.cfg' 81 '-C', dirname, 'cat-file', 'blob', commit+':infra/config/recipes.cfg'
83 ], json.dumps(config)), 82 ], json.dumps(config))
84 self.g([
85 '-C', dirname,
86 'diff-tree', '-r', '--no-commit-id', '--name-only', commit+'^!',
87 ], '\n'.join(diff))
88 ] 83 ]
89 84
90 @mock.patch('os.path.isdir') 85 @mock.patch('os.path.isdir')
91 @mock.patch('recipe_engine.fetch.GitBackend._execute') 86 @mock.patch('recipe_engine.fetch.GitBackend._execute')
92 def test_fresh_clone(self, git, isdir): 87 def test_fresh_clone(self, git, isdir):
93 isdir.return_value = False 88 isdir.return_value = False
94 git.side_effect = multi(*([ 89 git.side_effect = multi(*([
95 self.g(['init', 'dir']), 90 self.g(['init', 'dir']),
96 self.g(['-C', 'dir', 'ls-remote', 'repo', 'revision'], 'a'*40), 91 self.g(['-C', 'dir', 'ls-remote', 'repo', 'revision'], 'a'*40),
97 ] + self.g_metadata_calls() + [ 92 ] + self.g_metadata_calls() + [
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
195 self.g(['init', 'dir']), 190 self.g(['init', 'dir']),
196 self.g(['-C', 'dir', 'ls-remote', 'repo', 'revision'], 'a'*40), 191 self.g(['-C', 'dir', 'ls-remote', 'repo', 'revision'], 'a'*40),
197 ] + self.g_metadata_calls())) 192 ] + self.g_metadata_calls()))
198 193
199 result = fetch.GitBackend('dir', 'repo', True).commit_metadata('revision') 194 result = fetch.GitBackend('dir', 'repo', True).commit_metadata('revision')
200 self.assertEqual(result, fetch.CommitMetadata( 195 self.assertEqual(result, fetch.CommitMetadata(
201 revision = 'a'*40, 196 revision = 'a'*40,
202 author_email = 'foo@example.com', 197 author_email = 'foo@example.com',
203 commit_timestamp = 1492131405, 198 commit_timestamp = 1492131405,
204 message_lines = ('hello', 'world'), 199 message_lines = ('hello', 'world'),
205 spec = package_pb2.Package(api_version=2), 200 spec = package_pb2.Package(api_version=2)
206 roll_candidate = True,
207 )) 201 ))
208 self.assertMultiDone(git) 202 self.assertMultiDone(git)
209 203
210 204
211 class TestGitiles(unittest.TestCase): 205 class TestGitiles(unittest.TestCase):
212 def setUp(self): 206 def setUp(self):
213 requests_ssl.disable_check() 207 requests_ssl.disable_check()
214 fetch.Backend._GIT_METADATA_CACHE = {} 208 fetch.Backend._GIT_METADATA_CACHE = {}
215 fetch.GitilesBackend._COMMIT_JSON_CACHE = {} 209 fetch.GitilesBackend._COMMIT_JSON_CACHE = {}
216 210
217 self.proto_text = u"""{ 211 self.proto_text = u"""{
218 "api_version": 2, 212 "api_version": 2,
219 "project_id": "foo", 213 "project_id": "foo",
220 "recipes_path": "path/to/recipes" 214 "recipes_path": "path/to/recipes"
221 }""".lstrip() 215 }""".lstrip()
222 216
223 self.a = 'a'*40 217 self.a = 'a'*40
224 self.a_dat = { 218 self.a_dat = {
225 'commit': self.a, 219 'commit': self.a,
226 'author': {'email': 'foo@example.com'}, 220 'author': {'email': 'foo@example.com'},
227 'committer': {'time': 'Fri Apr 14 00:56:45 2017'}, 221 'committer': {'time': 'Fri Apr 14 00:56:45 2017'},
228 'message': 'message', 222 'message': 'message',
229 'tree_diff': [
230 {
231 'old_path': 'unrelated',
232 'new_path': 'unrelated',
233 },
234 {
235 'old_path': 'path/to/recipes/foo',
236 'new_path': 'path/to/recipes/bar',
237 },
238 ]
239 } 223 }
240 224
241 self.a_meta = fetch.CommitMetadata( 225 self.a_meta = fetch.CommitMetadata(
242 revision = 'a'*40, 226 revision = 'a'*40,
243 author_email = 'foo@example.com', 227 author_email = 'foo@example.com',
244 commit_timestamp = 1492131405, 228 commit_timestamp = 1492131405,
245 message_lines = ('message',), 229 message_lines = ('message',),
246 spec = package_pb2.Package( 230 spec = package_pb2.Package(
247 api_version = 2, 231 api_version = 2,
248 project_id = 'foo', 232 project_id = 'foo',
249 recipes_path = 'path/to/recipes', 233 recipes_path = 'path/to/recipes',
250 ), 234 )
251 roll_candidate = True,
252 ) 235 )
253 236
254 def assertMultiDone(self, mocked_call): 237 def assertMultiDone(self, mocked_call):
255 with self.assertRaises(NoMoreExpectatedCalls): 238 with self.assertRaises(NoMoreExpectatedCalls):
256 mocked_call() 239 mocked_call()
257 240
258 def j(self, url, data, status_code=200): 241 def j(self, url, data, status_code=200):
259 """Mock a request.get to return json data.""" 242 """Mock a request.get to return json data."""
260 return self.r(url, u')]}\'\n'+json.dumps(data), status_code) 243 return self.r(url, u')]}\'\n'+json.dumps(data), status_code)
261 244
(...skipping 20 matching lines...) Expand all
282 status_code=status_code) 265 status_code=status_code)
283 return _inner 266 return _inner
284 267
285 @mock.patch('__builtin__.open', mock.mock_open()) 268 @mock.patch('__builtin__.open', mock.mock_open())
286 @mock.patch('shutil.rmtree') 269 @mock.patch('shutil.rmtree')
287 @mock.patch('os.makedirs') 270 @mock.patch('os.makedirs')
288 @mock.patch('tarfile.open') 271 @mock.patch('tarfile.open')
289 @mock.patch('requests.get') 272 @mock.patch('requests.get')
290 def test_checkout(self, requests_get, _tarfile_open, makedirs, rmtree): 273 def test_checkout(self, requests_get, _tarfile_open, makedirs, rmtree):
291 requests_get.side_effect = multi( 274 requests_get.side_effect = multi(
292 self.j('repo/+/revision?name-status=1&format=JSON', self.a_dat), 275 self.j('repo/+/revision?format=JSON', self.a_dat),
293 self.j('repo/+/%s?name-status=1&format=JSON' % self.a, self.a_dat), 276 self.j('repo/+/%s?format=JSON' % self.a, self.a_dat),
294 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % self.a, 277 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % self.a,
295 self.proto_text), 278 self.proto_text),
296 self.d('repo/+archive/%s/path/to/recipes.tar.gz' % self.a, ''), 279 self.d('repo/+archive/%s/path/to/recipes.tar.gz' % self.a, ''),
297 ) 280 )
298 281
299 fetch.GitilesBackend('dir', 'repo', True).checkout('revision') 282 fetch.GitilesBackend('dir', 'repo', True).checkout('revision')
300 283
301 makedirs.assert_has_calls([ 284 makedirs.assert_has_calls([
302 mock.call('dir/infra/config'), 285 mock.call('dir/infra/config'),
303 mock.call('dir/path/to/recipes'), 286 mock.call('dir/path/to/recipes'),
304 ]) 287 ])
305 288
306 rmtree.assert_called_once_with('dir', ignore_errors=True) 289 rmtree.assert_called_once_with('dir', ignore_errors=True)
307 self.assertMultiDone(requests_get) 290 self.assertMultiDone(requests_get)
308 291
309 @mock.patch('requests.get') 292 @mock.patch('requests.get')
310 def test_updates(self, requests_get): 293 def test_updates(self, requests_get):
311 sha_a = 'a'*40 294 sha_a = 'a'*40
312 sha_b = 'b'*40 295 sha_b = 'b'*40
313 log_json = { 296 log_json = {
314 'log': [ 297 'log': [
315 { 298 {
316 'commit': sha_b, 299 'commit': sha_b,
317 'author': {'email': 'foo@example.com'}, 300 'author': {'email': 'foo@example.com'},
318 'committer': {'time': 'Fri Apr 14 00:58:45 2017'}, 301 'committer': {'time': 'Fri Apr 14 00:58:45 2017'},
319 'message': 'message', 302 'message': 'message',
320 'tree_diff': [ 303 'tree_diff': [
321 { 304 {
322 'old_path': '/dev/null', 305 'old_path': '/dev/null',
323 'new_path': 'path/to/recipes/path1/foo', 306 'new_path': 'path1/foo',
324 }, 307 },
325 ], 308 ],
326 }, 309 },
327 { 310 {
328 'commit': 'def456', 311 'commit': 'def456',
329 'author': {'email': 'foo@example.com'}, 312 'author': {'email': 'foo@example.com'},
330 'committer': {'time': 'Fri Apr 14 00:57:45 2017'}, 313 'committer': {'time': 'Fri Apr 14 00:57:45 2017'},
331 'message': 'message', 314 'message': 'message',
332 'tree_diff': [ 315 'tree_diff': [
333 { 316 {
334 'old_path': '/dev/null', 317 'old_path': '/dev/null',
335 'new_path': 'path8/foo', 318 'new_path': 'path8/foo',
336 }, 319 },
337 ], 320 ],
338 }, 321 },
339 { 322 {
340 'commit': sha_a, 323 'commit': sha_a,
341 'author': {'email': 'foo@example.com'}, 324 'author': {'email': 'foo@example.com'},
342 'committer': {'time': 'Fri Apr 14 00:56:45 2017'}, 325 'committer': {'time': 'Fri Apr 14 00:56:45 2017'},
343 'message': 'message', 326 'message': 'message',
344 'tree_diff': [ 327 'tree_diff': [
345 { 328 {
346 'old_path': '/dev/null', 329 'old_path': '/dev/null',
347 'new_path': 'path/to/recipes/path8/foo', 330 'new_path': 'path8/foo',
348 }, 331 },
349 { 332 {
350 'old_path': 'path2/foo', 333 'old_path': 'path2/foo',
351 'new_path': '/dev/null', 334 'new_path': '/dev/null',
352 }, 335 },
353 ], 336 ],
354 }, 337 },
355 ], 338 ],
356 } 339 }
357 340
358 requests_get.side_effect = multi( 341 requests_get.side_effect = multi(
359 self.j('repo/+/reva?name-status=1&format=JSON', log_json['log'][2]), 342 self.j('repo/+/reva?format=JSON', {
360 self.j('repo/+/revb?name-status=1&format=JSON', log_json['log'][0]), 343 'commit': sha_a,
344 'author': {'email': 'foo@example.com'},
345 'committer': {'time': 'Fri Apr 14 00:56:45 2017'},
346 'message': 'message',
347 }),
348 self.j('repo/+/revb?format=JSON', {
349 'commit': sha_b,
350 'author': {'email': 'foo@example.com'},
351 'committer': {'time': 'Fri Apr 14 00:58:45 2017'},
352 'message': 'message',
353 }),
361 self.j('repo/+log/%s..%s?name-status=1&format=JSON' % (sha_a, sha_b), 354 self.j('repo/+log/%s..%s?name-status=1&format=JSON' % (sha_a, sha_b),
362 log_json), 355 log_json),
363 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % sha_a, 356 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % sha_a,
364 self.proto_text), 357 self.proto_text),
365 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % 'def456',
366 self.proto_text),
367 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % sha_b, 358 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % sha_b,
368 self.proto_text), 359 self.proto_text),
369 ) 360 )
370 361
371 be = fetch.GitilesBackend('dir', 'repo', True) 362 be = fetch.GitilesBackend('dir', 'repo', True)
372 self.assertEqual(sha_a, be.resolve_refspec('reva')) 363 self.assertEqual(sha_a, be.resolve_refspec('reva'))
373 self.assertEqual(sha_b, be.resolve_refspec('revb')) 364 self.assertEqual(sha_b, be.resolve_refspec('revb'))
374 365
375 self.assertEqual( 366 self.assertEqual(
376 [self.a_meta, 367 [self.a_meta,
377 fetch.CommitMetadata( 368 fetch.CommitMetadata(
378 revision = 'def456',
379 author_email = 'foo@example.com',
380 commit_timestamp = 1492131465,
381 message_lines = ('message',),
382 spec = package_pb2.Package(
383 api_version = 2,
384 project_id = 'foo',
385 recipes_path = 'path/to/recipes',
386 ),
387 roll_candidate = False,
388 ),
389 fetch.CommitMetadata(
390 revision = sha_b, 369 revision = sha_b,
391 author_email = 'foo@example.com', 370 author_email = 'foo@example.com',
392 commit_timestamp = 1492131525, 371 commit_timestamp = 1492131525,
393 message_lines = ('message',), 372 message_lines = ('message',),
394 spec = package_pb2.Package( 373 spec = package_pb2.Package(
395 api_version = 2, 374 api_version = 2,
396 project_id = 'foo', 375 project_id = 'foo',
397 recipes_path = 'path/to/recipes', 376 recipes_path = 'path/to/recipes',
398 ), 377 )
399 roll_candidate = True,
400 )], 378 )],
401 be.updates(sha_a, sha_b)) 379 be.updates(sha_a, sha_b, ['path1', 'path2']))
402 self.assertMultiDone(requests_get) 380 self.assertMultiDone(requests_get)
403 381
404 382
405 @mock.patch('requests.get') 383 @mock.patch('requests.get')
406 def test_commit_metadata(self, requests_get): 384 def test_commit_metadata(self, requests_get):
407 requests_get.side_effect = multi( 385 requests_get.side_effect = multi(
408 self.j('repo/+/revision?name-status=1&format=JSON', self.a_dat), 386 self.j('repo/+/revision?format=JSON', self.a_dat),
409 self.j('repo/+/%s?name-status=1&format=JSON' % self.a, self.a_dat), 387 self.j('repo/+/%s?format=JSON' % self.a, self.a_dat),
410 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % self.a, 388 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % self.a,
411 self.proto_text) 389 self.proto_text)
412 ) 390 )
413 391
414 result = fetch.GitilesBackend('dir', 'repo', True).commit_metadata( 392 result = fetch.GitilesBackend('dir', 'repo', True).commit_metadata(
415 'revision') 393 'revision')
416 self.assertEqual(result, self.a_meta) 394 self.assertEqual(result, self.a_meta)
417 self.assertMultiDone(requests_get) 395 self.assertMultiDone(requests_get)
418 396
419 @mock.patch('requests.get') 397 @mock.patch('requests.get')
420 def test_non_transient_error(self, requests_get): 398 def test_non_transient_error(self, requests_get):
421 requests_get.side_effect = multi( 399 requests_get.side_effect = multi(
422 self.r('repo/+/revision?name-status=1&format=JSON', 400 self.r('repo/+/revision?format=JSON', fetch.GitilesFetchError(403, '')),
423 fetch.GitilesFetchError(403, '')),
424 ) 401 )
425 with self.assertRaises(fetch.GitilesFetchError): 402 with self.assertRaises(fetch.GitilesFetchError):
426 fetch.GitilesBackend('dir', 'repo', True).commit_metadata( 403 fetch.GitilesBackend('dir', 'repo', True).commit_metadata(
427 'revision') 404 'revision')
428 self.assertMultiDone(requests_get) 405 self.assertMultiDone(requests_get)
429 406
430 @mock.patch('requests.get') 407 @mock.patch('requests.get')
431 @mock.patch('time.sleep') 408 @mock.patch('time.sleep')
432 @mock.patch('logging.exception') 409 @mock.patch('logging.exception')
433 def test_transient_retry(self, _logging_exception, _time_sleep, requests_get): 410 def test_transient_retry(self, _logging_exception, _time_sleep, requests_get):
434 requests_get.side_effect = multi( 411 requests_get.side_effect = multi(
435 self.r('repo/+/revision?name-status=1&format=JSON', 412 self.r('repo/+/revision?format=JSON', fetch.GitilesFetchError(500, '')),
436 fetch.GitilesFetchError(500, '')), 413 self.r('repo/+/revision?format=JSON', fetch.GitilesFetchError(500, '')),
437 self.r('repo/+/revision?name-status=1&format=JSON', 414 self.r('repo/+/revision?format=JSON', fetch.GitilesFetchError(500, '')),
438 fetch.GitilesFetchError(500, '')), 415 self.r('repo/+/revision?format=JSON', fetch.GitilesFetchError(500, '')),
439 self.r('repo/+/revision?name-status=1&format=JSON', 416 self.j('repo/+/revision?format=JSON', self.a_dat),
440 fetch.GitilesFetchError(500, '')), 417 self.j('repo/+/%s?format=JSON' % self.a, self.a_dat),
441 self.r('repo/+/revision?name-status=1&format=JSON',
442 fetch.GitilesFetchError(500, '')),
443 self.j('repo/+/revision?name-status=1&format=JSON', self.a_dat),
444 self.j('repo/+/%s?name-status=1&format=JSON' % self.a, self.a_dat),
445 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % self.a, 418 self.d('repo/+/%s/infra/config/recipes.cfg?format=TEXT' % self.a,
446 self.proto_text), 419 self.proto_text),
447 ) 420 )
448 421
449 result = fetch.GitilesBackend('dir', 'repo', True).commit_metadata( 422 result = fetch.GitilesBackend('dir', 'repo', True).commit_metadata(
450 'revision') 423 'revision')
451 self.assertEqual(result, self.a_meta) 424 self.assertEqual(result, self.a_meta)
452 self.assertMultiDone(requests_get) 425 self.assertMultiDone(requests_get)
453 426
454 if __name__ == '__main__': 427 if __name__ == '__main__':
455 unittest.main() 428 unittest.main()
OLDNEW
« no previous file with comments | « recipe_engine/package.py ('k') | unittests/autoroll_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698