diff --git a/testing_support/fake_repos.py b/testing_support/fake_repos.py
index 3f90844..92483fa 100755
--- a/testing_support/fake_repos.py
+++ b/testing_support/fake_repos.py
@@ -59,36 +59,6 @@
   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 @@
 
 
 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 @@
   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 @@
         # 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 @@
       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 @@
     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 @@
     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 @@
     })
 
 
-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 @@
   '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 @@
     # 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'
     })
 
 
@@ -880,11 +546,6 @@
     # 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."""
     return self.FAKE_REPOS.git_base
@@ -919,22 +580,6 @@
       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 @@
   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()
diff --git a/testing_support/local_rietveld.py b/testing_support/local_rietveld.py
index c240de5..41b0166 100755
--- a/testing_support/local_rietveld.py
+++ b/testing_support/local_rietveld.py
@@ -81,11 +81,6 @@
       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...')
diff --git a/testing_support/super_mox.py b/testing_support/super_mox.py
index 3322719..36abab4 100644
--- a/testing_support/super_mox.py
+++ b/testing_support/super_mox.py
@@ -55,11 +55,6 @@
     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)
 
diff --git a/tests/checkout_test.py b/tests/checkout_test.py
index dfc88b0..de0d7e6 100755
--- a/tests/checkout_test.py
+++ b/tests/checkout_test.py
@@ -34,16 +34,6 @@
 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 @@
       '#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 @@
   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 @@
     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 @@
     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
diff --git a/tests/gcl_unittest.py b/tests/gcl_unittest.py
deleted file mode 100755
index 0391101..0000000
--- a/tests/gcl_unittest.py
+++ /dev/null
@@ -1,622 +0,0 @@
-#!/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()
diff --git a/tests/gclient_scm_test.py b/tests/gclient_scm_test.py
index 03a87fd..d3fdc68 100755
--- a/tests/gclient_scm_test.py
+++ b/tests/gclient_scm_test.py
@@ -115,690 +115,6 @@
     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."""
diff --git a/tests/gclient_smoketest.py b/tests/gclient_smoketest.py
index 6a8e3aa..96b5079 100755
--- a/tests/gclient_smoketest.py
+++ b/tests/gclient_smoketest.py
@@ -20,20 +20,17 @@
 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 @@
     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 @@
     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 @@
   """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 @@
         ['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)
diff --git a/tests/scm_unittest.py b/tests/scm_unittest.py
index 15676aa..49e9ee2 100755
--- a/tests/scm_unittest.py
+++ b/tests/scm_unittest.py
@@ -189,293 +189,6 @@
     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)
