blob: ebe5e45dca9a9b246194b1ab1f9d65de56567272 [file] [log] [blame]
maruel@chromium.org45d8db02011-03-31 20:43:56 +00001#!/usr/bin/env python
steveblock@chromium.org93567042012-02-15 01:02:26 +00002# Copyright (c) 2012 The Chromium Authors. All rights reserved.
maruel@chromium.orgba551772010-02-03 18:21:42 +00003# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
msb@chromium.orge28e4982009-09-25 20:51:45 +00005
6"""Unit tests for gclient_scm.py."""
7
maruel@chromium.org428342a2011-11-10 15:46:33 +00008# pylint: disable=E1103
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00009
maruel@chromium.orgba551772010-02-03 18:21:42 +000010# Import before super_mox to keep valid references.
11from os import rename
12from shutil import rmtree
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000013from subprocess import Popen, PIPE, STDOUT
maruel@chromium.org428342a2011-11-10 15:46:33 +000014
15import logging
16import os
17import sys
msb@chromium.orge28e4982009-09-25 20:51:45 +000018import tempfile
maruel@chromium.org389d6de2010-09-09 14:14:37 +000019import unittest
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +000020import __builtin__
msb@chromium.orge28e4982009-09-25 20:51:45 +000021
maruel@chromium.org428342a2011-11-10 15:46:33 +000022sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
maruel@chromium.orgba551772010-02-03 18:21:42 +000023
maruel@chromium.org0927b7e2011-11-11 16:06:22 +000024from testing_support.super_mox import mox, StdoutCheck, SuperMoxTestBase
25from testing_support.super_mox import TestCaseUtils
maruel@chromium.org428342a2011-11-10 15:46:33 +000026
msb@chromium.orge28e4982009-09-25 20:51:45 +000027import gclient_scm
maruel@chromium.orgfae707b2011-09-15 18:57:58 +000028import subprocess2
maruel@chromium.org96913eb2010-06-01 16:22:47 +000029
maruel@chromium.org795a8c12010-10-05 19:54:29 +000030# Shortcut since this function is used often
31join = gclient_scm.os.path.join
32
maruel@chromium.org96913eb2010-06-01 16:22:47 +000033
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +000034# Access to a protected member XXX of a client class
35# pylint: disable=W0212
36
37
maruel@chromium.org389d6de2010-09-09 14:14:37 +000038class GCBaseTestCase(object):
maruel@chromium.org96913eb2010-06-01 16:22:47 +000039 def assertRaisesError(self, msg, fn, *args, **kwargs):
maruel@chromium.org389d6de2010-09-09 14:14:37 +000040 """Like unittest's assertRaises() but checks for Gclient.Error."""
maruel@chromium.org428342a2011-11-10 15:46:33 +000041 # pylint: disable=E1101
maruel@chromium.org96913eb2010-06-01 16:22:47 +000042 try:
43 fn(*args, **kwargs)
44 except gclient_scm.gclient_utils.Error, e:
45 self.assertEquals(e.args[0], msg)
46 else:
47 self.fail('%s not raised' % msg)
msb@chromium.orge28e4982009-09-25 20:51:45 +000048
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000049
maruel@chromium.org389d6de2010-09-09 14:14:37 +000050class BaseTestCase(GCBaseTestCase, SuperMoxTestBase):
51 def setUp(self):
maruel@chromium.org389d6de2010-09-09 14:14:37 +000052 SuperMoxTestBase.setUp(self)
maruel@chromium.org389d6de2010-09-09 14:14:37 +000053 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'CheckCallAndFilter')
54 self.mox.StubOutWithMock(gclient_scm.gclient_utils,
55 'CheckCallAndFilterAndHeader')
56 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'FileRead')
57 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'FileWrite')
maruel@chromium.org389d6de2010-09-09 14:14:37 +000058 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'RemoveDirectory')
maruel@chromium.org389d6de2010-09-09 14:14:37 +000059 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Capture')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +000060 self.mox.StubOutWithMock(gclient_scm.scm.SVN, '_CaptureInfo')
maruel@chromium.org389d6de2010-09-09 14:14:37 +000061 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'CaptureStatus')
62 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'RunAndGetFileList')
maruel@chromium.orgfae707b2011-09-15 18:57:58 +000063 self.mox.StubOutWithMock(subprocess2, 'communicate')
64 self.mox.StubOutWithMock(subprocess2, 'Popen')
maruel@chromium.org389d6de2010-09-09 14:14:37 +000065 self._scm_wrapper = gclient_scm.CreateSCM
maruel@chromium.org389d6de2010-09-09 14:14:37 +000066 gclient_scm.scm.SVN.current_version = None
mukai@chromium.org9e3e82c2012-04-18 12:55:43 +000067 self._original_SVNBinaryExists = gclient_scm.SVNWrapper.BinaryExists
68 self._original_GitBinaryExists = gclient_scm.GitWrapper.BinaryExists
69 gclient_scm.SVNWrapper.BinaryExists = staticmethod(lambda : True)
70 gclient_scm.GitWrapper.BinaryExists = staticmethod(lambda : True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +000071 # Absolute path of the fake checkout directory.
72 self.base_path = join(self.root_dir, self.relpath)
maruel@chromium.org389d6de2010-09-09 14:14:37 +000073
74 def tearDown(self):
maruel@chromium.org389d6de2010-09-09 14:14:37 +000075 SuperMoxTestBase.tearDown(self)
mukai@chromium.org9e3e82c2012-04-18 12:55:43 +000076 gclient_scm.SVNWrapper.BinaryExists = self._original_SVNBinaryExists
77 gclient_scm.GitWrapper.BinaryExists = self._original_GitBinaryExists
maruel@chromium.org389d6de2010-09-09 14:14:37 +000078
79
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000080class SVNWrapperTestCase(BaseTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +000081 class OptionsObject(object):
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +000082 def __init__(self, verbose=False, revision=None, force=False):
msb@chromium.orge28e4982009-09-25 20:51:45 +000083 self.verbose = verbose
84 self.revision = revision
85 self.manually_grab_svn_rev = True
86 self.deps_os = None
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +000087 self.force = force
davemoore@chromium.org8bf27312010-02-19 17:29:44 +000088 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +000089 self.nohooks = False
maruel@chromium.org36ac2392011-10-12 16:36:11 +000090 # TODO(maruel): Test --jobs > 1.
91 self.jobs = 1
steveblock@chromium.org98e69452012-02-16 16:36:43 +000092 self.delete_unversioned_trees = False
msb@chromium.orge28e4982009-09-25 20:51:45 +000093
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000094 def Options(self, *args, **kwargs):
maruel@chromium.org8071c282010-09-20 19:44:19 +000095 return self.OptionsObject(*args, **kwargs)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000096
msb@chromium.orge28e4982009-09-25 20:51:45 +000097 def setUp(self):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000098 BaseTestCase.setUp(self)
maruel@chromium.org389d6de2010-09-09 14:14:37 +000099 self.url = self.SvnUrl()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000100
101 def testDir(self):
102 members = [
mukai@chromium.org9e3e82c2012-04-18 12:55:43 +0000103 'BinaryExists',
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +0000104 'FullUrlForRelativeUrl',
105 'GetRevisionDate',
106 'GetUsableRev',
107 'RunCommand',
108 'cleanup',
109 'diff',
110 'pack',
111 'relpath',
112 'revert',
113 'revinfo',
114 'runhooks',
115 'status',
116 'update',
117 'updatesingle',
118 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +0000119 ]
120
121 # If you add a member, be sure to add the relevant test!
maruel@chromium.org9eda4112010-06-11 18:56:10 +0000122 self.compareMembers(self._scm_wrapper('svn://a'), members)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000123
124 def testUnsupportedSCM(self):
maruel@chromium.org9eda4112010-06-11 18:56:10 +0000125 args = ['gopher://foo', self.root_dir, self.relpath]
126 exception_msg = 'No SCM found for url gopher://foo'
127 self.assertRaisesError(exception_msg, self._scm_wrapper, *args)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000128
msb@chromium.orge6f78352010-01-13 17:05:33 +0000129 def testSVNFullUrlForRelativeUrl(self):
130 self.url = 'svn://a/b/c/d'
131
132 self.mox.ReplayAll()
133 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
134 relpath=self.relpath)
135 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'svn://a/b/crap')
136
137 def testGITFullUrlForRelativeUrl(self):
138 self.url = 'git://a/b/c/d'
139
140 self.mox.ReplayAll()
141 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
142 relpath=self.relpath)
143 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'git://a/b/c/crap')
144
igorgatis@gmail.com4e075672011-11-21 16:35:08 +0000145 def testGITFakeHttpUrl(self):
146 self.url = 'git+http://foo'
147
148 self.mox.ReplayAll()
149 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
150 relpath=self.relpath)
151 self.assertEqual(scm.url, 'http://foo')
152
153 def testGITFakeHttpsUrl(self):
154 self.url = 'git+https://foo'
155
156 self.mox.ReplayAll()
157 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
158 relpath=self.relpath)
159 self.assertEqual(scm.url, 'https://foo')
160
msb@chromium.orge28e4982009-09-25 20:51:45 +0000161 def testRunCommandException(self):
162 options = self.Options(verbose=False)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000163 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
164 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000165
166 self.mox.ReplayAll()
167 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
168 relpath=self.relpath)
169 exception = "Unsupported argument(s): %s" % ','.join(self.args)
170 self.assertRaisesError(exception, scm.RunCommand,
171 'update', options, self.args)
172
173 def testRunCommandUnknown(self):
174 # TODO(maruel): if ever used.
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000175 pass
msb@chromium.orge28e4982009-09-25 20:51:45 +0000176
177 def testRevertMissing(self):
178 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000179 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000180 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000181 gclient_scm.scm.SVN.Capture(['--version'], None
maruel@chromium.org2b9aa8e2010-08-25 20:01:42 +0000182 ).AndReturn('svn, version 1.5.1 (r32289)')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000183 # It'll to a checkout instead.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000184 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
185 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000186 # Checkout.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000187 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.org6c48a302011-10-20 23:44:20 +0000188 parent = gclient_scm.os.path.dirname(self.base_path)
189 gclient_scm.os.path.exists(parent).AndReturn(False)
190 gclient_scm.os.makedirs(parent)
191 gclient_scm.os.path.exists(parent).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000192 files_list = self.mox.CreateMockAnything()
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000193 gclient_scm.scm.SVN.RunAndGetFileList(
194 options.verbose,
195 ['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
196 cwd=self.root_dir,
197 file_list=files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000198
199 self.mox.ReplayAll()
200 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
201 relpath=self.relpath)
202 scm.revert(options, self.args, files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000203 self.checkstdout(
204 ('\n_____ %s is missing, synching instead\n' % self.relpath))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000205
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000206 def testRevertNoDotSvn(self):
207 options = self.Options(verbose=True, force=True)
208 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
209 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(False)
210 gclient_scm.os.path.isdir(join(self.base_path, '.git')).AndReturn(False)
211 gclient_scm.os.path.isdir(join(self.base_path, '.hg')).AndReturn(False)
212 # Checkout.
213 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
214 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
215 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
216 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.org6c48a302011-10-20 23:44:20 +0000217 parent = gclient_scm.os.path.dirname(self.base_path)
218 gclient_scm.os.path.exists(parent).AndReturn(False)
219 gclient_scm.os.makedirs(parent)
220 gclient_scm.os.path.exists(parent).AndReturn(True)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000221 files_list = self.mox.CreateMockAnything()
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000222 gclient_scm.scm.SVN.Capture(['--version'], None
223 ).AndReturn('svn, version 1.6')
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000224 gclient_scm.scm.SVN.RunAndGetFileList(
225 options.verbose,
226 ['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
227 cwd=self.root_dir,
228 file_list=files_list)
229
230 self.mox.ReplayAll()
231 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
232 relpath=self.relpath)
233 scm.revert(options, self.args, files_list)
234 self.checkstdout(
235 '\n_____ %s is not a valid svn checkout, synching instead\n' %
236 self.relpath)
237
msb@chromium.orge28e4982009-09-25 20:51:45 +0000238 def testRevertNone(self):
239 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000240 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000241 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000242 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path).AndReturn([])
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000243 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000244 gclient_scm.scm.SVN.RunAndGetFileList(
245 options.verbose,
246 ['update', '--revision', 'BASE', '--ignore-externals'],
247 cwd=self.base_path,
248 file_list=mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000249
250 self.mox.ReplayAll()
251 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
252 relpath=self.relpath)
253 file_list = []
254 scm.revert(options, self.args, file_list)
255
msb@chromium.orge28e4982009-09-25 20:51:45 +0000256 def testRevertDirectory(self):
257 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000258 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000259 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000260 items = [
261 ('~ ', 'a'),
262 ]
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000263 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path).AndReturn(items)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000264 file_path = join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000265 gclient_scm.os.path.exists(file_path).AndReturn(True)
266 gclient_scm.os.path.isfile(file_path).AndReturn(False)
msb@chromium.org32906d12010-01-12 18:22:09 +0000267 gclient_scm.os.path.islink(file_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000268 gclient_scm.os.path.isdir(file_path).AndReturn(True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000269 gclient_scm.gclient_utils.RemoveDirectory(file_path)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000270 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000271 gclient_scm.scm.SVN.RunAndGetFileList(
272 options.verbose,
273 ['update', '--revision', 'BASE', '--ignore-externals'],
274 cwd=self.base_path,
275 file_list=mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000276
277 self.mox.ReplayAll()
278 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
279 relpath=self.relpath)
280 file_list2 = []
281 scm.revert(options, self.args, file_list2)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000282 self.checkstdout(('%s\n' % file_path))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000283
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000284 def testRevertDot(self):
285 self.mox.StubOutWithMock(gclient_scm.SVNWrapper, 'update')
286 options = self.Options(verbose=True)
287 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
288 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
289 items = [
290 ('~ ', '.'),
291 ]
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000292 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path).AndReturn(items)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000293 file_path = join(self.base_path, '.')
294 gclient_scm.os.path.exists(file_path).AndReturn(True)
295 gclient_scm.os.path.isfile(file_path).AndReturn(False)
296 gclient_scm.os.path.islink(file_path).AndReturn(False)
297 gclient_scm.os.path.isdir(file_path).AndReturn(True)
298 gclient_scm.gclient_utils.RemoveDirectory(file_path)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000299 # pylint: disable=E1120
maruel@chromium.org428342a2011-11-10 15:46:33 +0000300 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000301 gclient_scm.SVNWrapper.update(options, [], ['.'])
302
303 self.mox.ReplayAll()
304 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
305 relpath=self.relpath)
306 file_list2 = []
307 scm.revert(options, self.args, file_list2)
308 self.checkstdout(('%s\n' % file_path))
309
msb@chromium.orge28e4982009-09-25 20:51:45 +0000310 def testStatus(self):
311 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000312 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000313 gclient_scm.scm.SVN.RunAndGetFileList(
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000314 options.verbose,
315 ['status'] + self.args + ['--ignore-externals'],
316 cwd=self.base_path,
317 file_list=[]).AndReturn(None)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000318
319 self.mox.ReplayAll()
320 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
321 relpath=self.relpath)
322 file_list = []
323 self.assertEqual(scm.status(options, self.args, file_list), None)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000324
325 # TODO(maruel): TEST REVISIONS!!!
326 # TODO(maruel): TEST RELOCATE!!!
327 def testUpdateCheckout(self):
328 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000329 file_info = gclient_scm.gclient_utils.PrintableObject()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000330 file_info.root = 'blah'
331 file_info.url = self.url
332 file_info.uuid = 'ABC'
333 file_info.revision = 42
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000334 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
335 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000336 # Checkout.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000337 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.org6c48a302011-10-20 23:44:20 +0000338 parent = gclient_scm.os.path.dirname(self.base_path)
339 gclient_scm.os.path.exists(parent).AndReturn(False)
340 gclient_scm.os.makedirs(parent)
341 gclient_scm.os.path.exists(parent).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000342 files_list = self.mox.CreateMockAnything()
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000343 gclient_scm.scm.SVN.Capture(['--version'], None
maruel@chromium.org669600d2010-09-01 19:06:31 +0000344 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000345 gclient_scm.scm.SVN.RunAndGetFileList(
346 options.verbose,
347 ['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
348 cwd=self.root_dir,
349 file_list=files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000350 self.mox.ReplayAll()
351 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
352 relpath=self.relpath)
353 scm.update(options, (), files_list)
354
355 def testUpdateUpdate(self):
356 options = self.Options(verbose=True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000357 options.force = True
358 options.nohooks = False
359 file_info = {
360 'Repository Root': 'blah',
361 'URL': self.url,
362 'UUID': 'ABC',
363 'Revision': 42,
364 }
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000365 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
366 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000367 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000368
msb@chromium.orge28e4982009-09-25 20:51:45 +0000369 # Checkout or update.
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000370 dotted_path = join(self.base_path, '.')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000371 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000372
373 # Verify no locked files.
374 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
375
msb@chromium.orge28e4982009-09-25 20:51:45 +0000376 # Cheat a bit here.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000377 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
378 ).AndReturn(file_info)
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000379
380 # _AddAdditionalUpdateFlags()
381 gclient_scm.scm.SVN.Capture(['--version'], None
382 ).AndReturn('svn, version 1.5.1 (r32289)')
383
msb@chromium.orge28e4982009-09-25 20:51:45 +0000384 additional_args = []
385 if options.manually_grab_svn_rev:
386 additional_args = ['--revision', str(file_info['Revision'])]
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000387 additional_args.extend(['--force', '--ignore-externals'])
msb@chromium.orge28e4982009-09-25 20:51:45 +0000388 files_list = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000389 gclient_scm.scm.SVN.RunAndGetFileList(
maruel@chromium.org03807072010-08-16 17:18:44 +0000390 options.verbose,
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000391 ['update', self.base_path] + additional_args,
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000392 cwd=self.root_dir, file_list=files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000393
394 self.mox.ReplayAll()
395 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
396 relpath=self.relpath)
397 scm.update(options, (), files_list)
398
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000399 def testUpdateReset(self):
400 options = self.Options(verbose=True)
401 options.reset = True
402 file_info = {
403 'Repository Root': 'blah',
404 'URL': self.url,
405 'UUID': 'ABC',
406 'Revision': 42,
407 }
408 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
409 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
410 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
411
412 # Checkout or update.
413 dotted_path = join(self.base_path, '.')
414 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
415
416 # Create an untracked file and directory.
417 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
418 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
419
420 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
421 ).AndReturn(file_info)
422
423 self.mox.ReplayAll()
424 files_list = []
425 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
426 relpath=self.relpath)
427 scm.update(options, (), files_list)
428 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
429
430 def testUpdateResetDeleteUnversionedTrees(self):
431 options = self.Options(verbose=True)
432 options.reset = True
433 options.delete_unversioned_trees = True
434
435 file_info = {
436 'Repository Root': 'blah',
437 'URL': self.url,
438 'UUID': 'ABC',
439 'Revision': 42,
440 }
441 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
442 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
443 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
444
445 # Checkout or update.
446 dotted_path = join(self.base_path, '.')
447 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
448
449 # Create an untracked file and directory.
450 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
451 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
452
453 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
454 ).AndReturn(file_info)
455
456 # Confirm that the untracked file is removed.
457 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path
458 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
459 gclient_scm.os.path.isdir(join(self.base_path, 'dir')).AndReturn(True)
460 gclient_scm.os.path.isdir(join(self.base_path, 'file')).AndReturn(False)
461 gclient_scm.os.path.islink(join(self.base_path, 'dir')).AndReturn(False)
462 gclient_scm.gclient_utils.RemoveDirectory(join(self.base_path, 'dir'))
463
464 self.mox.ReplayAll()
465 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
466 relpath=self.relpath)
467 files_list = []
468 scm.update(options, (), files_list)
469 self.checkstdout(
470 ('\n_____ %s at 42\n'
471 '\n_____ removing unversioned directory dir\n') % self.relpath)
472
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000473 def testUpdateSingleCheckout(self):
474 options = self.Options(verbose=True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000475 file_info = {
476 'URL': self.url,
477 'Revision': 42,
478 }
tony@chromium.org57564662010-04-14 02:35:12 +0000479
480 # Checks to make sure that we support svn co --depth.
481 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000482 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000483 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000484 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
485 gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(False)
tony@chromium.org57564662010-04-14 02:35:12 +0000486
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000487 # Verify no locked files.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000488 dotted_path = join(self.base_path, '.')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000489 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000490
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000491 # When checking out a single file, we issue an svn checkout and svn update.
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000492 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000493 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000494 ['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000495 always=True,
496 cwd=self.root_dir)
497 gclient_scm.scm.SVN.RunAndGetFileList(
498 options.verbose,
499 ['update', 'DEPS', '--ignore-externals'],
500 cwd=self.base_path,
501 file_list=files_list)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000502
503 # Now we fall back on scm.update().
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000504 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
505 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
506 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000507 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
508 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
509 ).AndReturn(file_info)
tony@chromium.org57564662010-04-14 02:35:12 +0000510
511 self.mox.ReplayAll()
512 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
513 relpath=self.relpath)
514 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000515 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
tony@chromium.org57564662010-04-14 02:35:12 +0000516
517 def testUpdateSingleCheckoutSVN14(self):
518 options = self.Options(verbose=True)
tony@chromium.org57564662010-04-14 02:35:12 +0000519
520 # Checks to make sure that we support svn co --depth.
521 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000522 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000523 ).AndReturn('svn, version 1.4.4 (r25188)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000524 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
tony@chromium.org57564662010-04-14 02:35:12 +0000525
526 # When checking out a single file with svn 1.4, we use svn export
527 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000528 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000529 ['svn', 'export', join(self.url, 'DEPS'), join(self.base_path, 'DEPS')],
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000530 always=True, cwd=self.root_dir)
tony@chromium.org57564662010-04-14 02:35:12 +0000531
532 self.mox.ReplayAll()
533 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
534 relpath=self.relpath)
535 scm.updatesingle(options, ['DEPS'], files_list)
536
537 def testUpdateSingleCheckoutSVNUpgrade(self):
538 options = self.Options(verbose=True)
tony@chromium.org57564662010-04-14 02:35:12 +0000539 file_info = {
540 'URL': self.url,
541 'Revision': 42,
542 }
543
544 # Checks to make sure that we support svn co --depth.
545 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000546 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000547 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000548 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
tony@chromium.org57564662010-04-14 02:35:12 +0000549 # If DEPS already exists, assume we're upgrading from svn1.4, so delete
550 # the old DEPS file.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000551 gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(True)
552 gclient_scm.os.remove(join(self.base_path, 'DEPS'))
tony@chromium.org57564662010-04-14 02:35:12 +0000553
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000554 # Verify no locked files.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000555 gclient_scm.scm.SVN.CaptureStatus(
556 None, join(self.base_path, '.')).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000557
tony@chromium.org57564662010-04-14 02:35:12 +0000558 # When checking out a single file, we issue an svn checkout and svn update.
559 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000560 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000561 ['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000562 always=True,
563 cwd=self.root_dir)
564 gclient_scm.scm.SVN.RunAndGetFileList(
565 options.verbose,
566 ['update', 'DEPS', '--ignore-externals'],
567 cwd=self.base_path,
568 file_list=files_list)
tony@chromium.org57564662010-04-14 02:35:12 +0000569
570 # Now we fall back on scm.update().
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000571 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
572 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
573 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000574 gclient_scm.scm.SVN._CaptureInfo(
575 [], join(self.base_path, ".")).AndReturn(file_info)
576 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
577 ).AndReturn(file_info)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000578
579 self.mox.ReplayAll()
580 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
581 relpath=self.relpath)
582 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000583 self.checkstdout(
584 ('\n_____ %s at 42\n' % self.relpath))
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000585
586 def testUpdateSingleUpdate(self):
587 options = self.Options(verbose=True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000588 file_info = {
589 'URL': self.url,
590 'Revision': 42,
591 }
tony@chromium.org57564662010-04-14 02:35:12 +0000592 # Checks to make sure that we support svn co --depth.
593 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000594 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000595 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000596 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000597
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000598 # Verify no locked files.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000599 gclient_scm.scm.SVN.CaptureStatus(None, join(self.base_path, '.')
600 ).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000601
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000602 # Now we fall back on scm.update().
603 files_list = self.mox.CreateMockAnything()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000604 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
605 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
606 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000607 gclient_scm.scm.SVN._CaptureInfo(
608 [], join(self.base_path, '.')).AndReturn(file_info)
609 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
610 ).AndReturn(file_info)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000611
612 self.mox.ReplayAll()
613 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
614 relpath=self.relpath)
615 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000616 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000617
msb@chromium.orge28e4982009-09-25 20:51:45 +0000618 def testUpdateGit(self):
619 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000620 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
621 gclient_scm.os.path.exists(file_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000622
623 self.mox.ReplayAll()
624 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
625 relpath=self.relpath)
626 file_list = []
627 scm.update(options, self.args, file_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000628 self.checkstdout(
629 ('________ found .git directory; skipping %s\n' % self.relpath))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000630
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000631 def testUpdateHg(self):
632 options = self.Options(verbose=True)
633 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
634 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(True)
635
636 self.mox.ReplayAll()
637 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
638 relpath=self.relpath)
639 file_list = []
640 scm.update(options, self.args, file_list)
641 self.checkstdout(
642 ('________ found .hg directory; skipping %s\n' % self.relpath))
643
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +0000644 def testGetUsableRevSVN(self):
645 # pylint: disable=E1101
646 options = self.Options(verbose=True)
647
648 # Mock SVN revision validity checking.
649 self.mox.StubOutWithMock(
650 gclient_scm.scm.SVN, 'IsValidRevision', True)
651 gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 1)
652 ).AndReturn(True)
653 gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 'fake')
654 ).AndReturn(False)
655
656 self.mox.ReplayAll()
657
658 svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir)
659 # With an SVN checkout, 1 an example of a valid usable rev.
660 self.assertEquals(svn_scm.GetUsableRev(1, options), 1)
661 # With an SVN checkout, a fake or unknown rev should raise an excpetion.
662 self.assertRaises(gclient_scm.gclient_utils.Error,
663 svn_scm.GetUsableRev, 'fake', options)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000664
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +0000665class BaseGitWrapperTestCase(GCBaseTestCase, StdoutCheck, TestCaseUtils,
666 unittest.TestCase):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000667 """This class doesn't use pymox."""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000668 class OptionsObject(object):
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000669 def __init__(self, verbose=False, revision=None):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000670 self.verbose = verbose
671 self.revision = revision
672 self.manually_grab_svn_rev = True
673 self.deps_os = None
674 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +0000675 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000676 self.nohooks = False
bauerb@chromium.org4dd09372011-07-22 14:41:51 +0000677 self.merge = False
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000678 self.delete_unversioned_trees = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000679
680 sample_git_import = """blob
681mark :1
682data 6
683Hello
684
685blob
686mark :2
687data 4
688Bye
689
690reset refs/heads/master
691commit refs/heads/master
692mark :3
693author Bob <bob@example.com> 1253744361 -0700
694committer Bob <bob@example.com> 1253744361 -0700
695data 8
696A and B
697M 100644 :1 a
698M 100644 :2 b
699
700blob
701mark :4
702data 10
703Hello
704You
705
706blob
707mark :5
708data 8
709Bye
710You
711
712commit refs/heads/origin
713mark :6
714author Alice <alice@example.com> 1253744424 -0700
715committer Alice <alice@example.com> 1253744424 -0700
716data 13
717Personalized
718from :3
719M 100644 :4 a
720M 100644 :5 b
721
722reset refs/heads/master
723from :3
724"""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000725 def Options(self, *args, **kwargs):
maruel@chromium.org8071c282010-09-20 19:44:19 +0000726 return self.OptionsObject(*args, **kwargs)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000727
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000728 @staticmethod
729 def CreateGitRepo(git_import, path):
maruel@chromium.orgd5800f12009-11-12 20:03:43 +0000730 """Do it for real."""
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000731 try:
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000732 Popen(['git', 'init', '-q'], stdout=PIPE, stderr=STDOUT,
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000733 cwd=path).communicate()
734 except OSError:
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000735 # git is not available, skip this test.
736 return False
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000737 Popen(['git', 'fast-import', '--quiet'], stdin=PIPE, stdout=PIPE,
738 stderr=STDOUT, cwd=path).communicate(input=git_import)
739 Popen(['git', 'checkout', '-q'], stdout=PIPE, stderr=STDOUT,
740 cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000741 Popen(['git', 'remote', 'add', '-f', 'origin', '.'], stdout=PIPE,
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000742 stderr=STDOUT, cwd=path).communicate()
743 Popen(['git', 'checkout', '-b', 'new', 'origin/master', '-q'], stdout=PIPE,
744 stderr=STDOUT, cwd=path).communicate()
745 Popen(['git', 'push', 'origin', 'origin/origin:origin/master', '-q'],
746 stdout=PIPE, stderr=STDOUT, cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000747 Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE,
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000748 stderr=STDOUT, cwd=path).communicate()
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000749 return True
msb@chromium.orge28e4982009-09-25 20:51:45 +0000750
msb@chromium.orge28e4982009-09-25 20:51:45 +0000751 def setUp(self):
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000752 TestCaseUtils.setUp(self)
753 unittest.TestCase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000754 self.url = 'git://foo'
755 self.root_dir = tempfile.mkdtemp()
756 self.relpath = '.'
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000757 self.base_path = join(self.root_dir, self.relpath)
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000758 self.enabled = self.CreateGitRepo(self.sample_git_import, self.base_path)
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000759 StdoutCheck.setUp(self)
mukai@chromium.org9e3e82c2012-04-18 12:55:43 +0000760 self._original_GitBinaryExists = gclient_scm.GitWrapper.BinaryExists
761 self._original_SVNBinaryExists = gclient_scm.SVNWrapper.BinaryExists
762 gclient_scm.GitWrapper.BinaryExists = staticmethod(lambda : True)
763 gclient_scm.SVNWrapper.BinaryExists = staticmethod(lambda : True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000764
765 def tearDown(self):
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000766 StdoutCheck.tearDown(self)
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000767 TestCaseUtils.tearDown(self)
768 unittest.TestCase.tearDown(self)
maruel@chromium.orgba551772010-02-03 18:21:42 +0000769 rmtree(self.root_dir)
mukai@chromium.org9e3e82c2012-04-18 12:55:43 +0000770 gclient_scm.GitWrapper.BinaryExists = self._original_GitBinaryExists
771 gclient_scm.SVNWrapper.BinaryExists = self._original_SVNBinaryExists
msb@chromium.orge28e4982009-09-25 20:51:45 +0000772
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +0000773class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000774 def testDir(self):
775 members = [
mukai@chromium.org9e3e82c2012-04-18 12:55:43 +0000776 'BinaryExists',
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +0000777 'FullUrlForRelativeUrl',
778 'GetRevisionDate',
779 'GetUsableRev',
780 'RunCommand',
781 'cleanup',
782 'diff',
783 'pack',
784 'relpath',
785 'revert',
786 'revinfo',
787 'runhooks',
788 'status',
789 'update',
790 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +0000791 ]
792
793 # If you add a member, be sure to add the relevant test!
794 self.compareMembers(gclient_scm.CreateSCM(url=self.url), members)
795
796 def testRevertMissing(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000797 if not self.enabled:
798 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000799 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000800 file_path = join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000801 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
802 relpath=self.relpath)
803 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000804 scm.update(options, None, file_list)
805 gclient_scm.os.remove(file_path)
806 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000807 scm.revert(options, self.args, file_list)
808 self.assertEquals(file_list, [file_path])
809 file_list = []
810 scm.diff(options, self.args, file_list)
811 self.assertEquals(file_list, [])
szager@google.com85d3e3a2011-10-07 17:12:00 +0000812 expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000813 'Fast-forward\n a | 1 +\n b | 1 +\n'
814 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000815 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
szager@google.com85d3e3a2011-10-07 17:12:00 +0000816 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.')
817 self.assertTrue(sys.stdout.getvalue().startswith(expectation))
818 sys.stdout.close()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000819
820 def testRevertNone(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000821 if not self.enabled:
822 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000823 options = self.Options()
824 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
825 relpath=self.relpath)
826 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000827 scm.update(options, None, file_list)
828 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000829 scm.revert(options, self.args, file_list)
830 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000831 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000832 'a7142dc9f0009350b96a11f372b6ea658592aa95')
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000833 self.checkstdout(
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000834 ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
835 'Fast-forward\n a | 1 +\n b | 1 +\n'
836 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000837 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
838 'HEAD is now at a7142dc Personalized\n') %
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000839 join(self.root_dir, '.'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000840
841 def testRevertModified(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000842 if not self.enabled:
843 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000844 options = self.Options()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000845 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
846 relpath=self.relpath)
847 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000848 scm.update(options, None, file_list)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000849 file_path = join(self.base_path, 'a')
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000850 open(file_path, 'a').writelines('touched\n')
851 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000852 scm.revert(options, self.args, file_list)
853 self.assertEquals(file_list, [file_path])
854 file_list = []
855 scm.diff(options, self.args, file_list)
856 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000857 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000858 'a7142dc9f0009350b96a11f372b6ea658592aa95')
szager@google.com85d3e3a2011-10-07 17:12:00 +0000859 expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000860 'Fast-forward\n a | 1 +\n b | 1 +\n'
861 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000862 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
szager@google.com85d3e3a2011-10-07 17:12:00 +0000863 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.')
864 self.assertTrue(sys.stdout.getvalue().startswith(expectation))
865 sys.stdout.close()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000866
867 def testRevertNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000868 if not self.enabled:
869 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000870 options = self.Options()
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000871 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
872 relpath=self.relpath)
873 file_list = []
874 scm.update(options, None, file_list)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000875 file_path = join(self.base_path, 'c')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000876 f = open(file_path, 'w')
877 f.writelines('new\n')
878 f.close()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000879 Popen(['git', 'add', 'c'], stdout=PIPE,
880 stderr=STDOUT, cwd=self.base_path).communicate()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000881 file_list = []
882 scm.revert(options, self.args, file_list)
883 self.assertEquals(file_list, [file_path])
884 file_list = []
885 scm.diff(options, self.args, file_list)
886 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000887 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000888 'a7142dc9f0009350b96a11f372b6ea658592aa95')
szager@google.com85d3e3a2011-10-07 17:12:00 +0000889 expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000890 'Fast-forward\n a | 1 +\n b | 1 +\n'
891 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000892 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
szager@google.com85d3e3a2011-10-07 17:12:00 +0000893 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.')
894 self.assertTrue(sys.stdout.getvalue().startswith(expectation))
895 sys.stdout.close()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000896
897 def testStatusNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000898 if not self.enabled:
899 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000900 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000901 file_path = join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000902 open(file_path, 'a').writelines('touched\n')
903 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
904 relpath=self.relpath)
905 file_list = []
906 scm.status(options, self.args, file_list)
907 self.assertEquals(file_list, [file_path])
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000908 self.checkstdout(
909 ('\n________ running \'git diff --name-status '
910 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\n') %
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000911 join(self.root_dir, '.'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000912
913 def testStatus2New(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000914 if not self.enabled:
915 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000916 options = self.Options()
917 expected_file_list = []
918 for f in ['a', 'b']:
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000919 file_path = join(self.base_path, f)
920 open(file_path, 'a').writelines('touched\n')
921 expected_file_list.extend([file_path])
msb@chromium.orge28e4982009-09-25 20:51:45 +0000922 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
923 relpath=self.relpath)
924 file_list = []
925 scm.status(options, self.args, file_list)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000926 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000927 self.assertEquals(sorted(file_list), expected_file_list)
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000928 self.checkstdout(
929 ('\n________ running \'git diff --name-status '
930 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\nM\tb\n') %
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000931 join(self.root_dir, '.'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000932
msb@chromium.orge28e4982009-09-25 20:51:45 +0000933 def testUpdateUpdate(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000934 if not self.enabled:
935 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000936 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000937 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000938 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
939 relpath=self.relpath)
940 file_list = []
941 scm.update(options, (), file_list)
msb@chromium.org0f282062009-11-06 20:14:02 +0000942 self.assertEquals(file_list, expected_file_list)
943 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000944 'a7142dc9f0009350b96a11f372b6ea658592aa95')
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000945 self.checkstdout(
946 '\n_____ . at refs/heads/master\n'
947 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
948 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000949
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000950 def testUpdateReset(self):
951 if not self.enabled:
952 return
953 options = self.Options()
954 options.reset = True
955
956 dir_path = join(self.base_path, 'c')
957 os.mkdir(dir_path)
958 open(join(dir_path, 'nested'), 'w').writelines('new\n')
959
960 file_path = join(self.base_path, 'file')
961 open(file_path, 'w').writelines('new\n')
962
963 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
964 relpath=self.relpath)
965 file_list = []
966 scm.update(options, (), file_list)
967 self.assert_(gclient_scm.os.path.isdir(dir_path))
968 self.assert_(gclient_scm.os.path.isfile(file_path))
969 self.checkstdout(
970 '\n________ running \'git reset --hard HEAD\' in \'%s\''
971 '\nHEAD is now at 069c602 A and B\n'
972 '\n_____ . at refs/heads/master\n'
973 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
974 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n'
975 % join(self.root_dir, '.'))
976
977 def testUpdateResetDeleteUnversionedTrees(self):
978 if not self.enabled:
979 return
980 options = self.Options()
981 options.reset = True
982 options.delete_unversioned_trees = True
983
984 dir_path = join(self.base_path, 'dir')
985 os.mkdir(dir_path)
986 open(join(dir_path, 'nested'), 'w').writelines('new\n')
987
988 file_path = join(self.base_path, 'file')
989 open(file_path, 'w').writelines('new\n')
990
991 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
992 relpath=self.relpath)
993 file_list = []
994 scm.update(options, (), file_list)
995 self.assert_(not gclient_scm.os.path.isdir(dir_path))
996 self.assert_(gclient_scm.os.path.isfile(file_path))
997 self.checkstdout(
998 '\n________ running \'git reset --hard HEAD\' in \'%s\''
999 '\nHEAD is now at 069c602 A and B\n'
1000 '\n_____ . at refs/heads/master\n'
1001 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
1002 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n'
1003 '\n_____ removing unversioned directory dir/\n' % join(self.root_dir,
1004 '.'))
1005
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +00001006 def testUpdateUnstagedConflict(self):
1007 if not self.enabled:
1008 return
1009 options = self.Options()
1010 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1011 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001012 file_path = join(self.base_path, 'b')
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00001013 open(file_path, 'w').writelines('conflict\n')
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001014 try:
1015 scm.update(options, (), [])
1016 self.fail()
maruel@chromium.orgfae707b2011-09-15 18:57:58 +00001017 except (gclient_scm.gclient_utils.Error, subprocess2.CalledProcessError):
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001018 # The exact exception text varies across git versions so it's not worth
1019 # verifying it. It's fine as long as it throws.
1020 pass
1021 # Manually flush stdout since we can't verify it's content accurately across
1022 # git versions.
1023 sys.stdout.getvalue()
1024 sys.stdout.close()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +00001025
msb@chromium.org5bde4852009-12-14 16:47:12 +00001026 def testUpdateConflict(self):
1027 if not self.enabled:
1028 return
1029 options = self.Options()
1030 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1031 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001032 file_path = join(self.base_path, 'b')
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00001033 open(file_path, 'w').writelines('conflict\n')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001034 scm._Run(['commit', '-am', 'test'], options)
1035 __builtin__.raw_input = lambda x: 'y'
1036 exception = ('Conflict while rebasing this branch.\n'
1037 'Fix the conflict and run gclient again.\n'
1038 'See \'man git-rebase\' for details.\n')
msb@chromium.org5bde4852009-12-14 16:47:12 +00001039 self.assertRaisesError(exception, scm.update, options, (), [])
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001040 exception = ('\n____ . at refs/heads/master\n'
1041 '\tYou have unstaged changes.\n'
1042 '\tPlease commit, stash, or reset.\n')
msb@chromium.org5bde4852009-12-14 16:47:12 +00001043 self.assertRaisesError(exception, scm.update, options, (), [])
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001044 # The hash always changes. Use a cheap trick.
1045 start = ('\n________ running \'git commit -am test\' in \'%s\'\n'
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001046 '[new ') % join(self.root_dir, '.')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001047 end = ('] test\n 1 files changed, 1 insertions(+), '
1048 '1 deletions(-)\n\n_____ . at refs/heads/master\n'
1049 'Attempting rebase onto refs/remotes/origin/master...\n')
maruel@chromium.orgcb2985f2010-11-03 14:08:31 +00001050 self.assertTrue(sys.stdout.getvalue().startswith(start))
1051 self.assertTrue(sys.stdout.getvalue().endswith(end))
1052 self.assertEquals(len(sys.stdout.getvalue()),
maruel@chromium.orgdd057f32010-09-20 19:33:31 +00001053 len(start) + len(end) + 7)
maruel@chromium.orgcb2985f2010-11-03 14:08:31 +00001054 sys.stdout.close()
msb@chromium.org5bde4852009-12-14 16:47:12 +00001055
msb@chromium.orge4af1ab2010-01-13 21:26:09 +00001056 def testUpdateNotGit(self):
1057 if not self.enabled:
1058 return
1059 options = self.Options()
1060 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1061 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001062 git_path = join(self.base_path, '.git')
maruel@chromium.orgba551772010-02-03 18:21:42 +00001063 rename(git_path, git_path + 'foo')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001064 exception = ('\n____ . at refs/heads/master\n'
1065 '\tPath is not a git repo. No .git dir.\n'
1066 '\tTo resolve:\n'
1067 '\t\trm -rf .\n'
1068 '\tAnd run gclient sync again\n')
msb@chromium.orge4af1ab2010-01-13 21:26:09 +00001069 self.assertRaisesError(exception, scm.update, options, (), [])
1070
msb@chromium.org0f282062009-11-06 20:14:02 +00001071 def testRevinfo(self):
1072 if not self.enabled:
1073 return
1074 options = self.Options()
1075 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1076 relpath=self.relpath)
1077 rev_info = scm.revinfo(options, (), None)
1078 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458')
1079
msb@chromium.orge28e4982009-09-25 20:51:45 +00001080
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001081class ManagedGitWrapperTestCaseMox(BaseTestCase):
1082 class OptionsObject(object):
1083 def __init__(self, verbose=False, revision=None, force=False):
1084 self.verbose = verbose
1085 self.revision = revision
1086 self.deps_os = None
1087 self.force = force
1088 self.reset = False
1089 self.nohooks = False
1090 # TODO(maruel): Test --jobs > 1.
1091 self.jobs = 1
1092
1093 def Options(self, *args, **kwargs):
1094 return self.OptionsObject(*args, **kwargs)
1095
1096 def setUp(self):
1097 BaseTestCase.setUp(self)
1098 self.fake_hash_1 = 't0ta11yf4k3'
1099 self.fake_hash_2 = '3v3nf4k3r'
1100 self.url = 'git://foo'
1101 self.root_dir = '/tmp'
1102 self.relpath = 'fake'
1103 self.base_path = os.path.join(self.root_dir, self.relpath)
1104
1105 def tearDown(self):
1106 BaseTestCase.tearDown(self)
1107
1108 def testGetUsableRevGit(self):
1109 # pylint: disable=E1101
1110 options = self.Options(verbose=True)
1111
1112 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True)
1113 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1
1114 ).AndReturn(True)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001115
1116 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
1117 gclient_scm.scm.GIT.IsGitSvn(cwd=self.base_path).MultipleTimes(
1118 ).AndReturn(False)
1119
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001120 gclient_scm.scm.os.path.isdir(self.base_path).AndReturn(True)
1121
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001122 self.mox.ReplayAll()
1123
1124 git_scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1125 relpath=self.relpath)
1126 # A [fake] git sha1 with a git repo should work (this is in the case that
1127 # the LKGR gets flipped to git sha1's some day).
1128 self.assertEquals(git_scm.GetUsableRev(self.fake_hash_1, options),
1129 self.fake_hash_1)
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001130 # An SVN rev with an existing purely git repo should raise an exception.
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001131 self.assertRaises(gclient_scm.gclient_utils.Error,
1132 git_scm.GetUsableRev, '1', options)
1133
1134 def testGetUsableRevGitSvn(self):
1135 # pylint: disable=E1101
1136 options = self.Options()
1137 too_big = str(1e7)
1138
1139 # Pretend like the git-svn repo's HEAD is at r2.
1140 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'GetGitSvnHeadRev', True)
1141 gclient_scm.scm.GIT.GetGitSvnHeadRev(cwd=self.base_path).MultipleTimes(
1142 ).AndReturn(2)
1143
1144 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'GetSha1ForSvnRev', True)
1145 # r1 -> first fake hash, r3 -> second fake hash.
1146 gclient_scm.scm.GIT.GetSha1ForSvnRev(cwd=self.base_path, rev='1'
1147 ).AndReturn(self.fake_hash_1)
1148 gclient_scm.scm.GIT.GetSha1ForSvnRev(cwd=self.base_path, rev='3'
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001149 ).MultipleTimes().AndReturn(self.fake_hash_2)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001150
1151 # Ensure that we call git svn fetch if our LKGR is > the git-svn HEAD rev.
1152 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'Capture', True)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001153 gclient_scm.scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
1154 cwd=self.base_path).AndReturn('blah')
1155 gclient_scm.scm.GIT.Capture(['fetch'], cwd=self.base_path)
1156 gclient_scm.scm.GIT.Capture(['svn', 'fetch'], cwd=self.base_path)
1157 error = subprocess2.CalledProcessError(1, 'cmd', '/cwd', 'stdout', 'stderr')
1158 gclient_scm.scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
1159 cwd=self.base_path).AndRaise(error)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001160 gclient_scm.scm.GIT.Capture(['svn', 'fetch'], cwd=self.base_path)
1161
1162 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
1163 gclient_scm.scm.GIT.IsGitSvn(cwd=self.base_path).MultipleTimes(
1164 ).AndReturn(True)
1165
1166 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True)
1167 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1
1168 ).AndReturn(True)
1169 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=too_big
1170 ).AndReturn(False)
1171
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001172 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
1173 gclient_scm.os.path.isdir(self.base_path).MultipleTimes().AndReturn(True)
1174
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001175 self.mox.ReplayAll()
1176
1177 git_svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
1178 relpath=self.relpath)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001179 # Without an existing checkout, this should fail.
1180 # TODO(dbeam) Fix this. http://crbug.com/109184
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001181 self.assertRaises(gclient_scm.gclient_utils.Error,
1182 git_svn_scm.GetUsableRev, '1', options)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001183 # Given an SVN revision with a git-svn checkout, it should be translated to
1184 # a git sha1 and be usable.
1185 self.assertEquals(git_svn_scm.GetUsableRev('1', options),
1186 self.fake_hash_1)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001187 # Our fake HEAD rev is r2, so this should call git fetch and git svn fetch
1188 # to get more revs (pymox will complain if this doesn't happen). We mock an
1189 # optimized checkout the first time, so this run should call git fetch.
1190 self.assertEquals(git_svn_scm.GetUsableRev('3', options),
1191 self.fake_hash_2)
1192 # The time we pretend we're not optimized, so no git fetch should fire.
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001193 self.assertEquals(git_svn_scm.GetUsableRev('3', options),
1194 self.fake_hash_2)
1195 # Given a git sha1 with a git-svn checkout, it should be used as is.
1196 self.assertEquals(git_svn_scm.GetUsableRev(self.fake_hash_1, options),
1197 self.fake_hash_1)
1198 # We currently check for seemingly valid SVN revisions by assuming 6 digit
1199 # numbers, so assure that numeric revs >= 1000000 don't work.
1200 self.assertRaises(gclient_scm.gclient_utils.Error,
1201 git_svn_scm.GetUsableRev, too_big, options)
1202
1203
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001204class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001205 def testUpdateUpdate(self):
1206 if not self.enabled:
1207 return
1208 options = self.Options()
1209 expected_file_list = []
1210 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1211 relpath=self.relpath)
1212 file_list = []
1213 options.revision = 'unmanaged'
1214 scm.update(options, (), file_list)
1215 self.assertEquals(file_list, expected_file_list)
1216 self.assertEquals(scm.revinfo(options, (), None),
1217 '069c602044c5388d2d15c3f875b057c852003458')
1218 self.checkstdout('________ unmanaged solution; skipping .\n')
1219
1220
msb@chromium.orge28e4982009-09-25 20:51:45 +00001221if __name__ == '__main__':
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001222 if '-v' in sys.argv:
1223 logging.basicConfig(
1224 level=logging.DEBUG,
1225 format='%(asctime).19s %(levelname)s %(filename)s:'
1226 '%(lineno)s %(message)s')
msb@chromium.orge28e4982009-09-25 20:51:45 +00001227 unittest.main()
1228
1229# vim: ts=2:sw=2:tw=80:et: