blob: fb2ea42e70f6303f6cac3d90054b699e25aab35a [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.org8ef5f542009-11-12 02:05:02 +000019from gclient_test import BaseTestCase as GCBaseTestCase
msb@chromium.orge28e4982009-09-25 20:51:45 +000020
21
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000022class BaseTestCase(GCBaseTestCase):
23 def setUp(self):
24 GCBaseTestCase.setUp(self)
25 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'FileRead')
26 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'FileWrite')
27 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'SubprocessCall')
28 self.mox.StubOutWithMock(gclient_scm.gclient_utils, 'RemoveDirectory')
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +000029 self._CaptureSVNInfo = gclient_scm.scm.SVN.CaptureInfo
30 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Capture')
31 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'CaptureInfo')
32 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'CaptureStatus')
33 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'Run')
34 self.mox.StubOutWithMock(gclient_scm.scm.SVN, 'RunAndGetFileList')
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000035 self._scm_wrapper = gclient_scm.CreateSCM
36
37
38class SVNWrapperTestCase(BaseTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +000039 class OptionsObject(object):
40 def __init__(self, test_case, verbose=False, revision=None):
41 self.verbose = verbose
42 self.revision = revision
43 self.manually_grab_svn_rev = True
44 self.deps_os = None
45 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +000046 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +000047 self.nohooks = False
48
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000049 def Options(self, *args, **kwargs):
50 return self.OptionsObject(self, *args, **kwargs)
51
msb@chromium.orge28e4982009-09-25 20:51:45 +000052 def setUp(self):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000053 BaseTestCase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +000054 self.root_dir = self.Dir()
55 self.args = self.Args()
56 self.url = self.Url()
57 self.relpath = 'asf'
58
59 def testDir(self):
60 members = [
maruel@chromium.org55e724e2010-03-11 19:36:49 +000061 'FullUrlForRelativeUrl', 'RunCommand',
62 'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert',
tony@chromium.org4b5b1772010-04-08 01:52:56 +000063 'revinfo', 'runhooks', 'scm_name', 'status', 'update',
64 'updatesingle', 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +000065 ]
66
67 # If you add a member, be sure to add the relevant test!
68 self.compareMembers(self._scm_wrapper(), members)
69
70 def testUnsupportedSCM(self):
71 args = [self.url, self.root_dir, self.relpath]
72 kwargs = {'scm_name' : 'foo'}
73 exception_msg = 'Unsupported scm %(scm_name)s' % kwargs
74 self.assertRaisesError(exception_msg, self._scm_wrapper, *args, **kwargs)
75
msb@chromium.orge6f78352010-01-13 17:05:33 +000076 def testSVNFullUrlForRelativeUrl(self):
77 self.url = 'svn://a/b/c/d'
78
79 self.mox.ReplayAll()
80 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
81 relpath=self.relpath)
82 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'svn://a/b/crap')
83
84 def testGITFullUrlForRelativeUrl(self):
85 self.url = 'git://a/b/c/d'
86
87 self.mox.ReplayAll()
88 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
89 relpath=self.relpath)
90 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'git://a/b/c/crap')
91
msb@chromium.orge28e4982009-09-25 20:51:45 +000092 def testRunCommandException(self):
93 options = self.Options(verbose=False)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000094 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
95 gclient_scm.os.path.exists(file_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +000096
97 self.mox.ReplayAll()
98 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
99 relpath=self.relpath)
100 exception = "Unsupported argument(s): %s" % ','.join(self.args)
101 self.assertRaisesError(exception, scm.RunCommand,
102 'update', options, self.args)
103
104 def testRunCommandUnknown(self):
105 # TODO(maruel): if ever used.
106 pass
107
108 def testRevertMissing(self):
109 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000110 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
111 gclient_scm.os.path.isdir(base_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000112 # It'll to a checkout instead.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000113 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
114 ).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000115 print("\n_____ %s is missing, synching instead" % self.relpath)
116 # Checkout.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000117 gclient_scm.os.path.exists(base_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000118 files_list = self.mox.CreateMockAnything()
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000119 gclient_scm.scm.SVN.RunAndGetFileList(options,
120 ['checkout', self.url, base_path],
121 self.root_dir, files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000122
123 self.mox.ReplayAll()
124 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
125 relpath=self.relpath)
126 scm.revert(options, self.args, files_list)
127
128 def testRevertNone(self):
129 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000130 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
131 gclient_scm.os.path.isdir(base_path).AndReturn(True)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000132 gclient_scm.scm.SVN.CaptureStatus(base_path).AndReturn([])
133 gclient_scm.scm.SVN.RunAndGetFileList(options,
134 ['update', '--revision', 'BASE'],
135 base_path, mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000136
137 self.mox.ReplayAll()
138 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
139 relpath=self.relpath)
140 file_list = []
141 scm.revert(options, self.args, file_list)
142
143 def testRevert2Files(self):
144 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000145 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
146 gclient_scm.os.path.isdir(base_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000147 items = [
148 ('M ', 'a'),
149 ('A ', 'b'),
150 ]
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000151 file_path1 = gclient_scm.os.path.join(base_path, 'a')
152 file_path2 = gclient_scm.os.path.join(base_path, 'b')
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000153 gclient_scm.scm.SVN.CaptureStatus(base_path).AndReturn(items)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000154 gclient_scm.os.path.exists(file_path1).AndReturn(True)
155 gclient_scm.os.path.isfile(file_path1).AndReturn(True)
156 gclient_scm.os.remove(file_path1)
157 gclient_scm.os.path.exists(file_path2).AndReturn(True)
158 gclient_scm.os.path.isfile(file_path2).AndReturn(True)
159 gclient_scm.os.remove(file_path2)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000160 gclient_scm.scm.SVN.RunAndGetFileList(options,
161 ['update', '--revision', 'BASE'],
162 base_path, mox.IgnoreArg())
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000163 print(gclient_scm.os.path.join(base_path, 'a'))
164 print(gclient_scm.os.path.join(base_path, 'b'))
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 file_list = []
170 scm.revert(options, self.args, file_list)
171
172 def testRevertDirectory(self):
173 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000174 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
175 gclient_scm.os.path.isdir(base_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000176 items = [
177 ('~ ', 'a'),
178 ]
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000179 gclient_scm.scm.SVN.CaptureStatus(base_path).AndReturn(items)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000180 file_path = gclient_scm.os.path.join(base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000181 print(file_path)
182 gclient_scm.os.path.exists(file_path).AndReturn(True)
183 gclient_scm.os.path.isfile(file_path).AndReturn(False)
msb@chromium.org32906d12010-01-12 18:22:09 +0000184 gclient_scm.os.path.islink(file_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000185 gclient_scm.os.path.isdir(file_path).AndReturn(True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000186 gclient_scm.gclient_utils.RemoveDirectory(file_path)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000187 file_list1 = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000188 gclient_scm.scm.SVN.RunAndGetFileList(options,
189 ['update', '--revision', 'BASE'],
190 base_path, mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000191
192 self.mox.ReplayAll()
193 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
194 relpath=self.relpath)
195 file_list2 = []
196 scm.revert(options, self.args, file_list2)
197
198 def testStatus(self):
199 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000200 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
201 gclient_scm.os.path.isdir(base_path).AndReturn(True)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000202 gclient_scm.scm.SVN.RunAndGetFileList(options,
203 ['status'] + self.args,
204 base_path, []).AndReturn(None)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000205
206 self.mox.ReplayAll()
207 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
208 relpath=self.relpath)
209 file_list = []
210 self.assertEqual(scm.status(options, self.args, file_list), None)
211
212
213 # TODO(maruel): TEST REVISIONS!!!
214 # TODO(maruel): TEST RELOCATE!!!
215 def testUpdateCheckout(self):
216 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000217 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
218 file_info = gclient_scm.gclient_utils.PrintableObject()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000219 file_info.root = 'blah'
220 file_info.url = self.url
221 file_info.uuid = 'ABC'
222 file_info.revision = 42
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000223 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
224 ).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000225 # Checkout.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000226 gclient_scm.os.path.exists(base_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000227 files_list = self.mox.CreateMockAnything()
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000228 gclient_scm.scm.SVN.RunAndGetFileList(options,
229 ['checkout', self.url, base_path],
230 self.root_dir, files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000231 self.mox.ReplayAll()
232 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
233 relpath=self.relpath)
234 scm.update(options, (), files_list)
235
236 def testUpdateUpdate(self):
237 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000238 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000239 options.force = True
240 options.nohooks = False
241 file_info = {
242 'Repository Root': 'blah',
243 'URL': self.url,
244 'UUID': 'ABC',
245 'Revision': 42,
246 }
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000247 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
248 ).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000249 # Checkout or update.
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000250 gclient_scm.os.path.exists(base_path).AndReturn(True)
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000251 gclient_scm.scm.SVN.CaptureInfo(
252 gclient_scm.os.path.join(base_path, "."), '.'
253 ).AndReturn(file_info)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000254 # Cheat a bit here.
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000255 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000256 additional_args = []
257 if options.manually_grab_svn_rev:
258 additional_args = ['--revision', str(file_info['Revision'])]
259 files_list = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000260 gclient_scm.scm.SVN.RunAndGetFileList(
261 options,
262 ['update', base_path] + additional_args,
263 self.root_dir, files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000264
265 self.mox.ReplayAll()
266 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
267 relpath=self.relpath)
268 scm.update(options, (), files_list)
269
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000270 def testUpdateSingleCheckout(self):
271 options = self.Options(verbose=True)
272 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
273 file_info = {
274 'URL': self.url,
275 'Revision': 42,
276 }
tony@chromium.org57564662010-04-14 02:35:12 +0000277
278 # Checks to make sure that we support svn co --depth.
279 gclient_scm.scm.SVN.current_version = None
280 gclient_scm.scm.SVN.Capture(['--version']
281 ).AndReturn('svn, version 1.5.1 (r32289)')
282 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.svn')
283 ).AndReturn(False)
284 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, 'DEPS')
285 ).AndReturn(False)
286
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000287 # When checking out a single file, we issue an svn checkout and svn update.
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000288 files_list = self.mox.CreateMockAnything()
289 gclient_scm.scm.SVN.Run(
290 ['checkout', '--depth', 'empty', self.url, base_path], self.root_dir)
291 gclient_scm.scm.SVN.RunAndGetFileList(options, ['update', 'DEPS'],
292 gclient_scm.os.path.join(self.root_dir, self.relpath), files_list)
293
294 # Now we fall back on scm.update().
295 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
tony@chromium.org57564662010-04-14 02:35:12 +0000296 ).AndReturn(False)
297 gclient_scm.os.path.exists(base_path).AndReturn(True)
298 gclient_scm.scm.SVN.CaptureInfo(
299 gclient_scm.os.path.join(base_path, "."), '.'
300 ).AndReturn(file_info)
301 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
302 print("\n_____ %s at 42" % self.relpath)
303
304 self.mox.ReplayAll()
305 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
306 relpath=self.relpath)
307 scm.updatesingle(options, ['DEPS'], files_list)
308
309 def testUpdateSingleCheckoutSVN14(self):
310 options = self.Options(verbose=True)
311 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
312 file_info = {
313 'URL': self.url,
314 'Revision': 42,
315 }
316
317 # Checks to make sure that we support svn co --depth.
318 gclient_scm.scm.SVN.current_version = None
319 gclient_scm.scm.SVN.Capture(['--version']
320 ).AndReturn('svn, version 1.4.4 (r25188)')
321 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path)
322 ).AndReturn(True)
323
324 # When checking out a single file with svn 1.4, we use svn export
325 files_list = self.mox.CreateMockAnything()
326 gclient_scm.scm.SVN.Run(
327 ['export', gclient_scm.os.path.join(self.url, 'DEPS'),
328 gclient_scm.os.path.join(base_path, 'DEPS')], self.root_dir)
329
330 self.mox.ReplayAll()
331 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
332 relpath=self.relpath)
333 scm.updatesingle(options, ['DEPS'], files_list)
334
335 def testUpdateSingleCheckoutSVNUpgrade(self):
336 options = self.Options(verbose=True)
337 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
338 file_info = {
339 'URL': self.url,
340 'Revision': 42,
341 }
342
343 # Checks to make sure that we support svn co --depth.
344 gclient_scm.scm.SVN.current_version = None
345 gclient_scm.scm.SVN.Capture(['--version']
346 ).AndReturn('svn, version 1.5.1 (r32289)')
347 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.svn')
348 ).AndReturn(False)
349 # If DEPS already exists, assume we're upgrading from svn1.4, so delete
350 # the old DEPS file.
351 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, 'DEPS')
352 ).AndReturn(True)
353 gclient_scm.os.remove(gclient_scm.os.path.join(base_path, 'DEPS'))
354
355 # When checking out a single file, we issue an svn checkout and svn update.
356 files_list = self.mox.CreateMockAnything()
357 gclient_scm.scm.SVN.Run(
358 ['checkout', '--depth', 'empty', self.url, base_path], self.root_dir)
359 gclient_scm.scm.SVN.RunAndGetFileList(options, ['update', 'DEPS'],
360 gclient_scm.os.path.join(self.root_dir, self.relpath), files_list)
361
362 # Now we fall back on scm.update().
363 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
364 ).AndReturn(False)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000365 gclient_scm.os.path.exists(base_path).AndReturn(True)
366 gclient_scm.scm.SVN.CaptureInfo(
367 gclient_scm.os.path.join(base_path, "."), '.'
368 ).AndReturn(file_info)
369 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
370 print("\n_____ %s at 42" % self.relpath)
371
372 self.mox.ReplayAll()
373 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
374 relpath=self.relpath)
375 scm.updatesingle(options, ['DEPS'], files_list)
376
377 def testUpdateSingleUpdate(self):
378 options = self.Options(verbose=True)
379 base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
380 file_info = {
381 'URL': self.url,
382 'Revision': 42,
383 }
tony@chromium.org57564662010-04-14 02:35:12 +0000384 # Checks to make sure that we support svn co --depth.
385 gclient_scm.scm.SVN.current_version = None
386 gclient_scm.scm.SVN.Capture(['--version']
387 ).AndReturn('svn, version 1.5.1 (r32289)')
388 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.svn')
389 ).AndReturn(True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000390
391 # Now we fall back on scm.update().
392 files_list = self.mox.CreateMockAnything()
393 gclient_scm.os.path.exists(gclient_scm.os.path.join(base_path, '.git')
394 ).AndReturn(False)
395 gclient_scm.os.path.exists(base_path).AndReturn(True)
396 gclient_scm.scm.SVN.CaptureInfo(
397 gclient_scm.os.path.join(base_path, "."), '.'
398 ).AndReturn(file_info)
399 gclient_scm.scm.SVN.CaptureInfo(file_info['URL'], '.').AndReturn(file_info)
400 print("\n_____ %s at 42" % self.relpath)
401
402 self.mox.ReplayAll()
403 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
404 relpath=self.relpath)
405 scm.updatesingle(options, ['DEPS'], files_list)
406
msb@chromium.orge28e4982009-09-25 20:51:45 +0000407 def testUpdateGit(self):
408 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000409 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
410 gclient_scm.os.path.exists(file_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000411 print("________ found .git directory; skipping %s" % self.relpath)
412
413 self.mox.ReplayAll()
414 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
415 relpath=self.relpath)
416 file_list = []
417 scm.update(options, self.args, file_list)
418
msb@chromium.orge28e4982009-09-25 20:51:45 +0000419
msb@chromium.org5bde4852009-12-14 16:47:12 +0000420class GitWrapperTestCase(BaseTestCase):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000421 """This class doesn't use pymox."""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000422 class OptionsObject(object):
423 def __init__(self, test_case, verbose=False, revision=None):
424 self.verbose = verbose
425 self.revision = revision
426 self.manually_grab_svn_rev = True
427 self.deps_os = None
428 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +0000429 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000430 self.nohooks = False
431
432 sample_git_import = """blob
433mark :1
434data 6
435Hello
436
437blob
438mark :2
439data 4
440Bye
441
442reset refs/heads/master
443commit refs/heads/master
444mark :3
445author Bob <bob@example.com> 1253744361 -0700
446committer Bob <bob@example.com> 1253744361 -0700
447data 8
448A and B
449M 100644 :1 a
450M 100644 :2 b
451
452blob
453mark :4
454data 10
455Hello
456You
457
458blob
459mark :5
460data 8
461Bye
462You
463
464commit refs/heads/origin
465mark :6
466author Alice <alice@example.com> 1253744424 -0700
467committer Alice <alice@example.com> 1253744424 -0700
468data 13
469Personalized
470from :3
471M 100644 :4 a
472M 100644 :5 b
473
474reset refs/heads/master
475from :3
476"""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000477 def Options(self, *args, **kwargs):
478 return self.OptionsObject(self, *args, **kwargs)
479
480 def CreateGitRepo(self, git_import, path):
maruel@chromium.orgd5800f12009-11-12 20:03:43 +0000481 """Do it for real."""
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000482 try:
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000483 Popen(['git', 'init'], stdout=PIPE, stderr=STDOUT,
484 cwd=path).communicate()
485 except OSError:
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000486 # git is not available, skip this test.
487 return False
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000488 Popen(['git', 'fast-import'], stdin=PIPE, stdout=PIPE, stderr=STDOUT,
489 cwd=path).communicate(input=git_import)
490 Popen(['git', 'checkout'], stdout=PIPE, stderr=STDOUT,
491 cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000492 Popen(['git', 'remote', 'add', '-f', 'origin', '.'], stdout=PIPE,
493 stderr=STDOUT, cwd=path).communicate()
494 Popen(['git', 'checkout', '-b', 'new', 'origin/master'], stdout=PIPE,
495 stderr=STDOUT, cwd=path).communicate()
496 Popen(['git', 'push', 'origin', 'origin/origin:origin/master'], stdout=PIPE,
497 stderr=STDOUT, cwd=path).communicate()
498 Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE,
499 stderr=STDOUT, cwd=path).communicate()
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000500 return True
msb@chromium.orge28e4982009-09-25 20:51:45 +0000501
msb@chromium.orge28e4982009-09-25 20:51:45 +0000502 def setUp(self):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000503 self.args = self.Args()
504 self.url = 'git://foo'
505 self.root_dir = tempfile.mkdtemp()
506 self.relpath = '.'
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000507 self.base_path = gclient_scm.os.path.join(self.root_dir, self.relpath)
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000508 self.enabled = self.CreateGitRepo(self.sample_git_import, self.base_path)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000509 SuperMoxBaseTestBase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000510
511 def tearDown(self):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000512 SuperMoxBaseTestBase.tearDown(self)
maruel@chromium.orgba551772010-02-03 18:21:42 +0000513 rmtree(self.root_dir)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000514
515 def testDir(self):
516 members = [
maruel@chromium.org55e724e2010-03-11 19:36:49 +0000517 'FullUrlForRelativeUrl', 'RunCommand',
msb@chromium.orge6f78352010-01-13 17:05:33 +0000518 'cleanup', 'diff', 'export', 'pack', 'relpath', 'revert',
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000519 'revinfo', 'runhooks', 'scm_name', 'status', 'update', 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +0000520 ]
521
522 # If you add a member, be sure to add the relevant test!
523 self.compareMembers(gclient_scm.CreateSCM(url=self.url), members)
524
525 def testRevertMissing(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000526 if not self.enabled:
527 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000528 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000529 file_path = gclient_scm.os.path.join(self.base_path, 'a')
530 gclient_scm.os.remove(file_path)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000531 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
532 relpath=self.relpath)
533 file_list = []
534 scm.revert(options, self.args, file_list)
535 self.assertEquals(file_list, [file_path])
536 file_list = []
537 scm.diff(options, self.args, file_list)
538 self.assertEquals(file_list, [])
539
540 def testRevertNone(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000541 if not self.enabled:
542 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000543 options = self.Options()
544 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
545 relpath=self.relpath)
546 file_list = []
547 scm.revert(options, self.args, file_list)
548 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000549 self.assertEquals(scm.revinfo(options, self.args, None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000550 '069c602044c5388d2d15c3f875b057c852003458')
551
552
553 def testRevertModified(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000554 if not self.enabled:
555 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000556 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000557 file_path = gclient_scm.os.path.join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000558 open(file_path, 'a').writelines('touched\n')
559 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
560 relpath=self.relpath)
561 file_list = []
562 scm.revert(options, self.args, file_list)
563 self.assertEquals(file_list, [file_path])
564 file_list = []
565 scm.diff(options, self.args, file_list)
566 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000567 self.assertEquals(scm.revinfo(options, self.args, None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000568 '069c602044c5388d2d15c3f875b057c852003458')
569
570 def testRevertNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000571 if not self.enabled:
572 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000573 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000574 file_path = gclient_scm.os.path.join(self.base_path, 'c')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000575 f = open(file_path, 'w')
576 f.writelines('new\n')
577 f.close()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000578 Popen(['git', 'add', 'c'], stdout=PIPE,
579 stderr=STDOUT, cwd=self.base_path).communicate()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000580 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
581 relpath=self.relpath)
582 file_list = []
583 scm.revert(options, self.args, file_list)
584 self.assertEquals(file_list, [file_path])
585 file_list = []
586 scm.diff(options, self.args, file_list)
587 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000588 self.assertEquals(scm.revinfo(options, self.args, None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000589 '069c602044c5388d2d15c3f875b057c852003458')
590
591 def testStatusNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000592 if not self.enabled:
593 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000594 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000595 file_path = gclient_scm.os.path.join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000596 open(file_path, 'a').writelines('touched\n')
597 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
598 relpath=self.relpath)
599 file_list = []
600 scm.status(options, self.args, file_list)
601 self.assertEquals(file_list, [file_path])
602
603 def testStatus2New(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000604 if not self.enabled:
605 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000606 options = self.Options()
607 expected_file_list = []
608 for f in ['a', 'b']:
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000609 file_path = gclient_scm.os.path.join(self.base_path, f)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000610 open(file_path, 'a').writelines('touched\n')
611 expected_file_list.extend([file_path])
612 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
613 relpath=self.relpath)
614 file_list = []
615 scm.status(options, self.args, file_list)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000616 expected_file_list = [gclient_scm.os.path.join(self.base_path, x)
617 for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000618 self.assertEquals(sorted(file_list), expected_file_list)
619
620 def testUpdateCheckout(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000621 if not self.enabled:
622 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000623 options = self.Options(verbose=True)
624 root_dir = tempfile.mkdtemp()
625 relpath = 'foo'
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000626 base_path = gclient_scm.os.path.join(root_dir, relpath)
627 url = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000628 try:
629 scm = gclient_scm.CreateSCM(url=url, root_dir=root_dir,
630 relpath=relpath)
631 file_list = []
632 scm.update(options, (), file_list)
633 self.assertEquals(len(file_list), 2)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000634 self.assert_(gclient_scm.os.path.isfile(
635 gclient_scm.os.path.join(base_path, 'a')))
msb@chromium.org0f282062009-11-06 20:14:02 +0000636 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000637 '069c602044c5388d2d15c3f875b057c852003458')
638 finally:
maruel@chromium.orgba551772010-02-03 18:21:42 +0000639 rmtree(root_dir)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000640
641 def testUpdateUpdate(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000642 if not self.enabled:
643 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000644 options = self.Options()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000645 expected_file_list = [gclient_scm.os.path.join(self.base_path, x)
646 for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000647 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
648 relpath=self.relpath)
649 file_list = []
650 scm.update(options, (), file_list)
msb@chromium.org0f282062009-11-06 20:14:02 +0000651 self.assertEquals(file_list, expected_file_list)
652 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000653 'a7142dc9f0009350b96a11f372b6ea658592aa95')
654
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000655 def testUpdateUnstagedConflict(self):
656 if not self.enabled:
657 return
658 options = self.Options()
659 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
660 relpath=self.relpath)
661 file_path = gclient_scm.os.path.join(self.base_path, 'b')
662 f = open(file_path, 'w').writelines('conflict\n')
663 exception = (
664 "error: Your local changes to 'b' would be overwritten by merge. "
665 "Aborting.\n"
666 "Please, commit your changes or stash them before you can merge.\n")
667 self.assertRaisesError(exception, scm.update, options, (), [])
668
msb@chromium.org5bde4852009-12-14 16:47:12 +0000669 def testUpdateConflict(self):
670 if not self.enabled:
671 return
672 options = self.Options()
673 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
674 relpath=self.relpath)
675 file_path = gclient_scm.os.path.join(self.base_path, 'b')
676 f = open(file_path, 'w').writelines('conflict\n')
677 scm._Run(['commit', '-am', 'test'])
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000678 self.mox.StubOutWithMock(__builtin__, 'raw_input')
679 __builtin__.raw_input.__call__(mox.StrContains('Cannot fast-forward merge, '
680 'attempt to rebase? (y)es / '
681 '(q)uit / (s)kip : ')
682 ).AndReturn('y')
683 self.mox.ReplayAll()
msb@chromium.org5bde4852009-12-14 16:47:12 +0000684 exception = \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000685 'Conflict while rebasing this branch.\n' \
msb@chromium.org5bde4852009-12-14 16:47:12 +0000686 'Fix the conflict and run gclient again.\n' \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000687 "See 'man git-rebase' for details.\n"
msb@chromium.org5bde4852009-12-14 16:47:12 +0000688 self.assertRaisesError(exception, scm.update, options, (), [])
689 exception = \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000690 '\n____ . at refs/heads/master\n' \
msb@chromium.org5bde4852009-12-14 16:47:12 +0000691 '\tAlready in a conflict, i.e. (no branch).\n' \
692 '\tFix the conflict and run gclient again.\n' \
693 '\tOr to abort run:\n\t\tgit-rebase --abort\n' \
694 '\tSee man git-rebase for details.\n'
695 self.assertRaisesError(exception, scm.update, options, (), [])
696
msb@chromium.orge4af1ab2010-01-13 21:26:09 +0000697 def testUpdateNotGit(self):
698 if not self.enabled:
699 return
700 options = self.Options()
701 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
702 relpath=self.relpath)
703 git_path = gclient_scm.os.path.join(self.base_path, '.git')
maruel@chromium.orgba551772010-02-03 18:21:42 +0000704 rename(git_path, git_path + 'foo')
msb@chromium.orge4af1ab2010-01-13 21:26:09 +0000705 exception = \
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000706 '\n____ . at refs/heads/master\n' \
msb@chromium.orge4af1ab2010-01-13 21:26:09 +0000707 '\tPath is not a git repo. No .git dir.\n' \
708 '\tTo resolve:\n' \
709 '\t\trm -rf .\n' \
710 '\tAnd run gclient sync again\n'
711 self.assertRaisesError(exception, scm.update, options, (), [])
712
msb@chromium.org0f282062009-11-06 20:14:02 +0000713 def testRevinfo(self):
714 if not self.enabled:
715 return
716 options = self.Options()
717 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
718 relpath=self.relpath)
719 rev_info = scm.revinfo(options, (), None)
720 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458')
721
msb@chromium.orge28e4982009-09-25 20:51:45 +0000722
msb@chromium.orge28e4982009-09-25 20:51:45 +0000723if __name__ == '__main__':
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000724 import unittest
msb@chromium.orge28e4982009-09-25 20:51:45 +0000725 unittest.main()
726
727# vim: ts=2:sw=2:tw=80:et: