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 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'))])
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)])
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'])
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 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 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 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 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): 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 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 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 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' ' "deps_file" : "DEPS",\n' ' "managed" : True,\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' ' "deps_file" : "DEPS",\n' ' "managed" : True,\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' ' "deps_file" : "DEPS",\n' ' "managed" : True,\n' ' "custom_deps" : {\n' ' },\n' ' "safesync_url": "faa",\n' ' },\n' ']\n') test(['config', 'foo', '--deps', 'blah'], 'solutions = [\n' ' { "name" : "foo",\n' ' "url" : "foo",\n' ' "deps_file" : "blah",\n' ' "managed" : True,\n' ' "custom_deps" : {\n' ' },\n' ' "safesync_url": "",\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')))