OLD | NEW |
1 #!/usr/bin/python | 1 #!/usr/bin/python |
2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2010 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Generate fake repositories for testing.""" | 6 """Generate fake repositories for testing.""" |
7 | 7 |
8 import atexit | 8 import atexit |
9 import errno | 9 import errno |
10 import logging | 10 import logging |
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
207 HOST = '127.0.0.1' | 207 HOST = '127.0.0.1' |
208 | 208 |
209 def __init__(self, trial_dir=None, leak=None, host=None): | 209 def __init__(self, trial_dir=None, leak=None, host=None): |
210 global _FAKE_LOADED | 210 global _FAKE_LOADED |
211 if _FAKE_LOADED: | 211 if _FAKE_LOADED: |
212 raise Exception('You can only start one FakeRepos at a time.') | 212 raise Exception('You can only start one FakeRepos at a time.') |
213 _FAKE_LOADED = True | 213 _FAKE_LOADED = True |
214 # Quick hack. | 214 # Quick hack. |
215 if '-v' in sys.argv: | 215 if '-v' in sys.argv: |
216 logging.basicConfig(level=logging.DEBUG) | 216 logging.basicConfig(level=logging.DEBUG) |
217 if '-l' in sys.argv: | |
218 self.SHOULD_LEAK = True | |
219 sys.argv.remove('-l') | |
220 elif leak is not None: | 217 elif leak is not None: |
221 self.SHOULD_LEAK = leak | 218 self.SHOULD_LEAK = leak |
222 if host: | 219 if host: |
223 self.HOST = host | 220 self.HOST = host |
224 if trial_dir: | 221 if trial_dir: |
225 self.TRIAL_DIR = trial_dir | 222 self.TRIAL_DIR = trial_dir |
226 | 223 |
227 # Format is [ None, tree, tree, ...] | 224 # Format is [ None, tree, tree, ...] |
228 # i.e. revisions are 1-based. | 225 # i.e. revisions are 1-based. |
229 self.svn_revs = [None] | 226 self.svn_revs = [None] |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
334 | 331 |
335 # Testing: | 332 # Testing: |
336 # - dependency disapear | 333 # - dependency disapear |
337 # - dependency renamed | 334 # - dependency renamed |
338 # - versioned and unversioned reference | 335 # - versioned and unversioned reference |
339 # - relative and full reference | 336 # - relative and full reference |
340 # - deps_os | 337 # - deps_os |
341 # - var | 338 # - var |
342 # - hooks | 339 # - hooks |
343 # TODO(maruel): | 340 # TODO(maruel): |
| 341 # - From |
344 # - File | 342 # - File |
345 # - $matching_files | 343 # - $matching_files |
346 # - use_relative_paths | 344 # - use_relative_paths |
347 self._commit_svn(file_system(1, """ | 345 fs = file_system(1, """ |
348 vars = { | 346 vars = { |
349 'DummyVariable': 'third_party', | 347 'DummyVariable': 'third_party', |
350 } | 348 } |
351 deps = { | 349 deps = { |
352 'src/other': 'svn://%(host)s/svn/trunk/other', | 350 'src/other': 'svn://%(host)s/svn/trunk/other@1', |
353 'src/third_party/fpp': '/trunk/' + Var('DummyVariable') + '/foo', | 351 'src/third_party/fpp': '/trunk/' + Var('DummyVariable') + '/foo', |
354 } | 352 } |
355 deps_os = { | 353 deps_os = { |
356 'mac': { | 354 'mac': { |
357 'src/third_party/prout': '/trunk/third_party/prout', | 355 'src/third_party/prout': '/trunk/third_party/prout', |
358 }, | 356 }, |
359 }""" % { 'host': self.HOST })) | 357 }""" % { 'host': self.HOST }) |
| 358 self._commit_svn(fs) |
360 | 359 |
361 self._commit_svn(file_system(2, """ | 360 fs = file_system(2, """ |
362 deps = { | 361 deps = { |
363 'src/other': 'svn://%(host)s/svn/trunk/other', | 362 'src/other': 'svn://%(host)s/svn/trunk/other', |
364 'src/third_party/foo': '/trunk/third_party/foo@1', | 363 'src/third_party/foo': '/trunk/third_party/foo@1', |
| 364 #'src/third_party/foo': From('src/other', 'foo/bar'), |
365 } | 365 } |
366 # I think this is wrong to have the hooks run from the base of the gclient | 366 # I think this is wrong to have the hooks run from the base of the gclient |
367 # checkout. It's maybe a bit too late to change that behavior. | 367 # checkout. It's maybe a bit too late to change that behavior. |
368 hooks = [ | 368 hooks = [ |
369 { | 369 { |
370 'pattern': '.', | 370 'pattern': '.', |
371 'action': ['python', '-c', | 371 'action': ['python', '-c', |
372 'open(\\'src/svn_hooked1\\', \\'w\\').write(\\'svn_hooked1\\')'], | 372 'open(\\'src/svn_hooked1\\', \\'w\\').write(\\'svn_hooked1\\')'], |
373 }, | 373 }, |
374 { | 374 { |
375 # Should not be run. | 375 # Should not be run. |
376 'pattern': 'nonexistent', | 376 'pattern': 'nonexistent', |
377 'action': ['python', '-c', | 377 'action': ['python', '-c', |
378 'open(\\'src/svn_hooked2\\', \\'w\\').write(\\'svn_hooked2\\')'], | 378 'open(\\'src/svn_hooked2\\', \\'w\\').write(\\'svn_hooked2\\')'], |
379 }, | 379 }, |
380 ] | 380 ] |
381 """ % { 'host': self.HOST })) | 381 """ % { 'host': self.HOST }) |
| 382 fs['trunk/other/DEPS'] = """ |
| 383 deps = { |
| 384 'foo/bar': '/trunk/third_party/foo@1', |
| 385 } |
| 386 """ |
| 387 self._commit_svn(fs) |
382 | 388 |
383 def setUpGIT(self): | 389 def setUpGIT(self): |
384 """Creates git repositories and start the servers.""" | 390 """Creates git repositories and start the servers.""" |
385 if self.gitdaemon: | 391 if self.gitdaemon: |
386 return True | 392 return True |
387 self.setUp() | 393 self.setUp() |
388 if sys.platform == 'win32': | 394 if sys.platform == 'win32': |
389 return False | 395 return False |
390 for repo in ['repo_%d' % r for r in range(1, 5)]: | 396 for repo in ['repo_%d' % r for r in range(1, 5)]: |
391 check_call(['git', 'init', '-q', join(self.git_root, repo)]) | 397 check_call(['git', 'init', '-q', join(self.git_root, repo)]) |
392 self.git_hashes[repo] = [None] | 398 self.git_hashes[repo] = [None] |
393 | 399 |
394 # Testing: | 400 # Testing: |
395 # - dependency disapear | 401 # - dependency disapear |
396 # - dependency renamed | 402 # - dependency renamed |
397 # - versioned and unversioned reference | 403 # - versioned and unversioned reference |
398 # - relative and full reference | 404 # - relative and full reference |
399 # - deps_os | 405 # - deps_os |
400 # - var | 406 # - var |
401 # - hooks | 407 # - hooks |
402 # TODO(maruel): | 408 # TODO(maruel): |
| 409 # - From |
403 # - File | 410 # - File |
404 # - $matching_files | 411 # - $matching_files |
405 # - use_relative_paths | 412 # - use_relative_paths |
| 413 self._commit_git('repo_3', { |
| 414 'origin': 'git/repo_3@1\n', |
| 415 }) |
| 416 |
| 417 self._commit_git('repo_3', { |
| 418 'origin': 'git/repo_3@2\n', |
| 419 }) |
| 420 |
406 self._commit_git('repo_1', { | 421 self._commit_git('repo_1', { |
407 'DEPS': """ | 422 'DEPS': """ |
408 vars = { | 423 vars = { |
409 'DummyVariable': 'repo', | 424 'DummyVariable': 'repo', |
410 } | 425 } |
411 deps = { | 426 deps = { |
412 'src/repo2': 'git://%(host)s/git/repo_2', | 427 'src/repo2': 'git://%(host)s/git/repo_2', |
413 'src/repo2/repo3': '/' + Var('DummyVariable') + '_3', | 428 'src/repo2/repo3': '/' + Var('DummyVariable') + '_3@%(hash3)s', |
414 } | 429 } |
415 deps_os = { | 430 deps_os = { |
416 'mac': { | 431 'mac': { |
417 'src/repo4': '/repo_4', | 432 'src/repo4': '/repo_4', |
418 }, | 433 }, |
419 }""" % { 'host': self.HOST }, | 434 }""" % { |
420 'origin': 'git/repo_1@1\n', | 435 'host': self.HOST, |
| 436 # See self.__init__() for the format. Grab's the hash of the first |
| 437 # commit in repo_2. Only keep the first 7 character because of: |
| 438 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. |
| 439 # duh. |
| 440 'hash3': self.git_hashes['repo_3'][1][0][:7] |
| 441 }, |
| 442 'origin': 'git/repo_1@1\n', |
421 }) | 443 }) |
422 | 444 |
423 self._commit_git('repo_2', { | 445 self._commit_git('repo_2', { |
424 'origin': "git/repo_2@1\n" | 446 'origin': 'git/repo_2@1\n', |
| 447 'DEPS': """ |
| 448 deps = { |
| 449 'foo/bar': '/repo_3', |
| 450 } |
| 451 """, |
425 }) | 452 }) |
426 | 453 |
427 self._commit_git('repo_2', { | 454 self._commit_git('repo_2', { |
428 'origin': "git/repo_2@2\n" | 455 'origin': 'git/repo_2@2\n', |
429 }) | |
430 | |
431 self._commit_git('repo_3', { | |
432 'origin': "git/repo_3@1\n" | |
433 }) | |
434 | |
435 self._commit_git('repo_3', { | |
436 'origin': "git/repo_3@2\n" | |
437 }) | 456 }) |
438 | 457 |
439 self._commit_git('repo_4', { | 458 self._commit_git('repo_4', { |
440 'origin': "git/repo_4@1\n" | 459 'origin': 'git/repo_4@1\n', |
441 }) | 460 }) |
442 | 461 |
443 self._commit_git('repo_4', { | 462 self._commit_git('repo_4', { |
444 'origin': "git/repo_4@2\n" | 463 'origin': 'git/repo_4@2\n', |
445 }) | 464 }) |
446 | 465 |
447 self._commit_git('repo_1', { | 466 self._commit_git('repo_1', { |
448 'DEPS': """ | 467 'DEPS': """ |
449 deps = { | 468 deps = { |
450 'src/repo2': 'git://%(host)s/git/repo_2@%(hash)s', | 469 'src/repo2': 'git://%(host)s/git/repo_2@%(hash)s', |
451 'src/repo2/repo_renamed': '/repo_3', | 470 'src/repo2/repo_renamed': '/repo_3', |
| 471 #'src/repo2/repo_renamed': From('src/repo2', 'foo/bar'), |
452 } | 472 } |
453 # I think this is wrong to have the hooks run from the base of the gclient | 473 # I think this is wrong to have the hooks run from the base of the gclient |
454 # checkout. It's maybe a bit too late to change that behavior. | 474 # checkout. It's maybe a bit too late to change that behavior. |
455 hooks = [ | 475 hooks = [ |
456 { | 476 { |
457 'pattern': '.', | 477 'pattern': '.', |
458 'action': ['python', '-c', | 478 'action': ['python', '-c', |
459 'open(\\'src/git_hooked1\\', \\'w\\').write(\\'git_hooked1\\')'], | 479 'open(\\'src/git_hooked1\\', \\'w\\').write(\\'git_hooked1\\')'], |
460 }, | 480 }, |
461 { | 481 { |
462 # Should not be run. | 482 # Should not be run. |
463 'pattern': 'nonexistent', | 483 'pattern': 'nonexistent', |
464 'action': ['python', '-c', | 484 'action': ['python', '-c', |
465 'open(\\'src/git_hooked2\\', \\'w\\').write(\\'git_hooked2\\')'], | 485 'open(\\'src/git_hooked2\\', \\'w\\').write(\\'git_hooked2\\')'], |
466 }, | 486 }, |
467 ] | 487 ] |
468 """ % { | 488 """ % { |
469 'host': self.HOST, | 489 'host': self.HOST, |
470 # See self.__init__() for the format. Grab's the hash of the first | 490 # See self.__init__() for the format. Grab's the hash of the first |
471 # commit in repo_2. Only keep the first 7 character because of: | 491 # commit in repo_2. Only keep the first 7 character because of: |
472 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh. | 492 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh. |
473 'hash': self.git_hashes['repo_2'][1][0][:7] | 493 'hash': self.git_hashes['repo_2'][1][0][:7] |
474 }, | 494 }, |
475 'origin': "git/repo_1@2\n" | 495 'origin': 'git/repo_1@2\n', |
476 }) | 496 }) |
477 | 497 |
478 # Start the daemon. | 498 # Start the daemon. |
479 cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir] | 499 cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir] |
480 if self.HOST == '127.0.0.1': | 500 if self.HOST == '127.0.0.1': |
481 cmd.append('--listen=127.0.0.1') | 501 cmd.append('--listen=127.0.0.1') |
482 logging.debug(cmd) | 502 logging.debug(cmd) |
483 self.gitdaemon = Popen(cmd, cwd=self.repos_dir) | 503 self.gitdaemon = Popen(cmd, cwd=self.repos_dir) |
484 return True | 504 return True |
485 | 505 |
(...skipping 18 matching lines...) Expand all Loading... |
504 new_tree = tree.copy() | 524 new_tree = tree.copy() |
505 self.git_hashes[repo].append((hash, new_tree)) | 525 self.git_hashes[repo].append((hash, new_tree)) |
506 | 526 |
507 | 527 |
508 class FakeReposTestBase(unittest.TestCase): | 528 class FakeReposTestBase(unittest.TestCase): |
509 """This is vaguely inspired by twisted.""" | 529 """This is vaguely inspired by twisted.""" |
510 | 530 |
511 # Replace this in your subclass. | 531 # Replace this in your subclass. |
512 CLASS_ROOT_DIR = None | 532 CLASS_ROOT_DIR = None |
513 | 533 |
514 # static FakeRepos instance. | 534 # static FakeRepos instance. Lazy loaded. |
515 FAKE_REPOS = FakeRepos() | 535 FAKE_REPOS = None |
| 536 |
| 537 def __init__(self, *args, **kwargs): |
| 538 unittest.TestCase.__init__(self, *args, **kwargs) |
| 539 if not FakeReposTestBase.FAKE_REPOS: |
| 540 FakeReposTestBase.FAKE_REPOS = FakeRepos() |
516 | 541 |
517 def setUp(self): | 542 def setUp(self): |
518 unittest.TestCase.setUp(self) | 543 unittest.TestCase.setUp(self) |
519 self.FAKE_REPOS.setUp() | 544 self.FAKE_REPOS.setUp() |
520 | 545 |
521 # Remove left overs and start fresh. | 546 # Remove left overs and start fresh. |
522 if not self.CLASS_ROOT_DIR: | 547 if not self.CLASS_ROOT_DIR: |
523 self.CLASS_ROOT_DIR = join(self.FAKE_REPOS.trial_dir(), 'smoke') | 548 self.CLASS_ROOT_DIR = join(self.FAKE_REPOS.trial_dir(), 'smoke') |
524 self.root_dir = join(self.CLASS_ROOT_DIR, self.id()) | 549 self.root_dir = join(self.CLASS_ROOT_DIR, self.id()) |
525 rmtree(self.root_dir) | 550 rmtree(self.root_dir) |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
599 print 'Using %s' % fake.trial_dir() | 624 print 'Using %s' % fake.trial_dir() |
600 try: | 625 try: |
601 fake.setUp() | 626 fake.setUp() |
602 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.') | 627 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.') |
603 sys.stdin.readline() | 628 sys.stdin.readline() |
604 except KeyboardInterrupt: | 629 except KeyboardInterrupt: |
605 fake.SHOULD_LEAK = True | 630 fake.SHOULD_LEAK = True |
606 return 0 | 631 return 0 |
607 | 632 |
608 | 633 |
| 634 # Kind of hack. |
| 635 if '-l' in sys.argv: |
| 636 FakeRepos.SHOULD_LEAK = True |
| 637 sys.argv.remove('-l') |
| 638 |
| 639 |
609 if __name__ == '__main__': | 640 if __name__ == '__main__': |
610 sys.exit(main(sys.argv)) | 641 sys.exit(main(sys.argv)) |
OLD | NEW |