12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226 |
- #!/usr/bin/env python
- # Copyright (c) 2011 The Chromium Authors. All rights reserved.
- # Use of this source code is governed by a BSD-style license that can be
- # found in the LICENSE file.
- """Smoke tests for gclient.py.
- Shell out 'gclient' and run basic conformance tests.
- This test assumes GClientSmokeBase.URL_BASE is valid.
- """
- # pylint: disable=E1103,W0403
- import logging
- import os
- import re
- import subprocess
- import sys
- import unittest
- ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
- sys.path.insert(0, os.path.dirname(ROOT_DIR))
- from tests.fake_repos import join, write, FakeReposTestBase
- import subprocess2
- GCLIENT_PATH = os.path.join(os.path.dirname(ROOT_DIR), 'gclient')
- COVERAGE = False
- class GClientSmokeBase(FakeReposTestBase):
- def setUp(self):
- super(GClientSmokeBase, self).setUp()
- # Make sure it doesn't try to auto update when testing!
- self.env = os.environ.copy()
- self.env['DEPOT_TOOLS_UPDATE'] = '0'
- def gclient(self, cmd, cwd=None):
- if not cwd:
- cwd = self.root_dir
- if COVERAGE:
- # Don't use the wrapper script.
- cmd_base = ['coverage', 'run', '-a', GCLIENT_PATH + '.py']
- else:
- cmd_base = [GCLIENT_PATH]
- cmd = cmd_base + cmd
- process = subprocess.Popen(cmd, cwd=cwd, env=self.env,
- stdout=subprocess.PIPE, stderr=subprocess.PIPE,
- shell=sys.platform.startswith('win'))
- (stdout, stderr) = process.communicate()
- logging.debug("XXX: %s\n%s\nXXX" % (' '.join(cmd), stdout))
- logging.debug("YYY: %s\n%s\nYYY" % (' '.join(cmd), stderr))
- return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'),
- process.returncode)
- def parseGclient(self, cmd, items, expected_stderr='', untangle=False):
- """Parse gclient's output to make it easier to test.
- If untangle is True, tries to sort out the output from parallel checkout."""
- (stdout, stderr, returncode) = self.gclient(cmd)
- if untangle:
- tasks = {}
- remaining = []
- for line in stdout.splitlines(False):
- m = re.match(r'^(\d)+>(.*)$', line)
- if not m:
- remaining.append(line)
- else:
- self.assertEquals([], remaining)
- tasks.setdefault(int(m.group(1)), []).append(m.group(2))
- out = []
- for key in sorted(tasks.iterkeys()):
- out.extend(tasks[key])
- out.extend(remaining)
- stdout = '\n'.join(out)
- self.checkString(expected_stderr, stderr)
- self.assertEquals(0, returncode)
- return self.checkBlock(stdout, items)
- def splitBlock(self, stdout):
- """Split gclient's output into logical execution blocks.
- ___ running 'foo' at '/bar'
- (...)
- ___ running 'baz' at '/bar'
- (...)
- will result in 2 items of len((...).splitlines()) each.
- """
- results = []
- for line in stdout.splitlines(False):
- # Intentionally skips empty lines.
- if not line:
- continue
- if line.startswith('__'):
- match = re.match(r'^________ ([a-z]+) \'(.*)\' in \'(.*)\'$', line)
- if not match:
- match = re.match(r'^_____ (.*) is missing, synching instead$', line)
- if match:
- # Blah, it's when a dependency is deleted, we should probably not
- # output this message.
- results.append([line])
- elif (
- not re.match(
- r'_____ [^ ]+ : Attempting rebase onto [0-9a-f]+...',
- line) and
- not re.match(r'_____ [^ ]+ at [^ ]+', line)):
- # The two regexp above are a bit too broad, they are necessary only
- # for git checkouts.
- self.fail(line)
- else:
- results.append([[match.group(1), match.group(2), match.group(3)]])
- else:
- if not results:
- # TODO(maruel): gclient's git stdout is inconsistent.
- # This should fail the test instead!!
- pass
- else:
- results[-1].append(line)
- return results
- def checkBlock(self, stdout, items):
- results = self.splitBlock(stdout)
- for i in xrange(min(len(results), len(items))):
- if isinstance(items[i], (list, tuple)):
- verb = items[i][0]
- path = items[i][1]
- else:
- verb = items[i]
- path = self.root_dir
- self.checkString(results[i][0][0], verb, (i, results[i][0][0], verb))
- if sys.platform == 'win32':
- # Make path lower case since casing can change randomly.
- self.checkString(
- results[i][0][2].lower(),
- path.lower(),
- (i, results[i][0][2].lower(), path.lower()))
- else:
- self.checkString(results[i][0][2], path, (i, results[i][0][2], path))
- self.assertEquals(len(results), len(items), (stdout, items, len(results)))
- return results
- @staticmethod
- def svnBlockCleanup(out):
- """Work around svn status difference between svn 1.5 and svn 1.6
- I don't know why but on Windows they are reversed. So sorts the items."""
- for i in xrange(len(out)):
- if len(out[i]) < 2:
- continue
- out[i] = [out[i][0]] + sorted([x[1:].strip() for x in out[i][1:]])
- return out
- class GClientSmoke(GClientSmokeBase):
- """Doesn't require either svnserve nor git-daemon."""
- @property
- def svn_base(self):
- return 'svn://random.server/svn/'
- @property
- def git_base(self):
- return 'git://random.server/git/'
- def testHelp(self):
- """testHelp: make sure no new command was added."""
- result = self.gclient(['help'])
- # Roughly, not too short, not too long.
- self.assertTrue(1000 < len(result[0]) and len(result[0]) < 2000)
- self.assertEquals(0, len(result[1]))
- self.assertEquals(0, result[2])
- def testUnknown(self):
- result = self.gclient(['foo'])
- # Roughly, not too short, not too long.
- self.assertTrue(1000 < len(result[0]) and len(result[0]) < 2000)
- self.assertEquals(0, len(result[1]))
- self.assertEquals(0, result[2])
- def testNotConfigured(self):
- res = ('', 'Error: client not configured; see \'gclient config\'\n', 1)
- self.check(res, self.gclient(['cleanup']))
- self.check(res, self.gclient(['diff']))
- self.check(res, self.gclient(['pack']))
- self.check(res, self.gclient(['revert']))
- self.check(res, self.gclient(['revinfo']))
- self.check(res, self.gclient(['runhooks']))
- self.check(res, self.gclient(['status']))
- self.check(res, self.gclient(['sync']))
- self.check(res, self.gclient(['update']))
- def testConfig(self):
- p = join(self.root_dir, '.gclient')
- def test(cmd, expected):
- if os.path.exists(p):
- os.remove(p)
- results = self.gclient(cmd)
- self.check(('', '', 0), results)
- self.checkString(expected, open(p, 'rU').read())
- test(['config', self.svn_base + 'trunk/src/'],
- ('solutions = [\n'
- ' { "name" : "src",\n'
- ' "url" : "%strunk/src",\n'
- ' "custom_deps" : {\n'
- ' },\n'
- ' "safesync_url": "",\n'
- ' },\n'
- ']\n') % self.svn_base)
- test(['config', self.git_base + 'repo_1', '--name', 'src'],
- ('solutions = [\n'
- ' { "name" : "src",\n'
- ' "url" : "%srepo_1",\n'
- ' "custom_deps" : {\n'
- ' },\n'
- ' "safesync_url": "",\n'
- ' },\n'
- ']\n') % self.git_base)
- test(['config', 'foo', 'faa'],
- 'solutions = [\n'
- ' { "name" : "foo",\n'
- ' "url" : "foo",\n'
- ' "custom_deps" : {\n'
- ' },\n'
- ' "safesync_url": "faa",\n'
- ' },\n'
- ']\n')
- test(['config', '--spec', '["blah blah"]'], '["blah blah"]')
- os.remove(p)
- results = self.gclient(['config', 'foo', 'faa', 'fuu'])
- err = ('Usage: gclient.py config [options] [url] [safesync url]\n\n'
- 'gclient.py: error: Inconsistent arguments. Use either --spec or one'
- ' or 2 args\n')
- self.check(('', err, 2), results)
- self.assertFalse(os.path.exists(join(self.root_dir, '.gclient')))
- def testSolutionNone(self):
- results = self.gclient(['config', '--spec',
- 'solutions=[{"name": "./", "url": None}]'])
- self.check(('', '', 0), results)
- results = self.gclient(['sync'])
- self.check(('', '', 0), results)
- self.assertTree({})
- results = self.gclient(['revinfo'])
- self.check(('./: None\n', '', 0), results)
- self.check(('', '', 0), self.gclient(['cleanup']))
- self.check(('', '', 0), self.gclient(['diff']))
- self.assertTree({})
- self.check(('', '', 0), self.gclient(['pack']))
- self.check(('', '', 0), self.gclient(['revert']))
- self.assertTree({})
- self.check(('', '', 0), self.gclient(['runhooks']))
- self.assertTree({})
- self.check(('', '', 0), self.gclient(['status']))
- def testDifferentTopLevelDirectory(self):
- # Check that even if the .gclient file does not mention the directory src
- # itself, but it is included via dependencies, the .gclient file is used.
- self.gclient(['config', self.svn_base + 'trunk/src.DEPS'])
- deps = join(self.root_dir, 'src.DEPS')
- os.mkdir(deps)
- write(join(deps, 'DEPS'),
- 'deps = { "src": "%strunk/src" }' % (self.svn_base))
- src = join(self.root_dir, 'src')
- os.mkdir(src)
- res = self.gclient(['status', '--jobs', '1'], src)
- self.checkBlock(res[0], [('running', deps), ('running', src)])
- class GClientSmokeSVN(GClientSmokeBase):
- def setUp(self):
- super(GClientSmokeSVN, self).setUp()
- self.enabled = self.FAKE_REPOS.set_up_svn()
- def testSync(self):
- # TODO(maruel): safesync.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- # Test unversioned checkout.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running',
- # This is due to the way svn update is called for a
- # single file when File() is used in a DEPS file.
- ('running', os.path.join(self.root_dir, 'src', 'file', 'other')),
- 'running', 'running', 'running', 'running'])
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- # Manually remove svn_hooked1 before synching to make sure it's not
- # recreated.
- os.remove(join(self.root_dir, 'src', 'svn_hooked1'))
- # Test incremental versioned sync: sync backward.
- self.parseGclient(
- ['sync', '--revision', 'src@1', '--deps', 'mac',
- '--delete_unversioned_trees', '--jobs', '1'],
- ['running', 'running', 'running', 'running', 'deleting'])
- tree = self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/foo@2', 'src/third_party/prout'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- self.assertTree(tree)
- # Test incremental sync: delete-unversioned_trees isn't there.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running', 'running', 'running', 'running'])
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other'),
- ('trunk/third_party/foo@2', 'src/third_party/prout'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- def testSyncTransitive(self):
- # TODO(maruel): safesync.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- # Make sure we can populate a new repository with --transitive.
- self.parseGclient(
- ['sync', '--transitive', '--revision', 'src@1', '--deps', 'mac',
- '--jobs', '1'],
- ['running', 'running', 'running', 'running'])
- tree = self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/foo@1', 'src/third_party/prout'))
- # Get up to date, so we can test synching back.
- self.gclient(['sync', '--deps', 'mac', '--jobs', '1'])
- # Manually remove svn_hooked1 before synching to make sure it's not
- # recreated.
- os.remove(join(self.root_dir, 'src', 'svn_hooked1'))
- self.parseGclient(
- ['sync', '--transitive', '--revision', 'src@1', '--deps', 'mac',
- '--delete_unversioned_trees', '--jobs', '1'],
- ['running', 'running', 'running', 'running', 'deleting'])
- tree = self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/foo@1', 'src/third_party/prout'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- self.assertTree(tree)
- def testSyncIgnoredSolutionName(self):
- """TODO(maruel): This will become an error soon."""
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- results = self.gclient(
- ['sync', '--deps', 'mac', '-r', 'invalid@1', '--jobs', '1'])
- self.checkBlock(results[0], [
- 'running', 'running',
- # This is due to the way svn update is called for a single file when
- # File() is used in a DEPS file.
- ('running', os.path.join(self.root_dir, 'src', 'file', 'other')),
- 'running', 'running', 'running', 'running'])
- self.checkString('Please fix your script, having invalid --revision flags '
- 'will soon considered an error.\n', results[1])
- self.assertEquals(0, results[2])
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- def testSyncNoSolutionName(self):
- # When no solution name is provided, gclient uses the first solution listed.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.parseGclient(['sync', '--deps', 'mac', '-r', '1', '--jobs', '1'],
- ['running', 'running', 'running', 'running'])
- tree = self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/foo@2', 'src/third_party/prout'))
- self.assertTree(tree)
- def testSyncJobs(self):
- if not self.enabled:
- return
- # TODO(maruel): safesync.
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- # Test unversioned checkout.
- self.parseGclient(
- ['sync', '--deps', 'mac', '--jobs', '8'],
- ['running', 'running',
- # This is due to the way svn update is called for a
- # single file when File() is used in a DEPS file.
- ('running', os.path.join(self.root_dir, 'src', 'file', 'other')),
- 'running', 'running', 'running', 'running'],
- untangle=True)
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- # Manually remove svn_hooked1 before synching to make sure it's not
- # recreated.
- os.remove(join(self.root_dir, 'src', 'svn_hooked1'))
- # Test incremental versioned sync: sync backward.
- self.parseGclient(
- ['sync', '--revision', 'src@1', '--deps', 'mac',
- '--delete_unversioned_trees', '--jobs', '8'],
- ['running', 'running', 'running', 'running', 'deleting'],
- untangle=True)
- tree = self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/foo@2', 'src/third_party/prout'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- self.assertTree(tree)
- # Test incremental sync: delete-unversioned_trees isn't there.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
- ['running', 'running', 'running', 'running', 'running'],
- untangle=True)
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other'),
- ('trunk/third_party/foo@2', 'src/third_party/prout'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- def testSyncCustomDeps(self):
- if not self.enabled:
- return
- out = (
- 'solutions = [\n'
- ' { "name" : "src",\n'
- ' "url" : "%(base)s/src",\n'
- ' "custom_deps" : {\n'
- # Remove 2 deps, change 1, add 1.
- ' "src/other": None,\n'
- ' "src/third_party/foo": \'%(base)s/third_party/prout\',\n'
- ' "src/file/other": None,\n'
- ' "new_deps": "/trunk/src/third_party",\n'
- ' },\n'
- ' "safesync_url": "",\n'
- ' },\n'
- ']\n\n' %
- { 'base': self.svn_base + 'trunk' })
- fileobj = open(os.path.join(self.root_dir, '.gclient'), 'w')
- fileobj.write(out)
- fileobj.close()
- self.parseGclient(
- ['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running', 'running', 'running'],
- untangle=True)
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/prout@2', 'src/third_party/foo'),
- ('trunk/src/third_party@2', 'new_deps'))
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- def testSyncCustomDepsNoDeps(self):
- if not self.enabled:
- return
- out = (
- 'solutions = [\n'
- # This directory has no DEPS file.
- ' { "name" : "src/third_party",\n'
- ' "url" : "%(base)s/src/third_party",\n'
- ' "custom_deps" : {\n'
- # Add 1.
- ' "src/other": \'/trunk/other\',\n'
- ' },\n'
- ' "safesync_url": "",\n'
- ' },\n'
- ']\n\n' %
- { 'base': self.svn_base + 'trunk' })
- fileobj = open(os.path.join(self.root_dir, '.gclient'), 'w')
- fileobj.write(out)
- fileobj.close()
- self.parseGclient(
- ['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running'],
- untangle=True)
- tree = self.mangle_svn_tree(
- ('trunk/src/third_party@2', 'src/third_party'),
- ('trunk/other@2', 'src/other'))
- self.assertTree(tree)
- def testRevertAndStatus(self):
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- # Tested in testSync.
- self.gclient(['sync', '--deps', 'mac'])
- write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!')
- out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
- [['running', join(self.root_dir, 'src')],
- ['running', join(self.root_dir, 'src', 'other')]])
- out = self.svnBlockCleanup(out)
- self.checkString('file', out[0][1])
- self.checkString('other', out[0][2])
- self.checkString('svn_hooked1', out[0][3])
- self.checkString(join('third_party', 'foo'), out[0][4])
- self.checkString('hi', out[1][1])
- self.assertEquals(5, len(out[0]))
- self.assertEquals(2, len(out[1]))
- # Revert implies --force implies running hooks without looking at pattern
- # matching.
- results = self.gclient(['revert', '--deps', 'mac', '--jobs', '1'])
- out = self.splitBlock(results[0])
- # src, src/other is missing, src/other, src/third_party/foo is missing,
- # src/third_party/foo, 2 svn hooks, 3 related to File().
- self.assertEquals(10, len(out))
- self.checkString('', results[1])
- self.assertEquals(0, results[2])
- tree = self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other'))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/svn_hooked1'] = 'svn_hooked1'
- tree['src/svn_hooked2'] = 'svn_hooked2'
- self.assertTree(tree)
- out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
- [['running', join(self.root_dir, 'src')]])
- out = self.svnBlockCleanup(out)
- self.checkString('file', out[0][1])
- self.checkString('other', out[0][2])
- self.checkString('svn_hooked1', out[0][3])
- self.checkString('svn_hooked2', out[0][4])
- self.checkString(join('third_party', 'foo'), out[0][5])
- self.assertEquals(6, len(out[0]))
- self.assertEquals(1, len(out))
- def testRevertAndStatusDepsOs(self):
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- # Tested in testSync.
- self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1'])
- write(join(self.root_dir, 'src', 'other', 'hi'), 'Hey!')
- # Without --verbose, gclient won't output the directories without
- # modification.
- out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
- [['running', join(self.root_dir, 'src')],
- ['running', join(self.root_dir, 'src', 'other')]])
- out = self.svnBlockCleanup(out)
- self.checkString('other', out[0][1])
- self.checkString(join('third_party', 'fpp'), out[0][2])
- self.checkString(join('third_party', 'prout'), out[0][3])
- self.checkString('hi', out[1][1])
- self.assertEquals(4, len(out[0]))
- self.assertEquals(2, len(out[1]))
- # So verify it works with --verbose.
- out = self.parseGclient(
- ['status', '--deps', 'mac', '--verbose', '--jobs', '1'],
- [['running', join(self.root_dir, 'src')],
- ['running', join(self.root_dir, 'src', 'third_party', 'fpp')],
- ['running', join(self.root_dir, 'src', 'other')],
- ['running', join(self.root_dir, 'src', 'third_party', 'prout')]])
- out = self.svnBlockCleanup(out)
- self.checkString('other', out[0][1])
- self.checkString(join('third_party', 'fpp'), out[0][2])
- self.checkString(join('third_party', 'prout'), out[0][3])
- self.checkString('hi', out[2][1])
- self.assertEquals(4, len(out[0]))
- self.assertEquals(1, len(out[1]))
- self.assertEquals(2, len(out[2]))
- self.assertEquals(1, len(out[3]))
- self.assertEquals(4, len(out))
- # Revert implies --force implies running hooks without looking at pattern
- # matching.
- # TODO(maruel): In general, gclient revert output is wrong. It should output
- # the file list after some ___ running 'svn status'
- results = self.gclient(['revert', '--deps', 'mac', '--jobs', '1'])
- out = self.splitBlock(results[0])
- self.assertEquals(7, len(out))
- self.checkString('', results[1])
- self.assertEquals(0, results[2])
- tree = self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/prout@2', 'src/third_party/prout'))
- self.assertTree(tree)
- out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'],
- [['running', join(self.root_dir, 'src')]])
- out = self.svnBlockCleanup(out)
- self.checkString('other', out[0][1])
- self.checkString(join('third_party', 'fpp'), out[0][2])
- self.checkString(join('third_party', 'prout'), out[0][3])
- self.assertEquals(4, len(out[0]))
- def testRunHooks(self):
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.gclient(['sync', '--deps', 'mac'])
- out = self.parseGclient(['runhooks', '--deps', 'mac'],
- ['running', 'running'])
- self.checkString(1, len(out[0]))
- self.checkString(1, len(out[1]))
- def testRunHooksDepsOs(self):
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.gclient(['sync', '--deps', 'mac', '--revision', 'src@1'])
- out = self.parseGclient(['runhooks', '--deps', 'mac'], [])
- self.assertEquals([], out)
- def testRevInfo(self):
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.gclient(['sync', '--deps', 'mac'])
- results = self.gclient(['revinfo', '--deps', 'mac'])
- out = ('src: %(base)s/src\n'
- 'src/file/other: File("%(base)s/other/DEPS")\n'
- 'src/other: %(base)s/other\n'
- 'src/third_party/foo: %(base)s/third_party/foo@1\n' %
- { 'base': self.svn_base + 'trunk' })
- self.check((out, '', 0), results)
- results = self.gclient(['revinfo', '--deps', 'mac', '--actual'])
- out = ('src: %(base)s/src@2\n'
- 'src/file/other: %(base)s/other/DEPS@2\n'
- 'src/other: %(base)s/other@2\n'
- 'src/third_party/foo: %(base)s/third_party/foo@1\n' %
- { 'base': self.svn_base + 'trunk' })
- self.check((out, '', 0), results)
- results = self.gclient(['revinfo', '--deps', 'mac', '--snapshot'])
- out = ('# Snapshot generated with gclient revinfo --snapshot\n'
- 'solutions = [\n'
- ' { "name" : "src",\n'
- ' "url" : "%(base)s/src",\n'
- ' "custom_deps" : {\n'
- ' "foo/bar": None,\n'
- ' "invalid": None,\n'
- ' "src/file/other": \'%(base)s/other/DEPS@2\',\n'
- ' "src/other": \'%(base)s/other@2\',\n'
- ' "src/third_party/foo": '
- '\'%(base)s/third_party/foo@1\',\n'
- ' },\n'
- ' "safesync_url": "",\n'
- ' },\n'
- ']\n\n' %
- { 'base': self.svn_base + 'trunk' })
- self.check((out, '', 0), results)
- def testWrongDirectory(self):
- # Check that we're not using a .gclient configuration which only talks
- # about a subdirectory src when we're in a different subdirectory src-other.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.gclient(['sync'])
- other_src = join(self.root_dir, 'src-other')
- os.mkdir(other_src)
- res = ('', 'Error: client not configured; see \'gclient config\'\n', 1)
- self.check(res, self.gclient(['status'], other_src))
- def testCorrectDirectory(self):
- # Check that when we're in the subdirectory src, the .gclient configuration
- # is used.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.gclient(['sync'])
- src = join(self.root_dir, 'src')
- res = self.gclient(['status', '--jobs', '1'], src)
- self.checkBlock(res[0], [('running', src)])
- def testInitialCheckoutNotYetDone(self):
- # Check that gclient can be executed when the initial checkout hasn't been
- # done yet.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.parseGclient(
- ['sync', '--jobs', '1'],
- ['running', 'running',
- # This is due to the way svn update is called for a
- # single file when File() is used in a DEPS file.
- ('running', os.path.join(self.root_dir, 'src', 'file', 'other')),
- 'running', 'running', 'running', 'running'])
- def testInitialCheckoutFailed(self):
- # Check that gclient can be executed from an arbitrary sub directory if the
- # initial checkout has failed.
- if not self.enabled:
- return
- self.gclient(['config', self.svn_base + 'trunk/src/'])
- self.gclient(['sync'])
- # Cripple the checkout.
- os.remove(join(self.root_dir, '.gclient_entries'))
- src = join(self.root_dir, 'src')
- res = self.gclient(['sync', '--jobs', '1'], src)
- self.checkBlock(res[0],
- ['running', 'running', 'running'])
- class GClientSmokeGIT(GClientSmokeBase):
- def setUp(self):
- super(GClientSmokeGIT, self).setUp()
- self.enabled = self.FAKE_REPOS.set_up_git()
- def testSync(self):
- if not self.enabled:
- return
- # TODO(maruel): safesync.
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- # Test unversioned checkout.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running', 'running', 'running', 'running'])
- # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must
- # add sync parsing to get the list of updated files.
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- # Manually remove git_hooked1 before synching to make sure it's not
- # recreated.
- os.remove(join(self.root_dir, 'src', 'git_hooked1'))
- # Test incremental versioned sync: sync backward.
- self.parseGclient(['sync', '--jobs', '1', '--revision',
- 'src@' + self.githash('repo_1', 1),
- '--deps', 'mac', '--delete_unversioned_trees'],
- ['running', 'running', 'deleting'])
- tree = self.mangle_git_tree(('repo_1@1', 'src'),
- ('repo_2@2', 'src/repo2'),
- ('repo_3@1', 'src/repo2/repo3'),
- ('repo_4@2', 'src/repo4'))
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- # Test incremental sync: delete-unversioned_trees isn't there.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running', 'running'])
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@1', 'src/repo2/repo3'),
- ('repo_3@2', 'src/repo2/repo_renamed'),
- ('repo_4@2', 'src/repo4'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- def testSyncIgnoredSolutionName(self):
- """TODO(maruel): This will become an error soon."""
- if not self.enabled:
- return
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- self.parseGclient(
- ['sync', '--deps', 'mac', '--jobs', '1',
- '--revision', 'invalid@' + self.githash('repo_1', 1)],
- ['running', 'running', 'running', 'running', 'running'],
- 'Please fix your script, having invalid --revision flags '
- 'will soon considered an error.\n')
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- def testSyncNoSolutionName(self):
- if not self.enabled:
- return
- # When no solution name is provided, gclient uses the first solution listed.
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1',
- '--revision', self.githash('repo_1', 1)],
- ['running', 'running', 'running', 'running'])
- tree = self.mangle_git_tree(('repo_1@1', 'src'),
- ('repo_2@2', 'src/repo2'),
- ('repo_3@1', 'src/repo2/repo3'),
- ('repo_4@2', 'src/repo4'))
- self.assertTree(tree)
- def testSyncJobs(self):
- if not self.enabled:
- return
- # TODO(maruel): safesync.
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- # Test unversioned checkout.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
- ['running', 'running', 'running', 'running', 'running'],
- untangle=True)
- # TODO(maruel): http://crosbug.com/3582 hooks run even if not matching, must
- # add sync parsing to get the list of updated files.
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- # Manually remove git_hooked1 before synching to make sure it's not
- # recreated.
- os.remove(join(self.root_dir, 'src', 'git_hooked1'))
- # Test incremental versioned sync: sync backward.
- self.parseGclient(
- ['sync', '--revision', 'src@' + self.githash('repo_1', 1),
- '--deps', 'mac', '--delete_unversioned_trees', '--jobs', '8'],
- ['running', 'running', 'deleting'],
- untangle=True)
- tree = self.mangle_git_tree(('repo_1@1', 'src'),
- ('repo_2@2', 'src/repo2'),
- ('repo_3@1', 'src/repo2/repo3'),
- ('repo_4@2', 'src/repo4'))
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- # Test incremental sync: delete-unversioned_trees isn't there.
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
- ['running', 'running', 'running'], untangle=True)
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@1', 'src/repo2/repo3'),
- ('repo_3@2', 'src/repo2/repo_renamed'),
- ('repo_4@2', 'src/repo4'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- def testRevertAndStatus(self):
- """TODO(maruel): Remove this line once this test is fixed."""
- if not self.enabled:
- return
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- # Tested in testSync.
- self.gclient(['sync', '--deps', 'mac'])
- write(join(self.root_dir, 'src', 'repo2', 'hi'), 'Hey!')
- out = self.parseGclient(['status', '--deps', 'mac'], [])
- # TODO(maruel): http://crosbug.com/3584 It should output the unversioned
- # files.
- self.assertEquals(0, len(out))
- # Revert implies --force implies running hooks without looking at pattern
- # matching.
- results = self.gclient(['revert', '--deps', 'mac'])
- out = results[0].splitlines(False)
- # TODO(maruel): http://crosbug.com/3583 It just runs the hooks right now.
- self.assertEquals(13, len(out))
- self.checkString('', results[1])
- self.assertEquals(0, results[2])
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- # TODO(maruel): http://crosbug.com/3583 This file should have been removed.
- tree[join('src', 'repo2', 'hi')] = 'Hey!'
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- results = self.gclient(['status', '--deps', 'mac'])
- out = results[0].splitlines(False)
- # TODO(maruel): http://crosbug.com/3584 It should output the unversioned
- # files.
- self.assertEquals(0, len(out))
- def testRunHooks(self):
- if not self.enabled:
- return
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- self.gclient(['sync', '--deps', 'mac'])
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- os.remove(join(self.root_dir, 'src', 'git_hooked1'))
- os.remove(join(self.root_dir, 'src', 'git_hooked2'))
- # runhooks runs all hooks even if not matching by design.
- out = self.parseGclient(['runhooks', '--deps', 'mac'],
- ['running', 'running'])
- self.assertEquals(1, len(out[0]))
- self.assertEquals(1, len(out[1]))
- tree = self.mangle_git_tree(('repo_1@2', 'src'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- self.assertTree(tree)
- def testRevInfo(self):
- if not self.enabled:
- return
- self.gclient(['config', self.git_base + 'repo_1', '--name', 'src'])
- self.gclient(['sync', '--deps', 'mac'])
- results = self.gclient(['revinfo', '--deps', 'mac'])
- out = ('src: %(base)srepo_1\n'
- 'src/repo2: %(base)srepo_2@%(hash2)s\n'
- 'src/repo2/repo_renamed: %(base)srepo_3\n' %
- {
- 'base': self.git_base,
- 'hash2': self.githash('repo_2', 1)[:7],
- })
- self.check((out, '', 0), results)
- results = self.gclient(['revinfo', '--deps', 'mac', '--actual'])
- out = ('src: %(base)srepo_1@%(hash1)s\n'
- 'src/repo2: %(base)srepo_2@%(hash2)s\n'
- 'src/repo2/repo_renamed: %(base)srepo_3@%(hash3)s\n' %
- {
- 'base': self.git_base,
- 'hash1': self.githash('repo_1', 2),
- 'hash2': self.githash('repo_2', 1),
- 'hash3': self.githash('repo_3', 2),
- })
- self.check((out, '', 0), results)
- class GClientSmokeBoth(GClientSmokeBase):
- def setUp(self):
- super(GClientSmokeBoth, self).setUp()
- self.enabled = self.FAKE_REPOS.set_up_svn() and self.FAKE_REPOS.set_up_git()
- def testMultiSolutions(self):
- if not self.enabled:
- return
- self.gclient(['config', '--spec',
- 'solutions=['
- '{"name": "src",'
- ' "url": "' + self.svn_base + 'trunk/src/"},'
- '{"name": "src-git",'
- '"url": "' + self.git_base + 'repo_1"}]'])
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running', 'running',
- # This is due to the way svn update is called for a single
- # file when File() is used in a DEPS file.
- ('running', self.root_dir + '/src/file/other'),
- 'running', 'running', 'running', 'running', 'running', 'running',
- 'running', 'running'])
- tree = self.mangle_git_tree(('repo_1@2', 'src-git'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree.update(self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other')))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- def testMultiSolutionsJobs(self):
- if not self.enabled:
- return
- self.gclient(['config', '--spec',
- 'solutions=['
- '{"name": "src",'
- ' "url": "' + self.svn_base + 'trunk/src/"},'
- '{"name": "src-git",'
- '"url": "' + self.git_base + 'repo_1"}]'])
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '8'],
- ['running', 'running', 'running',
- # This is due to the way svn update is called for a single
- # file when File() is used in a DEPS file.
- ('running', self.root_dir + '/src/file/other'),
- 'running', 'running', 'running', 'running', 'running', 'running',
- 'running', 'running'],
- untangle=True)
- tree = self.mangle_git_tree(('repo_1@2', 'src-git'),
- ('repo_2@1', 'src/repo2'),
- ('repo_3@2', 'src/repo2/repo_renamed'))
- tree.update(self.mangle_svn_tree(
- ('trunk/src@2', 'src'),
- ('trunk/third_party/foo@1', 'src/third_party/foo'),
- ('trunk/other@2', 'src/other')))
- tree['src/file/other/DEPS'] = (
- self.FAKE_REPOS.svn_revs[2]['trunk/other/DEPS'])
- tree['src/git_hooked1'] = 'git_hooked1'
- tree['src/git_hooked2'] = 'git_hooked2'
- tree['src/svn_hooked1'] = 'svn_hooked1'
- self.assertTree(tree)
- def testMultiSolutionsMultiRev(self):
- if not self.enabled:
- return
- self.gclient(['config', '--spec',
- 'solutions=['
- '{"name": "src",'
- ' "url": "' + self.svn_base + 'trunk/src/"},'
- '{"name": "src-git",'
- '"url": "' + self.git_base + 'repo_1"}]'])
- self.parseGclient(
- ['sync', '--deps', 'mac', '--jobs', '1', '--revision', '1',
- '-r', 'src-git@' + self.githash('repo_1', 1)],
- ['running', 'running', 'running', 'running',
- 'running', 'running', 'running', 'running'])
- tree = self.mangle_git_tree(('repo_1@1', 'src-git'),
- ('repo_2@2', 'src/repo2'),
- ('repo_3@1', 'src/repo2/repo3'),
- ('repo_4@2', 'src/repo4'))
- tree.update(self.mangle_svn_tree(
- ('trunk/src@1', 'src'),
- ('trunk/third_party/foo@2', 'src/third_party/fpp'),
- ('trunk/other@1', 'src/other'),
- ('trunk/third_party/foo@2', 'src/third_party/prout')))
- self.assertTree(tree)
- def testRevInfo(self):
- if not self.enabled:
- return
- self.gclient(['config', '--spec',
- 'solutions=['
- '{"name": "src",'
- ' "url": "' + self.svn_base + 'trunk/src/"},'
- '{"name": "src-git",'
- '"url": "' + self.git_base + 'repo_1"}]'])
- self.gclient(['sync', '--deps', 'mac'])
- results = self.gclient(['revinfo', '--deps', 'mac'])
- out = ('src: %(svn_base)s/src/\n'
- 'src-git: %(git_base)srepo_1\n'
- 'src/file/other: File("%(svn_base)s/other/DEPS")\n'
- 'src/other: %(svn_base)s/other\n'
- 'src/repo2: %(git_base)srepo_2@%(hash2)s\n'
- 'src/repo2/repo_renamed: %(git_base)srepo_3\n'
- 'src/third_party/foo: %(svn_base)s/third_party/foo@1\n') % {
- 'svn_base': self.svn_base + 'trunk',
- 'git_base': self.git_base,
- 'hash2': self.githash('repo_2', 1)[:7],
- }
- self.check((out, '', 0), results)
- results = self.gclient(['revinfo', '--deps', 'mac', '--actual'])
- out = ('src: %(svn_base)s/src/@2\n'
- 'src-git: %(git_base)srepo_1@%(hash1)s\n'
- 'src/file/other: %(svn_base)s/other/DEPS@2\n'
- 'src/other: %(svn_base)s/other@2\n'
- 'src/repo2: %(git_base)srepo_2@%(hash2)s\n'
- 'src/repo2/repo_renamed: %(git_base)srepo_3@%(hash3)s\n'
- 'src/third_party/foo: %(svn_base)s/third_party/foo@1\n') % {
- 'svn_base': self.svn_base + 'trunk',
- 'git_base': self.git_base,
- 'hash1': self.githash('repo_1', 2),
- 'hash2': self.githash('repo_2', 1),
- 'hash3': self.githash('repo_3', 2),
- }
- self.check((out, '', 0), results)
- def testRecurse(self):
- if not self.enabled:
- return
- self.gclient(['config', '--spec',
- 'solutions=['
- '{"name": "src",'
- ' "url": "' + self.svn_base + 'trunk/src/"},'
- '{"name": "src-git",'
- '"url": "' + self.git_base + 'repo_1"}]'])
- self.gclient(['sync', '--deps', 'mac'])
- results = self.gclient(['recurse', 'sh', '-c',
- 'echo $GCLIENT_SCM,$GCLIENT_URL,`pwd`'])
- entries = [tuple(line.split(','))
- for line in results[0].strip().split('\n')]
- logging.debug(entries)
- bases = {'svn': self.svn_base, 'git': self.git_base}
- expected_source = [
- ('svn', 'trunk/src/', 'src'),
- ('git', 'repo_1', 'src-git'),
- ('svn', 'trunk/other', 'src/other'),
- ('git', 'repo_2@' + self.githash('repo_2', 1)[:7], 'src/repo2'),
- ('git', 'repo_3', 'src/repo2/repo_renamed'),
- ('svn', 'trunk/third_party/foo@1', 'src/third_party/foo'),
- ]
- expected = [(scm, bases[scm] + url, os.path.join(self.root_dir, path))
- for (scm, url, path) in expected_source]
- self.assertEquals(sorted(entries), sorted(expected))
- class GClientSmokeFromCheckout(GClientSmokeBase):
- # WebKit abuses this. It has a .gclient and a DEPS from a checkout.
- def setUp(self):
- super(GClientSmokeFromCheckout, self).setUp()
- self.enabled = self.FAKE_REPOS.set_up_svn()
- os.rmdir(self.root_dir)
- if self.enabled:
- usr, pwd = self.FAKE_REPOS.USERS[0]
- subprocess2.check_call(
- ['svn', 'checkout', self.svn_base + '/trunk/webkit',
- self.root_dir, '-q',
- '--non-interactive', '--no-auth-cache',
- '--username', usr, '--password', pwd])
- def testSync(self):
- if not self.enabled:
- return
- self.parseGclient(['sync', '--deps', 'mac', '--jobs', '1'],
- ['running', 'running'])
- tree = self.mangle_svn_tree(
- ('trunk/webkit@2', ''),
- ('trunk/third_party/foo@1', 'foo/bar'))
- self.assertTree(tree)
- def testRevertAndStatus(self):
- if not self.enabled:
- return
- self.gclient(['sync'])
- # TODO(maruel): This is incorrect.
- out = self.parseGclient(['status', '--deps', 'mac', '--jobs', '1'], [])
- # Revert implies --force implies running hooks without looking at pattern
- # matching.
- results = self.gclient(['revert', '--deps', 'mac', '--jobs', '1'])
- out = self.splitBlock(results[0])
- self.assertEquals(2, len(out))
- self.checkString(2, len(out[0]))
- self.checkString(2, len(out[1]))
- self.checkString('foo', out[1][1])
- self.checkString('', results[1])
- self.assertEquals(0, results[2])
- tree = self.mangle_svn_tree(
- ('trunk/webkit@2', ''),
- ('trunk/third_party/foo@1', 'foo/bar'))
- self.assertTree(tree)
- # TODO(maruel): This is incorrect.
- out = self.parseGclient(['status', '--deps', 'mac'], [])
- def testRunHooks(self):
- if not self.enabled:
- return
- # Hooks aren't really tested for now since there is no hook defined.
- self.gclient(['sync', '--deps', 'mac'])
- out = self.parseGclient(['runhooks', '--deps', 'mac'], ['running'])
- self.assertEquals(1, len(out))
- self.assertEquals(2, len(out[0]))
- self.assertEquals(3, len(out[0][0]))
- self.checkString('foo', out[0][1])
- tree = self.mangle_svn_tree(
- ('trunk/webkit@2', ''),
- ('trunk/third_party/foo@1', 'foo/bar'))
- self.assertTree(tree)
- def testRevInfo(self):
- if not self.enabled:
- return
- self.gclient(['sync', '--deps', 'mac'])
- results = self.gclient(['revinfo', '--deps', 'mac'])
- expected = (
- './: None\nfoo/bar: %strunk/third_party/foo@1\n' % self.svn_base,
- '', 0)
- self.check(expected, results)
- # TODO(maruel): To be added after the refactor.
- #results = self.gclient(['revinfo', '--snapshot'])
- #expected = (
- # './: None\nfoo/bar: %strunk/third_party/foo@1\n' % self.svn_base,
- # '', 0)
- #self.check(expected, results)
- def testRest(self):
- if not self.enabled:
- return
- self.gclient(['sync'])
- # TODO(maruel): This is incorrect, it should run on ./ too.
- self.parseGclient(
- ['cleanup', '--deps', 'mac', '--verbose', '--jobs', '1'],
- [('running', join(self.root_dir, 'foo', 'bar'))])
- self.parseGclient(
- ['diff', '--deps', 'mac', '--verbose', '--jobs', '1'],
- [('running', join(self.root_dir, 'foo', 'bar'))])
- if __name__ == '__main__':
- if '-v' in sys.argv:
- logging.basicConfig(level=logging.DEBUG)
- if '-c' in sys.argv:
- COVERAGE = True
- sys.argv.remove('-c')
- if os.path.exists('.coverage'):
- os.remove('.coverage')
- os.environ['COVERAGE_FILE'] = os.path.join(
- os.path.dirname(os.path.dirname(os.path.abspath(__file__))),
- '.coverage')
- unittest.main()
|