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

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

Powered by Google App Engine
This is Rietveld 408576698