Commit dbd102dc authored by maruel@chromium.org's avatar maruel@chromium.org

Remove most svn related testing.

Subversion usage is going away, tests get the kick first.

R=iannucci@chromium.org
BUG=475320

Review URL: https://codereview.chromium.org/1158043003

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@295411 0039d316-1c4b-4281-b951-d872f2087c98
parent c20f4700
......@@ -59,36 +59,6 @@ def dict_diff(dict1, dict2):
return diff
def commit_svn(repo, usr, pwd):
"""Commits the changes and returns the new revision number."""
to_add = []
to_remove = []
for status, filepath in scm.SVN.CaptureStatus(None, repo):
if status[0] == '?':
to_add.append(filepath)
elif status[0] == '!':
to_remove.append(filepath)
if to_add:
subprocess2.check_output(
['svn', 'add', '--no-auto-props', '-q'] + to_add, cwd=repo)
if to_remove:
subprocess2.check_output(['svn', 'remove', '-q'] + to_remove, cwd=repo)
out = subprocess2.check_output(
['svn', 'commit', repo, '-m', 'foo', '--non-interactive',
'--no-auth-cache',
'--username', usr, '--password', pwd],
cwd=repo)
match = re.search(r'(\d+)', out)
if not match:
raise Exception('Commit failed', out)
rev = match.group(1)
status = subprocess2.check_output(['svn', 'status'], cwd=repo)
assert len(status) == 0, status
logging.debug('At revision %s' % rev)
return rev
def commit_git(repo):
"""Commits the changes and returns the new hash."""
subprocess2.check_call(['git', 'add', '-A', '-f'], cwd=repo)
......@@ -162,14 +132,14 @@ def wait_for_port_to_free(host, port):
class FakeReposBase(object):
"""Generate both svn and git repositories to test gclient functionality.
"""Generate git repositories to test gclient functionality.
Many DEPS functionalities need to be tested: Var, File, From, deps_os, hooks,
use_relative_paths.
And types of dependencies: Relative urls, Full urls, both svn and git.
And types of dependencies: Relative urls, Full urls, git.
populateSvn() and populateGit() need to be implemented by the subclass.
populateGit() needs to be implemented by the subclass.
"""
# Hostname
NB_GIT_REPOS = 1
......@@ -181,25 +151,16 @@ class FakeReposBase(object):
def __init__(self, host=None):
self.trial = trial_dir.TrialDir('repos')
self.host = host or '127.0.0.1'
# Format is [ None, tree, tree, ...]
# i.e. revisions are 1-based.
self.svn_revs = [None]
# Format is { repo: [ None, (hash, tree), (hash, tree), ... ], ... }
# so reference looks like self.git_hashes[repo][rev][0] for hash and
# self.git_hashes[repo][rev][1] for it's tree snapshot.
# For consistency with self.svn_revs, it is 1-based too.
# It is 1-based too.
self.git_hashes = {}
self.svnserve = None
self.gitdaemon = None
self.git_pid_file = None
self.git_root = None
self.svn_checkout = None
self.svn_repo = None
self.git_dirty = False
self.svn_dirty = False
self.svn_port = None
self.git_port = None
self.svn_base = None
self.git_base = None
@property
......@@ -214,50 +175,23 @@ class FakeReposBase(object):
# self.root_dir is not set before this call.
self.trial.set_up()
self.git_root = join(self.root_dir, 'git')
self.svn_checkout = join(self.root_dir, 'svn_checkout')
self.svn_repo = join(self.root_dir, 'svn')
finally:
# Registers cleanup.
atexit.register(self.tear_down)
def cleanup_dirt(self):
"""For each dirty repository, destroy it."""
if self.svn_dirty:
if not self.tear_down_svn():
logging.error('Using both leaking checkout and svn dirty checkout')
if self.git_dirty:
if not self.tear_down_git():
logging.error('Using both leaking checkout and git dirty checkout')
def tear_down(self):
"""Kills the servers and delete the directories."""
self.tear_down_svn()
self.tear_down_git()
# This deletes the directories.
self.trial.tear_down()
self.trial = None
def tear_down_svn(self):
if self.svnserve:
logging.debug('Killing svnserve pid %s' % self.svnserve.pid)
try:
self.svnserve.kill()
except OSError as e:
if e.errno != errno.ESRCH: # no such process
raise
wait_for_port_to_free(self.host, self.svn_port)
self.svnserve = None
self.svn_port = None
self.svn_base = None
if not self.trial.SHOULD_LEAK:
logging.debug('Removing %s' % self.svn_repo)
gclient_utils.rmtree(self.svn_repo)
logging.debug('Removing %s' % self.svn_checkout)
gclient_utils.rmtree(self.svn_checkout)
else:
return False
return True
def tear_down_git(self):
if self.gitdaemon:
logging.debug('Killing git-daemon pid %s' % self.gitdaemon.pid)
......@@ -300,60 +234,6 @@ class FakeReposBase(object):
else:
write(join(root, k), v)
def set_up_svn(self):
"""Creates subversion repositories and start the servers."""
self.set_up()
if self.svnserve:
return True
try:
subprocess2.check_call(['svnadmin', 'create', self.svn_repo])
except (OSError, subprocess2.CalledProcessError):
return False
write(join(self.svn_repo, 'conf', 'svnserve.conf'),
'[general]\n'
'anon-access = read\n'
'auth-access = write\n'
'password-db = passwd\n')
text = '[users]\n'
text += ''.join('%s = %s\n' % (usr, pwd) for usr, pwd in self.USERS)
write(join(self.svn_repo, 'conf', 'passwd'), text)
# Necessary to be able to change revision properties
revprop_hook_filename = join(self.svn_repo, 'hooks', 'pre-revprop-change')
if sys.platform == 'win32':
# TODO(kustermann): Test on Windows one day.
write("%s.bat" % revprop_hook_filename, "")
else:
write(revprop_hook_filename,
'#!/bin/sh\n'
'exit 0\n')
os.chmod(revprop_hook_filename, 0755)
# Mac 10.6 ships with a buggy subversion build and we need this line
# to work around the bug.
write(join(self.svn_repo, 'db', 'fsfs.conf'),
'[rep-sharing]\n'
'enable-rep-sharing = false\n')
# Start the daemon.
self.svn_port = find_free_port(self.host, 10000)
logging.debug('Using port %d' % self.svn_port)
cmd = ['svnserve', '-d', '--foreground', '-r', self.root_dir,
'--listen-port=%d' % self.svn_port]
if self.host == '127.0.0.1':
cmd.append('--listen-host=' + self.host)
self.check_port_is_free(self.svn_port)
self.svnserve = subprocess2.Popen(
cmd,
cwd=self.svn_repo,
stdout=subprocess2.PIPE,
stderr=subprocess2.PIPE)
wait_for_port_to_bind(self.host, self.svn_port, self.svnserve)
self.svn_base = 'svn://%s:%d/svn/' % (self.host, self.svn_port)
self.populateSvn()
self.svn_dirty = False
return True
def set_up_git(self):
"""Creates git repositories and start the servers."""
self.set_up()
......@@ -390,24 +270,6 @@ class FakeReposBase(object):
self.git_dirty = False
return True
def _commit_svn(self, tree):
self._genTree(self.svn_checkout, tree)
commit_svn(self.svn_checkout, self.USERS[0][0], self.USERS[0][1])
if self.svn_revs and self.svn_revs[-1]:
new_tree = self.svn_revs[-1].copy()
new_tree.update(tree)
else:
new_tree = tree.copy()
self.svn_revs.append(new_tree)
def _set_svn_commit_date(self, revision, date):
subprocess2.check_output(
['svn', 'propset', 'svn:date', '--revprop', '-r', revision, date,
self.svn_base,
'--username', self.USERS[0][0],
'--password', self.USERS[0][1],
'--non-interactive'])
def _commit_git(self, repo, tree):
repo_root = join(self.git_root, repo)
self._genTree(repo_root, tree)
......@@ -430,133 +292,14 @@ class FakeReposBase(object):
finally:
sock.close()
def populateSvn(self):
raise NotImplementedError()
def populateGit(self):
raise NotImplementedError()
class FakeRepos(FakeReposBase):
"""Implements populateSvn() and populateGit()."""
"""Implements populateGit()."""
NB_GIT_REPOS = 5
def populateSvn(self):
"""Creates a few revisions of changes including DEPS files."""
# Repos
subprocess2.check_call(
['svn', 'checkout', self.svn_base, self.svn_checkout,
'-q', '--non-interactive', '--no-auth-cache',
'--username', self.USERS[0][0], '--password', self.USERS[0][1]])
assert os.path.isdir(join(self.svn_checkout, '.svn'))
def file_system(rev, DEPS, DEPS_ALT=None):
fs = {
'origin': 'svn@%(rev)d\n',
'trunk/origin': 'svn/trunk@%(rev)d\n',
'trunk/src/origin': 'svn/trunk/src@%(rev)d\n',
'trunk/src/third_party/origin': 'svn/trunk/src/third_party@%(rev)d\n',
'trunk/other/origin': 'src/trunk/other@%(rev)d\n',
'trunk/third_party/origin': 'svn/trunk/third_party@%(rev)d\n',
'trunk/third_party/foo/origin': 'svn/trunk/third_party/foo@%(rev)d\n',
'trunk/third_party/prout/origin': 'svn/trunk/third_party/foo@%(rev)d\n',
}
for k in fs.iterkeys():
fs[k] = fs[k] % { 'rev': rev }
fs['trunk/src/DEPS'] = DEPS
if DEPS_ALT:
fs['trunk/src/DEPS.alt'] = DEPS_ALT
return fs
# Testing:
# - dependency disapear
# - dependency renamed
# - versioned and unversioned reference
# - relative and full reference
# - deps_os
# - var
# - hooks
# - From
# - File
# TODO(maruel):
# - $matching_files
# - use_relative_paths
DEPS = """
vars = {
'DummyVariable': 'third_party',
}
deps = {
'src/other': '%(svn_base)strunk/other@1',
'src/third_party/fpp': '/trunk/' + Var('DummyVariable') + '/foo',
}
deps_os = {
'mac': {
'src/third_party/prout': '/trunk/third_party/prout',
},
}""" % { 'svn_base': self.svn_base }
DEPS_ALT = """
deps = {
'src/other2': '%(svn_base)strunk/other@2'
}
""" % { 'svn_base': self.svn_base }
fs = file_system(1, DEPS, DEPS_ALT)
self._commit_svn(fs)
fs = file_system(2, """
deps = {
'src/other': '%(svn_base)strunk/other',
# Load another DEPS and load a dependency from it. That's an example of
# WebKit's chromium checkout flow. Verify it works out of order.
'src/third_party/foo': From('src/file/other', 'foo/bar'),
'src/file/other': File('%(svn_base)strunk/other/DEPS'),
}
# I think this is wrong to have the hooks run from the base of the gclient
# checkout. It's maybe a bit too late to change that behavior.
hooks = [
{
'pattern': '.',
'action': ['python', '-c',
'open(\\'src/svn_hooked1\\', \\'w\\').write(\\'svn_hooked1\\')'],
},
{
# Should not be run.
'pattern': 'nonexistent',
'action': ['python', '-c',
'open(\\'src/svn_hooked2\\', \\'w\\').write(\\'svn_hooked2\\')'],
},
]
""" % { 'svn_base': self.svn_base })
fs['trunk/other/DEPS'] = """
deps = {
'foo/bar': '/trunk/third_party/foo@1',
# Only the requested deps should be processed.
'invalid': '/does_not_exist',
}
"""
# WebKit abuses this.
fs['trunk/webkit/.gclient'] = """
solutions = [
{
'name': './',
'url': None,
},
]
"""
fs['trunk/webkit/DEPS'] = """
deps = {
'foo/bar': '%(svn_base)strunk/third_party/foo@1'
}
hooks = [
{
'pattern': '.*',
'action': ['echo', 'foo'],
},
]
""" % { 'svn_base': self.svn_base }
self._commit_svn(fs)
def populateGit(self):
# Testing:
# - dependency disappear
......@@ -707,62 +450,11 @@ pre_deps_hooks = [
})
class FakeRepoTransitive(FakeReposBase):
"""Implements populateSvn()"""
def populateSvn(self):
"""Creates a few revisions of changes including a DEPS file."""
# Repos
subprocess2.check_call(
['svn', 'checkout', self.svn_base, self.svn_checkout,
'-q', '--non-interactive', '--no-auth-cache',
'--username', self.USERS[0][0], '--password', self.USERS[0][1]])
assert os.path.isdir(join(self.svn_checkout, '.svn'))
def file_system(rev):
DEPS = """deps = {
'src/different_repo': '%(svn_base)strunk/third_party',
'src/different_repo_fixed': '%(svn_base)strunk/third_party@1',
'src/same_repo': '/trunk/third_party',
'src/same_repo_fixed': '/trunk/third_party@1',
}""" % { 'svn_base': self.svn_base }
return {
'trunk/src/DEPS': DEPS,
'trunk/src/origin': 'svn/trunk/src@%(rev)d' % { 'rev': rev },
'trunk/third_party/origin':
'svn/trunk/third_party@%(rev)d' % { 'rev': rev },
}
# We make three commits. We use always the same DEPS contents but
# - 'trunk/src/origin' contains 'svn/trunk/src/origin@rX'
# - 'trunk/third_party/origin' contains 'svn/trunk/third_party/origin@rX'
# where 'X' is the revision number.
# So the 'origin' files will change in every commit.
self._commit_svn(file_system(1))
self._commit_svn(file_system(2))
self._commit_svn(file_system(3))
# We rewrite the timestamps so we can test that '--transitive' will take the
# parent timestamp on different repositories and the parent revision
# otherwise.
self._set_svn_commit_date('1', '2011-10-01T03:00:00.000000Z')
self._set_svn_commit_date('2', '2011-10-09T03:00:00.000000Z')
self._set_svn_commit_date('3', '2011-10-02T03:00:00.000000Z')
def populateGit(self):
pass
class FakeRepoSkiaDEPS(FakeReposBase):
"""Simulates the Skia DEPS transition in Chrome."""
NB_GIT_REPOS = 5
DEPS_svn_pre = """deps = {
'src/third_party/skia/gyp': '%(svn_base)sskia/gyp',
'src/third_party/skia/include': '%(svn_base)sskia/include',
'src/third_party/skia/src': '%(svn_base)sskia/src',
}"""
DEPS_git_pre = """deps = {
'src/third_party/skia/gyp': '%(git_base)srepo_3',
'src/third_party/skia/include': '%(git_base)srepo_4',
......@@ -773,32 +465,6 @@ class FakeRepoSkiaDEPS(FakeReposBase):
'src/third_party/skia': '%(git_base)srepo_1',
}"""
def populateSvn(self):
"""Create revisions which simulate the Skia DEPS transition in Chrome."""
subprocess2.check_call(
['svn', 'checkout', self.svn_base, self.svn_checkout,
'-q', '--non-interactive', '--no-auth-cache',
'--username', self.USERS[0][0], '--password', self.USERS[0][1]])
assert os.path.isdir(join(self.svn_checkout, '.svn'))
# Skia repo.
self._commit_svn({
'skia/skia_base_file': 'root-level file.',
'skia/gyp/gyp_file': 'file in the gyp directory',
'skia/include/include_file': 'file in the include directory',
'skia/src/src_file': 'file in the src directory',
})
# Chrome repo.
self._commit_svn({
'trunk/src/DEPS': self.DEPS_svn_pre % {'svn_base': self.svn_base},
'trunk/src/myfile': 'svn/trunk/src@1'
})
self._commit_svn({
'trunk/src/DEPS': self.DEPS_post % {'git_base': self.git_base},
'trunk/src/myfile': 'svn/trunk/src@2'
})
def populateGit(self):
# Skia repo.
self._commit_git('repo_1', {
......@@ -820,11 +486,11 @@ class FakeRepoSkiaDEPS(FakeReposBase):
# Chrome repo.
self._commit_git('repo_2', {
'DEPS': self.DEPS_git_pre % {'git_base': self.git_base},
'myfile': 'svn/trunk/src@1'
'myfile': 'src/trunk/src@1'
})
self._commit_git('repo_2', {
'DEPS': self.DEPS_post % {'git_base': self.git_base},
'myfile': 'svn/trunk/src@2'
'myfile': 'src/trunk/src@2'
})
......@@ -879,11 +545,6 @@ class FakeReposTestBase(trial_dir.TestCase):
# Do not define tearDown(), since super's version does the right thing and
# self.FAKE_REPOS is kept across tests.
@property
def svn_base(self):
"""Shortcut."""
return self.FAKE_REPOS.svn_base
@property
def git_base(self):
"""Shortcut."""
......@@ -919,22 +580,6 @@ class FakeReposTestBase(trial_dir.TestCase):
logging.debug('Diff\n%s' % pprint.pformat(diff))
self.assertEquals(diff, {})
def mangle_svn_tree(self, *args):
"""Creates a 'virtual directory snapshot' to compare with the actual result
on disk."""
result = {}
for item, new_root in args:
old_root, rev = item.split('@', 1)
tree = self.FAKE_REPOS.svn_revs[int(rev)]
for k, v in tree.iteritems():
if not k.startswith(old_root):
continue
item = k[len(old_root) + 1:]
if item.startswith('.'):
continue
result[join(new_root, item).replace(os.sep, '/')] = v
return result
def mangle_git_tree(self, *args):
"""Creates a 'virtual directory snapshot' to compare with the actual result
on disk."""
......@@ -959,7 +604,6 @@ def main(argv):
fake = FakeRepos()
print 'Using %s' % fake.root_dir
try:
fake.set_up_svn()
fake.set_up_git()
print('Fake setup, press enter to quit or Ctrl-C to keep the checkouts.')
sys.stdin.readline()
......
......@@ -81,11 +81,6 @@ class LocalRietveld(object):
raise Failure(
'Install google_appengine sdk in %s or higher up' % self.base_dir)
if os.path.isdir(os.path.join(self.rietveld, '.svn')):
# Left over from subversion. Delete it.
print('Deleting deprecated subversion rietveld files...')
shutil.rmtree(self.rietveld)
if os.path.isdir(os.path.join(self.rietveld, '.hg')):
# Left over from mercurial. Delete it.
print('Deleting deprecated mercurial rietveld files...')
......
......@@ -55,11 +55,6 @@ class TestCaseUtils(object):
return (self._RANDOM_CHOICE((self._OS_SEP, '')) +
self._DirElts(max_elt_count, max_elt_length))
def SvnUrl(self, max_elt_count=4, max_elt_length=8):
return ('svn://random_host:port/a' +
self._DirElts(max_elt_count, max_elt_length
).replace(self._OS_SEP, '/'))
def RootDir(self, max_elt_count=4, max_elt_length=8):
return self._OS_SEP + self._DirElts(max_elt_count, max_elt_length)
......
......@@ -34,16 +34,6 @@ BAD_PATCH = ''.join(
class FakeRepos(fake_repos.FakeReposBase):
TEST_GIT_REPO = 'repo_1'
def populateSvn(self):
"""Creates a few revisions of changes files."""
subprocess2.check_call(
['svn', 'checkout', self.svn_base, self.svn_checkout, '-q',
'--non-interactive', '--no-auth-cache',
'--username', self.USERS[0][0], '--password', self.USERS[0][1]])
assert os.path.isdir(os.path.join(self.svn_checkout, '.svn'))
self._commit_svn(self._svn_tree_1())
self._commit_svn(self._svn_tree_2())
def populateGit(self):
"""Creates a few revisions of changes files."""
self._commit_git(self.TEST_GIT_REPO, self._git_tree())
......@@ -96,52 +86,6 @@ class FakeRepos(fake_repos.FakeReposBase):
'#endif\n')
return fs
@staticmethod
def _svn_tree_1():
fs = {}
fs['trunk/origin'] = 'svn@1'
fs['trunk/codereview.settings'] = (
'# Test data\n'
'bar: pouet\n')
fs['trunk/chrome/file.cc'] = (
'a\n'
'bb\n'
'ccc\n'
'dd\n'
'e\n'
'ff\n'
'ggg\n'
'hh\n'
'i\n'
'jj\n'
'kkk\n'
'll\n'
'm\n'
'nn\n'
'ooo\n'
'pp\n'
'q\n')
return fs
@classmethod
def _svn_tree_2(cls):
fs = cls._svn_tree_1()
fs['trunk/origin'] = 'svn@2\n'
fs['trunk/extra'] = 'dummy\n'
fs['trunk/bin_file'] = '\x00'
fs['trunk/chromeos/views/DOMui_menu_widget.h'] = (
'// Copyright (c) 2010\n'
'// Use of this source code\n'
'// found in the LICENSE file.\n'
'\n'
'#ifndef DOM\n'
'#define DOM\n'
'#pragma once\n'
'\n'
'#include <string>\n'
'#endif\n')
return fs
# pylint: disable=R0201
class BaseTest(fake_repos.FakeReposTestBase):
......@@ -150,9 +94,6 @@ class BaseTest(fake_repos.FakeReposTestBase):
is_read_only = False
def setUp(self):
# Need to enforce subversion_config first.
checkout.SvnMixIn.svn_config_dir = os.path.join(
ROOT_DIR, 'subversion_config')
super(BaseTest, self).setUp()
self._old_call = subprocess2.call
def redirect_call(args, **kwargs):
......@@ -240,107 +181,6 @@ class BaseTest(fake_repos.FakeReposTestBase):
self.assertTree(tree, root)
class SvnBaseTest(BaseTest):
def setUp(self):
super(SvnBaseTest, self).setUp()
self.enabled = self.FAKE_REPOS.set_up_svn()
self.assertTrue(self.enabled)
self.svn_trunk = 'trunk'
self.svn_url = self.svn_base + self.svn_trunk
self.previous_log = self._log()
def _log(self):
# Don't use the local checkout in case of caching incorrency.
out = subprocess2.check_output(
['svn', 'log', self.svn_url,
'--non-interactive', '--no-auth-cache',
'--username', self.usr, '--password', self.pwd,
'--with-all-revprops', '--xml',
'--limit', '1'])
logentry = ElementTree.XML(out).find('logentry')
if logentry == None:
return {'revision': 0}
data = {
'revision': int(logentry.attrib['revision']),
}
def set_item(name):
item = logentry.find(name)
if item != None:
data[name] = item.text
set_item('author')
set_item('msg')
revprops = logentry.find('revprops')
if revprops != None:
data['revprops'] = []
for prop in revprops.getiterator('property'):
data['revprops'].append((prop.attrib['name'], prop.text))
return data
def _check_base(self, co, root, expected):
read_only = isinstance(co, checkout.ReadOnlyCheckout)
self.assertEquals(not read_only, bool(expected))
self.assertEquals(read_only, self.is_read_only)
if not read_only:
self.FAKE_REPOS.svn_dirty = True
self.assertEquals(root, co.project_path)
svn_rev = co.prepare(None)
self.assertEquals(int, type(svn_rev))
self.assertEquals(self.previous_log['revision'], svn_rev)
self.assertEquals('pouet', co.get_settings('bar'))
self.assertTree(self.get_trunk(False), root)
patches = self.get_patches()
co.apply_patch(patches)
self.assertEquals(
['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'],
patches.filenames)
# Verify that the patch is applied even for read only checkout.
self.assertTree(self.get_trunk(True), root)
fake_author = self.FAKE_REPOS.USERS[1][0]
revision = co.commit(u'msg', fake_author)
# Nothing changed.
self.assertTree(self.get_trunk(True), root)
if read_only:
self.assertEquals('FAKE', revision)
self.assertEquals(self.previous_log['revision'], co.prepare(None))
# Changes should be reverted now.
self.assertTree(self.get_trunk(False), root)
expected = self.previous_log
else:
self.assertEquals(self.previous_log['revision'] + 1, revision)
self.assertEquals(self.previous_log['revision'] + 1, co.prepare(None))
self.assertTree(self.get_trunk(True), root)
expected = expected.copy()
expected['msg'] = 'msg'
expected['revision'] = self.previous_log['revision'] + 1
expected.setdefault('author', fake_author)
actual = self._log()
self.assertEquals(expected, actual)
def _test_prepare(self, co):
self.assertEquals(1, co.prepare(1))
def get_trunk(self, modified):
tree = {}
subroot = 'trunk/'
for k, v in self.FAKE_REPOS.svn_revs[-1].iteritems():
if k.startswith(subroot):
f = k[len(subroot):]
assert f not in tree
tree[f] = v
if modified:
content_lines = tree['chrome/file.cc'].splitlines(True)
tree['chrome/file.cc'] = ''.join(
content_lines[0:5] + ['FOO!\n'] + content_lines[5:])
del tree['extra']
tree['new_dir/subdir/new_file'] = 'A new file\nshould exist.\n'
return tree
class GitBaseTest(BaseTest):
def setUp(self):
super(GitBaseTest, self).setUp()
......@@ -481,255 +321,6 @@ class GitCheckout(GitBaseTest):
self.assertEquals(expected, out)
class SvnCheckout(SvnBaseTest):
def _get_co(self, post_processors):
self.assertNotEqual(False, post_processors)
return checkout.SvnCheckout(
self.root_dir, self.name, self.usr, self.pwd, self.svn_url,
post_processors)
def testAll(self):
expected = {
'author': self.FAKE_REPOS.USERS[0][0],
'revprops': [('realauthor', self.FAKE_REPOS.USERS[1][0])]
}
root = os.path.join(self.root_dir, self.name)
self._check_base(self._get_co(None), root, expected)
def testException(self):
self._check_exception(
self._get_co(None),
'While running patch -p1 --forward --force --no-backup-if-mismatch;\n'
' patching file chrome/file.cc\n'
' Hunk #1 FAILED at 3.\n'
' 1 out of 1 hunk FAILED -- saving rejects to file '
'chrome/file.cc.rej\n')
def testSvnProps(self):
co = self._get_co(None)
co.prepare(None)
try:
# svn:ignore can only be applied to directories.
svn_props = [('svn:ignore', 'foo')]
co.apply_patch(
[patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, svn_props)])
self.fail()
except checkout.PatchApplicationFailed, e:
self.assertEquals(e.filename, 'chrome/file.cc')
# The last line of the output depends on the svn version so we can't
# check it precisely
self.assertRegexpMatches(
e.status,
'While running svn propset svn:ignore foo chrome/file.cc '
'--non-interactive;\n'
' patching file chrome/file.cc\n'
' svn:.*')
co.prepare(None)
svn_props = [('svn:eol-style', 'LF'), ('foo', 'bar')]
co.apply_patch(
[patch.FilePatchDiff('chrome/file.cc', RAW.PATCH, svn_props)])
filepath = os.path.join(self.root_dir, self.name, 'chrome/file.cc')
# Manually verify the properties.
props = subprocess2.check_output(
['svn', 'proplist', filepath],
cwd=self.root_dir).splitlines()[1:]
props = sorted(p.strip() for p in props)
expected_props = dict(svn_props)
self.assertEquals(sorted(expected_props.iterkeys()), props)
for k, v in expected_props.iteritems():
value = subprocess2.check_output(
['svn', 'propget', '--strict', k, filepath],
cwd=self.root_dir).strip()
self.assertEquals(v, value)
def testWithRevPropsSupport(self):
# Add the hook that will commit in a way that removes the race condition.
hook = os.path.join(self.FAKE_REPOS.svn_repo, 'hooks', 'pre-commit')
shutil.copyfile(os.path.join(ROOT_DIR, 'sample_pre_commit_hook'), hook)
os.chmod(hook, 0755)
expected = {
'revprops': [('commit-bot', 'user1@example.com')],
}
root = os.path.join(self.root_dir, self.name)
self._check_base(self._get_co(None), root, expected)
def testWithRevPropsSupportNotCommitBot(self):
# Add the hook that will commit in a way that removes the race condition.
hook = os.path.join(self.FAKE_REPOS.svn_repo, 'hooks', 'pre-commit')
shutil.copyfile(os.path.join(ROOT_DIR, 'sample_pre_commit_hook'), hook)
os.chmod(hook, 0755)
co = checkout.SvnCheckout(
self.root_dir, self.name,
self.FAKE_REPOS.USERS[1][0], self.FAKE_REPOS.USERS[1][1],
self.svn_url)
root = os.path.join(self.root_dir, self.name)
expected = {
'author': self.FAKE_REPOS.USERS[1][0],
}
self._check_base(co, root, expected)
def testAutoProps(self):
co = self._get_co(None)
co.svn_config = checkout.SvnConfig(
os.path.join(ROOT_DIR, 'subversion_config'))
co.prepare(None)
patches = self.get_patches()
co.apply_patch(patches)
self.assertEquals(
['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'],
patches.filenames)
# *.txt = svn:eol-style=LF in subversion_config/config.
out = subprocess2.check_output(
['svn', 'pget', 'svn:eol-style', 'chrome/file.cc'],
cwd=co.project_path)
self.assertEquals('LF\n', out)
def testProcess(self):
self._test_process(self._get_co)
def testPrepare(self):
self._test_prepare(self._get_co(None))
def testMove(self):
co = self._get_co(None)
self._check_move(co)
out = subprocess2.check_output(
['svn', 'status'], cwd=co.project_path)
out = sorted(out.splitlines())
expected = sorted(
[
'A + chromeos/views/webui_menu_widget.h',
'D chromeos/views/DOMui_menu_widget.h',
])
self.assertEquals(expected, out)
# Make sure ancestry is what is expected;
env = os.environ.copy()
env['LANGUAGE'] = 'en_US.UTF-8'
out = subprocess2.check_output(
['svn', 'info', 'chromeos/views/webui_menu_widget.h'],
cwd=co.project_path,
env=env)
values = dict(l.split(': ', 1) for l in out.splitlines() if l)
expected = {
# checksum seems to vary with svn version so we can't check it
#'Checksum': '65837bb3da662c8fa88a4a50940ea7c6',
'Copied From Rev': '2',
'Copied From URL':
'%strunk/chromeos/views/DOMui_menu_widget.h' % self.svn_base,
'Name': 'webui_menu_widget.h',
'Node Kind': 'file',
'Path': 'chromeos/views/webui_menu_widget.h',
'Repository Root': '%s' % self.svn_base.rstrip('/'),
'Revision': '2',
'Schedule': 'add',
'URL': '%strunk/chromeos/views/webui_menu_widget.h' % self.svn_base,
}
for key in expected:
self.assertIn(key, values)
self.assertEquals(expected[key], values[key])
class RawCheckout(SvnBaseTest):
def setUp(self):
super(RawCheckout, self).setUp()
# Use a svn checkout as the base.
self.base_co = checkout.SvnCheckout(
self.root_dir, self.name, None, None, self.svn_url)
self.base_co.prepare(None)
def _get_co(self, post_processors):
self.assertNotEqual(False, post_processors)
return checkout.RawCheckout(self.root_dir, self.name, post_processors)
def testAll(self):
# Can't use self._check_base() since it's too different.
root = os.path.join(self.root_dir, self.name)
co = self._get_co(None)
# A copy of BaseTest._check_base()
self.assertEquals(root, co.project_path)
self.assertEquals(None, co.prepare(None))
self.assertEquals('pouet', co.get_settings('bar'))
self.assertTree(self.get_trunk(False), root)
patches = self.get_patches()
co.apply_patch(patches)
self.assertEquals(
['bin_file', 'chrome/file.cc', 'new_dir/subdir/new_file', 'extra'],
patches.filenames)
# Verify that the patch is applied even for read only checkout.
self.assertTree(self.get_trunk(True), root)
try:
co.commit(u'msg', self.FAKE_REPOS.USERS[1][0])
self.fail()
except NotImplementedError:
pass
self.assertTree(self.get_trunk(True), root)
# Verify that prepare() is a no-op.
self.assertEquals(None, co.prepare(None))
self.assertTree(self.get_trunk(True), root)
def testException(self):
self._check_exception(
self._get_co(None),
'While running patch -u --binary -p1;\n'
' patching file chrome/file.cc\n'
' Hunk #1 FAILED at 3.\n'
' 1 out of 1 hunk FAILED -- saving rejects to file '
'chrome/file.cc.rej\n')
def testProcess(self):
self._test_process(self._get_co)
def testPrepare(self):
# RawCheckout doesn't support prepare() but emulate it.
co = self._get_co(None)
revs = [1]
def prepare(asked):
self.assertEquals(1, asked)
return revs.pop(0)
co.prepare = prepare
self._test_prepare(co)
self.assertEquals([], revs)
def testMove(self):
self._check_move(self._get_co(None))
class ReadOnlyCheckout(SvnBaseTest):
# Use SvnCheckout as the backed since it support read-only checkouts too.
is_read_only = True
def _get_co(self, post_processors):
self.assertNotEqual(False, post_processors)
return checkout.ReadOnlyCheckout(
checkout.SvnCheckout(
self.root_dir, self.name, None, None, self.svn_url, None),
post_processors)
def testAll(self):
root = os.path.join(self.root_dir, self.name)
self._check_base(self._get_co(None), root, None)
def testException(self):
self._check_exception(
self._get_co(None),
'While running patch -p1 --forward --force --no-backup-if-mismatch;\n'
' patching file chrome/file.cc\n'
' Hunk #1 FAILED at 3.\n'
' 1 out of 1 hunk FAILED -- saving rejects to file '
'chrome/file.cc.rej\n')
def testProcess(self):
self._test_process(self._get_co)
def testPrepare(self):
self._test_prepare(self._get_co(None))
def testMove(self):
self._check_move(self._get_co(None))
if __name__ == '__main__':
if '-v' in sys.argv:
DEBUGGING = True
......
#!/usr/bin/env python
# Copyright (c) 2012 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.
"""Unit tests for gcl.py."""
# pylint: disable=E1103,E1101,E1120
import os
import sys
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from testing_support.super_mox import mox, SuperMoxTestBase
import gcl
import presubmit_support
class GclTestsBase(SuperMoxTestBase):
"""Setups and tear downs the mocks but doesn't test anything as-is."""
def setUp(self):
SuperMoxTestBase.setUp(self)
self.fake_root_dir = self.RootDir()
self.mox.StubOutWithMock(gcl, 'RunShell')
self.mox.StubOutWithMock(gcl.SVN, '_CaptureInfo')
self.mox.StubOutWithMock(gcl.SVN, 'GetCheckoutRoot')
self.mox.StubOutWithMock(gcl, 'tempfile')
self.mox.StubOutWithMock(gcl.upload, 'RealMain')
self.mox.StubOutWithMock(gcl.gclient_utils, 'FileRead')
self.mox.StubOutWithMock(gcl.gclient_utils, 'FileWrite')
gcl.REPOSITORY_ROOT = None
self.old_review_settings = gcl.CODEREVIEW_SETTINGS
self.assertEquals(gcl.CODEREVIEW_SETTINGS, {})
def tearDown(self):
gcl.CODEREVIEW_SETTINGS = self.old_review_settings
def fakeChange(self, files=None): # pylint: disable=R0201
if files == None:
files = [('A', 'aa'), ('M', 'bb')]
change_info = self.mox.CreateMock(gcl.ChangeInfo)
change_info.name = 'naame'
change_info.issue = 1
change_info.patchset = 0
change_info.description = 'deescription'
change_info.files = files
change_info.GetFiles = lambda : change_info.files
change_info.GetIssueDescription = lambda : change_info.description
change_info.GetFileNames = lambda : [f[1] for f in change_info.files]
change_info.GetLocalRoot = lambda : 'proout'
change_info.patch = None
change_info.rietveld = 'https://my_server'
change_info._closed = False
change_info._deleted = False
change_info._comments_added = []
class RpcServer(object):
# pylint: disable=R0201,W0613
def get_issue_properties(self, issue, messages):
return { 'patchsets': [1337] }
change_info.RpcServer = RpcServer
def AddComment(comment):
# pylint: disable=W0212
change_info._comments_added.append(comment)
change_info.AddComment = AddComment
def Delete():
change_info._deleted = True
change_info.Delete = Delete
def CloseIssue():
change_info._closed = True
change_info.CloseIssue = CloseIssue
return change_info
class GclUnittest(GclTestsBase):
"""General gcl.py tests."""
def tearDown(self):
gcl.CODEREVIEW_SETTINGS = {}
def testMembersChanged(self):
self.mox.ReplayAll()
members = [
'CODEREVIEW_SETTINGS', 'CODEREVIEW_SETTINGS_FILE',
'CODEREVIEW_SETTINGS_FILE_NOT_FOUND',
'CMDchange', 'CMDchanges', 'CMDcommit', 'CMDdelete', 'CMDdeleteempties',
'CMDdescription', 'CMDdiff', 'CMDhelp', 'CMDlint', 'CMDnothave',
'CMDopened', 'CMDpassthru', 'CMDpresubmit', 'CMDrename', 'CMDsettings',
'CMDstatus', 'CMDtry', 'CMDupload',
'ChangeInfo', 'Command', 'DEFAULT_LINT_IGNORE_REGEX',
'DEFAULT_LINT_REGEX', 'CheckHomeForFile', 'DoPresubmitChecks',
'ErrorExit', 'FILES_CACHE', 'FilterFlag', 'GenUsage',
'GenerateChangeName', 'GenerateDiff', 'GetCLs', 'GetCacheDir',
'GetCachedFile', 'GetChangelistInfoFile', 'GetChangesDir',
'GetCodeReviewSetting', 'GetFilesNotInCL', 'GetInfoDir',
'GetModifiedFiles', 'GetRepositoryRoot', 'GetTreeStatus', 'ListFiles',
'LoadChangelistInfoForMultiple', 'MISSING_TEST_MSG',
'OptionallyDoPresubmitChecks', 'REPOSITORY_ROOT',
'RunShell', 'RunShellWithReturnCode', 'SVN',
'TryChange', 'UnknownFiles', 'Warn',
'attrs', 'auth', 'breakpad', 'defer_attributes', 'fix_encoding',
'gclient_utils', 'git_cl', 'json', 'main', 'need_change',
'need_change_and_args', 'no_args', 'optparse', 'os',
'presubmit_support', 'random', 're', 'rietveld',
'ssl', 'string', 'subprocess2', 'sys', 'tempfile', 'time',
'upload', 'urllib2',
]
# If this test fails, you should add the relevant test.
self.compareMembers(gcl, members)
def testIsSVNMoved(self):
# TODO(maruel): TEST ME
pass
def testGetSVNFileProperty(self):
# TODO(maruel): TEST ME
pass
def testUnknownFiles(self):
# TODO(maruel): TEST ME
pass
def testCheckHomeForFile(self):
# TODO(maruel): TEST ME
pass
def testDefaultSettings(self):
self.assertEquals({}, gcl.CODEREVIEW_SETTINGS)
def testGetCodeReviewSettingOk(self):
self.mox.StubOutWithMock(gcl, 'GetCachedFile')
gcl.GetCachedFile(gcl.CODEREVIEW_SETTINGS_FILE).AndReturn(
'foo:bar\n'
'# comment\n'
' c : d \n\r'
'e: f')
self.mox.ReplayAll()
self.assertEquals('bar', gcl.GetCodeReviewSetting('foo'))
self.assertEquals('d', gcl.GetCodeReviewSetting('c'))
self.assertEquals('f', gcl.GetCodeReviewSetting('e'))
self.assertEquals('', gcl.GetCodeReviewSetting('other'))
self.assertEquals(
{'foo': 'bar', 'c': 'd', 'e': 'f', '__just_initialized': None},
gcl.CODEREVIEW_SETTINGS)
def testGetCodeReviewSettingFail(self):
self.mox.StubOutWithMock(gcl, 'GetCachedFile')
gcl.GetCachedFile(gcl.CODEREVIEW_SETTINGS_FILE).AndReturn(
'aaa\n'
' c : d \n\r'
'e: f')
self.mox.ReplayAll()
try:
gcl.GetCodeReviewSetting('c')
self.fail()
except gcl.gclient_utils.Error:
pass
self.assertEquals({}, gcl.CODEREVIEW_SETTINGS)
def testGetRepositoryRootNone(self):
gcl.os.getcwd().AndReturn(self.fake_root_dir)
gcl.SVN.GetCheckoutRoot(self.fake_root_dir).AndReturn(None)
self.mox.ReplayAll()
self.assertRaises(gcl.gclient_utils.Error, gcl.GetRepositoryRoot)
def testGetRepositoryRootGood(self):
root_path = gcl.os.path.join('bleh', 'prout', 'pouet')
gcl.os.getcwd().AndReturn(root_path)
gcl.SVN.GetCheckoutRoot(root_path).AndReturn(root_path + '.~')
self.mox.ReplayAll()
self.assertEquals(gcl.GetRepositoryRoot(), root_path + '.~')
def testHelp(self):
gcl.sys.stdout.write = lambda x: None
self.mox.ReplayAll()
gcl.CMDhelp([])
class ChangeInfoUnittest(GclTestsBase):
def setUp(self):
GclTestsBase.setUp(self)
self.mox.StubOutWithMock(gcl, 'GetChangelistInfoFile')
self.mox.StubOutWithMock(gcl, 'GetRepositoryRoot')
def testChangeInfoMembers(self):
self.mox.ReplayAll()
members = [
'AddComment', 'CloseIssue', 'Delete', 'Exists', 'GetFiles',
'GetApprovingReviewers', 'GetFileNames', 'GetIssueDescription',
'GetLocalRoot', 'Load',
'MissingTests', 'NeedsUpload', 'PrimeLint', 'RpcServer', 'Save',
'SendToRietveld',
'SEPARATOR',
'UpdateDescriptionFromIssue', 'UpdateRietveldDescription',
'append_footer',
'description', 'force_description', 'get_reviewers', 'issue', 'name',
'needs_upload', 'patch', 'patchset', 'rietveld', 'update_reviewers',
]
# If this test fails, you should add the relevant test.
self.compareMembers(
gcl.ChangeInfo('', 0, 0, '', None, self.fake_root_dir, 'foo', False),
members)
def testChangeInfoBase(self):
files = [('M', 'foo'), ('A', 'bar')]
self.mox.ReplayAll()
o = gcl.ChangeInfo(
'name2',
'42',
'53',
'description2',
files,
self.fake_root_dir,
'foo',
False)
self.assertEquals(o.name, 'name2')
self.assertEquals(o.issue, 42)
self.assertEquals(o.patchset, 53)
self.assertEquals(o.description, 'description2')
self.assertEquals(o.patch, None)
self.assertEquals(o.GetFileNames(), ['foo', 'bar'])
self.assertEquals(o.GetFiles(), files)
self.assertEquals(o.GetLocalRoot(), self.fake_root_dir)
def testLoadWithIssue(self):
self.mox.StubOutWithMock(gcl, 'GetCodeReviewSetting')
description = ["This is some description.", "force an extra separator."]
gcl.GetChangelistInfoFile('bleh').AndReturn('bleeeh')
gcl.os.path.exists('bleeeh').AndReturn(True)
gcl.gclient_utils.FileRead('bleeeh').AndReturn(
gcl.ChangeInfo.SEPARATOR.join(["42, 53", "G b.cc"] + description))
gcl.GetCodeReviewSetting('CODE_REVIEW_SERVER').AndReturn('foo')
# Does an upgrade.
gcl.GetChangelistInfoFile('bleh').AndReturn('bleeeh')
gcl.gclient_utils.FileWrite('bleeeh', mox.IgnoreArg())
self.mox.ReplayAll()
change_info = gcl.ChangeInfo.Load('bleh', self.fake_root_dir, True, False)
self.assertEquals(change_info.name, 'bleh')
self.assertEquals(change_info.issue, 42)
self.assertEquals(change_info.patchset, 53)
self.assertEquals(change_info.description,
gcl.ChangeInfo.SEPARATOR.join(description))
self.assertEquals(change_info.GetFiles(), [('G ', 'b.cc')])
def testLoadEmpty(self):
self.mox.StubOutWithMock(gcl, 'GetCodeReviewSetting')
gcl.GetChangelistInfoFile('bleh').AndReturn('bleeeh')
gcl.os.path.exists('bleeeh').AndReturn(True)
gcl.gclient_utils.FileRead('bleeeh').AndReturn(
gcl.ChangeInfo.SEPARATOR.join(["", "", ""]))
gcl.GetCodeReviewSetting('CODE_REVIEW_SERVER').AndReturn('foo')
# Does an upgrade.
gcl.GetChangelistInfoFile('bleh').AndReturn('bleeeh')
gcl.gclient_utils.FileWrite('bleeeh', mox.IgnoreArg())
self.mox.ReplayAll()
change_info = gcl.ChangeInfo.Load('bleh', self.fake_root_dir, True, False)
self.assertEquals(change_info.name, 'bleh')
self.assertEquals(change_info.issue, 0)
self.assertEquals(change_info.patchset, 0)
self.assertEquals(change_info.description, "")
self.assertEquals(change_info.GetFiles(), [])
def testSaveEmpty(self):
gcl.GetChangelistInfoFile('').AndReturn('foo')
values = {
'description': '', 'patchset': 2, 'issue': 1,
'files': [], 'needs_upload': False, 'rietveld': 'https://foo'}
gcl.gclient_utils.FileWrite(
'foo', gcl.json.dumps(values, sort_keys=True, indent=2))
self.mox.ReplayAll()
change_info = gcl.ChangeInfo(
'', 1, 2, '', None, self.fake_root_dir, 'foo', False)
change_info.Save()
def testSaveDirty(self):
gcl.GetChangelistInfoFile('n').AndReturn('foo')
values = {
'description': 'des', 'patchset': 0, 'issue': 0,
'files': [], 'needs_upload': True, 'rietveld': 'https://foo'}
gcl.gclient_utils.FileWrite(
'foo', gcl.json.dumps(values, sort_keys=True, indent=2))
self.mox.ReplayAll()
change_info = gcl.ChangeInfo('n', 0, 0, 'des', None, self.fake_root_dir,
'foo', needs_upload=True)
change_info.Save()
class CMDuploadUnittest(GclTestsBase):
def setUp(self):
GclTestsBase.setUp(self)
self.mox.StubOutWithMock(gcl, 'CheckHomeForFile')
self.mox.StubOutWithMock(gcl, 'DoPresubmitChecks')
self.mox.StubOutWithMock(gcl, 'GenerateDiff')
self.mox.StubOutWithMock(gcl, 'GetCodeReviewSetting')
self.mox.StubOutWithMock(gcl, 'GetRepositoryRoot')
self.mox.StubOutWithMock(gcl.ChangeInfo, 'SendToRietveld')
self.mox.StubOutWithMock(gcl, 'TryChange')
self.mox.StubOutWithMock(gcl.ChangeInfo, 'Load')
def testNew(self):
change_info = self.mox.CreateMock(gcl.ChangeInfo)
change_info.name = 'naame'
change_info.issue = 1
change_info.patchset = 0
change_info.description = 'deescription\n\nR=foo@bar.com',
change_info.files = [('A', 'aa'), ('M', 'bb')]
change_info.patch = None
change_info.rietveld = 'https://my_server'
files = [item[1] for item in change_info.files]
output = presubmit_support.PresubmitOutput()
gcl.DoPresubmitChecks(change_info, False, True).AndReturn(output)
#gcl.GetCodeReviewSetting('CODE_REVIEW_SERVER').AndReturn('my_server')
gcl.os.getcwd().AndReturn('somewhere')
change_info.GetFiles().AndReturn(change_info.files)
gcl.os.chdir('proout')
change_info.get_reviewers().AndReturn('foo@bar.com')
change_info.GetFileNames().AndReturn(files)
gcl.GenerateDiff(files)
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server',
'-r', 'georges@example.com',
'--issue=1', '--title= '],
change_info.patch).AndReturn(("1",
"2"))
change_info.GetLocalRoot().AndReturn('proout')
change_info.Save()
change_info.PrimeLint()
gcl.os.chdir('somewhere')
gcl.sys.stdout.write("*** Upload does not submit a try; use gcl try to"
" submit a try. ***")
gcl.sys.stdout.write("\n")
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(change_info)
self.mox.ReplayAll()
gcl.CMDupload(['naame', '-r', 'georges@example.com'])
self.checkstdout('*** Upload does not submit a try; use gcl try to submit '
'a try. ***\n'
'*** Upload does not submit a try; use gcl try to submit a try. ***\n')
def testServerOverride(self):
change_info = gcl.ChangeInfo(
'naame',
0,
0,
'deescription',
[('A', 'aa'), ('M', 'bb')],
self.fake_root_dir,
'my_server',
False)
self.mox.StubOutWithMock(change_info, 'Save')
change_info.Save()
output = presubmit_support.PresubmitOutput()
gcl.DoPresubmitChecks(change_info, False, True).AndReturn(output)
gcl.tempfile.mkstemp(text=True).AndReturn((42, 'descfile'))
gcl.os.write(42, change_info.description)
gcl.os.close(42)
gcl.GetCodeReviewSetting('CC_LIST')
gcl.GetCodeReviewSetting('PRIVATE')
gcl.GetCodeReviewSetting('PROJECT')
gcl.os.getcwd().AndReturn('somewhere')
gcl.os.chdir(change_info.GetLocalRoot())
gcl.GenerateDiff(change_info.GetFileNames())
gcl.upload.RealMain(
[ 'upload.py', '-y', '--server=https://my_server', '--server=a',
'--file=descfile'],
change_info.patch).AndReturn(("1", "2"))
gcl.os.remove('descfile')
change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=60)
gcl.os.chdir('somewhere')
gcl.sys.stdout.write("*** Upload does not submit a try; use gcl try to"
" submit a try. ***")
gcl.sys.stdout.write("\n")
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(change_info)
self.mox.ReplayAll()
gcl.CMDupload(['naame', '--server=a', '--no_watchlists'])
self.checkstdout('*** Upload does not submit a try; use gcl try to submit '
'a try. ***\n'
'*** Upload does not submit a try; use gcl try to submit a try. ***\n')
def testNormal(self):
change_info = gcl.ChangeInfo(
'naame',
0,
0,
'deescription',
[('A', 'aa'), ('M', 'bb')],
self.fake_root_dir,
'my_server',
False)
self.mox.StubOutWithMock(change_info, 'Save')
change_info.Save()
output = presubmit_support.PresubmitOutput()
gcl.DoPresubmitChecks(change_info, False, True).AndReturn(output)
gcl.tempfile.mkstemp(text=True).AndReturn((42, 'descfile'))
gcl.os.write(42, change_info.description)
gcl.os.close(42)
gcl.GetCodeReviewSetting('CC_LIST')
gcl.GetCodeReviewSetting('PRIVATE')
gcl.GetCodeReviewSetting('PROJECT')
gcl.os.getcwd().AndReturn('somewhere')
gcl.os.chdir(change_info.GetLocalRoot())
gcl.GenerateDiff(change_info.GetFileNames())
gcl.upload.RealMain(
['upload.py', '-y', '--server=https://my_server', "--file=descfile" ],
change_info.patch).AndReturn(("1", "2"))
gcl.os.remove('descfile')
change_info.SendToRietveld("/lint/issue%s_%s" % ('1', '2'), timeout=60)
gcl.os.chdir('somewhere')
gcl.sys.stdout.write("*** Upload does not submit a try; use gcl try to"
" submit a try. ***")
gcl.sys.stdout.write("\n")
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(change_info)
self.mox.ReplayAll()
gcl.CMDupload(['naame', '--no_watchlists'])
self.assertEquals(change_info.issue, 1)
self.assertEquals(change_info.patchset, 2)
self.checkstdout('*** Upload does not submit a try; use gcl try to submit '
'a try. ***\n'
'*** Upload does not submit a try; use gcl try to submit a try. ***\n')
def testNoServer(self):
self.mox.StubOutWithMock(gcl.sys, 'stderr')
gcl.sys.stderr.write(
'Don\'t use the -s flag, fix codereview.settings instead')
gcl.sys.stderr.write('\n')
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(1)
self.mox.ReplayAll()
try:
gcl.CMDupload(['naame', '-s', 'foo'])
self.fail()
except SystemExit:
pass
def testReviewersInDescription(self):
change_info = self.mox.CreateMock(gcl.ChangeInfo)
change_info.name = 'naame'
change_info.issue = 1
change_info.patchset = 0
change_info.description = 'deescription\n\nR=georges@example.com',
change_info.files = [('A', 'aa'), ('M', 'bb')]
change_info.patch = None
change_info.rietveld = 'https://my_server'
files = [item[1] for item in change_info.files]
output = presubmit_support.PresubmitOutput()
gcl.DoPresubmitChecks(change_info, False, True).AndReturn(output)
#gcl.GetCodeReviewSetting('CODE_REVIEW_SERVER').AndReturn('my_server')
gcl.os.getcwd().AndReturn('somewhere')
change_info.GetFiles().AndReturn(change_info.files)
change_info.get_reviewers().AndReturn(['georges@example.com'])
change_info.GetFileNames().AndReturn(files)
change_info.GetLocalRoot().AndReturn('proout')
gcl.os.chdir('proout')
gcl.GenerateDiff(files)
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server',
'--reviewers=georges@example.com',
'--issue=1', '--title= '],
change_info.patch).AndReturn(("1", "2"))
change_info.Save()
change_info.PrimeLint()
gcl.os.chdir('somewhere')
gcl.sys.stdout.write("*** Upload does not submit a try; use gcl try to"
" submit a try. ***")
gcl.sys.stdout.write("\n")
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(change_info)
self.mox.ReplayAll()
gcl.CMDupload(['naame'])
self.checkstdout('*** Upload does not submit a try; use gcl try to submit '
'a try. ***\n'
'*** Upload does not submit a try; use gcl try to submit a try. ***\n')
def testSuggestReviewers(self):
change_info = self.fakeChange()
output = presubmit_support.PresubmitOutput()
output.reviewers = ['foo@example.com', 'bar@example.com']
gcl.DoPresubmitChecks(change_info, False, True).AndReturn(output)
#gcl.GetCodeReviewSetting('CODE_REVIEW_SERVER').AndReturn('my_server')
gcl.os.getcwd().AndReturn('somewhere')
gcl.os.chdir('proout')
gcl.GenerateDiff(change_info.GetFileNames())
gcl.upload.RealMain(['upload.py', '-y', '--server=https://my_server',
'--reviewers=foo@example.com,bar@example.com',
'--issue=1', '--title= '],
change_info.patch).AndReturn(("1", "2"))
change_info.get_reviewers().AndReturn(['foo@example.com,bar@example.com'])
change_info.Save()
change_info.PrimeLint()
gcl.os.chdir('somewhere')
gcl.sys.stdout.write("*** Upload does not submit a try; use gcl try to"
" submit a try. ***")
gcl.sys.stdout.write("\n")
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(change_info)
self.mox.ReplayAll()
gcl.CMDupload(['naame'])
self.checkstdout('*** Upload does not submit a try; use gcl try to submit '
'a try. ***\n'
'*** Upload does not submit a try; use gcl try to submit a try. ***\n')
class CMDCommitUnittest(GclTestsBase):
def mockLoad(self, files=None):
self.mox.StubOutWithMock(gcl, 'GetRepositoryRoot')
self.mox.StubOutWithMock(gcl.ChangeInfo, 'Load')
gcl.GetRepositoryRoot().AndReturn(self.fake_root_dir)
change_info = self.fakeChange(files)
gcl.ChangeInfo.Load('naame', self.fake_root_dir, True, True
).AndReturn(change_info)
return change_info
def mockPresubmit(self, change_info, fail):
self.mox.StubOutWithMock(gcl, 'OptionallyDoPresubmitChecks')
output = presubmit_support.PresubmitOutput()
if fail:
output.fail()
gcl.OptionallyDoPresubmitChecks(change_info, True, []).AndReturn(output)
def mockCommit(self, change_info, commit_message, shell_output):
gcl.tempfile.mkstemp(text=True).AndReturn((42, 'commit'))
gcl.os.write(42, commit_message)
gcl.os.close(42)
gcl.tempfile.mkstemp(text=True).AndReturn((43, 'files'))
gcl.os.write(43, '\n'.join(change_info.GetFileNames()))
gcl.os.close(43)
gcl.RunShell(['svn', 'commit', '--file=commit', '--targets=files'],
True).AndReturn(shell_output)
if 'Committed' in shell_output:
self.mox.StubOutWithMock(gcl, 'GetCodeReviewSetting')
gcl.GetCodeReviewSetting('VIEW_VC').AndReturn('http://view/')
gcl.os.remove('commit')
gcl.os.remove('files')
def testPresubmitEmpty(self):
self.mockLoad(files=[])
self.mox.ReplayAll()
retval = gcl.CMDcommit(['naame'])
self.assertEquals(retval, 1)
def testPresubmitFails(self):
change_info = self.mockLoad()
self.mockPresubmit(change_info, fail=True)
self.mox.ReplayAll()
retval = gcl.CMDcommit(['naame'])
self.assertEquals(retval, 1)
def testPresubmitSucceeds(self):
change_info = self.mockLoad()
self.mockPresubmit(change_info, fail=False)
self.mockCommit(
change_info, 'deescription\n\nReview URL: https://my_server/1', '')
change_info.UpdateDescriptionFromIssue()
change_info.GetApprovingReviewers().AndReturn(['a@c'])
change_info.update_reviewers(['a@c'])
self.mox.ReplayAll()
retval = gcl.CMDcommit(['naame'])
self.assertEquals(retval, 0)
self.assertEquals(change_info.description, 'deescription')
# pylint: disable=W0212
self.assertFalse(change_info._deleted)
self.assertFalse(change_info._closed)
def testPresubmitSucceedsWithCommittedMessage(self):
change_info = self.mockLoad()
self.mockPresubmit(change_info, fail=False)
self.mockCommit(
change_info,
'deescription\n\nReview URL: https://my_server/1',
'\nCommitted revision 12345')
change_info.UpdateDescriptionFromIssue()
change_info.GetApprovingReviewers().AndReturn(['a@c'])
change_info.update_reviewers(['a@c'])
change_info.append_footer('Committed: http://view/12345')
self.mox.ReplayAll()
retval = gcl.CMDcommit(['naame'])
self.assertEquals(retval, 0)
# This is because append_footer is mocked.
self.assertEquals(change_info.description, 'deescription')
# pylint: disable=W0212
self.assertTrue(change_info._deleted)
self.assertTrue(change_info._closed)
self.assertEqual(
change_info._comments_added,
["Committed patchset #1 (id:1337) manually as r12345 (presubmit "
"successful)."])
if __name__ == '__main__':
import unittest
unittest.main()
......@@ -115,690 +115,6 @@ class BasicTests(SuperMoxTestBase):
SuperMoxTestBase.tearDown(self)
class SVNWrapperTestCase(BaseTestCase):
class OptionsObject(object):
def __init__(self, verbose=False, revision=None, force=False):
self.verbose = verbose
self.revision = revision
self.manually_grab_svn_rev = True
self.deps_os = None
self.force = force
self.reset = False
self.nohooks = False
# TODO(maruel): Test --jobs > 1.
self.jobs = 1
self.delete_unversioned_trees = False
def checkstdout(self, expected):
value = sys.stdout.getvalue()
sys.stdout.close()
# pylint: disable=E1101
self.assertEquals(expected, strip_timestamps(value))
def Options(self, *args, **kwargs):
return self.OptionsObject(*args, **kwargs)
def setUp(self):
BaseTestCase.setUp(self)
self.url = self.SvnUrl()
def testUnsupportedSCM(self):
args = ['gopher://foo', self.root_dir, self.relpath]
exception_msg = 'No SCM found for url gopher://foo'
self.assertRaisesError(exception_msg, self._scm_wrapper, *args)
def testSVNFullUrlForRelativeUrl(self):
self.url = 'svn://a/b/c/d'
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'svn://a/b/crap')
def testGITFullUrlForRelativeUrl(self):
self.url = 'git://a/b/c/d'
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'git://a/b/c/crap')
def testGITFakeHttpUrl(self):
self.url = 'git+http://foo'
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
self.assertEqual(scm.url, 'http://foo')
def testGITFakeHttpsUrl(self):
self.url = 'git+https://foo'
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
self.assertEqual(scm.url, 'https://foo')
def testRunCommandException(self):
options = self.Options(verbose=False)
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
exception = "Unsupported argument(s): %s" % ','.join(self.args)
self.assertRaisesError(exception, scm.RunCommand,
'update', options, self.args)
def testRunCommandUnknown(self):
# TODO(maruel): if ever used.
pass
def testRevertMissing(self):
options = self.Options(verbose=True)
gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(False)
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
# It'll to a checkout instead.
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
# Checkout.
gclient_scm.os.path.exists(self.base_path).AndReturn(False)
parent = gclient_scm.os.path.dirname(self.base_path)
gclient_scm.os.path.exists(parent).AndReturn(False)
gclient_scm.os.makedirs(parent)
gclient_scm.os.path.exists(parent).AndReturn(True)
files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
cwd=self.root_dir,
file_list=files_list)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.revert(options, self.args, files_list)
self.checkstdout(
('_____ %s is missing, synching instead\n' % self.relpath))
def testRevertNoDotSvn(self):
options = self.Options(verbose=True, force=True)
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(False)
gclient_scm.os.path.isdir(join(self.base_path, '.git')).AndReturn(False)
gclient_scm.os.path.isdir(join(self.base_path, '.hg')).AndReturn(False)
# Checkout.
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(False)
parent = gclient_scm.os.path.dirname(self.base_path)
gclient_scm.os.path.exists(parent).AndReturn(False)
gclient_scm.os.makedirs(parent)
gclient_scm.os.path.exists(parent).AndReturn(True)
files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.6')
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
cwd=self.root_dir,
file_list=files_list)
gclient_scm.gclient_utils.rmtree(self.base_path)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.revert(options, self.args, files_list)
self.checkstdout(
'\n_____ %s is not a valid svn checkout, synching instead\n' %
self.relpath)
def testRevertNone(self):
options = self.Options(verbose=True)
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
gclient_scm.scm.SVN.CaptureStatus(
None, self.base_path, no_ignore=False).AndReturn([])
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['update', '--revision', 'BASE', '--ignore-externals'],
cwd=self.base_path,
file_list=mox.IgnoreArg())
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list = []
scm.revert(options, self.args, file_list)
def testRevertDirectory(self):
options = self.Options(verbose=True)
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
items = [
('~ ', 'a'),
]
gclient_scm.scm.SVN.CaptureStatus(
None, self.base_path, no_ignore=False).AndReturn(items)
file_path = join(self.base_path, 'a')
gclient_scm.os.path.exists(file_path).AndReturn(True)
gclient_scm.os.path.isfile(file_path).AndReturn(False)
gclient_scm.os.path.islink(file_path).AndReturn(False)
gclient_scm.os.path.isdir(file_path).AndReturn(True)
gclient_scm.gclient_utils.rmtree(file_path)
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['update', '--revision', 'BASE', '--ignore-externals'],
cwd=self.base_path,
file_list=mox.IgnoreArg())
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list2 = []
scm.revert(options, self.args, file_list2)
self.checkstdout(('%s\n' % file_path))
def testRevertDot(self):
self.mox.StubOutWithMock(gclient_scm.SVNWrapper, 'update')
options = self.Options(verbose=True)
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
items = [
('~ ', '.'),
]
gclient_scm.scm.SVN.CaptureStatus(
None, self.base_path, no_ignore=False).AndReturn(items)
# gclient_utils.rmtree() doesn't work on path ending with '.', like 'foo/.'.
file_path = self.base_path
gclient_scm.os.path.exists(file_path).AndReturn(True)
gclient_scm.os.path.isfile(file_path).AndReturn(False)
gclient_scm.os.path.islink(file_path).AndReturn(False)
gclient_scm.os.path.isdir(file_path).AndReturn(True)
gclient_scm.gclient_utils.rmtree(file_path)
# pylint: disable=E1120
gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
gclient_scm.SVNWrapper.update(options, [], ['.'])
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list2 = []
scm.revert(options, self.args, file_list2)
self.checkstdout(('%s\n' % os.path.join(file_path, '.')))
def testStatus(self):
options = self.Options(verbose=True)
gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['status'] + self.args + ['--ignore-externals'],
cwd=self.base_path,
file_list=[]).AndReturn(None)
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list = []
self.assertEqual(scm.status(options, self.args, file_list), None)
# TODO(maruel): TEST REVISIONS!!!
# TODO(maruel): TEST RELOCATE!!!
def testUpdateCheckout(self):
options = self.Options(verbose=True)
file_info = gclient_scm.gclient_utils.PrintableObject()
file_info.root = 'blah'
file_info.url = self.url
file_info.uuid = 'ABC'
file_info.revision = 42
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
# Checkout.
gclient_scm.os.path.exists(self.base_path).AndReturn(False)
parent = gclient_scm.os.path.dirname(self.base_path)
gclient_scm.os.path.exists(parent).AndReturn(False)
gclient_scm.os.makedirs(parent)
gclient_scm.os.path.exists(parent).AndReturn(True)
files_list = self.mox.CreateMockAnything()
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
cwd=self.root_dir,
file_list=files_list)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.update(options, (), files_list)
def testUpdateUpdate(self):
options = self.Options(verbose=True)
options.force = True
options.nohooks = False
file_info = {
'Repository Root': 'blah',
'URL': self.url,
'UUID': 'ABC',
'Revision': 42,
}
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
# Checkout or update.
dotted_path = join(self.base_path, '.')
gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
# Verify no locked files.
gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
# Cheat a bit here.
gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
).AndReturn(file_info)
# _AddAdditionalUpdateFlags()
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
additional_args = []
if options.manually_grab_svn_rev:
additional_args = ['--revision', str(file_info['Revision'])]
additional_args.extend(['--force', '--ignore-externals'])
files_list = []
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['update', self.base_path] + additional_args,
cwd=self.root_dir, file_list=files_list)
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.update(options, (), files_list)
def testUpdateReset(self):
options = self.Options(verbose=True)
options.reset = True
file_info = {
'Repository Root': 'blah',
'URL': self.url,
'UUID': 'ABC',
'Revision': 42,
}
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
# Checkout or update.
dotted_path = join(self.base_path, '.')
gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
# Create an untracked file and directory.
gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
).AndReturn([['? ', 'dir'], ['? ', 'file']])
gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
files_list = []
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.update(options, (), files_list)
self.checkstdout('_____ %s at 42\n' % self.relpath)
def testUpdateResetDeleteUnversionedTrees(self):
options = self.Options(verbose=True)
options.reset = True
options.delete_unversioned_trees = True
file_info = {
'Repository Root': 'blah',
'URL': self.url,
'UUID': 'ABC',
'Revision': 42,
}
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
# Checkout or update.
dotted_path = join(self.base_path, '.')
gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
# Create an untracked file and directory.
gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
).AndReturn([['? ', 'dir'], ['? ', 'file']])
gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
).AndReturn(file_info)
# Confirm that the untracked file is removed.
gclient_scm.scm.SVN.CaptureStatus(None, self.base_path
).AndReturn([['? ', 'dir'], ['? ', 'file']])
gclient_scm.os.path.isdir(join(self.base_path, 'dir')).AndReturn(True)
gclient_scm.os.path.isdir(join(self.base_path, 'file')).AndReturn(False)
gclient_scm.os.path.islink(join(self.base_path, 'dir')).AndReturn(False)
gclient_scm.gclient_utils.rmtree(join(self.base_path, 'dir'))
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
files_list = []
scm.update(options, (), files_list)
self.checkstdout(
('_____ %s at 42\n'
'_____ removing unversioned directory dir\n') % self.relpath)
def testUpdateSingleCheckout(self):
options = self.Options(verbose=True)
file_info = {
'URL': self.url,
'Revision': 42,
}
# Checks to make sure that we support svn co --depth.
gclient_scm.scm.SVN.current_version = None
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(False)
# Verify no locked files.
dotted_path = join(self.base_path, '.')
gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
# When checking out a single file, we issue an svn checkout and svn update.
files_list = self.mox.CreateMockAnything()
gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
always=True,
cwd=self.root_dir)
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['update', 'DEPS', '--ignore-externals'],
cwd=self.base_path,
file_list=files_list)
# Now we fall back on scm.update().
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.updatesingle(options, ['DEPS'], files_list)
self.checkstdout('_____ %s at 42\n' % self.relpath)
def testUpdateSingleCheckoutSVN14(self):
options = self.Options(verbose=True)
# Checks to make sure that we support svn co --depth.
gclient_scm.scm.SVN.current_version = None
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.4.4')
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
# When checking out a single file with svn 1.4, we use svn export
files_list = self.mox.CreateMockAnything()
gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
['svn', 'export', join(self.url, 'DEPS'), join(self.base_path, 'DEPS')],
always=True, cwd=self.root_dir)
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.updatesingle(options, ['DEPS'], files_list)
def testUpdateSingleCheckoutSVNUpgrade(self):
options = self.Options(verbose=True)
file_info = {
'URL': self.url,
'Revision': 42,
}
# Checks to make sure that we support svn co --depth.
gclient_scm.scm.SVN.current_version = None
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
# If DEPS already exists, assume we're upgrading from svn1.4, so delete
# the old DEPS file.
gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(True)
gclient_scm.os.remove(join(self.base_path, 'DEPS'))
# Verify no locked files.
gclient_scm.scm.SVN.CaptureStatus(
None, join(self.base_path, '.')).AndReturn([])
# When checking out a single file, we issue an svn checkout and svn update.
files_list = self.mox.CreateMockAnything()
gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
always=True,
cwd=self.root_dir)
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['update', 'DEPS', '--ignore-externals'],
cwd=self.base_path,
file_list=files_list)
# Now we fall back on scm.update().
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
gclient_scm.scm.SVN._CaptureInfo(
[], join(self.base_path, ".")).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.updatesingle(options, ['DEPS'], files_list)
self.checkstdout(
('_____ %s at 42\n' % self.relpath))
def testUpdateSingleUpdate(self):
options = self.Options(verbose=True)
file_info = {
'URL': self.url,
'Revision': 42,
}
# Checks to make sure that we support svn co --depth.
gclient_scm.scm.SVN.current_version = None
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(True)
# Verify no locked files.
gclient_scm.scm.SVN.CaptureStatus(None, join(self.base_path, '.')
).AndReturn([])
# Now we fall back on scm.update().
files_list = self.mox.CreateMockAnything()
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
gclient_scm.scm.SVN._CaptureInfo(
[], join(self.base_path, '.')).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
).AndReturn(file_info)
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.updatesingle(options, ['DEPS'], files_list)
self.checkstdout('_____ %s at 42\n' % self.relpath)
def testUpdateGit(self):
options = self.Options(verbose=True)
file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.hg')
gclient_scm.os.path.exists(file_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
error = gclient_scm.subprocess2.CalledProcessError(
1, 'cmd', '/cwd', 'stdout', 'stderr')
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.').AndRaise(error)
bad_scm_path = os.path.join(self.root_dir, '_bad_scm',
os.path.dirname(self.relpath))
gclient_scm.os.makedirs(bad_scm_path)
dest_path = os.path.join(bad_scm_path,
os.path.basename(self.relpath) + 'ABCD')
self.mox.StubOutWithMock(gclient_scm.tempfile, 'mkdtemp', True)
gclient_scm.tempfile.mkdtemp(
prefix=os.path.basename(self.relpath),
dir=os.path.join(self.root_dir, '_bad_scm',
os.path.dirname(self.relpath))).AndReturn(dest_path)
self.mox.StubOutWithMock(gclient_scm.shutil, 'move', True)
gclient_scm.shutil.move(self.base_path, dest_path)
gclient_scm.os.path.exists(self.root_dir).AndReturn(True)
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
cwd=self.root_dir,
file_list=[])
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
scm.update(options, None, [])
self.checkstdout('_____ Conflicting directory found in %s. Moving to %s.\n'
% (self.base_path, dest_path))
def testUpdateGitForce(self):
options = self.Options(verbose=True, force=True)
old_environ = dict(gclient_scm.os.environ)
gclient_scm.os.environ['CHROME_HEADLESS'] = '1'
try:
file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.hg')
gclient_scm.os.path.exists(file_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(False)
error = gclient_scm.subprocess2.CalledProcessError(
1, 'cmd', '/cwd', 'stdout', 'stderr')
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.').AndRaise(error)
gclient_scm.gclient_utils.rmtree(self.base_path)
gclient_scm.os.path.exists(self.root_dir).AndReturn(True)
gclient_scm.scm.SVN.Capture(['--version', '--quiet'], None
).AndReturn('1.5.1')
gclient_scm.scm.SVN.RunAndGetFileList(
options.verbose,
['checkout', self.url, self.base_path, '--force',
'--ignore-externals'],
cwd=self.root_dir,
file_list=[])
gclient_scm.scm.SVN._CaptureInfo([], self.base_path+'/.'
).AndReturn({'Revision': 100})
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list = []
scm.update(options, None, file_list)
self.checkstdout('_____ Conflicting directory found in %s. Removing.\n'
% self.base_path)
finally:
gclient_scm.os.environ = old_environ
def testUpdateGitSvn(self):
options = self.Options(verbose=True)
file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.hg')
gclient_scm.os.path.exists(file_path).AndReturn(False)
gclient_scm.os.path.exists(self.base_path).AndReturn(True)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
gclient_scm.scm.GIT.IsGitSvn(self.base_path).AndReturn(True)
self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'Capture', True)
gclient_scm.scm.GIT.Capture(['config', '--local', '--get',
'svn-remote.svn.url'],
cwd=self.base_path).AndReturn(self.url)
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list = []
scm.update(options, [], file_list)
self.checkstdout(
('\n_____ %s looks like a git-svn checkout. Skipping.\n' % self.relpath)
)
def testUpdateHg(self):
options = self.Options(verbose=True)
gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(True)
self.mox.ReplayAll()
scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
relpath=self.relpath)
file_list = []
scm.update(options, self.args, file_list)
self.checkstdout(
('________ found .hg directory; skipping %s\n' % self.relpath))
def testGetUsableRevSVN(self):
# pylint: disable=E1101
options = self.Options(verbose=True)
# Mock SVN revision validity checking.
self.mox.StubOutWithMock(
gclient_scm.scm.SVN, 'IsValidRevision', True)
gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 1)
).AndReturn(True)
gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 'fake')
).AndReturn(False)
self.mox.ReplayAll()
svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir)
# With an SVN checkout, 1 an example of a valid usable rev.
self.assertEquals(svn_scm.GetUsableRev(1, options), 1)
# With an SVN checkout, a fake or unknown rev should raise an excpetion.
self.assertRaises(gclient_scm.gclient_utils.Error,
svn_scm.GetUsableRev, 'fake', options)
class BaseGitWrapperTestCase(GCBaseTestCase, StdoutCheck, TestCaseUtils,
unittest.TestCase):
"""This class doesn't use pymox."""
......
......@@ -20,20 +20,17 @@ import unittest
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, ROOT_DIR)
from testing_support.fake_repos import join, write
from testing_support.fake_repos import FakeReposTestBase, FakeRepoTransitive, \
FakeRepoSkiaDEPS, FakeRepoBlinkDEPS
import gclient_utils
import scm as gclient_scm
import subprocess2
from testing_support import fake_repos
from testing_support.fake_repos import join, write
GCLIENT_PATH = os.path.join(ROOT_DIR, 'gclient')
COVERAGE = False
class GClientSmokeBase(FakeReposTestBase):
class GClientSmokeBase(fake_repos.FakeReposTestBase):
def setUp(self):
super(GClientSmokeBase, self).setUp()
# Make sure it doesn't try to auto update when testing!
......@@ -301,544 +298,6 @@ class GClientSmoke(GClientSmokeBase):
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 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.
# Use --jobs 1 otherwise the order is not deterministic.
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',
],
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( 8, 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', 'other')],
['running', join(self.root_dir, 'src', 'third_party', 'fpp')],
['running', join(self.root_dir, 'src', 'third_party', 'prout')]])
out = self.svnBlockCleanup(out)
self.checkString('other', out[0][5])
self.checkString(join('third_party', 'fpp'), out[0][7])
self.checkString(join('third_party', 'prout'), out[0][8])
self.checkString('hi', out[1][5])
self.assertEquals(9, len(out[0]))
self.assertEquals(7, len(out[1]))
self.assertEquals(6, len(out[2]))
self.assertEquals(6, 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(4, 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'
' "deps_file" : "DEPS",\n'
' "managed" : True,\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 testRevInfoAltDeps(self):
if not self.enabled:
return
self.gclient(['config', self.svn_base + 'trunk/src/', '--deps-file',
'DEPS.alt'])
self.gclient(['sync'])
results = self.gclient(['revinfo', '--snapshot'])
out = ('# Snapshot generated with gclient revinfo --snapshot\n'
'solutions = [\n'
' { "name" : "src",\n'
' "url" : "%(base)s/src",\n'
' "deps_file" : "DEPS.alt",\n'
' "managed" : True,\n'
' "custom_deps" : {\n'
' "foo/bar": None,\n'
' "invalid": None,\n'
' "src/other2": \'%(base)s/other@2\',\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'])
def testUnversionedRepository(self):
# Check that gclient automatically deletes crippled SVN repositories.
if not self.enabled:
return
self.gclient(['config', self.svn_base + 'trunk/src/'])
cmd = ['sync', '--jobs', '1', '--delete_unversioned_trees', '--reset']
self.assertEquals(0, self.gclient(cmd)[-1])
third_party = join(self.root_dir, 'src', 'third_party')
subprocess2.check_call(['svn', 'propset', '-q', 'svn:ignore', 'foo', '.'],
cwd=third_party)
# Cripple src/third_party/foo and make sure gclient still succeeds.
gclient_utils.rmtree(join(third_party, 'foo', '.svn'))
self.assertEquals(0, self.gclient(cmd)[-1])
class GClientSmokeSVNTransitive(GClientSmokeBase):
FAKE_REPOS_CLASS = FakeRepoTransitive
def setUp(self):
super(GClientSmokeSVNTransitive, self).setUp()
self.enabled = self.FAKE_REPOS.set_up_svn()
def testSyncTransitive(self):
if not self.enabled:
return
self.gclient(['config', self.svn_base + 'trunk/src/'])
def test_case(parent, timestamp, fixed, output):
# We check out revision 'parent' and expect the following:
# - src/ is checked out at r'parent'
# - src/same_repo is checked out at r'parent' (due to --transitive)
# - src/same_repo_fixed is checked out at r'fixed'
# - src/different_repo is checked out at r'timestamp'
# (due to --transitive)
# - src/different_repo_fixed is checked out at r'fixed'
revisions = self.FAKE_REPOS.svn_revs
self.parseGclient(
['sync', '--transitive', '--revision', 'src@%d' % parent,
'--jobs', '1'], output)
self.assertTree({
'src/origin': revisions[parent]['trunk/src/origin'],
'src/DEPS': revisions[parent]['trunk/src/DEPS'],
'src/same_repo/origin': revisions[parent]['trunk/third_party/origin'],
'src/same_repo_fixed/origin':
revisions[fixed]['trunk/third_party/origin'],
'src/different_repo/origin':
revisions[timestamp]['trunk/third_party/origin'],
'src/different_repo_fixed/origin':
revisions[fixed]['trunk/third_party/origin'],
})
# Here are the test cases for checking out 'trunk/src' at r1, r2 and r3
# r1: Everything is normal
test_case(parent=1, timestamp=1, fixed=1,
output=['running', 'running', 'running', 'running', 'running'])
# r2: Svn will scan from r1 upwards until it finds a revision matching the
# given timestamp or it takes the next smallest one (which is r2 in this
# case).
test_case(parent=2, timestamp=2, fixed=1,
output=['running', 'running', 'running'])
# r3: Svn will scan from r1 upwards until it finds a revision matching the
# given timestamp or it takes the next smallest one. Since
# timestamp(r3) < timestamp(r2) svn will checkout r1.
# This happens often on http://googlecode.com but is unexpected to happen
# with svnserve (unless you manually change 'svn:date')
test_case(parent=3, timestamp=1, fixed=1,
output=['running', 'running', 'running'])
class GClientSmokeGIT(GClientSmokeBase):
def setUp(self):
super(GClientSmokeGIT, self).setUp()
......@@ -1220,247 +679,15 @@ class GClientSmokeGITMutates(GClientSmokeBase):
self.assertTrue(os.path.exists(join(repo2_root, 'last_file')))
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',
# 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'])
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"}]'])
# There is no guarantee that the ordering will be consistent.
(stdout, stderr, returncode) = self.gclient(
['sync', '--deps', 'mac', '--jobs', '8'])
stdout = self.untangle(stdout)
self.checkString('', stderr)
self.assertEquals(0, returncode)
results = self.splitBlock(stdout)
self.assertEquals(9, len(results))
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'],
expected_stderr=
'You must specify the full solution name like --revision src@1\n'
'when you have multiple solutions setup in your .gclient file.\n'
'Other solutions present are: src-git.\n')
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', '-j1', '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 SkiaDEPSTransitionSmokeTest(GClientSmokeBase):
"""Simulate the behavior of bisect bots as they transition across the Skia
DEPS change."""
FAKE_REPOS_CLASS = FakeRepoSkiaDEPS
FAKE_REPOS_CLASS = fake_repos.FakeRepoSkiaDEPS
def setUp(self):
super(SkiaDEPSTransitionSmokeTest, self).setUp()
self.enabled = self.FAKE_REPOS.set_up_git() and self.FAKE_REPOS.set_up_svn()
def testSkiaDEPSChangeSVN(self):
if not self.enabled:
return
# Create an initial checkout:
# - Single checkout at the root.
# - Multiple checkouts in a shared subdirectory.
self.gclient(['config', '--spec',
'solutions=['
'{"name": "src",'
' "url": "' + self.svn_base + 'trunk/src/",'
'}]'])
checkout_path = os.path.join(self.root_dir, 'src')
skia = os.path.join(checkout_path, 'third_party', 'skia')
skia_gyp = os.path.join(skia, 'gyp')
skia_include = os.path.join(skia, 'include')
skia_src = os.path.join(skia, 'src')
gyp_svn_url = self.svn_base + 'skia/gyp'
include_svn_url = self.svn_base + 'skia/include'
src_svn_url = self.svn_base + 'skia/src'
skia_git_url = self.git_base + 'repo_1'
# Initial sync. Verify that we get the expected checkout.
res = self.gclient(['sync', '--deps', 'mac', '--revision', 'src@2'])
self.assertEqual(res[2], 0, 'Initial sync failed.')
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_gyp)['URL'],
gyp_svn_url)
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_include)['URL'],
include_svn_url)
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_src)['URL'],
src_svn_url)
# Verify that the sync succeeds. Verify that we have the expected merged
# checkout.
res = self.gclient(['sync', '--deps', 'mac', '--revision', 'src@3'])
self.assertEqual(res[2], 0, 'DEPS change sync failed.')
self.assertEqual(gclient_scm.GIT.Capture(['config', 'remote.origin.url'],
skia), skia_git_url)
# Sync again. Verify that we still have the expected merged checkout.
res = self.gclient(['sync', '--deps', 'mac', '--revision', 'src@3'])
self.assertEqual(res[2], 0, 'Subsequent sync failed.')
self.assertEqual(gclient_scm.GIT.Capture(['config', 'remote.origin.url'],
skia), skia_git_url)
# Sync back to the original DEPS. Verify that we get the original structure.
res = self.gclient(['sync', '--deps', 'mac', '--revision', 'src@2'])
self.assertEqual(res[2], 0, 'Reverse sync failed.')
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_gyp)['URL'],
gyp_svn_url)
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_include)['URL'],
include_svn_url)
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_src)['URL'],
src_svn_url)
# Sync again. Verify that we still have the original structure.
res = self.gclient(['sync', '--deps', 'mac', '--revision', 'src@2'])
self.assertEqual(res[2], 0, 'Subsequent sync #2 failed.')
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_gyp)['URL'],
gyp_svn_url)
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_include)['URL'],
include_svn_url)
self.assertEqual(gclient_scm.SVN.CaptureLocalInfo([], skia_src)['URL'],
src_svn_url)
self.enabled = self.FAKE_REPOS.set_up_git()
def testSkiaDEPSChangeGit(self):
if not self.enabled:
......@@ -1542,7 +769,7 @@ class BlinkDEPSTransitionSmokeTest(GClientSmokeBase):
"""Simulate the behavior of bisect bots as they transition across the Blink
DEPS change."""
FAKE_REPOS_CLASS = FakeRepoBlinkDEPS
FAKE_REPOS_CLASS = fake_repos.FakeRepoBlinkDEPS
def setUp(self):
super(BlinkDEPSTransitionSmokeTest, self).setUp()
......@@ -1673,103 +900,6 @@ class BlinkDEPSTransitionSmokeTest(GClientSmokeBase):
['git', 'show-ref', '-q', '--verify', 'refs/heads/foo'], cwd=self.blink)
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))
# This value varies depending on the version of svn being run.
# New vesions (the one in Trust) print "Updating '.':" and "At revision 1.".
# Older versions (the one in Precise) print just "At revision 1.".
#self.assertEquals(3, len(out[0]))
self.assertEquals(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)
......
......@@ -189,293 +189,6 @@ class RealGitTest(fake_repos.FakeReposTestBase):
self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='HEAD'))
class RealGitSvnTest(fake_repos.FakeReposTestBase):
def setUp(self):
super(RealGitSvnTest, self).setUp()
self.enabled = self.FAKE_REPOS.set_up_git() and self.FAKE_REPOS.set_up_svn()
if self.enabled:
self.tree_name = 'git-svn'
self.svn_url = scm.os.path.join(self.FAKE_REPOS.svn_base, 'trunk')
self.clone_dir = scm.os.path.join(self.FAKE_REPOS.git_root,
self.tree_name)
scm.os.makedirs(self.clone_dir)
self._capture(['svn', 'clone', '-q', '-q', self.svn_url, self.clone_dir])
# git rev-list gives revisions in reverse chronological order.
hashes = reversed(self._capture(['rev-list', 'HEAD']).splitlines())
# We insert a null value at 0 to do 1-based indexing, not 0-based, as SVN
# revisions are 1-based (i.e. they start at r1, not r0).
self.git_hashes = ([None] + list(hashes))
def tearDown(self):
scm.gclient_utils.rmtree(self.clone_dir)
def _capture(self, cmd, **kwargs):
kwargs.setdefault('cwd', self.clone_dir)
return scm.GIT.Capture(cmd, **kwargs)
def testGetGitSvnHeadRev(self):
if not self.enabled:
return
self.assertEquals(scm.GIT.GetGitSvnHeadRev(cwd=self.clone_dir), 2)
self._capture(['reset', '--hard', 'HEAD^'])
self.assertEquals(scm.GIT.GetGitSvnHeadRev(cwd=self.clone_dir), 1)
def testIsGitSvn(self):
if not self.enabled:
return
# Git-svn
self.assertTrue(scm.GIT.IsGitSvn(self.clone_dir))
# Pure git
git_dir = scm.os.path.join(self.FAKE_REPOS.git_root, 'repo_1')
self.assertFalse(scm.GIT.IsGitSvn(git_dir))
# Pure svn
svn_dir = scm.os.path.join(self.FAKE_REPOS.svn_checkout, 'trunk')
self.assertFalse(scm.GIT.IsGitSvn(svn_dir))
def testParseGitSvnSha1(self):
test_sha1 = 'a5c63ce8671922e5c59c0dea49ef4f9d4a3020c9'
expected_output = test_sha1 + '\n'
# Cygwin git-svn 1.7.9 prints extra escape sequences when run under
# TERM=xterm
cygwin_output = test_sha1 + '\n\033[?1034h'
self.assertEquals(scm.GIT.ParseGitSvnSha1(expected_output), test_sha1)
self.assertEquals(scm.GIT.ParseGitSvnSha1(cygwin_output), test_sha1)
def testGetGetSha1ForSvnRev(self):
if not self.enabled:
return
self.assertEquals(scm.GIT.GetSha1ForSvnRev(cwd=self.clone_dir, rev=1),
self.git_hashes[1])
self.assertEquals(scm.GIT.GetSha1ForSvnRev(cwd=self.clone_dir, rev=2),
self.git_hashes[2])
class SVNTestCase(BaseSCMTestCase):
def setUp(self):
BaseSCMTestCase.setUp(self)
self.mox.StubOutWithMock(scm.SVN, 'Capture')
self.url = self.SvnUrl()
def testMembersChanged(self):
self.mox.ReplayAll()
members = [
'AssertVersion',
'Capture',
'CaptureLocalInfo',
'CaptureRemoteInfo',
'CaptureRevision',
'CaptureStatus',
'current_version',
'GenerateDiff',
'GetCheckoutRoot',
'GetEmail',
'GetFileProperty',
'IsMoved',
'IsMovedInfo',
'IsValidRevision',
'ReadSimpleAuth',
'Revert',
'RunAndGetFileList',
]
# If this test fails, you should add the relevant test.
self.compareMembers(scm.SVN, members)
def testGetCheckoutRoot(self):
# pylint: disable=E1103
self.mox.StubOutWithMock(scm.SVN, '_CaptureInfo')
self.mox.StubOutWithMock(scm, 'GetCasedPath')
scm.os.path.abspath = lambda x: x
scm.GetCasedPath = lambda x: x
scm.SVN._CaptureInfo([], self.root_dir + '/foo/bar').AndReturn({
'Repository Root': 'svn://svn.chromium.org/chrome',
'URL': 'svn://svn.chromium.org/chrome/trunk/src',
})
scm.SVN._CaptureInfo([], self.root_dir + '/foo').AndReturn({
'Repository Root': 'svn://svn.chromium.org/chrome',
'URL': 'svn://svn.chromium.org/chrome/trunk',
})
scm.SVN._CaptureInfo([], self.root_dir).AndReturn({
'Repository Root': 'svn://svn.chromium.org/chrome',
'URL': 'svn://svn.chromium.org/chrome/trunk/tools/commit-queue/workdir',
})
self.mox.ReplayAll()
self.assertEquals(scm.SVN.GetCheckoutRoot(self.root_dir + '/foo/bar'),
self.root_dir + '/foo')
def testGetFileInfo(self):
xml_text = r"""<?xml version="1.0"?>
<info>
<entry kind="file" path="%s" revision="14628">
<url>http://src.chromium.org/svn/trunk/src/chrome/app/d</url>
<repository><root>http://src.chromium.org/svn</root></repository>
<wc-info>
<schedule>add</schedule>
<depth>infinity</depth>
<copy-from-url>http://src.chromium.org/svn/trunk/src/chrome/app/DEPS</copy-from-url>
<copy-from-rev>14628</copy-from-rev>
<checksum>369f59057ba0e6d9017e28f8bdfb1f43</checksum>
</wc-info>
</entry>
</info>
""" % self.url
scm.SVN.Capture(['info', '--xml', self.url], None).AndReturn(xml_text)
expected = {
'URL': 'http://src.chromium.org/svn/trunk/src/chrome/app/d',
'UUID': None,
'Repository Root': 'http://src.chromium.org/svn',
'Schedule': 'add',
'Copied From URL':
'http://src.chromium.org/svn/trunk/src/chrome/app/DEPS',
'Copied From Rev': '14628',
'Path': self.url,
'Revision': 14628,
'Node Kind': 'file',
}
self.mox.ReplayAll()
file_info = scm.SVN._CaptureInfo([self.url], None)
self.assertEquals(sorted(file_info.items()), sorted(expected.items()))
def testCaptureInfo(self):
xml_text = """<?xml version="1.0"?>
<info>
<entry
kind="dir"
path="."
revision="35">
<url>%s</url>
<repository>
<root>%s</root>
<uuid>7b9385f5-0452-0410-af26-ad4892b7a1fb</uuid>
</repository>
<wc-info>
<schedule>normal</schedule>
<depth>infinity</depth>
</wc-info>
<commit
revision="35">
<author>maruel</author>
<date>2008-12-04T20:12:19.685120Z</date>
</commit>
</entry>
</info>
""" % (self.url, self.root_dir)
scm.SVN.Capture(['info', '--xml', self.url], None).AndReturn(xml_text)
self.mox.ReplayAll()
file_info = scm.SVN._CaptureInfo([self.url], None)
expected = {
'URL': self.url,
'UUID': '7b9385f5-0452-0410-af26-ad4892b7a1fb',
'Revision': 35,
'Repository Root': self.root_dir,
'Schedule': 'normal',
'Copied From URL': None,
'Copied From Rev': None,
'Path': '.',
'Node Kind': 'directory',
}
self.assertEqual(file_info, expected)
def testCaptureStatus(self):
text = r"""<?xml version="1.0"?>
<status>
<target path=".">
<entry path="unversionned_file.txt">
<wc-status props="none" item="unversioned"></wc-status>
</entry>
<entry path="build\internal\essential.vsprops">
<wc-status props="normal" item="modified" revision="14628">
<commit revision="13818">
<author>ajwong@chromium.org</author>
<date>2009-04-16T00:42:06.872358Z</date>
</commit>
</wc-status>
</entry>
<entry path="chrome\app\d">
<wc-status props="none" copied="true" tree-conflicted="true" item="added">
</wc-status>
</entry>
<entry path="chrome\app\DEPS">
<wc-status props="modified" item="modified" revision="14628">
<commit revision="1279">
<author>brettw@google.com</author>
<date>2008-08-23T17:16:42.090152Z</date>
</commit>
</wc-status>
</entry>
<entry path="scripts\master\factory\gclient_factory.py">
<wc-status props="normal" item="conflicted" revision="14725">
<commit revision="14633">
<author>nsylvain@chromium.org</author>
<date>2009-04-27T19:37:17.977400Z</date>
</commit>
</wc-status>
</entry>
</target>
</status>
"""
scm.SVN.Capture(['status', '--xml'], '.').AndReturn(text)
self.mox.ReplayAll()
info = scm.SVN.CaptureStatus(None, '.')
expected = [
('? ', 'unversionned_file.txt'),
('M ', 'build\\internal\\essential.vsprops'),
('A + ', 'chrome\\app\\d'),
('MM ', 'chrome\\app\\DEPS'),
('C ', 'scripts\\master\\factory\\gclient_factory.py'),
]
self.assertEquals(sorted(info), sorted(expected))
def testCaptureStatusEmpty(self):
text = r"""<?xml version="1.0"?>
<status>
<target
path="perf">
</target>
</status>"""
scm.SVN.Capture(['status', '--xml'], None).AndReturn(text)
self.mox.ReplayAll()
info = scm.SVN.CaptureStatus(None, None)
self.assertEquals(info, [])
class RealSvnTest(fake_repos.FakeReposTestBase):
# Tests that work with a checkout.
def setUp(self):
super(RealSvnTest, self).setUp()
self.enabled = self.FAKE_REPOS.set_up_svn()
if self.enabled:
self.svn_root = scm.os.path.join(self.root_dir, 'base')
scm.SVN.Capture(
['checkout', self.svn_base + 'trunk/third_party', 'base'],
cwd=self.root_dir)
self.tree = self.mangle_svn_tree(('trunk/third_party@-1', ''),)
def _capture(self, cmd, **kwargs):
kwargs.setdefault('cwd', self.svn_root)
return scm.SVN.Capture(cmd, **kwargs)
def testCheckout(self):
if not self.enabled:
return
# Checkout and verify the tree.
self.assertTree(self.tree, self.svn_root)
def testIsValidRevision(self):
if not self.enabled:
return
url_at_rev = self.svn_base + 'trunk/third_party@%s'
# Invalid or non-existent.
self.assertFalse(scm.SVN.IsValidRevision('url://totally_invalid/trunk/foo'))
self.assertFalse(scm.SVN.IsValidRevision(url_at_rev % 0))
self.assertFalse(scm.SVN.IsValidRevision(url_at_rev % 123))
# Valid.
self.assertTrue(scm.SVN.IsValidRevision(url_at_rev % 1))
self.assertTrue(scm.SVN.IsValidRevision(url_at_rev % 2))
self.assertTrue(scm.SVN.IsValidRevision(url_at_rev % 'HEAD'))
if __name__ == '__main__':
if '-v' in sys.argv:
logging.basicConfig(level=logging.DEBUG)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment