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

Side by Side Diff: testing_support/fake_repos.py

Issue 13814012: Changed the behaviour of '--transitive' in gclient.py to use revision instead of timestamp for iden… (Closed) Base URL: https://chromium.googlesource.com/chromium/tools/depot_tools.git@master
Patch Set: Created 7 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 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 datetime 9 import datetime
10 import errno 10 import errno
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 sock.connect((host, port)) 154 sock.connect((host, port))
155 logging.debug('%d was bound, waiting to free' % port) 155 logging.debug('%d was bound, waiting to free' % port)
156 except (socket.error, EnvironmentError): 156 except (socket.error, EnvironmentError):
157 logging.debug('%d now free' % port) 157 logging.debug('%d now free' % port)
158 return 158 return
159 finally: 159 finally:
160 sock.close() 160 sock.close()
161 assert False, '%d is still bound' % port 161 assert False, '%d is still bound' % port
162 162
163 163
164 _FAKE_LOADED = False
165
166 class FakeReposBase(object): 164 class FakeReposBase(object):
167 """Generate both svn and git repositories to test gclient functionality. 165 """Generate both svn and git repositories to test gclient functionality.
168 166
169 Many DEPS functionalities need to be tested: Var, File, From, deps_os, hooks, 167 Many DEPS functionalities need to be tested: Var, File, From, deps_os, hooks,
170 use_relative_paths. 168 use_relative_paths.
171 169
172 And types of dependencies: Relative urls, Full urls, both svn and git. 170 And types of dependencies: Relative urls, Full urls, both svn and git.
173 171
174 populateSvn() and populateGit() need to be implemented by the subclass. 172 populateSvn() and populateGit() need to be implemented by the subclass.
175 """ 173 """
176 # Hostname 174 # Hostname
177 NB_GIT_REPOS = 1 175 NB_GIT_REPOS = 1
178 USERS = [ 176 USERS = [
179 ('user1@example.com', 'foo'), 177 ('user1@example.com', 'foo'),
180 ('user2@example.com', 'bar'), 178 ('user2@example.com', 'bar'),
181 ] 179 ]
182 180
183 def __init__(self, host=None): 181 def __init__(self, host=None):
184 global _FAKE_LOADED
185 if _FAKE_LOADED:
186 raise Exception('You can only start one FakeRepos at a time.')
187 _FAKE_LOADED = True
188
189 self.trial = trial_dir.TrialDir('repos') 182 self.trial = trial_dir.TrialDir('repos')
190 self.host = host or '127.0.0.1' 183 self.host = host or '127.0.0.1'
191 # Format is [ None, tree, tree, ...] 184 # Format is [ None, tree, tree, ...]
192 # i.e. revisions are 1-based. 185 # i.e. revisions are 1-based.
193 self.svn_revs = [None] 186 self.svn_revs = [None]
194 # Format is { repo: [ None, (hash, tree), (hash, tree), ... ], ... } 187 # Format is { repo: [ None, (hash, tree), (hash, tree), ... ], ... }
195 # so reference looks like self.git_hashes[repo][rev][0] for hash and 188 # so reference looks like self.git_hashes[repo][rev][0] for hash and
196 # self.git_hashes[repo][rev][1] for it's tree snapshot. 189 # self.git_hashes[repo][rev][1] for it's tree snapshot.
197 # For consistency with self.svn_revs, it is 1-based too. 190 # For consistency with self.svn_revs, it is 1-based too.
198 self.git_hashes = {} 191 self.git_hashes = {}
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
314 return False 307 return False
315 write(join(self.svn_repo, 'conf', 'svnserve.conf'), 308 write(join(self.svn_repo, 'conf', 'svnserve.conf'),
316 '[general]\n' 309 '[general]\n'
317 'anon-access = read\n' 310 'anon-access = read\n'
318 'auth-access = write\n' 311 'auth-access = write\n'
319 'password-db = passwd\n') 312 'password-db = passwd\n')
320 text = '[users]\n' 313 text = '[users]\n'
321 text += ''.join('%s = %s\n' % (usr, pwd) for usr, pwd in self.USERS) 314 text += ''.join('%s = %s\n' % (usr, pwd) for usr, pwd in self.USERS)
322 write(join(self.svn_repo, 'conf', 'passwd'), text) 315 write(join(self.svn_repo, 'conf', 'passwd'), text)
323 316
317 # Necessary to be able to change revision properties
318 revprop_hook_filename = join(self.svn_repo, 'hooks', 'pre-revprop-change')
319 if sys.platform == 'win32':
320 write("%s.bat" % revprop_hook_filename, "")
M-A Ruel 2013/04/17 14:54:09 Add a # TODO(kustermann): Test on Windows one day.
kustermann 2013/04/18 08:28:40 Done :-)
321 else:
322 write(revprop_hook_filename,
323 '#!/bin/sh\n'
324 'exit 0\n')
325 os.chmod(revprop_hook_filename, 0755)
326
324 # Mac 10.6 ships with a buggy subversion build and we need this line 327 # Mac 10.6 ships with a buggy subversion build and we need this line
325 # to work around the bug. 328 # to work around the bug.
326 write(join(self.svn_repo, 'db', 'fsfs.conf'), 329 write(join(self.svn_repo, 'db', 'fsfs.conf'),
327 '[rep-sharing]\n' 330 '[rep-sharing]\n'
328 'enable-rep-sharing = false\n') 331 'enable-rep-sharing = false\n')
329 332
330 # Start the daemon. 333 # Start the daemon.
331 self.svn_port = find_free_port(self.host, 10000) 334 self.svn_port = find_free_port(self.host, 10000)
332 logging.debug('Using port %d' % self.svn_port) 335 logging.debug('Using port %d' % self.svn_port)
333 cmd = ['svnserve', '-d', '--foreground', '-r', self.root_dir, 336 cmd = ['svnserve', '-d', '--foreground', '-r', self.root_dir,
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
385 def _commit_svn(self, tree): 388 def _commit_svn(self, tree):
386 self._genTree(self.svn_checkout, tree) 389 self._genTree(self.svn_checkout, tree)
387 commit_svn(self.svn_checkout, self.USERS[0][0], self.USERS[0][1]) 390 commit_svn(self.svn_checkout, self.USERS[0][0], self.USERS[0][1])
388 if self.svn_revs and self.svn_revs[-1]: 391 if self.svn_revs and self.svn_revs[-1]:
389 new_tree = self.svn_revs[-1].copy() 392 new_tree = self.svn_revs[-1].copy()
390 new_tree.update(tree) 393 new_tree.update(tree)
391 else: 394 else:
392 new_tree = tree.copy() 395 new_tree = tree.copy()
393 self.svn_revs.append(new_tree) 396 self.svn_revs.append(new_tree)
394 397
398 def _set_svn_commit_date(self, revision, date):
399 subprocess2.check_output(
400 ['svn', 'propset', 'svn:date', '--revprop', '-r', revision, date,
401 self.svn_base,
402 '--username', self.USERS[0][0],
403 '--password', self.USERS[0][1],
404 '--non-interactive'])
405
395 def _commit_git(self, repo, tree): 406 def _commit_git(self, repo, tree):
396 repo_root = join(self.git_root, repo) 407 repo_root = join(self.git_root, repo)
397 self._genTree(repo_root, tree) 408 self._genTree(repo_root, tree)
398 commit_hash = commit_git(repo_root) 409 commit_hash = commit_git(repo_root)
399 if self.git_hashes[repo][-1]: 410 if self.git_hashes[repo][-1]:
400 new_tree = self.git_hashes[repo][-1][1].copy() 411 new_tree = self.git_hashes[repo][-1][1].copy()
401 new_tree.update(tree) 412 new_tree.update(tree)
402 else: 413 else:
403 new_tree = tree.copy() 414 new_tree = tree.copy()
404 self.git_hashes[repo].append((commit_hash, new_tree)) 415 self.git_hashes[repo].append((commit_hash, new_tree))
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 'git_base': self.git_base, 646 'git_base': self.git_base,
636 # See self.__init__() for the format. Grab's the hash of the first 647 # See self.__init__() for the format. Grab's the hash of the first
637 # commit in repo_2. Only keep the first 7 character because of: 648 # commit in repo_2. Only keep the first 7 character because of:
638 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh. 649 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh.
639 'hash': self.git_hashes['repo_2'][1][0][:7] 650 'hash': self.git_hashes['repo_2'][1][0][:7]
640 }, 651 },
641 'origin': 'git/repo_1@2\n', 652 'origin': 'git/repo_1@2\n',
642 }) 653 })
643 654
644 655
656 class FakeRepoTransitive(FakeReposBase):
657 """Implements populateSvn()"""
658
659 def populateSvn(self):
660 """Creates a few revisions of changes including a DEPS file."""
661 # Repos
662 subprocess2.check_call(
663 ['svn', 'checkout', self.svn_base, self.svn_checkout,
664 '-q', '--non-interactive', '--no-auth-cache',
665 '--username', self.USERS[0][0], '--password', self.USERS[0][1]])
666 assert os.path.isdir(join(self.svn_checkout, '.svn'))
667
668 def file_system(rev):
669 DEPS = """deps = {
670 'src/different_repo': '%(svn_base)strunk/third_party',
671 'src/different_repo_fixed': '%(svn_base)strunk/third_party@1',
672 'src/same_repo': '/trunk/third_party',
673 'src/same_repo_fixed': '/trunk/third_party@1',
674 }""" % { 'svn_base': self.svn_base }
675 return {
676 'trunk/src/DEPS': DEPS,
677 'trunk/src/origin': 'svn/trunk/src@%(rev)d' % { 'rev': rev },
678 'trunk/third_party/origin':
679 'svn/trunk/third_party@%(rev)d' % { 'rev': rev },
680 }
681
682 # We make three commits. We use always the same DEPS contents but
683 # - 'trunk/src/origin' contains 'svn/trunk/src/origin@rX'
684 # - 'trunk/third_party/origin' contains 'svn/trunk/third_party/origin@rX'
685 # where 'X' is the revision number.
686 # So the 'origin' files will change in every commit.
687 self._commit_svn(file_system(1))
688 self._commit_svn(file_system(2))
689 self._commit_svn(file_system(3))
690 # We rewrite the timestamps so we can test that '--transitive' will take the
691 # parent timestamp on different repositories and the parent revision
692 # otherwise.
693 self._set_svn_commit_date('1', '2011-10-01T03:00:00.000000Z')
694 self._set_svn_commit_date('2', '2011-10-09T03:00:00.000000Z')
695 self._set_svn_commit_date('3', '2011-10-02T03:00:00.000000Z')
696
697 def populateGit(self):
698 pass
699
700
645 class FakeReposTestBase(trial_dir.TestCase): 701 class FakeReposTestBase(trial_dir.TestCase):
646 """This is vaguely inspired by twisted.""" 702 """This is vaguely inspired by twisted."""
647 # static FakeRepos instance. Lazy loaded. 703 # Static FakeRepos instances. Lazy loaded.
648 FAKE_REPOS = None 704 CACHED_FAKE_REPOS = {}
649 # Override if necessary. 705 # Override if necessary.
650 FAKE_REPOS_CLASS = FakeRepos 706 FAKE_REPOS_CLASS = FakeRepos
651 707
652 def setUp(self): 708 def setUp(self):
653 super(FakeReposTestBase, self).setUp() 709 super(FakeReposTestBase, self).setUp()
654 if not FakeReposTestBase.FAKE_REPOS: 710 if not self.FAKE_REPOS_CLASS in self.CACHED_FAKE_REPOS:
M-A Ruel 2013/04/17 14:54:09 Thanks, that's a good idea.
655 # Lazy create the global instance. 711 self.CACHED_FAKE_REPOS[self.FAKE_REPOS_CLASS] = self.FAKE_REPOS_CLASS()
656 FakeReposTestBase.FAKE_REPOS = self.FAKE_REPOS_CLASS() 712 self.FAKE_REPOS = self.CACHED_FAKE_REPOS[self.FAKE_REPOS_CLASS]
657 # No need to call self.FAKE_REPOS.setUp(), it will be called by the child 713 # No need to call self.FAKE_REPOS.setUp(), it will be called by the child
658 # class. 714 # class.
659 # Do not define tearDown(), since super's version does the right thing and 715 # Do not define tearDown(), since super's version does the right thing and
660 # FAKE_REPOS is kept across tests. 716 # self.FAKE_REPOS is kept across tests.
661 717
662 @property 718 @property
663 def svn_base(self): 719 def svn_base(self):
664 """Shortcut.""" 720 """Shortcut."""
665 return self.FAKE_REPOS.svn_base 721 return self.FAKE_REPOS.svn_base
666 722
667 @property 723 @property
668 def git_base(self): 724 def git_base(self):
669 """Shortcut.""" 725 """Shortcut."""
670 return self.FAKE_REPOS.git_base 726 return self.FAKE_REPOS.git_base
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 fake.set_up_git() 799 fake.set_up_git()
744 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.') 800 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.')
745 sys.stdin.readline() 801 sys.stdin.readline()
746 except KeyboardInterrupt: 802 except KeyboardInterrupt:
747 trial_dir.TrialDir.SHOULD_LEAK.leak = True 803 trial_dir.TrialDir.SHOULD_LEAK.leak = True
748 return 0 804 return 0
749 805
750 806
751 if __name__ == '__main__': 807 if __name__ == '__main__':
752 sys.exit(main(sys.argv)) 808 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698