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

Side by Side Diff: tests/gclient_smoketest.py

Issue 3357020: Enable parallel checkout by default to --jobs=8 and smoke tests. (Closed)
Patch Set: more fixes Created 10 years, 3 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_utils.py ('k') | no next file » | 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 """Smoke tests for gclient.py. 6 """Smoke tests for gclient.py.
7 7
8 Shell out 'gclient' and run basic conformance tests. 8 Shell out 'gclient' and run basic conformance tests.
9 9
10 This test assumes GClientSmokeBase.URL_BASE is valid. 10 This test assumes GClientSmokeBase.URL_BASE is valid.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
42 cmd = cmd_base + cmd 42 cmd = cmd_base + cmd
43 process = subprocess.Popen(cmd, cwd=cwd, env=self.env, 43 process = subprocess.Popen(cmd, cwd=cwd, env=self.env,
44 stdout=subprocess.PIPE, stderr=subprocess.PIPE, 44 stdout=subprocess.PIPE, stderr=subprocess.PIPE,
45 shell=sys.platform.startswith('win')) 45 shell=sys.platform.startswith('win'))
46 (stdout, stderr) = process.communicate() 46 (stdout, stderr) = process.communicate()
47 logging.debug("XXX: %s\n%s\nXXX" % (' '.join(cmd), stdout)) 47 logging.debug("XXX: %s\n%s\nXXX" % (' '.join(cmd), stdout))
48 logging.debug("YYY: %s\n%s\nYYY" % (' '.join(cmd), stderr)) 48 logging.debug("YYY: %s\n%s\nYYY" % (' '.join(cmd), stderr))
49 return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'), 49 return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'),
50 process.returncode) 50 process.returncode)
51 51
52 def parseGclient(self, cmd, items, expected_stderr=''): 52 def parseGclient(self, cmd, items, expected_stderr='', untangle=False):
53 """Parse gclient's output to make it easier to test.""" 53 """Parse gclient's output to make it easier to test.
54 If untangle is True, tries to sort out the output from parallel checkout."""
54 (stdout, stderr, returncode) = self.gclient(cmd) 55 (stdout, stderr, returncode) = self.gclient(cmd)
56 if untangle:
57 tasks = {}
58 remaining = []
59 for line in stdout.splitlines(False):
60 m = re.match(r'^(\d)+>(.*)$', line)
61 if not m:
62 remaining.append(line)
63 else:
64 self.assertEquals([], remaining)
65 tasks.setdefault(int(m.group(1)), []).append(m.group(2))
66 out = []
67 for key in sorted(tasks.iterkeys()):
68 out.extend(tasks[key])
69 out.extend(remaining)
70 stdout = '\n'.join(out)
55 self.checkString(expected_stderr, stderr) 71 self.checkString(expected_stderr, stderr)
56 self.assertEquals(0, returncode) 72 self.assertEquals(0, returncode)
57 return self.checkBlock(stdout, items) 73 return self.checkBlock(stdout, items)
58 74
59 def splitBlock(self, stdout): 75 def splitBlock(self, stdout):
60 """Split gclient's output into logical execution blocks. 76 """Split gclient's output into logical execution blocks.
61 ___ running 'foo' at '/bar' 77 ___ running 'foo' at '/bar'
62 (...) 78 (...)
63 ___ running 'baz' at '/bar' 79 ___ running 'baz' at '/bar'
64 (...) 80 (...)
65 81
66 will result in 2 items of len((...).splitlines()) each. 82 will result in 2 items of len((...).splitlines()) each.
67 """ 83 """
68 results = [] 84 results = []
69 for line in stdout.splitlines(False): 85 for line in stdout.splitlines(False):
70 # Intentionally skips empty lines. 86 # Intentionally skips empty lines.
71 if not line: 87 if not line:
72 continue 88 continue
73 if line.startswith('__'): 89 if line.startswith('__'):
74 match = re.match(r'^________ ([a-z]+) \'(.*)\' in \'(.*)\'$', line) 90 match = re.match(r'^________ ([a-z]+) \'(.*)\' in \'(.*)\'$', line)
75 if not match: 91 if not match:
76 match = re.match(r'^_____ (.*) is missing, synching instead$', line) 92 match = re.match(r'^_____ (.*) is missing, synching instead$', line)
77 if match: 93 if match:
78 # Blah, it's when a dependency is deleted, we should probably not 94 # Blah, it's when a dependency is deleted, we should probably not
79 # output this message. 95 # output this message.
80 results.append([line]) 96 results.append([line])
81 else: 97 elif (
82 print line 98 not re.match(
83 raise Exception('fail', line) 99 r'_____ [^ ]+ : Attempting rebase onto [0-9a-f]+...',
100 line) and
101 not re.match(r'_____ [^ ]+ at [^ ]+', line)):
102 # The two regexp above are a bit too broad, they are necessary only
103 # for git checkouts.
104 self.fail(line)
84 else: 105 else:
85 results.append([[match.group(1), match.group(2), match.group(3)]]) 106 results.append([[match.group(1), match.group(2), match.group(3)]])
86 else: 107 else:
87 if not results: 108 if not results:
88 # TODO(maruel): gclient's git stdout is inconsistent. 109 # TODO(maruel): gclient's git stdout is inconsistent.
89 # This should fail the test instead!! 110 # This should fail the test instead!!
90 pass 111 pass
91 else: 112 else:
92 results[-1].append(line) 113 results[-1].append(line)
93 return results 114 return results
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
217 def testDifferentTopLevelDirectory(self): 238 def testDifferentTopLevelDirectory(self):
218 # Check that even if the .gclient file does not mention the directory src 239 # Check that even if the .gclient file does not mention the directory src
219 # itself, but it is included via dependencies, the .gclient file is used. 240 # itself, but it is included via dependencies, the .gclient file is used.
220 self.gclient(['config', self.svn_base + 'trunk/src.DEPS']) 241 self.gclient(['config', self.svn_base + 'trunk/src.DEPS'])
221 deps = join(self.root_dir, 'src.DEPS') 242 deps = join(self.root_dir, 'src.DEPS')
222 os.mkdir(deps) 243 os.mkdir(deps)
223 write(join(deps, 'DEPS'), 244 write(join(deps, 'DEPS'),
224 'deps = { "src": "%strunk/src" }' % (self.svn_base)) 245 'deps = { "src": "%strunk/src" }' % (self.svn_base))
225 src = join(self.root_dir, 'src') 246 src = join(self.root_dir, 'src')
226 os.mkdir(src) 247 os.mkdir(src)
227 res = self.gclient(['status'], src) 248 res = self.gclient(['status', '--jobs', '1'], src)
228 self.checkBlock(res[0], [('running', deps), ('running', src)]) 249 self.checkBlock(res[0], [('running', deps), ('running', src)])
229 250
230 251
231 class GClientSmokeSVN(GClientSmokeBase): 252 class GClientSmokeSVN(GClientSmokeBase):
232 def setUp(self): 253 def setUp(self):
233 GClientSmokeBase.setUp(self) 254 GClientSmokeBase.setUp(self)
234 self.FAKE_REPOS.setUpSVN() 255 self.FAKE_REPOS.setUpSVN()
235 256
236 def testSync(self): 257 def testSync(self):
237 # TODO(maruel): safesync. 258 # TODO(maruel): safesync.
238 self.gclient(['config', self.svn_base + 'trunk/src/']) 259 self.gclient(['config', self.svn_base + 'trunk/src/'])
239 # Test unversioned checkout. 260 # Test unversioned checkout.
240 self.parseGclient(['sync', '--deps', 'mac'], 261 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
241 ['running', 'running', 262 ['running', 'running',
242 # This is due to the way svn update is called for a 263 # This is due to the way svn update is called for a
243 # single file when File() is used in a DEPS file. 264 # single file when File() is used in a DEPS file.
244 ('running', self.root_dir + '/src/file/other'), 265 ('running', self.root_dir + '/src/file/other'),
245 'running', 'running', 'running', 'running']) 266 'running', 'running', 'running', 'running'])
246 tree = self.mangle_svn_tree( 267 tree = self.mangle_svn_tree(
247 ('trunk/src@2', 'src'), 268 ('trunk/src@2', 'src'),
248 ('trunk/third_party/foo@1', 'src/third_party/foo'), 269 ('trunk/third_party/foo@1', 'src/third_party/foo'),
249 ('trunk/other@2', 'src/other')) 270 ('trunk/other@2', 'src/other'))
250 tree['src/file/other/DEPS'] = ( 271 tree['src/file/other/DEPS'] = (
251 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS']) 272 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
252 tree['src/svn_hooked1'] = 'svn_hooked1' 273 tree['src/svn_hooked1'] = 'svn_hooked1'
253 self.assertTree(tree) 274 self.assertTree(tree)
254 275
255 # Manually remove svn_hooked1 before synching to make sure it's not 276 # Manually remove svn_hooked1 before synching to make sure it's not
256 # recreated. 277 # recreated.
257 os.remove(join(self.root_dir, 'src', 'svn_hooked1')) 278 os.remove(join(self.root_dir, 'src', 'svn_hooked1'))
258 279
259 # Test incremental versioned sync: sync backward. 280 # Test incremental versioned sync: sync backward.
260 self.parseGclient(['sync', '--revision', 'src@1', '--deps', 'mac', 281 self.parseGclient(
261 '--delete_unversioned_trees'], 282 ['sync', '--revision', 'src@1', '--deps', 'mac',
262 ['running', 'running', 'running', 'running', 'deleting']) 283 '--delete_unversioned_trees', '--jobs', '1'],
284 ['running', 'running', 'running', 'running', 'deleting'])
263 tree = self.mangle_svn_tree( 285 tree = self.mangle_svn_tree(
264 ('trunk/src@1', 'src'), 286 ('trunk/src@1', 'src'),
265 ('trunk/third_party/foo@2', 'src/third_party/fpp'), 287 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
266 ('trunk/other@1', 'src/other'), 288 ('trunk/other@1', 'src/other'),
267 ('trunk/third_party/foo@2', 'src/third_party/prout')) 289 ('trunk/third_party/foo@2', 'src/third_party/prout'))
268 tree['src/file/other/DEPS'] = ( 290 tree['src/file/other/DEPS'] = (
269 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS']) 291 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
270 self.assertTree(tree) 292 self.assertTree(tree)
271 # Test incremental sync: delete-unversioned_trees isn't there. 293 # Test incremental sync: delete-unversioned_trees isn't there.
272 self.parseGclient(['sync', '--deps', 'mac'], 294 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
273 ['running', 'running', 'running', 'running', 'running']) 295 ['running', 'running', 'running', 'running', 'running'])
274 tree = self.mangle_svn_tree( 296 tree = self.mangle_svn_tree(
275 ('trunk/src@2', 'src'), 297 ('trunk/src@2', 'src'),
276 ('trunk/third_party/foo@2', 'src/third_party/fpp'), 298 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
277 ('trunk/third_party/foo@1', 'src/third_party/foo'), 299 ('trunk/third_party/foo@1', 'src/third_party/foo'),
278 ('trunk/other@2', 'src/other'), 300 ('trunk/other@2', 'src/other'),
279 ('trunk/third_party/foo@2', 'src/third_party/prout')) 301 ('trunk/third_party/foo@2', 'src/third_party/prout'))
280 tree['src/file/other/DEPS'] = ( 302 tree['src/file/other/DEPS'] = (
281 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS']) 303 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
282 tree['src/svn_hooked1'] = 'svn_hooked1' 304 tree['src/svn_hooked1'] = 'svn_hooked1'
283 self.assertTree(tree) 305 self.assertTree(tree)
284 306
285 def testSyncIgnoredSolutionName(self): 307 def testSyncIgnoredSolutionName(self):
286 """TODO(maruel): This will become an error soon.""" 308 """TODO(maruel): This will become an error soon."""
287 self.gclient(['config', self.svn_base + 'trunk/src/']) 309 self.gclient(['config', self.svn_base + 'trunk/src/'])
288 results = self.gclient(['sync', '--deps', 'mac', '-r', 'invalid@1']) 310 results = self.gclient(
311 ['sync', '--deps', 'mac', '-r', 'invalid@1', '--jobs', '1'])
289 self.checkBlock(results[0], [ 312 self.checkBlock(results[0], [
290 'running', 'running', 313 'running', 'running',
291 # This is due to the way svn update is called for a single file when 314 # This is due to the way svn update is called for a single file when
292 # File() is used in a DEPS file. 315 # File() is used in a DEPS file.
293 ('running', self.root_dir + '/src/file/other'), 316 ('running', self.root_dir + '/src/file/other'),
294 'running', 'running', 'running', 'running']) 317 'running', 'running', 'running', 'running'])
295 self.checkString('Please fix your script, having invalid --revision flags ' 318 self.checkString('Please fix your script, having invalid --revision flags '
296 'will soon considered an error.\n', results[1]) 319 'will soon considered an error.\n', results[1])
297 self.assertEquals(0, results[2]) 320 self.assertEquals(0, results[2])
298 tree = self.mangle_svn_tree( 321 tree = self.mangle_svn_tree(
299 ('trunk/src@2', 'src'), 322 ('trunk/src@2', 'src'),
300 ('trunk/third_party/foo@1', 'src/third_party/foo'), 323 ('trunk/third_party/foo@1', 'src/third_party/foo'),
301 ('trunk/other@2', 'src/other')) 324 ('trunk/other@2', 'src/other'))
302 tree['src/file/other/DEPS'] = ( 325 tree['src/file/other/DEPS'] = (
303 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS']) 326 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
304 tree['src/svn_hooked1'] = 'svn_hooked1' 327 tree['src/svn_hooked1'] = 'svn_hooked1'
305 self.assertTree(tree) 328 self.assertTree(tree)
306 329
307 def testSyncNoSolutionName(self): 330 def testSyncNoSolutionName(self):
308 # When no solution name is provided, gclient uses the first solution listed. 331 # When no solution name is provided, gclient uses the first solution listed.
309 self.gclient(['config', self.svn_base + 'trunk/src/']) 332 self.gclient(['config', self.svn_base + 'trunk/src/'])
310 self.parseGclient(['sync', '--deps', 'mac', '-r', '1'], 333 self.parseGclient(['sync', '--deps', 'mac', '-r', '1', '--jobs', '1'],
311 ['running', 'running', 'running', 'running']) 334 ['running', 'running', 'running', 'running'])
312 tree = self.mangle_svn_tree( 335 tree = self.mangle_svn_tree(
313 ('trunk/src@1', 'src'), 336 ('trunk/src@1', 'src'),
314 ('trunk/third_party/foo@2', 'src/third_party/fpp'), 337 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
315 ('trunk/other@1', 'src/other'), 338 ('trunk/other@1', 'src/other'),
316 ('trunk/third_party/foo@2', 'src/third_party/prout')) 339 ('trunk/third_party/foo@2', 'src/third_party/prout'))
317 self.assertTree(tree) 340 self.assertTree(tree)
318 341
342 def testSyncJobs(self):
343 # TODO(maruel): safesync.
344 self.gclient(['config', self.svn_base + 'trunk/src/'])
345 # Test unversioned checkout.
346 self.parseGclient(
347 ['sync', '--deps', 'mac', '--jobs', '8'],
348 ['running', 'running',
349 # This is due to the way svn update is called for a
350 # single file when File() is used in a DEPS file.
351 ('running', self.root_dir + '/src/file/other'),
352 'running', 'running', 'running', 'running'],
353 untangle=True)
354 tree = self.mangle_svn_tree(
355 ('trunk/src@2', 'src'),
356 ('trunk/third_party/foo@1', 'src/third_party/foo'),
357 ('trunk/other@2', 'src/other'))
358 tree['src/file/other/DEPS'] = (
359 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
360 tree['src/svn_hooked1'] = 'svn_hooked1'
361 self.assertTree(tree)
362
363 # Manually remove svn_hooked1 before synching to make sure it's not
364 # recreated.
365 os.remove(join(self.root_dir, 'src', 'svn_hooked1'))
366
367 # Test incremental versioned sync: sync backward.
368 self.parseGclient(
369 ['sync', '--revision', 'src@1', '--deps', 'mac',
370 '--delete_unversioned_trees', '--jobs', '8'],
371 ['running', 'running', 'running', 'running', 'deleting'],
372 untangle=True)
373 tree = self.mangle_svn_tree(
374 ('trunk/src@1', 'src'),
375 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
376 ('trunk/other@1', 'src/other'),
377 ('trunk/third_party/foo@2', 'src/third_party/prout'))
378 tree['src/file/other/DEPS'] = (
379 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
380 self.assertTree(tree)
381 # Test incremental sync: delete-unversioned_trees isn't there.
382 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
383 ['running', 'running', 'running', 'running', 'running'],
384 untangle=True)
385 tree = self.mangle_svn_tree(
386 ('trunk/src@2', 'src'),
387 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
388 ('trunk/third_party/foo@1', 'src/third_party/foo'),
389 ('trunk/other@2', 'src/other'),
390 ('trunk/third_party/foo@2', 'src/third_party/prout'))
391 tree['src/file/other/DEPS'] = (
392 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
393 tree['src/svn_hooked1'] = 'svn_hooked1'
394 self.assertTree(tree)
395
319 def testRevertAndStatus(self): 396 def testRevertAndStatus(self):
320 self.gclient(['config', self.svn_base + 'trunk/src/']) 397 self.gclient(['config', self.svn_base + 'trunk/src/'])
321 # Tested in testSync. 398 # Tested in testSync.
322 self.gclient(['sync', '--deps', 'mac']) 399 self.gclient(['sync', '--deps', 'mac'])
323 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') 400 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!')
324 401
325 out = self.parseGclient(['status', '--deps', 'mac'], 402 out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
326 [['running', join(self.root_dir, 'src')], 403 [['running', join(self.root_dir, 'src')],
327 ['running', join(self.root_dir, 'src', 'other')]]) 404 ['running', join(self.root_dir, 'src', 'other')]])
328 out = self.svnBlockCleanup(out) 405 out = self.svnBlockCleanup(out)
329 self.checkString('file', out[0][1]) 406 self.checkString('file', out[0][1])
330 self.checkString('other', out[0][2]) 407 self.checkString('other', out[0][2])
331 self.checkString('svn_hooked1', out[0][3]) 408 self.checkString('svn_hooked1', out[0][3])
332 self.checkString(join('third_party', 'foo'), out[0][4]) 409 self.checkString(join('third_party', 'foo'), out[0][4])
333 self.checkString('hi', out[1][1]) 410 self.checkString('hi', out[1][1])
334 self.assertEquals(5, len(out[0])) 411 self.assertEquals(5, len(out[0]))
335 self.assertEquals(2, len(out[1])) 412 self.assertEquals(2, len(out[1]))
336 413
337 # Revert implies --force implies running hooks without looking at pattern 414 # Revert implies --force implies running hooks without looking at pattern
338 # matching. 415 # matching.
339 results = self.gclient(['revert', '--deps', 'mac']) 416 results = self.gclient(['revert', '--deps', 'mac', '--jobs', '1'])
340 out = self.splitBlock(results[0]) 417 out = self.splitBlock(results[0])
341 # src, src/other is missing, src/other, src/third_party/foo is missing, 418 # src, src/other is missing, src/other, src/third_party/foo is missing,
342 # src/third_party/foo, 2 svn hooks, 3 related to File(). 419 # src/third_party/foo, 2 svn hooks, 3 related to File().
343 self.assertEquals(10, len(out)) 420 self.assertEquals(10, len(out))
344 self.checkString('', results[1]) 421 self.checkString('', results[1])
345 self.assertEquals(0, results[2]) 422 self.assertEquals(0, results[2])
346 tree = self.mangle_svn_tree( 423 tree = self.mangle_svn_tree(
347 ('trunk/src@2', 'src'), 424 ('trunk/src@2', 'src'),
348 ('trunk/third_party/foo@1', 'src/third_party/foo'), 425 ('trunk/third_party/foo@1', 'src/third_party/foo'),
349 ('trunk/other@2', 'src/other')) 426 ('trunk/other@2', 'src/other'))
350 tree['src/file/other/DEPS'] = ( 427 tree['src/file/other/DEPS'] = (
351 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS']) 428 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
352 tree['src/svn_hooked1'] = 'svn_hooked1' 429 tree['src/svn_hooked1'] = 'svn_hooked1'
353 tree['src/svn_hooked2'] = 'svn_hooked2' 430 tree['src/svn_hooked2'] = 'svn_hooked2'
354 self.assertTree(tree) 431 self.assertTree(tree)
355 432
356 out = self.parseGclient(['status', '--deps', 'mac'], 433 out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
357 [['running', join(self.root_dir, 'src')]]) 434 [['running', join(self.root_dir, 'src')]])
358 out = self.svnBlockCleanup(out) 435 out = self.svnBlockCleanup(out)
359 self.checkString('file', out[0][1]) 436 self.checkString('file', out[0][1])
360 self.checkString('other', out[0][2]) 437 self.checkString('other', out[0][2])
361 self.checkString('svn_hooked1', out[0][3]) 438 self.checkString('svn_hooked1', out[0][3])
362 self.checkString('svn_hooked2', out[0][4]) 439 self.checkString('svn_hooked2', out[0][4])
363 self.checkString(join('third_party', 'foo'), out[0][5]) 440 self.checkString(join('third_party', 'foo'), out[0][5])
364 self.assertEquals(6, len(out[0])) 441 self.assertEquals(6, len(out[0]))
365 self.assertEquals(1, len(out)) 442 self.assertEquals(1, len(out))
366 443
367 def testRevertAndStatusDepsOs(self): 444 def testRevertAndStatusDepsOs(self):
368 self.gclient(['config', self.svn_base + 'trunk/src/']) 445 self.gclient(['config', self.svn_base + 'trunk/src/'])
369 # Tested in testSync. 446 # Tested in testSync.
370 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1']) 447 self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1'])
371 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!') 448 write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!')
372 449
373 # Without --verbose, gclient won't output the directories without 450 # Without --verbose, gclient won't output the directories without
374 # modification. 451 # modification.
375 out = self.parseGclient(['status', '--deps', 'mac'], 452 out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
376 [['running', join(self.root_dir, 'src')], 453 [['running', join(self.root_dir, 'src')],
377 ['running', join(self.root_dir, 'src', 'other')]]) 454 ['running', join(self.root_dir, 'src', 'other')]])
378 out = self.svnBlockCleanup(out) 455 out = self.svnBlockCleanup(out)
379 self.checkString('other', out[0][1]) 456 self.checkString('other', out[0][1])
380 self.checkString(join('third_party', 'fpp'), out[0][2]) 457 self.checkString(join('third_party', 'fpp'), out[0][2])
381 self.checkString(join('third_party', 'prout'), out[0][3]) 458 self.checkString(join('third_party', 'prout'), out[0][3])
382 self.checkString('hi', out[1][1]) 459 self.checkString('hi', out[1][1])
383 self.assertEquals(4, len(out[0])) 460 self.assertEquals(4, len(out[0]))
384 self.assertEquals(2, len(out[1])) 461 self.assertEquals(2, len(out[1]))
385 462
386 # So verify it works with --verbose. 463 # So verify it works with --verbose.
387 out = self.parseGclient(['status', '--deps', 'mac', '--verbose'], 464 out = self.parseGclient(
465 ['status', '--deps', 'mac', '--verbose', '--jobs', '1'],
388 [['running', join(self.root_dir, 'src')], 466 [['running', join(self.root_dir, 'src')],
389 ['running', join(self.root_dir, 'src', 'third_party', 'fpp')], 467 ['running', join(self.root_dir, 'src', 'third_party', 'fpp')],
390 ['running', join(self.root_dir, 'src', 'other')], 468 ['running', join(self.root_dir, 'src', 'other')],
391 ['running', join(self.root_dir, 'src', 'third_party', 'prout')]]) 469 ['running', join(self.root_dir, 'src', 'third_party', 'prout')]])
392 out = self.svnBlockCleanup(out) 470 out = self.svnBlockCleanup(out)
393 self.checkString('other', out[0][1]) 471 self.checkString('other', out[0][1])
394 self.checkString(join('third_party', 'fpp'), out[0][2]) 472 self.checkString(join('third_party', 'fpp'), out[0][2])
395 self.checkString(join('third_party', 'prout'), out[0][3]) 473 self.checkString(join('third_party', 'prout'), out[0][3])
396 self.checkString('hi', out[2][1]) 474 self.checkString('hi', out[2][1])
397 self.assertEquals(4, len(out[0])) 475 self.assertEquals(4, len(out[0]))
398 self.assertEquals(1, len(out[1])) 476 self.assertEquals(1, len(out[1]))
399 self.assertEquals(2, len(out[2])) 477 self.assertEquals(2, len(out[2]))
400 self.assertEquals(1, len(out[3])) 478 self.assertEquals(1, len(out[3]))
401 self.assertEquals(4, len(out)) 479 self.assertEquals(4, len(out))
402 480
403 # Revert implies --force implies running hooks without looking at pattern 481 # Revert implies --force implies running hooks without looking at pattern
404 # matching. 482 # matching.
405 # TODO(maruel): In general, gclient revert output is wrong. It should output 483 # TODO(maruel): In general, gclient revert output is wrong. It should output
406 # the file list after some ___ running 'svn status' 484 # the file list after some ___ running 'svn status'
407 results = self.gclient(['revert', '--deps', 'mac']) 485 results = self.gclient(['revert', '--deps', 'mac', '--jobs', '1'])
408 out = self.splitBlock(results[0]) 486 out = self.splitBlock(results[0])
409 self.assertEquals(7, len(out)) 487 self.assertEquals(7, len(out))
410 self.checkString('', results[1]) 488 self.checkString('', results[1])
411 self.assertEquals(0, results[2]) 489 self.assertEquals(0, results[2])
412 tree = self.mangle_svn_tree( 490 tree = self.mangle_svn_tree(
413 ('trunk/src@1', 'src'), 491 ('trunk/src@1', 'src'),
414 ('trunk/third_party/foo@2', 'src/third_party/fpp'), 492 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
415 ('trunk/other@1', 'src/other'), 493 ('trunk/other@1', 'src/other'),
416 ('trunk/third_party/prout@2', 'src/third_party/prout')) 494 ('trunk/third_party/prout@2', 'src/third_party/prout'))
417 self.assertTree(tree) 495 self.assertTree(tree)
418 496
419 out = self.parseGclient(['status', '--deps', 'mac'], 497 out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
420 [['running', join(self.root_dir, 'src')]]) 498 [['running', join(self.root_dir, 'src')]])
421 out = self.svnBlockCleanup(out) 499 out = self.svnBlockCleanup(out)
422 self.checkString('other', out[0][1]) 500 self.checkString('other', out[0][1])
423 self.checkString(join('third_party', 'fpp'), out[0][2]) 501 self.checkString(join('third_party', 'fpp'), out[0][2])
424 self.checkString(join('third_party', 'prout'), out[0][3]) 502 self.checkString(join('third_party', 'prout'), out[0][3])
425 self.assertEquals(4, len(out[0])) 503 self.assertEquals(4, len(out[0]))
426 504
427 def testRunHooks(self): 505 def testRunHooks(self):
428 self.gclient(['config', self.svn_base + 'trunk/src/']) 506 self.gclient(['config', self.svn_base + 'trunk/src/'])
429 self.gclient(['sync', '--deps', 'mac']) 507 self.gclient(['sync', '--deps', 'mac'])
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
483 os.mkdir(other_src) 561 os.mkdir(other_src)
484 res = ('', 'Error: client not configured; see \'gclient config\'\n', 1) 562 res = ('', 'Error: client not configured; see \'gclient config\'\n', 1)
485 self.check(res, self.gclient(['status'], other_src)) 563 self.check(res, self.gclient(['status'], other_src))
486 564
487 def testCorrectDirectory(self): 565 def testCorrectDirectory(self):
488 # Check that when we're in the subdirectory src, the .gclient configuration 566 # Check that when we're in the subdirectory src, the .gclient configuration
489 # is used. 567 # is used.
490 self.gclient(['config', self.svn_base + 'trunk/src/']) 568 self.gclient(['config', self.svn_base + 'trunk/src/'])
491 self.gclient(['sync']) 569 self.gclient(['sync'])
492 src = join(self.root_dir, 'src') 570 src = join(self.root_dir, 'src')
493 res = self.gclient(['status'], src) 571 res = self.gclient(['status', '--jobs', '1'], src)
494 self.checkBlock(res[0], [('running', src)]) 572 self.checkBlock(res[0], [('running', src)])
495 573
496 def testInitialCheckoutNotYetDone(self): 574 def testInitialCheckoutNotYetDone(self):
497 # Check that gclient can be executed when the initial checkout hasn't been 575 # Check that gclient can be executed when the initial checkout hasn't been
498 # done yet. 576 # done yet.
499 self.gclient(['config', self.svn_base + 'trunk/src/']) 577 self.gclient(['config', self.svn_base + 'trunk/src/'])
500 self.parseGclient(['sync'], 578 self.parseGclient(['sync', '--jobs', '1'],
501 ['running', 'running', 579 ['running', 'running',
502 # This is due to the way svn update is called for a 580 # This is due to the way svn update is called for a
503 # single file when File() is used in a DEPS file. 581 # single file when File() is used in a DEPS file.
504 ('running', self.root_dir + '/src/file/other'), 582 ('running', self.root_dir + '/src/file/other'),
505 'running', 'running', 'running', 'running']) 583 'running', 'running', 'running', 'running'])
506 584
507 def testInitialCheckoutFailed(self): 585 def testInitialCheckoutFailed(self):
508 # Check that gclient can be executed from an arbitrary sub directory if the 586 # Check that gclient can be executed from an arbitrary sub directory if the
509 # initial checkout has failed. 587 # initial checkout has failed.
510 self.gclient(['config', self.svn_base + 'trunk/src/']) 588 self.gclient(['config', self.svn_base + 'trunk/src/'])
511 self.gclient(['sync']) 589 self.gclient(['sync'])
512 # Cripple the checkout. 590 # Cripple the checkout.
513 os.remove(join(self.root_dir, '.gclient_entries')) 591 os.remove(join(self.root_dir, '.gclient_entries'))
514 src = join(self.root_dir, 'src') 592 src = join(self.root_dir, 'src')
515 res = self.gclient(['sync'], src) 593 res = self.gclient(['sync', '--jobs', '1'], src)
516 self.checkBlock(res[0], 594 self.checkBlock(res[0],
517 ['running', 'running', 'running']) 595 ['running', 'running', 'running'])
518 596
519 597
520 class GClientSmokeGIT(GClientSmokeBase): 598 class GClientSmokeGIT(GClientSmokeBase):
521 def setUp(self): 599 def setUp(self):
522 GClientSmokeBase.setUp(self) 600 GClientSmokeBase.setUp(self)
523 self.enabled = self.FAKE_REPOS.setUpGIT() 601 self.enabled = self.FAKE_REPOS.setUpGIT()
524 602
525 def testSync(self): 603 def testSync(self):
526 if not self.enabled: 604 if not self.enabled:
527 return 605 return
528 # TODO(maruel): safesync. 606 # TODO(maruel): safesync.
529 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) 607 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
530 # Test unversioned checkout. 608 # Test unversioned checkout.
531 self.parseGclient(['sync', '--deps', 'mac'], 609 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
532 ['running', 'running', 'running', 'running', 'running']) 610 ['running', 'running', 'running', 'running', 'running'])
533 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must 611 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must
534 # add sync parsing to get the list of updated files. 612 # add sync parsing to get the list of updated files.
535 tree = self.mangle_git_tree(('repo_1@2', 'src'), 613 tree = self.mangle_git_tree(('repo_1@2', 'src'),
536 ('repo_2@1', 'src/repo2'), 614 ('repo_2@1', 'src/repo2'),
537 ('repo_3@2', 'src/repo2/repo_renamed')) 615 ('repo_3@2', 'src/repo2/repo_renamed'))
538 tree['src/git_hooked1'] = 'git_hooked1' 616 tree['src/git_hooked1'] = 'git_hooked1'
539 tree['src/git_hooked2'] = 'git_hooked2' 617 tree['src/git_hooked2'] = 'git_hooked2'
540 self.assertTree(tree) 618 self.assertTree(tree)
541 619
542 # Manually remove git_hooked1 before synching to make sure it's not 620 # Manually remove git_hooked1 before synching to make sure it's not
543 # recreated. 621 # recreated.
544 os.remove(join(self.root_dir, 'src', 'git_hooked1')) 622 os.remove(join(self.root_dir, 'src', 'git_hooked1'))
545 623
546 # Test incremental versioned sync: sync backward. 624 # Test incremental versioned sync: sync backward.
547 results = self.gclient(['sync', '--revision', 625 self.parseGclient(['sync', '--jobs', '1', '--revision',
548 'src@' + self.githash('repo_1', 1), 626 'src@' + self.githash('repo_1', 1),
549 '--deps', 'mac', '--delete_unversioned_trees']) 627 '--deps', 'mac', '--delete_unversioned_trees'],
550 # gclient's git output is unparsable and all messed up. Don't look at it, it 628 ['running', 'running', 'deleting'])
551 # hurts the smoke test's eyes. Add "print out" here if you want to dare to
552 # parse it. So just assert it's not empty and look at the result on the file
553 # system instead.
554 self.assertEquals('', results[1])
555 self.assertEquals(0, results[2])
556 tree = self.mangle_git_tree(('repo_1@1', 'src'), 629 tree = self.mangle_git_tree(('repo_1@1', 'src'),
557 ('repo_2@2', 'src/repo2'), 630 ('repo_2@2', 'src/repo2'),
558 ('repo_3@1', 'src/repo2/repo3'), 631 ('repo_3@1', 'src/repo2/repo3'),
559 ('repo_4@2', 'src/repo4')) 632 ('repo_4@2', 'src/repo4'))
560 tree['src/git_hooked2'] = 'git_hooked2' 633 tree['src/git_hooked2'] = 'git_hooked2'
561 self.assertTree(tree) 634 self.assertTree(tree)
562 # Test incremental sync: delete-unversioned_trees isn't there. 635 # Test incremental sync: delete-unversioned_trees isn't there.
563 results = self.gclient(['sync', '--deps', 'mac']) 636 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
564 # See comment above about parsing gclient's git output. 637 ['running', 'running', 'running'])
565 self.assertEquals('', results[1])
566 self.assertEquals(0, results[2])
567 tree = self.mangle_git_tree(('repo_1@2', 'src'), 638 tree = self.mangle_git_tree(('repo_1@2', 'src'),
568 ('repo_2@1', 'src/repo2'), 639 ('repo_2@1', 'src/repo2'),
569 ('repo_3@1', 'src/repo2/repo3'), 640 ('repo_3@1', 'src/repo2/repo3'),
570 ('repo_3@2', 'src/repo2/repo_renamed'), 641 ('repo_3@2', 'src/repo2/repo_renamed'),
571 ('repo_4@2', 'src/repo4')) 642 ('repo_4@2', 'src/repo4'))
572 tree['src/git_hooked1'] = 'git_hooked1' 643 tree['src/git_hooked1'] = 'git_hooked1'
573 tree['src/git_hooked2'] = 'git_hooked2' 644 tree['src/git_hooked2'] = 'git_hooked2'
574 self.assertTree(tree) 645 self.assertTree(tree)
575 646
576 def testSyncIgnoredSolutionName(self): 647 def testSyncIgnoredSolutionName(self):
577 """TODO(maruel): This will become an error soon.""" 648 """TODO(maruel): This will become an error soon."""
578 if not self.enabled: 649 if not self.enabled:
579 return 650 return
580 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) 651 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
581 self.parseGclient( 652 self.parseGclient(
582 ['sync', '--deps', 'mac', 653 ['sync', '--deps', 'mac', '--jobs', '1',
583 '--revision', 'invalid@' + self.githash('repo_1', 1)], 654 '--revision', 'invalid@' + self.githash('repo_1', 1)],
584 ['running', 'running', 'running', 'running', 'running'], 655 ['running', 'running', 'running', 'running', 'running'],
585 'Please fix your script, having invalid --revision flags ' 656 'Please fix your script, having invalid --revision flags '
586 'will soon considered an error.\n') 657 'will soon considered an error.\n')
587 tree = self.mangle_git_tree(('repo_1@2', 'src'), 658 tree = self.mangle_git_tree(('repo_1@2', 'src'),
588 ('repo_2@1', 'src/repo2'), 659 ('repo_2@1', 'src/repo2'),
589 ('repo_3@2', 'src/repo2/repo_renamed')) 660 ('repo_3@2', 'src/repo2/repo_renamed'))
590 tree['src/git_hooked1'] = 'git_hooked1' 661 tree['src/git_hooked1'] = 'git_hooked1'
591 tree['src/git_hooked2'] = 'git_hooked2' 662 tree['src/git_hooked2'] = 'git_hooked2'
592 self.assertTree(tree) 663 self.assertTree(tree)
593 664
594 def testSyncNoSolutionName(self): 665 def testSyncNoSolutionName(self):
595 if not self.enabled: 666 if not self.enabled:
596 return 667 return
597 # When no solution name is provided, gclient uses the first solution listed. 668 # When no solution name is provided, gclient uses the first solution listed.
598 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) 669 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
599 self.parseGclient(['sync', '--deps', 'mac', 670 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1',
600 '--revision', self.githash('repo_1', 1)], 671 '--revision', self.githash('repo_1', 1)],
601 ['running', 'running', 'running', 'running']) 672 ['running', 'running', 'running', 'running'])
602 tree = self.mangle_git_tree(('repo_1@1', 'src'), 673 tree = self.mangle_git_tree(('repo_1@1', 'src'),
603 ('repo_2@2', 'src/repo2'), 674 ('repo_2@2', 'src/repo2'),
604 ('repo_3@1', 'src/repo2/repo3'), 675 ('repo_3@1', 'src/repo2/repo3'),
605 ('repo_4@2', 'src/repo4')) 676 ('repo_4@2', 'src/repo4'))
606 self.assertTree(tree) 677 self.assertTree(tree)
607 678
679 def testSyncJobs(self):
680 if not self.enabled:
681 return
682 # TODO(maruel): safesync.
683 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
684 # Test unversioned checkout.
685 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
686 ['running', 'running', 'running', 'running', 'running'],
687 untangle=True)
688 # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must
689 # add sync parsing to get the list of updated files.
690 tree = self.mangle_git_tree(('repo_1@2', 'src'),
691 ('repo_2@1', 'src/repo2'),
692 ('repo_3@2', 'src/repo2/repo_renamed'))
693 tree['src/git_hooked1'] = 'git_hooked1'
694 tree['src/git_hooked2'] = 'git_hooked2'
695 self.assertTree(tree)
696
697 # Manually remove git_hooked1 before synching to make sure it's not
698 # recreated.
699 os.remove(join(self.root_dir, 'src', 'git_hooked1'))
700
701 # Test incremental versioned sync: sync backward.
702 self.parseGclient(
703 ['sync', '--revision', 'src@' + self.githash('repo_1', 1),
704 '--deps', 'mac', '--delete_unversioned_trees', '--jobs', '8'],
705 ['running', 'running', 'deleting'],
706 untangle=True)
707 tree = self.mangle_git_tree(('repo_1@1', 'src'),
708 ('repo_2@2', 'src/repo2'),
709 ('repo_3@1', 'src/repo2/repo3'),
710 ('repo_4@2', 'src/repo4'))
711 tree['src/git_hooked2'] = 'git_hooked2'
712 self.assertTree(tree)
713 # Test incremental sync: delete-unversioned_trees isn't there.
714 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
715 ['running', 'running', 'running'], untangle=True)
716 tree = self.mangle_git_tree(('repo_1@2', 'src'),
717 ('repo_2@1', 'src/repo2'),
718 ('repo_3@1', 'src/repo2/repo3'),
719 ('repo_3@2', 'src/repo2/repo_renamed'),
720 ('repo_4@2', 'src/repo4'))
721 tree['src/git_hooked1'] = 'git_hooked1'
722 tree['src/git_hooked2'] = 'git_hooked2'
723 self.assertTree(tree)
724
608 def testRevertAndStatus(self): 725 def testRevertAndStatus(self):
609 """TODO(maruel): Remove this line once this test is fixed.""" 726 """TODO(maruel): Remove this line once this test is fixed."""
610 if not self.enabled: 727 if not self.enabled:
611 return 728 return
612 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src']) 729 self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
613 # Tested in testSync. 730 # Tested in testSync.
614 self.gclient(['sync', '--deps', 'mac']) 731 self.gclient(['sync', '--deps', 'mac'])
615 write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!') 732 write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!')
616 733
617 out = self.parseGclient(['status', '--deps', 'mac'], []) 734 out = self.parseGclient(['status', '--deps', 'mac'], [])
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
705 822
706 def testMultiSolutions(self): 823 def testMultiSolutions(self):
707 if not self.enabled: 824 if not self.enabled:
708 return 825 return
709 self.gclient(['config', '--spec', 826 self.gclient(['config', '--spec',
710 'solutions=[' 827 'solutions=['
711 '{"name": "src",' 828 '{"name": "src",'
712 ' "url": "' + self.svn_base + 'trunk/src/"},' 829 ' "url": "' + self.svn_base + 'trunk/src/"},'
713 '{"name": "src-git",' 830 '{"name": "src-git",'
714 '"url": "' + self.git_base + 'repo_1"}]']) 831 '"url": "' + self.git_base + 'repo_1"}]'])
715 self.parseGclient(['sync', '--deps', 'mac'], 832 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
716 ['running', 'running', 'running', 833 ['running', 'running', 'running',
717 # This is due to the way svn update is called for a single 834 # This is due to the way svn update is called for a single
718 # file when File() is used in a DEPS file. 835 # file when File() is used in a DEPS file.
719 ('running', self.root_dir + '/src/file/other'), 836 ('running', self.root_dir + '/src/file/other'),
720 'running', 'running', 'running', 'running', 'running', 'running', 837 'running', 'running', 'running', 'running', 'running', 'running',
721 'running', 'running']) 838 'running', 'running'])
722 tree = self.mangle_git_tree(('repo_1@2', 'src-git'), 839 tree = self.mangle_git_tree(('repo_1@2', 'src-git'),
723 ('repo_2@1', 'src/repo2'), 840 ('repo_2@1', 'src/repo2'),
724 ('repo_3@2', 'src/repo2/repo_renamed')) 841 ('repo_3@2', 'src/repo2/repo_renamed'))
725 tree.update(self.mangle_svn_tree( 842 tree.update(self.mangle_svn_tree(
726 ('trunk/src@2', 'src'), 843 ('trunk/src@2', 'src'),
727 ('trunk/third_party/foo@1', 'src/third_party/foo'), 844 ('trunk/third_party/foo@1', 'src/third_party/foo'),
728 ('trunk/other@2', 'src/other'))) 845 ('trunk/other@2', 'src/other')))
729 tree['src/file/other/DEPS'] = ( 846 tree['src/file/other/DEPS'] = (
730 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS']) 847 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
731 tree['src/git_hooked1'] = 'git_hooked1' 848 tree['src/git_hooked1'] = 'git_hooked1'
732 tree['src/git_hooked2'] = 'git_hooked2' 849 tree['src/git_hooked2'] = 'git_hooked2'
733 tree['src/svn_hooked1'] = 'svn_hooked1' 850 tree['src/svn_hooked1'] = 'svn_hooked1'
734 self.assertTree(tree) 851 self.assertTree(tree)
735 852
853 def testMultiSolutionsJobs(self):
854 if not self.enabled:
855 return
856 self.gclient(['config', '--spec',
857 'solutions=['
858 '{"name": "src",'
859 ' "url": "' + self.svn_base + 'trunk/src/"},'
860 '{"name": "src-git",'
861 '"url": "' + self.git_base + 'repo_1"}]'])
862 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
863 ['running', 'running', 'running',
864 # This is due to the way svn update is called for a single
865 # file when File() is used in a DEPS file.
866 ('running', self.root_dir + '/src/file/other'),
867 'running', 'running', 'running', 'running', 'running', 'running',
868 'running', 'running'],
869 untangle=True)
870 tree = self.mangle_git_tree(('repo_1@2', 'src-git'),
871 ('repo_2@1', 'src/repo2'),
872 ('repo_3@2', 'src/repo2/repo_renamed'))
873 tree.update(self.mangle_svn_tree(
874 ('trunk/src@2', 'src'),
875 ('trunk/third_party/foo@1', 'src/third_party/foo'),
876 ('trunk/other@2', 'src/other')))
877 tree['src/file/other/DEPS'] = (
878 self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
879 tree['src/git_hooked1'] = 'git_hooked1'
880 tree['src/git_hooked2'] = 'git_hooked2'
881 tree['src/svn_hooked1'] = 'svn_hooked1'
882 self.assertTree(tree)
883
736 def testMultiSolutionsMultiRev(self): 884 def testMultiSolutionsMultiRev(self):
737 if not self.enabled: 885 if not self.enabled:
738 return 886 return
739 self.gclient(['config', '--spec', 887 self.gclient(['config', '--spec',
740 'solutions=[' 888 'solutions=['
741 '{"name": "src",' 889 '{"name": "src",'
742 ' "url": "' + self.svn_base + 'trunk/src/"},' 890 ' "url": "' + self.svn_base + 'trunk/src/"},'
743 '{"name": "src-git",' 891 '{"name": "src-git",'
744 '"url": "' + self.git_base + 'repo_1"}]']) 892 '"url": "' + self.git_base + 'repo_1"}]'])
745 self.parseGclient( 893 self.parseGclient(
746 ['sync', '--deps', 'mac', '--revision', '1', 894 ['sync', '--deps', 'mac', '--jobs', '1', '--revision', '1',
747 '-r', 'src-git@' + self.githash('repo_1', 1)], 895 '-r', 'src-git@' + self.githash('repo_1', 1)],
748 ['running', 'running', 'running', 'running', 896 ['running', 'running', 'running', 'running',
749 'running', 'running', 'running', 'running']) 897 'running', 'running', 'running', 'running'])
750 tree = self.mangle_git_tree(('repo_1@1', 'src-git'), 898 tree = self.mangle_git_tree(('repo_1@1', 'src-git'),
751 ('repo_2@2', 'src/repo2'), 899 ('repo_2@2', 'src/repo2'),
752 ('repo_3@1', 'src/repo2/repo3'), 900 ('repo_3@1', 'src/repo2/repo3'),
753 ('repo_4@2', 'src/repo4')) 901 ('repo_4@2', 'src/repo4'))
754 tree.update(self.mangle_svn_tree( 902 tree.update(self.mangle_svn_tree(
755 ('trunk/src@1', 'src'), 903 ('trunk/src@1', 'src'),
756 ('trunk/third_party/foo@2', 'src/third_party/fpp'), 904 ('trunk/third_party/foo@2', 'src/third_party/fpp'),
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
836 def setUp(self): 984 def setUp(self):
837 GClientSmokeBase.setUp(self) 985 GClientSmokeBase.setUp(self)
838 self.FAKE_REPOS.setUpSVN() 986 self.FAKE_REPOS.setUpSVN()
839 os.rmdir(self.root_dir) 987 os.rmdir(self.root_dir)
840 check_call(['svn', 'checkout', 'svn://127.0.0.1/svn/trunk/webkit', 988 check_call(['svn', 'checkout', 'svn://127.0.0.1/svn/trunk/webkit',
841 self.root_dir, '-q', 989 self.root_dir, '-q',
842 '--non-interactive', '--no-auth-cache', 990 '--non-interactive', '--no-auth-cache',
843 '--username', 'user1', '--password', 'foo']) 991 '--username', 'user1', '--password', 'foo'])
844 992
845 def testSync(self): 993 def testSync(self):
846 self.parseGclient(['sync', '--deps', 'mac'], ['running', 'running']) 994 self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
995 ['running', 'running'])
847 tree = self.mangle_svn_tree( 996 tree = self.mangle_svn_tree(
848 ('trunk/webkit@2', ''), 997 ('trunk/webkit@2', ''),
849 ('trunk/third_party/foo@1', 'foo/bar')) 998 ('trunk/third_party/foo@1', 'foo/bar'))
850 self.assertTree(tree) 999 self.assertTree(tree)
851 1000
852 def testRevertAndStatus(self): 1001 def testRevertAndStatus(self):
853 self.gclient(['sync']) 1002 self.gclient(['sync'])
854 1003
855 # TODO(maruel): This is incorrect. 1004 # TODO(maruel): This is incorrect.
856 out = self.parseGclient(['status', '--deps', 'mac'], []) 1005 out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'], [])
857 1006
858 # Revert implies --force implies running hooks without looking at pattern 1007 # Revert implies --force implies running hooks without looking at pattern
859 # matching. 1008 # matching.
860 results = self.gclient(['revert', '--deps', 'mac']) 1009 results = self.gclient(['revert', '--deps', 'mac', '--jobs', '1'])
861 out = self.splitBlock(results[0]) 1010 out = self.splitBlock(results[0])
862 self.assertEquals(2, len(out)) 1011 self.assertEquals(2, len(out))
863 self.checkString(2, len(out[0])) 1012 self.checkString(2, len(out[0]))
864 self.checkString(2, len(out[1])) 1013 self.checkString(2, len(out[1]))
865 self.checkString('foo', out[1][1]) 1014 self.checkString('foo', out[1][1])
866 self.checkString('', results[1]) 1015 self.checkString('', results[1])
867 self.assertEquals(0, results[2]) 1016 self.assertEquals(0, results[2])
868 tree = self.mangle_svn_tree( 1017 tree = self.mangle_svn_tree(
869 ('trunk/webkit@2', ''), 1018 ('trunk/webkit@2', ''),
870 ('trunk/third_party/foo@1', 'foo/bar')) 1019 ('trunk/third_party/foo@1', 'foo/bar'))
(...skipping 25 matching lines...) Expand all
896 # TODO(maruel): To be added after the refactor. 1045 # TODO(maruel): To be added after the refactor.
897 #results = self.gclient(['revinfo', '--snapshot']) 1046 #results = self.gclient(['revinfo', '--snapshot'])
898 #expected = ( 1047 #expected = (
899 # './: None\nfoo/bar: svn://127.0.0.1/svn/trunk/third_party/foo@1\n', 1048 # './: None\nfoo/bar: svn://127.0.0.1/svn/trunk/third_party/foo@1\n',
900 # '', 0) 1049 # '', 0)
901 #self.check(expected, results) 1050 #self.check(expected, results)
902 1051
903 def testRest(self): 1052 def testRest(self):
904 self.gclient(['sync']) 1053 self.gclient(['sync'])
905 # TODO(maruel): This is incorrect, it should run on ./ too. 1054 # TODO(maruel): This is incorrect, it should run on ./ too.
906 out = self.parseGclient(['cleanup', '--deps', 'mac', '--verbose'], 1055 out = self.parseGclient(
907 [('running', join(self.root_dir, 'foo', 'bar'))]) 1056 ['cleanup', '--deps', 'mac', '--verbose', '--jobs', '1'],
908 out = self.parseGclient(['diff', '--deps', 'mac', '--verbose'], 1057 [('running', join(self.root_dir, 'foo', 'bar'))])
909 [('running', join(self.root_dir, 'foo', 'bar'))]) 1058 out = self.parseGclient(
1059 ['diff', '--deps', 'mac', '--verbose', '--jobs', '1'],
1060 [('running', join(self.root_dir, 'foo', 'bar'))])
910 1061
911 1062
912 if __name__ == '__main__': 1063 if __name__ == '__main__':
913 if '-c' in sys.argv: 1064 if '-c' in sys.argv:
914 COVERAGE = True 1065 COVERAGE = True
915 sys.argv.remove('-c') 1066 sys.argv.remove('-c')
916 if os.path.exists('.coverage'): 1067 if os.path.exists('.coverage'):
917 os.remove('.coverage') 1068 os.remove('.coverage')
918 os.environ['COVERAGE_FILE'] = os.path.join( 1069 os.environ['COVERAGE_FILE'] = os.path.join(
919 os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 1070 os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
920 '.coverage') 1071 '.coverage')
921 unittest.main() 1072 unittest.main()
OLDNEW
« no previous file with comments | « gclient_utils.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698