blob: bd49adde77be72e0ea0d815b14b8991c1a27a980 [file] [log] [blame]
msb@chromium.orge28e4982009-09-25 20:51:45 +00001#!/usr/bin/python
maruel@chromium.orgba551772010-02-03 18:21:42 +00002# Copyright (c) 2010 The Chromium Authors. All rights reserved.
3# 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.orgba551772010-02-03 18:21:42 +00008# Import before super_mox to keep valid references.
9from os import rename
10from shutil import rmtree
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000011from subprocess import Popen, PIPE, STDOUT
msb@chromium.orge28e4982009-09-25 20:51:45 +000012import tempfile
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +000013import __builtin__
msb@chromium.orge28e4982009-09-25 20:51:45 +000014
maruel@chromium.orgba551772010-02-03 18:21:42 +000015# Fixes include path.
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +000016from super_mox import mox, SuperMoxBaseTestBase, SuperMoxTestBase
maruel@chromium.orgba551772010-02-03 18:21:42 +000017
msb@chromium.orge28e4982009-09-25 20:51:45 +000018import gclient_scm
maruel@chromium.org96913eb2010-06-01 16:22:47 +000019
20
21class GCBaseTestCase(SuperMoxTestBase):
22 # Like unittest's assertRaises, but checks for Gclient.Error.
23 def assertRaisesError(self, msg, fn, *args, **kwargs):
24 try:
25 fn(*args, **kwargs)
26 except gclient_scm.gclient_utils.Error, e:
27 self.assertEquals(e.args[0], msg)
28 else:
29 self.fail('%s not raised' % msg)
msb@chromium.orge28e4982009-09-25 20:51:45 +000030
31
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000032class BaseTestCase(GCBaseTestCase):
33 def setUp(self):
34 GCBaseTestCase.setUp(self)
35 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'FileRead')
36 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'FileWrite')
37 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'SubprocessCall')
38 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'RemoveDirectory')
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +000039 self._CaptureSVNInfo = gclient_scm.scm.SVN.CaptureInfo
40 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Capture')
41 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'CaptureInfo')
42 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'CaptureStatus')
43 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Run')
44 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'RunAndGetFileList')
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000045 self._scm_wrapper = gclient_scm.CreateSCM
46
47
48class SVNWrapperTestCase(BaseTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +000049 class OptionsObject(object):
50 def __init__(self, test_case, verbose=False, revision=None):
51 self.verbose = verbose
52 self.revision = revision
53 self.manually_grab_svn_rev = True
54 self.deps_os = None
55 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +000056 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +000057 self.nohooks = False
58
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000059 def Options(self, *args, **kwargs):
60 return self.OptionsObject(self, *args, **kwargs)
61
msb@chromium.orge28e4982009-09-25 20:51:45 +000062 def setUp(self):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000063 BaseTestCase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +000064 self.root_dir = self.Dir()
65 self.args = self.Args()
66 self.url = self.Url()
67 self.relpath = 'asf'
68
69 def testDir(self):
70 members = [
tony@chromium.org99828122010-06-04 01:41:02 +000071 'AddAdditionalFlags', 'FullUrlForRelativeUrl', 'RunCommand',
maruel@chromium.org55e724e2010-03-11 19:36:49 +000072 'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert',
tony@chromium.org4b5b1772010-04-08 01:52:56 +000073 'revinfo', 'runhooks', 'scm_name', 'status', 'update',
74 'updatesingle', 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +000075 ]
76
77 # If you add a member, be sure to add the relevant test!
78 self.compareMembers(self._scm_wrapper(), members)
79
80 def testUnsupportedSCM(self):
81 args = [self.url, self.root_dir, self.relpath]
82 kwargs = {'scm_name' : 'foo'}
83 exception_msg = 'Unsupported scm %(scm_name)s' % kwargs
84 self.assertRaisesError(exception_msg, self._scm_wrapper, *args, **kwargs)
85
msb@chromium.orge6f78352010-01-13 17:05:33 +000086 def testSVNFullUrlForRelativeUrl(self):
87 self.url = 'svn://a/b/c/d'
88
89 self.mox.ReplayAll()
90 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
91 relpath=self.relpath)
92 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'svn://a/b/crap')
93
94 def testGITFullUrlForRelativeUrl(self):
95 self.url = 'git://a/b/c/d'
96
97 self.mox.ReplayAll()
98 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
99 relpath=self.relpath)
100 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'git://a/b/c/crap')
101
msb@chromium.orge28e4982009-09-25 20:51:45 +0000102 def testRunCommandException(self):
103 options = self.Options(verbose=False)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000104 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
105 gclient_scm.os.path.exists(file_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000106
107 self.mox.ReplayAll()
108 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
109 relpath=self.relpath)
110 exception = "Unsupported argument(s): %s" % ','.join(self.args)
111 self.assertRaisesError(exception, scm.RunCommand,
112 'update', options, self.args)
113
114 def testRunCommandUnknown(self):
115 # TODO(maruel): if ever used.
116 pass
117
118 def testRevertMissing(self):
119 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000120 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
121 gclient_scm.os.path.isdir(base_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000122 # It'll to a checkout instead.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000123 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
124 ).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000125 print("\n_____ %s is missing, synching instead" % self.relpath)
126 # Checkout.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000127 gclient_scm.os.path.exists(base_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000128 files_list = self.mox.CreateMockAnything()
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000129 gclient_scm.scm.SVN.RunAndGetFileList(options,
130 ['checkout', self.url, base_path],
131 self.root_dir, files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000132
133 self.mox.ReplayAll()
134 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
135 relpath=self.relpath)
136 scm.revert(options, self.args, files_list)
137
138 def testRevertNone(self):
139 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000140 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
141 gclient_scm.os.path.isdir(base_path).AndReturn(True)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000142 gclient_scm.scm.SVN.CaptureStatus(base_path).AndReturn([])
143 gclient_scm.scm.SVN.RunAndGetFileList(options,
144 ['update', '--revision', 'BASE'],
145 base_path, mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000146
147 self.mox.ReplayAll()
148 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
149 relpath=self.relpath)
150 file_list = []
151 scm.revert(options, self.args, file_list)
152
153 def testRevert2Files(self):
154 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000155 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
156 gclient_scm.os.path.isdir(base_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000157 items = [
158 ('M ', 'a'),
159 ('A ', 'b'),
160 ]
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000161 file_path1 = gclient_scm.os.path.join(base_path, 'a')
162 file_path2 = gclient_scm.os.path.join(base_path, 'b')
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000163 gclient_scm.scm.SVN.CaptureStatus(base_path).AndReturn(items)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000164 gclient_scm.os.path.exists(file_path1).AndReturn(True)
165 gclient_scm.os.path.isfile(file_path1).AndReturn(True)
166 gclient_scm.os.remove(file_path1)
167 gclient_scm.os.path.exists(file_path2).AndReturn(True)
168 gclient_scm.os.path.isfile(file_path2).AndReturn(True)
169 gclient_scm.os.remove(file_path2)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000170 gclient_scm.scm.SVN.RunAndGetFileList(options,
171 ['update', '--revision', 'BASE'],
172 base_path, mox.IgnoreArg())
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000173 print(gclient_scm.os.path.join(base_path, 'a'))
174 print(gclient_scm.os.path.join(base_path, 'b'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000175
176 self.mox.ReplayAll()
177 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
178 relpath=self.relpath)
179 file_list = []
180 scm.revert(options, self.args, file_list)
181
182 def testRevertDirectory(self):
183 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000184 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
185 gclient_scm.os.path.isdir(base_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000186 items = [
187 ('~ ', 'a'),
188 ]
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000189 gclient_scm.scm.SVN.CaptureStatus(base_path).AndReturn(items)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000190 file_path = gclient_scm.os.path.join(base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000191 print(file_path)
192 gclient_scm.os.path.exists(file_path).AndReturn(True)
193 gclient_scm.os.path.isfile(file_path).AndReturn(False)
msb@chromium.org32906d12010-01-12 18:22:09 +0000194 gclient_scm.os.path.islink(file_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000195 gclient_scm.os.path.isdir(file_path).AndReturn(True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000196 gclient_scm.gclient_utils.RemoveDirectory(file_path)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000197 file_list1 = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000198 gclient_scm.scm.SVN.RunAndGetFileList(options,
199 ['update', '--revision', 'BASE'],
200 base_path, mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000201
202 self.mox.ReplayAll()
203 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
204 relpath=self.relpath)
205 file_list2 = []
206 scm.revert(options, self.args, file_list2)
207
208 def testStatus(self):
209 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000210 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
211 gclient_scm.os.path.isdir(base_path).AndReturn(True)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000212 gclient_scm.scm.SVN.RunAndGetFileList(options,
213 ['status'] + self.args,
214 base_path, []).AndReturn(None)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000215
216 self.mox.ReplayAll()
217 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
218 relpath=self.relpath)
219 file_list = []
220 self.assertEqual(scm.status(options, self.args, file_list), None)
221
222
223 # TODO(maruel): TEST REVISIONS!!!
224 # TODO(maruel): TEST RELOCATE!!!
225 def testUpdateCheckout(self):
226 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000227 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
228 file_info = gclient_scm.gclient_utils.PrintableObject()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000229 file_info.root = 'blah'
230 file_info.url = self.url
231 file_info.uuid = 'ABC'
232 file_info.revision = 42
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000233 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
234 ).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000235 # Checkout.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000236 gclient_scm.os.path.exists(base_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000237 files_list = self.mox.CreateMockAnything()
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000238 gclient_scm.scm.SVN.RunAndGetFileList(options,
239 ['checkout', self.url, base_path],
240 self.root_dir, files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000241 self.mox.ReplayAll()
242 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
243 relpath=self.relpath)
244 scm.update(options, (), files_list)
245
246 def testUpdateUpdate(self):
247 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000248 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000249 options.force = True
250 options.nohooks = False
251 file_info = {
252 'Repository Root': 'blah',
253 'URL': self.url,
254 'UUID': 'ABC',
255 'Revision': 42,
256 }
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000257 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
258 ).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000259 # Checkout or update.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000260 gclient_scm.os.path.exists(base_path).AndReturn(True)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000261 gclient_scm.scm.SVN.CaptureInfo(
262 gclient_scm.os.path.join(base_path, "."), '.'
263 ).AndReturn(file_info)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000264 # Cheat a bit here.
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000265 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000266 additional_args = []
267 if options.manually_grab_svn_rev:
268 additional_args = ['--revision', str(file_info['Revision'])]
tony@chromium.org99828122010-06-04 01:41:02 +0000269 if options.force and gclient_scm.scm.SVN.AssertVersion("1.5")[0]:
270 additional_args.append('--force')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000271 files_list = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000272 gclient_scm.scm.SVN.RunAndGetFileList(
273 options,
274 ['update', base_path] + additional_args,
275 self.root_dir, files_list)
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 scm.update(options, (), files_list)
281
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000282 def testUpdateSingleCheckout(self):
283 options = self.Options(verbose=True)
284 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
285 file_info = {
286 'URL': self.url,
287 'Revision': 42,
288 }
tony@chromium.org57564662010-04-14 02:35:12 +0000289
290 # Checks to make sure that we support svn co --depth.
291 gclient_scm.scm.SVN.current_version = None
292 gclient_scm.scm.SVN.Capture(['--version']
293 ).AndReturn('svn, version 1.5.1 (r32289)')
294 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.svn')
295 ).AndReturn(False)
296 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, 'DEPS')
297 ).AndReturn(False)
298
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000299 # When checking out a single file, we issue an svn checkout and svn update.
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000300 files_list = self.mox.CreateMockAnything()
301 gclient_scm.scm.SVN.Run(
302 ['checkout', '--depth', 'empty', self.url, base_path], self.root_dir)
303 gclient_scm.scm.SVN.RunAndGetFileList(options, ['update', 'DEPS'],
304 gclient_scm.os.path.join(self.root_dir, self.relpath), files_list)
305
306 # Now we fall back on scm.update().
307 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
tony@chromium.org57564662010-04-14 02:35:12 +0000308 ).AndReturn(False)
309 gclient_scm.os.path.exists(base_path).AndReturn(True)
310 gclient_scm.scm.SVN.CaptureInfo(
311 gclient_scm.os.path.join(base_path, "."), '.'
312 ).AndReturn(file_info)
313 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
314 print("\n_____ %s at 42" % self.relpath)
315
316 self.mox.ReplayAll()
317 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
318 relpath=self.relpath)
319 scm.updatesingle(options, ['DEPS'], files_list)
320
321 def testUpdateSingleCheckoutSVN14(self):
322 options = self.Options(verbose=True)
323 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
324 file_info = {
325 'URL': self.url,
326 'Revision': 42,
327 }
328
329 # Checks to make sure that we support svn co --depth.
330 gclient_scm.scm.SVN.current_version = None
331 gclient_scm.scm.SVN.Capture(['--version']
332 ).AndReturn('svn, version 1.4.4 (r25188)')
333 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path)
334 ).AndReturn(True)
335
336 # When checking out a single file with svn 1.4, we use svn export
337 files_list = self.mox.CreateMockAnything()
338 gclient_scm.scm.SVN.Run(
339 ['export', gclient_scm.os.path.join(self.url, 'DEPS'),
340 gclient_scm.os.path.join(base_path, 'DEPS')], self.root_dir)
341
342 self.mox.ReplayAll()
343 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
344 relpath=self.relpath)
345 scm.updatesingle(options, ['DEPS'], files_list)
346
347 def testUpdateSingleCheckoutSVNUpgrade(self):
348 options = self.Options(verbose=True)
349 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
350 file_info = {
351 'URL': self.url,
352 'Revision': 42,
353 }
354
355 # Checks to make sure that we support svn co --depth.
356 gclient_scm.scm.SVN.current_version = None
357 gclient_scm.scm.SVN.Capture(['--version']
358 ).AndReturn('svn, version 1.5.1 (r32289)')
359 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.svn')
360 ).AndReturn(False)
361 # If DEPS already exists, assume we're upgrading from svn1.4, so delete
362 # the old DEPS file.
363 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, 'DEPS')
364 ).AndReturn(True)
365 gclient_scm.os.remove(gclient_scm.os.path.join(base_path, 'DEPS'))
366
367 # When checking out a single file, we issue an svn checkout and svn update.
368 files_list = self.mox.CreateMockAnything()
369 gclient_scm.scm.SVN.Run(
370 ['checkout', '--depth', 'empty', self.url, base_path], self.root_dir)
371 gclient_scm.scm.SVN.RunAndGetFileList(options, ['update', 'DEPS'],
372 gclient_scm.os.path.join(self.root_dir, self.relpath), files_list)
373
374 # Now we fall back on scm.update().
375 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
376 ).AndReturn(False)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000377 gclient_scm.os.path.exists(base_path).AndReturn(True)
378 gclient_scm.scm.SVN.CaptureInfo(
379 gclient_scm.os.path.join(base_path, "."), '.'
380 ).AndReturn(file_info)
381 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
382 print("\n_____ %s at 42" % self.relpath)
383
384 self.mox.ReplayAll()
385 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
386 relpath=self.relpath)
387 scm.updatesingle(options, ['DEPS'], files_list)
388
389 def testUpdateSingleUpdate(self):
390 options = self.Options(verbose=True)
391 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
392 file_info = {
393 'URL': self.url,
394 'Revision': 42,
395 }
tony@chromium.org57564662010-04-14 02:35:12 +0000396 # Checks to make sure that we support svn co --depth.
397 gclient_scm.scm.SVN.current_version = None
398 gclient_scm.scm.SVN.Capture(['--version']
399 ).AndReturn('svn, version 1.5.1 (r32289)')
400 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.svn')
401 ).AndReturn(True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000402
403 # Now we fall back on scm.update().
404 files_list = self.mox.CreateMockAnything()
405 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
406 ).AndReturn(False)
407 gclient_scm.os.path.exists(base_path).AndReturn(True)
408 gclient_scm.scm.SVN.CaptureInfo(
409 gclient_scm.os.path.join(base_path, "."), '.'
410 ).AndReturn(file_info)
411 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
412 print("\n_____ %s at 42" % self.relpath)
413
414 self.mox.ReplayAll()
415 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
416 relpath=self.relpath)
417 scm.updatesingle(options, ['DEPS'], files_list)
418
msb@chromium.orge28e4982009-09-25 20:51:45 +0000419 def testUpdateGit(self):
420 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000421 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
422 gclient_scm.os.path.exists(file_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000423 print("________ found .git directory; skipping %s" % self.relpath)
424
425 self.mox.ReplayAll()
426 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
427 relpath=self.relpath)
428 file_list = []
429 scm.update(options, self.args, file_list)
430
msb@chromium.orge28e4982009-09-25 20:51:45 +0000431
msb@chromium.org5bde4852009-12-14 16:47:12 +0000432class GitWrapperTestCase(BaseTestCase):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000433 """This class doesn't use pymox."""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000434 class OptionsObject(object):
435 def __init__(self, test_case, verbose=False, revision=None):
436 self.verbose = verbose
437 self.revision = revision
438 self.manually_grab_svn_rev = True
439 self.deps_os = None
440 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +0000441 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000442 self.nohooks = False
443
444 sample_git_import = """blob
445mark :1
446data 6
447Hello
448
449blob
450mark :2
451data 4
452Bye
453
454reset refs/heads/master
455commit refs/heads/master
456mark :3
457author Bob <bob@example.com> 1253744361 -0700
458committer Bob <bob@example.com> 1253744361 -0700
459data 8
460A and B
461M 100644 :1 a
462M 100644 :2 b
463
464blob
465mark :4
466data 10
467Hello
468You
469
470blob
471mark :5
472data 8
473Bye
474You
475
476commit refs/heads/origin
477mark :6
478author Alice <alice@example.com> 1253744424 -0700
479committer Alice <alice@example.com> 1253744424 -0700
480data 13
481Personalized
482from :3
483M 100644 :4 a
484M 100644 :5 b
485
486reset refs/heads/master
487from :3
488"""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000489 def Options(self, *args, **kwargs):
490 return self.OptionsObject(self, *args, **kwargs)
491
492 def CreateGitRepo(self, git_import, path):
maruel@chromium.orgd5800f12009-11-12 20:03:43 +0000493 """Do it for real."""
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000494 try:
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000495 Popen(['git', 'init'], stdout=PIPE, stderr=STDOUT,
496 cwd=path).communicate()
497 except OSError:
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000498 # git is not available, skip this test.
499 return False
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000500 Popen(['git', 'fast-import'], stdin=PIPE, stdout=PIPE, stderr=STDOUT,
501 cwd=path).communicate(input=git_import)
502 Popen(['git', 'checkout'], stdout=PIPE, stderr=STDOUT,
503 cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000504 Popen(['git', 'remote', 'add', '-f', 'origin', '.'], stdout=PIPE,
505 stderr=STDOUT, cwd=path).communicate()
506 Popen(['git', 'checkout', '-b', 'new', 'origin/master'], stdout=PIPE,
507 stderr=STDOUT, cwd=path).communicate()
508 Popen(['git', 'push', 'origin', 'origin/origin:origin/master'], stdout=PIPE,
509 stderr=STDOUT, cwd=path).communicate()
510 Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE,
511 stderr=STDOUT, cwd=path).communicate()
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000512 return True
msb@chromium.orge28e4982009-09-25 20:51:45 +0000513
msb@chromium.orge28e4982009-09-25 20:51:45 +0000514 def setUp(self):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000515 self.args = self.Args()
516 self.url = 'git://foo'
517 self.root_dir = tempfile.mkdtemp()
518 self.relpath = '.'
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000519 self.base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000520 self.enabled = self.CreateGitRepo(self.sample_git_import, self.base_path)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000521 SuperMoxBaseTestBase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000522
523 def tearDown(self):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000524 SuperMoxBaseTestBase.tearDown(self)
maruel@chromium.orgba551772010-02-03 18:21:42 +0000525 rmtree(self.root_dir)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000526
527 def testDir(self):
528 members = [
maruel@chromium.org55e724e2010-03-11 19:36:49 +0000529 'FullUrlForRelativeUrl', 'RunCommand',
msb@chromium.orge6f78352010-01-13 17:05:33 +0000530 'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert',
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000531 'revinfo', 'runhooks', 'scm_name', 'status', 'update', 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +0000532 ]
533
534 # If you add a member, be sure to add the relevant test!
535 self.compareMembers(gclient_scm.CreateSCM(url=self.url), members)
536
537 def testRevertMissing(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000538 if not self.enabled:
539 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000540 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000541 file_path = gclient_scm.os.path.join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000542 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
543 relpath=self.relpath)
544 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000545 scm.update(options, None, file_list)
546 gclient_scm.os.remove(file_path)
547 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000548 scm.revert(options, self.args, file_list)
549 self.assertEquals(file_list, [file_path])
550 file_list = []
551 scm.diff(options, self.args, file_list)
552 self.assertEquals(file_list, [])
553
554 def testRevertNone(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000555 if not self.enabled:
556 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000557 options = self.Options()
558 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
559 relpath=self.relpath)
560 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000561 scm.update(options, None, file_list)
562 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000563 scm.revert(options, self.args, file_list)
564 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000565 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000566 'a7142dc9f0009350b96a11f372b6ea658592aa95')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000567
568
569 def testRevertModified(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000570 if not self.enabled:
571 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000572 options = self.Options()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000573 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
574 relpath=self.relpath)
575 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000576 scm.update(options, None, file_list)
577 file_path = gclient_scm.os.path.join(self.base_path, 'a')
578 open(file_path, 'a').writelines('touched\n')
579 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000580 scm.revert(options, self.args, file_list)
581 self.assertEquals(file_list, [file_path])
582 file_list = []
583 scm.diff(options, self.args, file_list)
584 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000585 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000586 'a7142dc9f0009350b96a11f372b6ea658592aa95')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000587
588 def testRevertNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000589 if not self.enabled:
590 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000591 options = self.Options()
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000592 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
593 relpath=self.relpath)
594 file_list = []
595 scm.update(options, None, file_list)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000596 file_path = gclient_scm.os.path.join(self.base_path, 'c')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000597 f = open(file_path, 'w')
598 f.writelines('new\n')
599 f.close()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000600 Popen(['git', 'add', 'c'], stdout=PIPE,
601 stderr=STDOUT, cwd=self.base_path).communicate()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000602 file_list = []
603 scm.revert(options, self.args, file_list)
604 self.assertEquals(file_list, [file_path])
605 file_list = []
606 scm.diff(options, self.args, file_list)
607 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000608 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000609 'a7142dc9f0009350b96a11f372b6ea658592aa95')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000610
611 def testStatusNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000612 if not self.enabled:
613 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000614 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000615 file_path = gclient_scm.os.path.join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000616 open(file_path, 'a').writelines('touched\n')
617 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
618 relpath=self.relpath)
619 file_list = []
620 scm.status(options, self.args, file_list)
621 self.assertEquals(file_list, [file_path])
622
623 def testStatus2New(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000624 if not self.enabled:
625 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000626 options = self.Options()
627 expected_file_list = []
628 for f in ['a', 'b']:
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000629 file_path = gclient_scm.os.path.join(self.base_path, f)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000630 open(file_path, 'a').writelines('touched\n')
631 expected_file_list.extend([file_path])
632 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
633 relpath=self.relpath)
634 file_list = []
635 scm.status(options, self.args, file_list)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000636 expected_file_list = [gclient_scm.os.path.join(self.base_path, x)
637 for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000638 self.assertEquals(sorted(file_list), expected_file_list)
639
640 def testUpdateCheckout(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000641 if not self.enabled:
642 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000643 options = self.Options(verbose=True)
644 root_dir = tempfile.mkdtemp()
645 relpath = 'foo'
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000646 base_path = gclient_scm.os.path.join(root_dir, relpath)
647 url = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000648 try:
649 scm = gclient_scm.CreateSCM(url=url, root_dir=root_dir,
650 relpath=relpath)
651 file_list = []
652 scm.update(options, (), file_list)
653 self.assertEquals(len(file_list), 2)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000654 self.assert_(gclient_scm.os.path.isfile(
655 gclient_scm.os.path.join(base_path, 'a')))
msb@chromium.org0f282062009-11-06 20:14:02 +0000656 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000657 '069c602044c5388d2d15c3f875b057c852003458')
658 finally:
maruel@chromium.orgba551772010-02-03 18:21:42 +0000659 rmtree(root_dir)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000660
661 def testUpdateUpdate(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000662 if not self.enabled:
663 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000664 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000665 expected_file_list = [gclient_scm.os.path.join(self.base_path, x)
666 for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000667 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
668 relpath=self.relpath)
669 file_list = []
670 scm.update(options, (), file_list)
msb@chromium.org0f282062009-11-06 20:14:02 +0000671 self.assertEquals(file_list, expected_file_list)
672 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000673 'a7142dc9f0009350b96a11f372b6ea658592aa95')
674
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000675 def testUpdateUnstagedConflict(self):
676 if not self.enabled:
677 return
678 options = self.Options()
679 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
680 relpath=self.relpath)
681 file_path = gclient_scm.os.path.join(self.base_path, 'b')
682 f = open(file_path, 'w').writelines('conflict\n')
683 exception = (
684 "error: Your local changes to 'b' would be overwritten by merge. "
685 "Aborting.\n"
686 "Please, commit your changes or stash them before you can merge.\n")
687 self.assertRaisesError(exception, scm.update, options, (), [])
688
msb@chromium.org5bde4852009-12-14 16:47:12 +0000689 def testUpdateConflict(self):
690 if not self.enabled:
691 return
692 options = self.Options()
693 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
694 relpath=self.relpath)
695 file_path = gclient_scm.os.path.join(self.base_path, 'b')
696 f = open(file_path, 'w').writelines('conflict\n')
697 scm._Run(['commit', '-am', 'test'])
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000698 self.mox.StubOutWithMock(__builtin__, 'raw_input')
699 __builtin__.raw_input.__call__(mox.StrContains('Cannot fast-forward merge, '
700 'attempt to rebase? (y)es / '
701 '(q)uit / (s)kip : ')
702 ).AndReturn('y')
703 self.mox.ReplayAll()
msb@chromium.org5bde4852009-12-14 16:47:12 +0000704 exception = \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000705 'Conflict while rebasing this branch.\n' \
msb@chromium.org5bde4852009-12-14 16:47:12 +0000706 'Fix the conflict and run gclient again.\n' \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000707 "See 'man git-rebase' for details.\n"
msb@chromium.org5bde4852009-12-14 16:47:12 +0000708 self.assertRaisesError(exception, scm.update, options, (), [])
709 exception = \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000710 '\n____ . at refs/heads/master\n' \
msb@chromium.org786fb682010-06-02 15:16:23 +0000711 '\tYou have unstaged changes.\n' \
712 '\tPlease commit, stash, or reset.\n'
msb@chromium.org5bde4852009-12-14 16:47:12 +0000713 self.assertRaisesError(exception, scm.update, options, (), [])
714
msb@chromium.orge4af1ab2010-01-13 21:26:09 +0000715 def testUpdateNotGit(self):
716 if not self.enabled:
717 return
718 options = self.Options()
719 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
720 relpath=self.relpath)
721 git_path = gclient_scm.os.path.join(self.base_path, '.git')
maruel@chromium.orgba551772010-02-03 18:21:42 +0000722 rename(git_path, git_path + 'foo')
msb@chromium.orge4af1ab2010-01-13 21:26:09 +0000723 exception = \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000724 '\n____ . at refs/heads/master\n' \
msb@chromium.orge4af1ab2010-01-13 21:26:09 +0000725 '\tPath is not a git repo. No .git dir.\n' \
726 '\tTo resolve:\n' \
727 '\t\trm -rf .\n' \
728 '\tAnd run gclient sync again\n'
729 self.assertRaisesError(exception, scm.update, options, (), [])
730
msb@chromium.org0f282062009-11-06 20:14:02 +0000731 def testRevinfo(self):
732 if not self.enabled:
733 return
734 options = self.Options()
735 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
736 relpath=self.relpath)
737 rev_info = scm.revinfo(options, (), None)
738 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458')
739
msb@chromium.orge28e4982009-09-25 20:51:45 +0000740
msb@chromium.orge28e4982009-09-25 20:51:45 +0000741if __name__ == '__main__':
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000742 import unittest
msb@chromium.orge28e4982009-09-25 20:51:45 +0000743 unittest.main()
744
745# vim: ts=2:sw=2:tw=80:et: