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

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
M-A Ruel 2013/04/16 20:28:04 Sadly, this will break tests on Windows. But I don
kustermann 2013/04/17 13:55:06 I introduced a branch for windows, but I've no ide
318 revprop_hook_filename = join(self.svn_repo, 'hooks', 'pre-revprop-change')
319 write(revprop_hook_filename,
320 '#!/bin/sh\n'
321 'exit 0\n')
322 os.chmod(revprop_hook_filename, 0755)
323
324 # Mac 10.6 ships with a buggy subversion build and we need this line 324 # Mac 10.6 ships with a buggy subversion build and we need this line
325 # to work around the bug. 325 # to work around the bug.
326 write(join(self.svn_repo, 'db', 'fsfs.conf'), 326 write(join(self.svn_repo, 'db', 'fsfs.conf'),
327 '[rep-sharing]\n' 327 '[rep-sharing]\n'
328 'enable-rep-sharing = false\n') 328 'enable-rep-sharing = false\n')
329 329
330 # Start the daemon. 330 # Start the daemon.
331 self.svn_port = find_free_port(self.host, 10000) 331 self.svn_port = find_free_port(self.host, 10000)
332 logging.debug('Using port %d' % self.svn_port) 332 logging.debug('Using port %d' % self.svn_port)
333 cmd = ['svnserve', '-d', '--foreground', '-r', self.root_dir, 333 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): 385 def _commit_svn(self, tree):
386 self._genTree(self.svn_checkout, tree) 386 self._genTree(self.svn_checkout, tree)
387 commit_svn(self.svn_checkout, self.USERS[0][0], self.USERS[0][1]) 387 commit_svn(self.svn_checkout, self.USERS[0][0], self.USERS[0][1])
388 if self.svn_revs and self.svn_revs[-1]: 388 if self.svn_revs and self.svn_revs[-1]:
389 new_tree = self.svn_revs[-1].copy() 389 new_tree = self.svn_revs[-1].copy()
390 new_tree.update(tree) 390 new_tree.update(tree)
391 else: 391 else:
392 new_tree = tree.copy() 392 new_tree = tree.copy()
393 self.svn_revs.append(new_tree) 393 self.svn_revs.append(new_tree)
394 394
395 def _set_svn_commit_date(self, revision, date):
396 subprocess2.check_output(
397 ['svn', 'propset', 'svn:date', '--revprop', '-r', revision, date,
398 self.svn_base,
399 '--username', self.USERS[0][0],
400 '--password', self.USERS[0][1],
401 '--non-interactive'])
402
395 def _commit_git(self, repo, tree): 403 def _commit_git(self, repo, tree):
396 repo_root = join(self.git_root, repo) 404 repo_root = join(self.git_root, repo)
397 self._genTree(repo_root, tree) 405 self._genTree(repo_root, tree)
398 commit_hash = commit_git(repo_root) 406 commit_hash = commit_git(repo_root)
399 if self.git_hashes[repo][-1]: 407 if self.git_hashes[repo][-1]:
400 new_tree = self.git_hashes[repo][-1][1].copy() 408 new_tree = self.git_hashes[repo][-1][1].copy()
401 new_tree.update(tree) 409 new_tree.update(tree)
402 else: 410 else:
403 new_tree = tree.copy() 411 new_tree = tree.copy()
404 self.git_hashes[repo].append((commit_hash, new_tree)) 412 self.git_hashes[repo].append((commit_hash, new_tree))
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
633 ] 641 ]
634 """ % { 642 """ % {
635 'git_base': self.git_base, 643 'git_base': self.git_base,
636 # See self.__init__() for the format. Grab's the hash of the first 644 # 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: 645 # 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. 646 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh.
639 'hash': self.git_hashes['repo_2'][1][0][:7] 647 'hash': self.git_hashes['repo_2'][1][0][:7]
640 }, 648 },
641 'origin': 'git/repo_1@2\n', 649 'origin': 'git/repo_1@2\n',
642 }) 650 })
643 651
M-A Ruel 2013/04/16 20:28:04 2 lines between file-level symbols
kustermann 2013/04/17 13:55:06 Done.
652 class FakeRepoTransitive(FakeReposBase):
653 """Implements populateSvn()"""
654
655 def populateSvn(self):
656 """Creates a few revisions of changes including a DEPS file."""
657 # Repos
658 subprocess2.check_call(
659 ['svn', 'checkout', self.svn_base, self.svn_checkout,
660 '-q', '--non-interactive', '--no-auth-cache',
661 '--username', self.USERS[0][0], '--password', self.USERS[0][1]])
662 assert os.path.isdir(join(self.svn_checkout, '.svn'))
663
664 def file_system(rev):
665 DEPS = """deps = {
666 'src/different_repo': '%(svn_base)strunk/third_party',
667 'src/different_repo_fixed': '%(svn_base)strunk/third_party@1',
668 'src/same_repo': '/trunk/third_party',
669 'src/same_repo_fixed': '/trunk/third_party@1',
670 }""" % { 'svn_base': self.svn_base }
671 return {
672 'trunk/src/DEPS': DEPS,
673 'trunk/src/origin': 'svn/trunk/src@%(rev)d' % { 'rev': rev },
674 'trunk/third_party/origin':
675 'svn/trunk/third_party@%(rev)d' % { 'rev': rev },
676 }
677
678 # We make three commits. We use always the same DEPS contents but
679 # - 'trunk/src/origin' contains 'svn/trunk/src/origin@rX'
680 # - 'trunk/third_party/origin' contains 'svn/trunk/third_party/origin@rX'
681 # where 'X' is the revision number.
682 # So the 'origin' files will change in every commit.
683 self._commit_svn(file_system(1))
684 self._commit_svn(file_system(2))
685 self._commit_svn(file_system(3))
686 # We rewrite the timestamps so we can test that '--transitive' will take the
687 # parent timestamp on different repositories and the parent revision
688 # otherwise.
689 self._set_svn_commit_date('1', '2011-10-01T03:00:00.000000Z')
690 self._set_svn_commit_date('2', '2011-10-09T03:00:00.000000Z')
691 self._set_svn_commit_date('3', '2011-10-02T03:00:00.000000Z')
692
693 def populateGit(self):
694 pass
644 695
M-A Ruel 2013/04/16 20:28:04 here too
kustermann 2013/04/17 13:55:06 Done.
645 class FakeReposTestBase(trial_dir.TestCase): 696 class FakeReposTestBase(trial_dir.TestCase):
646 """This is vaguely inspired by twisted.""" 697 """This is vaguely inspired by twisted."""
647 # static FakeRepos instance. Lazy loaded.
648 FAKE_REPOS = None
649 # Override if necessary. 698 # Override if necessary.
650 FAKE_REPOS_CLASS = FakeRepos 699 FAKE_REPOS_CLASS = FakeRepos
651 700
652 def setUp(self): 701 def setUp(self):
653 super(FakeReposTestBase, self).setUp() 702 super(FakeReposTestBase, self).setUp()
654 if not FakeReposTestBase.FAKE_REPOS: 703 FakeReposTestBase.FAKE_REPOS = self.FAKE_REPOS_CLASS()
M-A Ruel 2013/04/16 20:28:04 That will significantly slow down the test but oh
kustermann 2013/04/17 13:55:06 We can cache it based on 'self.FAKE_REPOS_CLASS'.
655 # Lazy create the global instance.
656 FakeReposTestBase.FAKE_REPOS = self.FAKE_REPOS_CLASS()
657 # No need to call self.FAKE_REPOS.setUp(), it will be called by the child 704 # No need to call self.FAKE_REPOS.setUp(), it will be called by the child
658 # class. 705 # class.
659 # Do not define tearDown(), since super's version does the right thing and 706 # Do not define tearDown(), since super's version does the right thing and
660 # FAKE_REPOS is kept across tests. 707 # FAKE_REPOS is kept across tests.
661 708
662 @property 709 @property
663 def svn_base(self): 710 def svn_base(self):
664 """Shortcut.""" 711 """Shortcut."""
665 return self.FAKE_REPOS.svn_base 712 return self.FAKE_REPOS.svn_base
666 713
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 fake.set_up_git() 790 fake.set_up_git()
744 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.') 791 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.')
745 sys.stdin.readline() 792 sys.stdin.readline()
746 except KeyboardInterrupt: 793 except KeyboardInterrupt:
747 trial_dir.TrialDir.SHOULD_LEAK.leak = True 794 trial_dir.TrialDir.SHOULD_LEAK.leak = True
748 return 0 795 return 0
749 796
750 797
751 if __name__ == '__main__': 798 if __name__ == '__main__':
752 sys.exit(main(sys.argv)) 799 sys.exit(main(sys.argv))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698