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

Side by Side Diff: tests/fake_repos.py

Issue 2352002: Make FakeRepos more reusable. Make it work with 'coverage'. (Closed)
Patch Set: Created 10 years, 6 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/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 logging 9 import logging
9 import os 10 import os
10 import re 11 import re
11 import shutil 12 import shutil
12 import subprocess 13 import subprocess
13 import sys 14 import sys
15 import unittest
16
17
18 ## Utility functions
14 19
15 20
16 def addKill(): 21 def addKill():
17 """Add kill() method to subprocess.Popen for python <2.6""" 22 """Add kill() method to subprocess.Popen for python <2.6"""
18 if getattr(subprocess.Popen, 'kill', None): 23 if getattr(subprocess.Popen, 'kill', None):
19 return 24 return
20 if sys.platform.startswith('win'): 25 if sys.platform.startswith('win'):
21 def kill_win(process): 26 def kill_win(process):
22 import win32process 27 import win32process
23 return win32process.TerminateProcess(process._handle, -1) 28 return win32process.TerminateProcess(process._handle, -1)
(...skipping 13 matching lines...) Expand all
37 42
38 def write(path, content): 43 def write(path, content):
39 f = open(path, 'wb') 44 f = open(path, 'wb')
40 f.write(content) 45 f.write(content)
41 f.close() 46 f.close()
42 47
43 48
44 join = os.path.join 49 join = os.path.join
45 50
46 51
47 def call(*args, **kwargs):
48 logging.debug(args[0])
49 subprocess.call(*args, **kwargs)
50
51
52 def check_call(*args, **kwargs): 52 def check_call(*args, **kwargs):
53 logging.debug(args[0]) 53 logging.debug(args[0])
54 subprocess.check_call(*args, **kwargs) 54 subprocess.check_call(*args, **kwargs)
55 55
56 56
57 def Popen(*args, **kwargs): 57 def Popen(*args, **kwargs):
58 kwargs.setdefault('stdout', subprocess.PIPE) 58 kwargs.setdefault('stdout', subprocess.PIPE)
59 kwargs.setdefault('stderr', subprocess.STDOUT) 59 kwargs.setdefault('stderr', subprocess.STDOUT)
60 logging.debug(args[0]) 60 logging.debug(args[0])
61 return subprocess.Popen(*args, **kwargs) 61 return subprocess.Popen(*args, **kwargs)
62 62
63 63
64 def read_tree(tree_root):
65 """Returns a dict of all the files in a tree. Defaults to self.root_dir."""
66 tree = {}
67 for root, dirs, files in os.walk(tree_root):
68 for d in filter(lambda x: x.startswith('.'), dirs):
69 dirs.remove(d)
70 for f in [join(root, f) for f in files if not f.startswith('.')]:
71 tree[f[len(tree_root) + 1:]] = open(join(root, f), 'rb').read()
72 return tree
73
74
75 def dict_diff(dict1, dict2):
76 diff = {}
77 for k, v in dict1.iteritems():
78 if k not in dict2:
79 diff[k] = v
80 elif v != dict2[k]:
81 diff[k] = (v, dict2[k])
82 for k, v in dict2.iteritems():
83 if k not in dict1:
84 diff[k] = v
85 return diff
86
87
88 def mangle_svn_tree(*args):
89 result = {}
90 for old_root, new_root, tree in args:
91 for k, v in tree.iteritems():
92 if not k.startswith(old_root):
93 continue
94 result[join(new_root, k[len(old_root) + 1:])] = v
95 return result
96
97
98 def mangle_git_tree(*args):
99 result = {}
100 for new_root, tree in args:
101 for k, v in tree.iteritems():
102 result[join(new_root, k)] = v
103 return result
104
105
64 def commit_svn(repo): 106 def commit_svn(repo):
65 """Commits the changes and returns the new revision number.""" 107 """Commits the changes and returns the new revision number."""
66 # Basic parsing. 108 # Basic parsing.
67 to_add = [] 109 to_add = []
68 to_remove = [] 110 to_remove = []
69 for item in Popen(['svn', 'status'], 111 for item in Popen(['svn', 'status'],
70 cwd=repo).communicate()[0].splitlines(False): 112 cwd=repo).communicate()[0].splitlines(False):
71 if item[0] == '?': 113 if item[0] == '?':
72 to_add.append(item[8:]) 114 to_add.append(item[8:])
73 elif item[0] == '!': 115 elif item[0] == '!':
(...skipping 15 matching lines...) Expand all
89 def commit_git(repo): 131 def commit_git(repo):
90 """Commits the changes and returns the new hash.""" 132 """Commits the changes and returns the new hash."""
91 check_call(['git', 'add', '-A', '-f'], cwd=repo) 133 check_call(['git', 'add', '-A', '-f'], cwd=repo)
92 check_call(['git', 'commit', '-q', '--message', 'foo'], cwd=repo) 134 check_call(['git', 'commit', '-q', '--message', 'foo'], cwd=repo)
93 rev = Popen(['git', 'show-ref', '--head', 'HEAD'], 135 rev = Popen(['git', 'show-ref', '--head', 'HEAD'],
94 cwd=repo).communicate()[0].split(' ', 1)[0] 136 cwd=repo).communicate()[0].split(' ', 1)[0]
95 logging.debug('At revision %s' % rev) 137 logging.debug('At revision %s' % rev)
96 return rev 138 return rev
97 139
98 140
141 _FAKE_LOADED = False
142
99 class FakeRepos(object): 143 class FakeRepos(object):
100 """Generate both svn and git repositories to test gclient functionality. 144 """Generate both svn and git repositories to test gclient functionality.
101 145
102 Many DEPS functionalities need to be tested: Var, File, From, deps_os, hooks, 146 Many DEPS functionalities need to be tested: Var, File, From, deps_os, hooks,
103 use_relative_paths. 147 use_relative_paths.
104 148
105 And types of dependencies: Relative urls, Full urls, both svn and git.""" 149 And types of dependencies: Relative urls, Full urls, both svn and git."""
106 150
107 def __init__(self, trial_dir, leak, local_only): 151 # Should leak the repositories.
108 self.trial_dir = trial_dir 152 SHOULD_LEAK = False
109 self.repos_dir = os.path.join(self.trial_dir, 'repos') 153 # Override if unhappy.
110 self.git_root = join(self.repos_dir, 'git') 154 TRIAL_DIR = None
111 self.svn_root = join(self.repos_dir, 'svn_checkout') 155 # Hostname
112 self.leak = leak 156 HOST = '127.0.0.1'
113 self.local_only = local_only 157
114 self.svnserve = [] 158 def __init__(self, trial_dir=None, leak=None, host=None):
115 self.gitdaemon = [] 159 global _FAKE_LOADED
116 addKill() 160 if _FAKE_LOADED:
117 rmtree(self.trial_dir) 161 raise Exception('You can only start one FakeRepos at a time.')
118 os.mkdir(self.trial_dir) 162 _FAKE_LOADED = True
119 os.mkdir(self.repos_dir) 163 # Quick hack.
164 if '-v' in sys.argv:
165 logging.basicConfig(level=logging.DEBUG)
166 if '-l' in sys.argv:
167 self.SHOULD_LEAK = True
168 sys.argv.remove('-l')
169 elif leak is not None:
170 self.SHOULD_LEAK = leak
171 if host:
172 self.HOST = host
173 if trial_dir:
174 self.TRIAL_DIR = trial_dir
175
120 # Format is [ None, tree, tree, ...] 176 # Format is [ None, tree, tree, ...]
121 self.svn_revs = [None] 177 self.svn_revs = [None]
122 # Format is { repo: [ (hash, tree), (hash, tree), ... ], ... } 178 # Format is { repo: [ (hash, tree), (hash, tree), ... ], ... }
123 self.git_hashes = {} 179 self.git_hashes = {}
180 self.svnserve = None
181 self.gitdaemon = None
182 self.common_init = False
183
184 def trial_dir(self):
185 if not self.TRIAL_DIR:
186 self.TRIAL_DIR = os.path.join(
187 os.path.dirname(os.path.abspath(__file__)), '_trial')
188 return self.TRIAL_DIR
124 189
125 def setUp(self): 190 def setUp(self):
126 self.setUpSVN() 191 """All late initialization comes here.
127 self.setUpGIT() 192
193 Note that it deletes all trial_dir() and not only repos_dir."""
194 if not self.common_init:
195 self.common_init = True
196 self.repos_dir = os.path.join(self.trial_dir(), 'repos')
197 self.git_root = join(self.repos_dir, 'git')
198 self.svn_root = join(self.repos_dir, 'svn_checkout')
199 addKill()
200 rmtree(self.trial_dir())
201 os.makedirs(self.repos_dir)
202 atexit.register(self.tearDown)
128 203
129 def tearDown(self): 204 def tearDown(self):
130 for i in self.svnserve: 205 if self.svnserve:
131 logging.debug('Killing svnserve pid %s' % i.pid) 206 logging.debug('Killing svnserve pid %s' % self.svnserve.pid)
132 i.kill() 207 self.svnserve.kill()
133 for i in self.gitdaemon: 208 self.svnserve = None
134 logging.debug('Killing git-daemon pid %s' % i.pid) 209 if self.gitdaemon:
135 i.kill() 210 logging.debug('Killing git-daemon pid %s' % self.gitdaemon.pid)
136 if not self.leak: 211 self.gitdaemon.kill()
137 logging.debug('Removing %s' % self.trial_dir) 212 self.gitdaemon = None
138 rmtree(self.trial_dir) 213 if not self.SHOULD_LEAK:
214 logging.debug('Removing %s' % self.trial_dir())
215 rmtree(self.trial_dir())
139 216
140 def _genTree(self, root, tree_dict): 217 def _genTree(self, root, tree_dict):
141 """For a dictionary of file contents, generate a filesystem.""" 218 """For a dictionary of file contents, generate a filesystem."""
142 if not os.path.isdir(root): 219 if not os.path.isdir(root):
143 os.makedirs(root) 220 os.makedirs(root)
144 for (k, v) in tree_dict.iteritems(): 221 for (k, v) in tree_dict.iteritems():
145 k_os = k.replace('/', os.sep) 222 k_os = k.replace('/', os.sep)
146 k_arr = k_os.split(os.sep) 223 k_arr = k_os.split(os.sep)
147 if len(k_arr) > 1: 224 if len(k_arr) > 1:
148 p = os.sep.join([root] + k_arr[:-1]) 225 p = os.sep.join([root] + k_arr[:-1])
149 if not os.path.isdir(p): 226 if not os.path.isdir(p):
150 os.makedirs(p) 227 os.makedirs(p)
151 if v is None: 228 if v is None:
152 os.remove(join(root, k)) 229 os.remove(join(root, k))
153 else: 230 else:
154 write(join(root, k), v) 231 write(join(root, k), v)
155 232
156 def setUpSVN(self): 233 def setUpSVN(self):
157 """Creates subversion repositories and start the servers.""" 234 """Creates subversion repositories and start the servers."""
158 assert not self.svnserve 235 if self.svnserve:
236 return
237 self.setUp()
159 root = join(self.repos_dir, 'svn') 238 root = join(self.repos_dir, 'svn')
160 rmtree(root)
161 check_call(['svnadmin', 'create', root]) 239 check_call(['svnadmin', 'create', root])
162 write(join(root, 'conf', 'svnserve.conf'), 240 write(join(root, 'conf', 'svnserve.conf'),
163 '[general]\n' 241 '[general]\n'
164 'anon-access = read\n' 242 'anon-access = read\n'
165 'auth-access = write\n' 243 'auth-access = write\n'
166 'password-db = passwd\n') 244 'password-db = passwd\n')
167 write(join(root, 'conf', 'passwd'), 245 write(join(root, 'conf', 'passwd'),
168 '[users]\n' 246 '[users]\n'
169 'user1 = foo\n' 247 'user1 = foo\n'
170 'user2 = bar\n') 248 'user2 = bar\n')
171 249
172 # Start the daemon. 250 # Start the daemon.
173 cmd = ['svnserve', '-d', '--foreground', '-r', self.repos_dir] 251 cmd = ['svnserve', '-d', '--foreground', '-r', self.repos_dir]
174 if self.local_only: 252 if self.HOST == '127.0.0.1':
175 cmd.append('--listen-host=127.0.0.1') 253 cmd.append('--listen-host=127.0.0.1')
176 logging.debug(cmd) 254 logging.debug(cmd)
177 self.svnserve.append(Popen(cmd, cwd=root)) 255 self.svnserve = Popen(cmd, cwd=root)
178 self.populateSvn() 256 self.populateSvn()
179 257
180 def populateSvn(self): 258 def populateSvn(self):
181 """Creates a few revisions of changes including DEPS files.""" 259 """Creates a few revisions of changes including DEPS files."""
182 # Repos 260 # Repos
183 check_call(['svn', 'checkout', 'svn://127.0.0.1/svn', self.svn_root, '-q', 261 check_call(['svn', 'checkout', 'svn://127.0.0.1/svn', self.svn_root, '-q',
184 '--non-interactive', '--no-auth-cache', 262 '--non-interactive', '--no-auth-cache',
185 '--username', 'user1', '--password', 'foo']) 263 '--username', 'user1', '--password', 'foo'])
186 assert os.path.isdir(join(self.svn_root, '.svn')) 264 assert os.path.isdir(join(self.svn_root, '.svn'))
187 def file_system(rev, DEPS): 265 def file_system(rev, DEPS):
(...skipping 29 matching lines...) Expand all
217 'DummyVariable': 'third_party', 295 'DummyVariable': 'third_party',
218 } 296 }
219 deps = { 297 deps = {
220 'src/other': 'svn://%(host)s/svn/trunk/other', 298 'src/other': 'svn://%(host)s/svn/trunk/other',
221 'src/third_party/fpp': '/trunk/' + Var('DummyVariable') + '/foo', 299 'src/third_party/fpp': '/trunk/' + Var('DummyVariable') + '/foo',
222 } 300 }
223 deps_os = { 301 deps_os = {
224 'mac': { 302 'mac': {
225 'src/third_party/prout': '/trunk/third_party/prout', 303 'src/third_party/prout': '/trunk/third_party/prout',
226 }, 304 },
227 }""" % { 'host': '127.0.0.1' })) 305 }""" % { 'host': self.HOST }))
228 306
229 self._commit_svn(file_system(2, """ 307 self._commit_svn(file_system(2, """
230 deps = { 308 deps = {
231 'src/other': 'svn://%(host)s/svn/trunk/other', 309 'src/other': 'svn://%(host)s/svn/trunk/other',
232 'src/third_party/foo': '/trunk/third_party/foo@1', 310 'src/third_party/foo': '/trunk/third_party/foo@1',
233 } 311 }
234 # I think this is wrong to have the hooks run from the base of the gclient 312 # I think this is wrong to have the hooks run from the base of the gclient
235 # checkout. It's maybe a bit too late to change that behavior. 313 # checkout. It's maybe a bit too late to change that behavior.
236 hooks = [ 314 hooks = [
237 { 315 {
238 'pattern': '.', 316 'pattern': '.',
239 'action': ['python', '-c', 317 'action': ['python', '-c',
240 'open(\\'src/hooked1\\', \\'w\\').write(\\'hooked1\\')'], 318 'open(\\'src/hooked1\\', \\'w\\').write(\\'hooked1\\')'],
241 }, 319 },
242 { 320 {
243 # Should not be run. 321 # Should not be run.
244 'pattern': 'nonexistent', 322 'pattern': 'nonexistent',
245 'action': ['python', '-c', 323 'action': ['python', '-c',
246 'open(\\'src/hooked2\\', \\'w\\').write(\\'hooked2\\')'], 324 'open(\\'src/hooked2\\', \\'w\\').write(\\'hooked2\\')'],
247 }, 325 },
248 ] 326 ]
249 """ % { 'host': '127.0.0.1' })) 327 """ % { 'host': self.HOST }))
250 328
251 def setUpGIT(self): 329 def setUpGIT(self):
252 """Creates git repositories and start the servers.""" 330 """Creates git repositories and start the servers."""
253 assert not self.gitdaemon 331 if self.gitdaemon:
254 rmtree(self.git_root) 332 return
333 self.setUp()
255 for repo in ['repo_%d' % r for r in range(1, 5)]: 334 for repo in ['repo_%d' % r for r in range(1, 5)]:
256 check_call(['git', 'init', '-q', join(self.git_root, repo)]) 335 check_call(['git', 'init', '-q', join(self.git_root, repo)])
257 self.git_hashes[repo] = [] 336 self.git_hashes[repo] = []
258 337
259 # Testing: 338 # Testing:
260 # - dependency disapear 339 # - dependency disapear
261 # - dependency renamed 340 # - dependency renamed
262 # - versioned and unversioned reference 341 # - versioned and unversioned reference
263 # - relative and full reference 342 # - relative and full reference
264 # - deps_os 343 # - deps_os
265 # - var 344 # - var
266 # - hooks 345 # - hooks
267 # TODO(maruel): 346 # TODO(maruel):
268 # - File 347 # - File
269 # - $matching_files 348 # - $matching_files
270 # - use_relative_paths 349 # - use_relative_paths
271 self._commit_git('repo_1', { 350 self._commit_git('repo_1', {
272 'DEPS': """ 351 'DEPS': """
273 vars = { 352 vars = {
274 'DummyVariable': 'repo', 353 'DummyVariable': 'repo',
275 } 354 }
276 deps = { 355 deps = {
277 'src/repo2': 'git://%(host)s/git/repo_2', 356 'src/repo2': 'git://%(host)s/git/repo_2',
278 'src/repo2/repo3': '/' + Var('DummyVariable') + '_3', 357 'src/repo2/repo3': '/' + Var('DummyVariable') + '_3',
279 } 358 }
280 deps_os = { 359 deps_os = {
281 'mac': { 360 'mac': {
282 'src/repo4': '/repo_4', 361 'src/repo4': '/repo_4',
283 }, 362 },
284 }""" % { 'host': '127.0.0.1' }, 363 }""" % { 'host': self.HOST },
285 'origin': 'git/repo_1@1\n', 364 'origin': 'git/repo_1@1\n',
286 }) 365 })
287 366
288 self._commit_git('repo_2', { 367 self._commit_git('repo_2', {
289 'origin': "git/repo_2@1\n" 368 'origin': "git/repo_2@1\n"
290 }) 369 })
291 370
292 self._commit_git('repo_2', { 371 self._commit_git('repo_2', {
293 'origin': "git/repo_2@2\n" 372 'origin': "git/repo_2@2\n"
294 }) 373 })
(...skipping 29 matching lines...) Expand all
324 'open(\\'src/hooked1\\', \\'w\\').write(\\'hooked1\\')'], 403 'open(\\'src/hooked1\\', \\'w\\').write(\\'hooked1\\')'],
325 }, 404 },
326 { 405 {
327 # Should not be run. 406 # Should not be run.
328 'pattern': 'nonexistent', 407 'pattern': 'nonexistent',
329 'action': ['python', '-c', 408 'action': ['python', '-c',
330 'open(\\'src/hooked2\\', \\'w\\').write(\\'hooked2\\')'], 409 'open(\\'src/hooked2\\', \\'w\\').write(\\'hooked2\\')'],
331 }, 410 },
332 ] 411 ]
333 """ % { 412 """ % {
334 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh. 413 # TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh.
335 'host': '127.0.0.1', 'hash': self.git_hashes['repo_2'][0][0][:7] }, 414 'host': self.HOST,
415 'hash': self.git_hashes['repo_2'][0][0][:7]
416 },
336 'origin': "git/repo_1@2\n" 417 'origin': "git/repo_1@2\n"
337 }) 418 })
338 419
339 # Start the daemon. 420 # Start the daemon.
340 cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir] 421 cmd = ['git', 'daemon', '--export-all', '--base-path=' + self.repos_dir]
341 if self.local_only: 422 if self.HOST == '127.0.0.1':
342 cmd.append('--listen=127.0.0.1') 423 cmd.append('--listen=127.0.0.1')
343 logging.debug(cmd) 424 logging.debug(cmd)
344 self.gitdaemon.append(Popen(cmd, cwd=self.repos_dir)) 425 self.gitdaemon = Popen(cmd, cwd=self.repos_dir)
345 426
346 def _commit_svn(self, tree): 427 def _commit_svn(self, tree):
347 self._genTree(self.svn_root, tree) 428 self._genTree(self.svn_root, tree)
348 commit_svn(self.svn_root) 429 commit_svn(self.svn_root)
349 if self.svn_revs and self.svn_revs[-1]: 430 if self.svn_revs and self.svn_revs[-1]:
350 new_tree = self.svn_revs[-1].copy() 431 new_tree = self.svn_revs[-1].copy()
351 new_tree.update(tree) 432 new_tree.update(tree)
352 else: 433 else:
353 new_tree = tree.copy() 434 new_tree = tree.copy()
354 self.svn_revs.append(new_tree) 435 self.svn_revs.append(new_tree)
355 436
356 def _commit_git(self, repo, tree): 437 def _commit_git(self, repo, tree):
357 repo_root = join(self.git_root, repo) 438 repo_root = join(self.git_root, repo)
358 self._genTree(repo_root, tree) 439 self._genTree(repo_root, tree)
359 hash = commit_git(repo_root) 440 hash = commit_git(repo_root)
360 if self.git_hashes[repo]: 441 if self.git_hashes[repo]:
361 new_tree = self.git_hashes[repo][-1][1].copy() 442 new_tree = self.git_hashes[repo][-1][1].copy()
362 new_tree.update(tree) 443 new_tree.update(tree)
363 else: 444 else:
364 new_tree = tree.copy() 445 new_tree = tree.copy()
365 self.git_hashes[repo].append((hash, new_tree)) 446 self.git_hashes[repo].append((hash, new_tree))
366 447
367 448
449 class FakeReposTestBase(unittest.TestCase):
450 """This is vaguely inspired by twisted."""
451
452 # Replace this in your subclass.
453 CLASS_ROOT_DIR = None
454
455 # static FakeRepos instance.
456 FAKE_REPOS = FakeRepos()
457
458 def setUp(self):
459 unittest.TestCase.setUp(self)
460 self.FAKE_REPOS.setUp()
461
462 # Remove left overs and start fresh.
463 if not self.CLASS_ROOT_DIR:
464 self.CLASS_ROOT_DIR = join(self.FAKE_REPOS.trial_dir(), 'smoke')
465 self.root_dir = join(self.CLASS_ROOT_DIR, self.id())
466 rmtree(self.root_dir)
467 os.makedirs(self.root_dir)
468 self.svn_base = 'svn://%s/svn/' % self.FAKE_REPOS.HOST
469 self.git_base = 'git://%s/git/' % self.FAKE_REPOS.HOST
470
471 def tearDown(self):
472 if not self.FAKE_REPOS.SHOULD_LEAK:
473 rmtree(self.root_dir)
474
475 def checkString(self, expected, result):
476 """Prints the diffs to ease debugging."""
477 if expected != result:
478 # Strip the begining
479 while expected and result and expected[0] == result[0]:
480 expected = expected[1:]
481 result = result[1:]
482 # The exception trace makes it hard to read so dump it too.
483 if '\n' in result:
484 print result
485 self.assertEquals(expected, result)
486
487 def check(self, expected, results):
488 """Checks stdout, stderr, retcode."""
489 self.checkString(expected[0], results[0])
490 self.checkString(expected[1], results[1])
491 self.assertEquals(expected[2], results[2])
492
493 def assertTree(self, tree, tree_root=None):
494 """Diff the checkout tree with a dict."""
495 if not tree_root:
496 tree_root = self.root_dir
497 actual = read_tree(tree_root)
498 diff = dict_diff(tree, actual)
499 if diff:
500 logging.debug('Actual %s\n%s' % (tree_root, pprint.pformat(actual)))
501 logging.debug('Expected\n%s' % pprint.pformat(tree))
502 logging.debug('Diff\n%s' % pprint.pformat(diff))
503
504
368 def main(argv): 505 def main(argv):
369 leak = '-l' in argv 506 fake = FakeRepos()
370 if leak: 507 print 'Using %s' % fake.trial_dir()
371 argv.remove('-l')
372 verbose = '-v' in argv
373 if verbose:
374 logging.basicConfig(level=logging.DEBUG)
375 argv.remove('-v')
376 assert len(argv) == 1, argv
377 trial_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
378 '_trial')
379 print 'Using %s' % trial_dir
380 fake = FakeRepos(trial_dir, leak, True)
381 try: 508 try:
382 fake.setUp() 509 fake.setUp()
383 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.') 510 print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.')
384 sys.stdin.readline() 511 sys.stdin.readline()
385 except KeyboardInterrupt: 512 except KeyboardInterrupt:
386 fake.leak = True 513 fake.SHOULD_LEAK = True
387 finally:
388 fake.tearDown()
389 return 0 514 return 0
390 515
391 516
392 if __name__ == '__main__': 517 if __name__ == '__main__':
393 sys.exit(main(sys.argv)) 518 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