blob: 581b2734bf93e0ff28c6f39303c0fa9906003176 [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
maruel@chromium.org795a8c12010-10-05 19:54:29 +000067 # Absolute path of the fake checkout directory.
68 self.base_path = join(self.root_dir, self.relpath)
maruel@chromium.org389d6de2010-09-09 14:14:37 +000069
70 def tearDown(self):
maruel@chromium.org389d6de2010-09-09 14:14:37 +000071 SuperMoxTestBase.tearDown(self)
72
73
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000074class SVNWrapperTestCase(BaseTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +000075 class OptionsObject(object):
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +000076 def __init__(self, verbose=False, revision=None, force=False):
msb@chromium.orge28e4982009-09-25 20:51:45 +000077 self.verbose = verbose
78 self.revision = revision
79 self.manually_grab_svn_rev = True
80 self.deps_os = None
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +000081 self.force = force
davemoore@chromium.org8bf27312010-02-19 17:29:44 +000082 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +000083 self.nohooks = False
maruel@chromium.org36ac2392011-10-12 16:36:11 +000084 # TODO(maruel): Test --jobs > 1.
85 self.jobs = 1
steveblock@chromium.org93567042012-02-15 01:02:26 +000086 self.delete_unversioned_trees = False
msb@chromium.orge28e4982009-09-25 20:51:45 +000087
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000088 def Options(self, *args, **kwargs):
maruel@chromium.org8071c282010-09-20 19:44:19 +000089 return self.OptionsObject(*args, **kwargs)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000090
msb@chromium.orge28e4982009-09-25 20:51:45 +000091 def setUp(self):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +000092 BaseTestCase.setUp(self)
maruel@chromium.org389d6de2010-09-09 14:14:37 +000093 self.url = self.SvnUrl()
msb@chromium.orge28e4982009-09-25 20:51:45 +000094
95 def testDir(self):
96 members = [
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +000097 'FullUrlForRelativeUrl',
98 'GetRevisionDate',
99 'GetUsableRev',
100 'RunCommand',
101 'cleanup',
102 'diff',
103 'pack',
104 'relpath',
105 'revert',
106 'revinfo',
107 'runhooks',
108 'status',
109 'update',
110 'updatesingle',
111 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +0000112 ]
113
114 # If you add a member, be sure to add the relevant test!
maruel@chromium.org9eda4112010-06-11 18:56:10 +0000115 self.compareMembers(self._scm_wrapper('svn://a'), members)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000116
117 def testUnsupportedSCM(self):
maruel@chromium.org9eda4112010-06-11 18:56:10 +0000118 args = ['gopher://foo', self.root_dir, self.relpath]
119 exception_msg = 'No SCM found for url gopher://foo'
120 self.assertRaisesError(exception_msg, self._scm_wrapper, *args)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000121
msb@chromium.orge6f78352010-01-13 17:05:33 +0000122 def testSVNFullUrlForRelativeUrl(self):
123 self.url = 'svn://a/b/c/d'
124
125 self.mox.ReplayAll()
126 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
127 relpath=self.relpath)
128 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'svn://a/b/crap')
129
130 def testGITFullUrlForRelativeUrl(self):
131 self.url = 'git://a/b/c/d'
132
133 self.mox.ReplayAll()
134 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
135 relpath=self.relpath)
136 self.assertEqual(scm.FullUrlForRelativeUrl('/crap'), 'git://a/b/c/crap')
137
igorgatis@gmail.com4e075672011-11-21 16:35:08 +0000138 def testGITFakeHttpUrl(self):
139 self.url = 'git+http://foo'
140
141 self.mox.ReplayAll()
142 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
143 relpath=self.relpath)
144 self.assertEqual(scm.url, 'http://foo')
145
146 def testGITFakeHttpsUrl(self):
147 self.url = 'git+https://foo'
148
149 self.mox.ReplayAll()
150 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
151 relpath=self.relpath)
152 self.assertEqual(scm.url, 'https://foo')
153
msb@chromium.orge28e4982009-09-25 20:51:45 +0000154 def testRunCommandException(self):
155 options = self.Options(verbose=False)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000156 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
157 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000158
159 self.mox.ReplayAll()
160 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
161 relpath=self.relpath)
162 exception = "Unsupported argument(s): %s" % ','.join(self.args)
163 self.assertRaisesError(exception, scm.RunCommand,
164 'update', options, self.args)
165
166 def testRunCommandUnknown(self):
167 # TODO(maruel): if ever used.
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000168 pass
msb@chromium.orge28e4982009-09-25 20:51:45 +0000169
170 def testRevertMissing(self):
171 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000172 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000173 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000174 gclient_scm.scm.SVN.Capture(['--version'], None
maruel@chromium.org2b9aa8e2010-08-25 20:01:42 +0000175 ).AndReturn('svn, version 1.5.1 (r32289)')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000176 # It'll to a checkout instead.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000177 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
178 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000179 # Checkout.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000180 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.org6c48a302011-10-20 23:44:20 +0000181 parent = gclient_scm.os.path.dirname(self.base_path)
182 gclient_scm.os.path.exists(parent).AndReturn(False)
183 gclient_scm.os.makedirs(parent)
184 gclient_scm.os.path.exists(parent).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000185 files_list = self.mox.CreateMockAnything()
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000186 gclient_scm.scm.SVN.RunAndGetFileList(
187 options.verbose,
188 ['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
189 cwd=self.root_dir,
190 file_list=files_list)
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 scm.revert(options, self.args, files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000196 self.checkstdout(
197 ('\n_____ %s is missing, synching instead\n' % self.relpath))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000198
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000199 def testRevertNoDotSvn(self):
200 options = self.Options(verbose=True, force=True)
201 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
202 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(False)
203 gclient_scm.os.path.isdir(join(self.base_path, '.git')).AndReturn(False)
204 gclient_scm.os.path.isdir(join(self.base_path, '.hg')).AndReturn(False)
205 # Checkout.
206 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
207 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
208 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
209 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.org6c48a302011-10-20 23:44:20 +0000210 parent = gclient_scm.os.path.dirname(self.base_path)
211 gclient_scm.os.path.exists(parent).AndReturn(False)
212 gclient_scm.os.makedirs(parent)
213 gclient_scm.os.path.exists(parent).AndReturn(True)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000214 files_list = self.mox.CreateMockAnything()
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000215 gclient_scm.scm.SVN.Capture(['--version'], None
216 ).AndReturn('svn, version 1.6')
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000217 gclient_scm.scm.SVN.RunAndGetFileList(
218 options.verbose,
219 ['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
220 cwd=self.root_dir,
221 file_list=files_list)
222
223 self.mox.ReplayAll()
224 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
225 relpath=self.relpath)
226 scm.revert(options, self.args, files_list)
227 self.checkstdout(
228 '\n_____ %s is not a valid svn checkout, synching instead\n' %
229 self.relpath)
230
msb@chromium.orge28e4982009-09-25 20:51:45 +0000231 def testRevertNone(self):
232 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000233 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000234 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000235 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path).AndReturn([])
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000236 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000237 gclient_scm.scm.SVN.RunAndGetFileList(
238 options.verbose,
239 ['update', '--revision', 'BASE', '--ignore-externals'],
240 cwd=self.base_path,
241 file_list=mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000242
243 self.mox.ReplayAll()
244 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
245 relpath=self.relpath)
246 file_list = []
247 scm.revert(options, self.args, file_list)
248
msb@chromium.orge28e4982009-09-25 20:51:45 +0000249 def testRevertDirectory(self):
250 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000251 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgc0cc0872011-10-12 17:02:41 +0000252 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000253 items = [
254 ('~ ', 'a'),
255 ]
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000256 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path).AndReturn(items)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000257 file_path = join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000258 gclient_scm.os.path.exists(file_path).AndReturn(True)
259 gclient_scm.os.path.isfile(file_path).AndReturn(False)
msb@chromium.org32906d12010-01-12 18:22:09 +0000260 gclient_scm.os.path.islink(file_path).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000261 gclient_scm.os.path.isdir(file_path).AndReturn(True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000262 gclient_scm.gclient_utils.RemoveDirectory(file_path)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000263 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000264 gclient_scm.scm.SVN.RunAndGetFileList(
265 options.verbose,
266 ['update', '--revision', 'BASE', '--ignore-externals'],
267 cwd=self.base_path,
268 file_list=mox.IgnoreArg())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000269
270 self.mox.ReplayAll()
271 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
272 relpath=self.relpath)
273 file_list2 = []
274 scm.revert(options, self.args, file_list2)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000275 self.checkstdout(('%s\n' % file_path))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000276
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000277 def testRevertDot(self):
278 self.mox.StubOutWithMock(gclient_scm.SVNWrapper, 'update')
279 options = self.Options(verbose=True)
280 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
281 gclient_scm.os.path.isdir(join(self.base_path, '.svn')).AndReturn(True)
282 items = [
283 ('~ ', '.'),
284 ]
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000285 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path).AndReturn(items)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000286 file_path = join(self.base_path, '.')
287 gclient_scm.os.path.exists(file_path).AndReturn(True)
288 gclient_scm.os.path.isfile(file_path).AndReturn(False)
289 gclient_scm.os.path.islink(file_path).AndReturn(False)
290 gclient_scm.os.path.isdir(file_path).AndReturn(True)
291 gclient_scm.gclient_utils.RemoveDirectory(file_path)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000292 # pylint: disable=E1120
maruel@chromium.org428342a2011-11-10 15:46:33 +0000293 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
maruel@chromium.org8b322b32011-11-01 19:05:50 +0000294 gclient_scm.SVNWrapper.update(options, [], ['.'])
295
296 self.mox.ReplayAll()
297 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
298 relpath=self.relpath)
299 file_list2 = []
300 scm.revert(options, self.args, file_list2)
301 self.checkstdout(('%s\n' % file_path))
302
msb@chromium.orge28e4982009-09-25 20:51:45 +0000303 def testStatus(self):
304 options = self.Options(verbose=True)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000305 gclient_scm.os.path.isdir(self.base_path).AndReturn(True)
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000306 gclient_scm.scm.SVN.RunAndGetFileList(
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000307 options.verbose,
308 ['status'] + self.args + ['--ignore-externals'],
309 cwd=self.base_path,
310 file_list=[]).AndReturn(None)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000311
312 self.mox.ReplayAll()
313 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
314 relpath=self.relpath)
315 file_list = []
316 self.assertEqual(scm.status(options, self.args, file_list), None)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000317
318 # TODO(maruel): TEST REVISIONS!!!
319 # TODO(maruel): TEST RELOCATE!!!
320 def testUpdateCheckout(self):
321 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000322 file_info = gclient_scm.gclient_utils.PrintableObject()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000323 file_info.root = 'blah'
324 file_info.url = self.url
325 file_info.uuid = 'ABC'
326 file_info.revision = 42
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000327 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
328 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000329 # Checkout.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000330 gclient_scm.os.path.exists(self.base_path).AndReturn(False)
maruel@chromium.org6c48a302011-10-20 23:44:20 +0000331 parent = gclient_scm.os.path.dirname(self.base_path)
332 gclient_scm.os.path.exists(parent).AndReturn(False)
333 gclient_scm.os.makedirs(parent)
334 gclient_scm.os.path.exists(parent).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000335 files_list = self.mox.CreateMockAnything()
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000336 gclient_scm.scm.SVN.Capture(['--version'], None
maruel@chromium.org669600d2010-09-01 19:06:31 +0000337 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000338 gclient_scm.scm.SVN.RunAndGetFileList(
339 options.verbose,
340 ['checkout', self.url, self.base_path, '--force', '--ignore-externals'],
341 cwd=self.root_dir,
342 file_list=files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000343 self.mox.ReplayAll()
344 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
345 relpath=self.relpath)
346 scm.update(options, (), files_list)
347
348 def testUpdateUpdate(self):
349 options = self.Options(verbose=True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000350 options.force = True
351 options.nohooks = False
352 file_info = {
353 'Repository Root': 'blah',
354 'URL': self.url,
355 'UUID': 'ABC',
356 'Revision': 42,
357 }
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000358 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
359 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000360
361 # Verify no locked files.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000362 dotted_path = join(self.base_path, '.')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000363 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000364
msb@chromium.orge28e4982009-09-25 20:51:45 +0000365 # Checkout or update.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000366 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000367 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000368 # Cheat a bit here.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000369 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
370 ).AndReturn(file_info)
steveblock@chromium.org93567042012-02-15 01:02:26 +0000371 gclient_scm.scm.SVN.Capture(['--version'], None
372 ).AndReturn('svn, version 1.5.1 (r32289)')
373
msb@chromium.orge28e4982009-09-25 20:51:45 +0000374 additional_args = []
375 if options.manually_grab_svn_rev:
376 additional_args = ['--revision', str(file_info['Revision'])]
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000377 additional_args.extend(['--force', '--ignore-externals'])
msb@chromium.orge28e4982009-09-25 20:51:45 +0000378 files_list = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000379 gclient_scm.scm.SVN.RunAndGetFileList(
maruel@chromium.org03807072010-08-16 17:18:44 +0000380 options.verbose,
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000381 ['update', self.base_path] + additional_args,
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000382 cwd=self.root_dir, file_list=files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000383
384 self.mox.ReplayAll()
385 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
386 relpath=self.relpath)
387 scm.update(options, (), files_list)
388
steveblock@chromium.org93567042012-02-15 01:02:26 +0000389 def testUpdateForceNoDeleteUnversionedTrees(self):
390 options = self.Options(verbose=True)
391 options.force = True
392
393 file_info = {
394 'Repository Root': 'blah',
395 'URL': self.url,
396 'UUID': 'ABC',
397 'Revision': 42,
398 }
399 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
400 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
401
402 # Create an untracked file and directory.
403 dotted_path = join(self.base_path, '.')
404 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
405 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
406
407 # Checkout or update.
408 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
409 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
410 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
411 ).AndReturn(file_info)
412 gclient_scm.scm.SVN.Capture(['--version'], None
413 ).AndReturn('svn, version 1.5.1 (r32289)')
414
415 additional_args = []
416 if options.manually_grab_svn_rev:
417 additional_args = ['--revision', str(file_info['Revision'])]
418 additional_args.extend(['--force', '--ignore-externals'])
419 files_list = []
420 gclient_scm.scm.SVN.RunAndGetFileList(
421 options.verbose,
422 ['update', self.base_path] + additional_args,
423 cwd=self.root_dir, file_list=files_list)
424
425 self.mox.ReplayAll()
426 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
427 relpath=self.relpath)
428 scm.update(options, (), files_list)
429
430 def testUpdateForceDeleteUnversionedTrees(self):
431 options = self.Options(verbose=True)
432 options.force = 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
444 # Create an untracked file and directory.
445 dotted_path = join(self.base_path, '.')
446 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
447 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
448
449 # Checkout or update.
450 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
451 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
452 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
453 ).AndReturn(file_info)
454 gclient_scm.scm.SVN.Capture(['--version'], None
455 ).AndReturn('svn, version 1.5.1 (r32289)')
456
457 # Confirm that the untracked file is removed.
458 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path
459 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
460 gclient_scm.os.path.isdir(join(self.base_path, 'dir')).AndReturn(True)
461 gclient_scm.os.path.isdir(join(self.base_path, 'file')).AndReturn(False)
462 gclient_scm.gclient_utils.RemoveDirectory(join(self.base_path, 'dir'))
463
464 additional_args = []
465 if options.manually_grab_svn_rev:
466 additional_args = ['--revision', str(file_info['Revision'])]
467 additional_args.extend(['--force', '--ignore-externals'])
468 files_list = []
469 gclient_scm.scm.SVN.RunAndGetFileList(
470 options.verbose,
471 ['update', self.base_path] + additional_args,
472 cwd=self.root_dir, file_list=files_list)
473
474 self.mox.ReplayAll()
475 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
476 relpath=self.relpath)
477 scm.update(options, (), files_list)
478 self.checkstdout('\n_____ removing unversioned directory dir\n')
479
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000480 def testUpdateSingleCheckout(self):
481 options = self.Options(verbose=True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000482 file_info = {
483 'URL': self.url,
484 'Revision': 42,
485 }
tony@chromium.org57564662010-04-14 02:35:12 +0000486
487 # Checks to make sure that we support svn co --depth.
488 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000489 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000490 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000491 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
492 gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(False)
tony@chromium.org57564662010-04-14 02:35:12 +0000493
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000494 # Verify no locked files.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000495 dotted_path = join(self.base_path, '.')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000496 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000497
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000498 # When checking out a single file, we issue an svn checkout and svn update.
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000499 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000500 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000501 ['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000502 always=True,
503 cwd=self.root_dir)
504 gclient_scm.scm.SVN.RunAndGetFileList(
505 options.verbose,
506 ['update', 'DEPS', '--ignore-externals'],
507 cwd=self.base_path,
508 file_list=files_list)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000509
510 # Now we fall back on scm.update().
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000511 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
512 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
513 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000514 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
515 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
516 ).AndReturn(file_info)
tony@chromium.org57564662010-04-14 02:35:12 +0000517
518 self.mox.ReplayAll()
519 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
520 relpath=self.relpath)
521 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000522 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
tony@chromium.org57564662010-04-14 02:35:12 +0000523
524 def testUpdateSingleCheckoutSVN14(self):
525 options = self.Options(verbose=True)
tony@chromium.org57564662010-04-14 02:35:12 +0000526
527 # Checks to make sure that we support svn co --depth.
528 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000529 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000530 ).AndReturn('svn, version 1.4.4 (r25188)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000531 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
tony@chromium.org57564662010-04-14 02:35:12 +0000532
533 # When checking out a single file with svn 1.4, we use svn export
534 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000535 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000536 ['svn', 'export', join(self.url, 'DEPS'), join(self.base_path, 'DEPS')],
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000537 always=True, cwd=self.root_dir)
tony@chromium.org57564662010-04-14 02:35:12 +0000538
539 self.mox.ReplayAll()
540 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
541 relpath=self.relpath)
542 scm.updatesingle(options, ['DEPS'], files_list)
543
544 def testUpdateSingleCheckoutSVNUpgrade(self):
545 options = self.Options(verbose=True)
tony@chromium.org57564662010-04-14 02:35:12 +0000546 file_info = {
547 'URL': self.url,
548 'Revision': 42,
549 }
550
551 # Checks to make sure that we support svn co --depth.
552 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000553 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000554 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000555 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
tony@chromium.org57564662010-04-14 02:35:12 +0000556 # If DEPS already exists, assume we're upgrading from svn1.4, so delete
557 # the old DEPS file.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000558 gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(True)
559 gclient_scm.os.remove(join(self.base_path, 'DEPS'))
tony@chromium.org57564662010-04-14 02:35:12 +0000560
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000561 # Verify no locked files.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000562 gclient_scm.scm.SVN.CaptureStatus(
563 None, join(self.base_path, '.')).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000564
tony@chromium.org57564662010-04-14 02:35:12 +0000565 # When checking out a single file, we issue an svn checkout and svn update.
566 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000567 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000568 ['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000569 always=True,
570 cwd=self.root_dir)
571 gclient_scm.scm.SVN.RunAndGetFileList(
572 options.verbose,
573 ['update', 'DEPS', '--ignore-externals'],
574 cwd=self.base_path,
575 file_list=files_list)
tony@chromium.org57564662010-04-14 02:35:12 +0000576
577 # Now we fall back on scm.update().
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000578 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
579 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
580 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000581 gclient_scm.scm.SVN._CaptureInfo(
582 [], join(self.base_path, ".")).AndReturn(file_info)
583 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
584 ).AndReturn(file_info)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000585
586 self.mox.ReplayAll()
587 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
588 relpath=self.relpath)
589 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000590 self.checkstdout(
591 ('\n_____ %s at 42\n' % self.relpath))
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000592
593 def testUpdateSingleUpdate(self):
594 options = self.Options(verbose=True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000595 file_info = {
596 'URL': self.url,
597 'Revision': 42,
598 }
tony@chromium.org57564662010-04-14 02:35:12 +0000599 # Checks to make sure that we support svn co --depth.
600 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000601 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000602 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000603 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000604
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000605 # Verify no locked files.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000606 gclient_scm.scm.SVN.CaptureStatus(None, join(self.base_path, '.')
607 ).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000608
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000609 # Now we fall back on scm.update().
610 files_list = self.mox.CreateMockAnything()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000611 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
612 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
613 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000614 gclient_scm.scm.SVN._CaptureInfo(
615 [], join(self.base_path, '.')).AndReturn(file_info)
616 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
617 ).AndReturn(file_info)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000618
619 self.mox.ReplayAll()
620 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
621 relpath=self.relpath)
622 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000623 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000624
msb@chromium.orge28e4982009-09-25 20:51:45 +0000625 def testUpdateGit(self):
626 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000627 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
628 gclient_scm.os.path.exists(file_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000629
630 self.mox.ReplayAll()
631 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
632 relpath=self.relpath)
633 file_list = []
634 scm.update(options, self.args, file_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000635 self.checkstdout(
636 ('________ found .git directory; skipping %s\n' % self.relpath))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000637
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000638 def testUpdateHg(self):
639 options = self.Options(verbose=True)
640 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
641 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(True)
642
643 self.mox.ReplayAll()
644 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
645 relpath=self.relpath)
646 file_list = []
647 scm.update(options, self.args, file_list)
648 self.checkstdout(
649 ('________ found .hg directory; skipping %s\n' % self.relpath))
650
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +0000651 def testGetUsableRevSVN(self):
652 # pylint: disable=E1101
653 options = self.Options(verbose=True)
654
655 # Mock SVN revision validity checking.
656 self.mox.StubOutWithMock(
657 gclient_scm.scm.SVN, 'IsValidRevision', True)
658 gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 1)
659 ).AndReturn(True)
660 gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 'fake')
661 ).AndReturn(False)
662
663 self.mox.ReplayAll()
664
665 svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir)
666 # With an SVN checkout, 1 an example of a valid usable rev.
667 self.assertEquals(svn_scm.GetUsableRev(1, options), 1)
668 # With an SVN checkout, a fake or unknown rev should raise an excpetion.
669 self.assertRaises(gclient_scm.gclient_utils.Error,
670 svn_scm.GetUsableRev, 'fake', options)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000671
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +0000672class BaseGitWrapperTestCase(GCBaseTestCase, StdoutCheck, TestCaseUtils,
673 unittest.TestCase):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000674 """This class doesn't use pymox."""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000675 class OptionsObject(object):
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000676 def __init__(self, verbose=False, revision=None):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000677 self.verbose = verbose
678 self.revision = revision
679 self.manually_grab_svn_rev = True
680 self.deps_os = None
681 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +0000682 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000683 self.nohooks = False
bauerb@chromium.org4dd09372011-07-22 14:41:51 +0000684 self.merge = False
steveblock@chromium.org93567042012-02-15 01:02:26 +0000685 self.delete_unversioned_trees = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000686
687 sample_git_import = """blob
688mark :1
689data 6
690Hello
691
692blob
693mark :2
694data 4
695Bye
696
697reset refs/heads/master
698commit refs/heads/master
699mark :3
700author Bob <bob@example.com> 1253744361 -0700
701committer Bob <bob@example.com> 1253744361 -0700
702data 8
703A and B
704M 100644 :1 a
705M 100644 :2 b
706
707blob
708mark :4
709data 10
710Hello
711You
712
713blob
714mark :5
715data 8
716Bye
717You
718
719commit refs/heads/origin
720mark :6
721author Alice <alice@example.com> 1253744424 -0700
722committer Alice <alice@example.com> 1253744424 -0700
723data 13
724Personalized
725from :3
726M 100644 :4 a
727M 100644 :5 b
728
729reset refs/heads/master
730from :3
731"""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000732 def Options(self, *args, **kwargs):
maruel@chromium.org8071c282010-09-20 19:44:19 +0000733 return self.OptionsObject(*args, **kwargs)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000734
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000735 @staticmethod
736 def CreateGitRepo(git_import, path):
maruel@chromium.orgd5800f12009-11-12 20:03:43 +0000737 """Do it for real."""
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000738 try:
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000739 Popen(['git', 'init', '-q'], stdout=PIPE, stderr=STDOUT,
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000740 cwd=path).communicate()
741 except OSError:
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000742 # git is not available, skip this test.
743 return False
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000744 Popen(['git', 'fast-import', '--quiet'], stdin=PIPE, stdout=PIPE,
745 stderr=STDOUT, cwd=path).communicate(input=git_import)
746 Popen(['git', 'checkout', '-q'], stdout=PIPE, stderr=STDOUT,
747 cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000748 Popen(['git', 'remote', 'add', '-f', 'origin', '.'], stdout=PIPE,
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000749 stderr=STDOUT, cwd=path).communicate()
750 Popen(['git', 'checkout', '-b', 'new', 'origin/master', '-q'], stdout=PIPE,
751 stderr=STDOUT, cwd=path).communicate()
752 Popen(['git', 'push', 'origin', 'origin/origin:origin/master', '-q'],
753 stdout=PIPE, stderr=STDOUT, cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000754 Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE,
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000755 stderr=STDOUT, cwd=path).communicate()
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000756 return True
msb@chromium.orge28e4982009-09-25 20:51:45 +0000757
msb@chromium.orge28e4982009-09-25 20:51:45 +0000758 def setUp(self):
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000759 TestCaseUtils.setUp(self)
760 unittest.TestCase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000761 self.url = 'git://foo'
762 self.root_dir = tempfile.mkdtemp()
763 self.relpath = '.'
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000764 self.base_path = join(self.root_dir, self.relpath)
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000765 self.enabled = self.CreateGitRepo(self.sample_git_import, self.base_path)
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000766 StdoutCheck.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000767
768 def tearDown(self):
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000769 StdoutCheck.tearDown(self)
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000770 TestCaseUtils.tearDown(self)
771 unittest.TestCase.tearDown(self)
maruel@chromium.orgba551772010-02-03 18:21:42 +0000772 rmtree(self.root_dir)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000773
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +0000774class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000775 def testDir(self):
776 members = [
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
933 def testUpdateCheckout(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(verbose=True)
dpranke@chromium.org330f5342011-03-13 02:56:43 +0000937 root_dir = gclient_scm.os.path.realpath(tempfile.mkdtemp())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000938 relpath = 'foo'
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000939 base_path = join(root_dir, relpath)
940 url = join(self.base_path, '.git')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000941 try:
942 scm = gclient_scm.CreateSCM(url=url, root_dir=root_dir,
943 relpath=relpath)
944 file_list = []
945 scm.update(options, (), file_list)
946 self.assertEquals(len(file_list), 2)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000947 self.assert_(gclient_scm.os.path.isfile(join(base_path, 'a')))
msb@chromium.org0f282062009-11-06 20:14:02 +0000948 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000949 '069c602044c5388d2d15c3f875b057c852003458')
950 finally:
maruel@chromium.orgba551772010-02-03 18:21:42 +0000951 rmtree(root_dir)
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000952 msg1 = (
953 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +0000954 "________ running 'git clone --progress -b master --verbose %s %s' "
955 "in '%s'\n"
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000956 "Initialized empty Git repository in %s\n") % (
957 join(self.root_dir, '.', '.git'),
958 join(root_dir, 'foo'),
959 root_dir,
960 join(gclient_scm.os.path.realpath(root_dir), 'foo', '.git') + '/')
961 msg2 = (
962 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +0000963 "________ running 'git clone --progress -b master --verbose %s %s'"
964 " in '%s'\n"
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000965 "Cloning into %s...\ndone.\n") % (
966 join(self.root_dir, '.', '.git'),
967 join(root_dir, 'foo'),
968 root_dir,
969 join(gclient_scm.os.path.realpath(root_dir), 'foo'))
970 out = sys.stdout.getvalue()
971 sys.stdout.close()
dpranke@chromium.org330f5342011-03-13 02:56:43 +0000972 sys.stdout = self._old_stdout
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000973 self.assertTrue(out in (msg1, msg2), (out, msg1, msg2))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000974
975 def testUpdateUpdate(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000976 if not self.enabled:
977 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000978 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000979 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000980 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
981 relpath=self.relpath)
982 file_list = []
983 scm.update(options, (), file_list)
msb@chromium.org0f282062009-11-06 20:14:02 +0000984 self.assertEquals(file_list, expected_file_list)
985 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000986 'a7142dc9f0009350b96a11f372b6ea658592aa95')
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000987 self.checkstdout(
988 '\n_____ . at refs/heads/master\n'
989 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
990 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000991
steveblock@chromium.org93567042012-02-15 01:02:26 +0000992 def testUpdateForceNoDeleteUnversionedTrees(self):
993 if not self.enabled:
994 return
995 options = self.Options()
996 options.force = True
997
998 dir_path = join(self.base_path, 'c')
999 os.mkdir(dir_path)
1000 open(join(dir_path, 'nested'), 'w').writelines('new\n')
1001
1002 file_path = join(self.base_path, 'file')
1003 open(file_path, 'w').writelines('new\n')
1004
1005 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1006 relpath=self.relpath)
1007 file_list = []
1008 scm.update(options, (), file_list)
1009 self.assert_(gclient_scm.os.path.isdir(dir_path))
1010 self.assert_(gclient_scm.os.path.isfile(file_path))
1011 self.checkstdout(
1012 '\n________ running \'git reset --hard HEAD\' in \'%s\''
1013 '\nHEAD is now at 069c602 A and B\n'
1014 '\n_____ . at refs/heads/master\n'
1015 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
1016 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n'
1017 % join(self.root_dir, '.'))
1018
1019 def testUpdateForceDeleteUnversionedTrees(self):
1020 if not self.enabled:
1021 return
1022 options = self.Options()
1023 options.force = True
1024 options.delete_unversioned_trees = True
1025
1026 dir_path = join(self.base_path, 'dir')
1027 os.mkdir(dir_path)
1028 open(join(dir_path, 'nested'), 'w').writelines('new\n')
1029
1030 file_path = join(self.base_path, 'file')
1031 open(file_path, 'w').writelines('new\n')
1032
1033 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1034 relpath=self.relpath)
1035 file_list = []
1036 scm.update(options, (), file_list)
1037 self.assert_(not gclient_scm.os.path.isdir(dir_path))
1038 self.assert_(gclient_scm.os.path.isfile(file_path))
1039 self.checkstdout(
1040 '\n________ running \'git reset --hard HEAD\' in \'%s\''
1041 '\nHEAD is now at 069c602 A and B\n'
1042 '\n_____ . at refs/heads/master\n'
1043 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
1044 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n'
1045 '\n_____ removing unversioned directory dir/\n' % join(self.root_dir,
1046 '.'))
1047
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +00001048 def testUpdateUnstagedConflict(self):
1049 if not self.enabled:
1050 return
1051 options = self.Options()
1052 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1053 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001054 file_path = join(self.base_path, 'b')
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00001055 open(file_path, 'w').writelines('conflict\n')
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001056 try:
1057 scm.update(options, (), [])
1058 self.fail()
maruel@chromium.orgfae707b2011-09-15 18:57:58 +00001059 except (gclient_scm.gclient_utils.Error, subprocess2.CalledProcessError):
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001060 # The exact exception text varies across git versions so it's not worth
1061 # verifying it. It's fine as long as it throws.
1062 pass
1063 # Manually flush stdout since we can't verify it's content accurately across
1064 # git versions.
1065 sys.stdout.getvalue()
1066 sys.stdout.close()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +00001067
msb@chromium.org5bde4852009-12-14 16:47:12 +00001068 def testUpdateConflict(self):
1069 if not self.enabled:
1070 return
1071 options = self.Options()
1072 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1073 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001074 file_path = join(self.base_path, 'b')
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00001075 open(file_path, 'w').writelines('conflict\n')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001076 scm._Run(['commit', '-am', 'test'], options)
1077 __builtin__.raw_input = lambda x: 'y'
1078 exception = ('Conflict while rebasing this branch.\n'
1079 'Fix the conflict and run gclient again.\n'
1080 'See \'man git-rebase\' for details.\n')
msb@chromium.org5bde4852009-12-14 16:47:12 +00001081 self.assertRaisesError(exception, scm.update, options, (), [])
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001082 exception = ('\n____ . at refs/heads/master\n'
1083 '\tYou have unstaged changes.\n'
1084 '\tPlease commit, stash, or reset.\n')
msb@chromium.org5bde4852009-12-14 16:47:12 +00001085 self.assertRaisesError(exception, scm.update, options, (), [])
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001086 # The hash always changes. Use a cheap trick.
1087 start = ('\n________ running \'git commit -am test\' in \'%s\'\n'
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001088 '[new ') % join(self.root_dir, '.')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001089 end = ('] test\n 1 files changed, 1 insertions(+), '
1090 '1 deletions(-)\n\n_____ . at refs/heads/master\n'
1091 'Attempting rebase onto refs/remotes/origin/master...\n')
maruel@chromium.orgcb2985f2010-11-03 14:08:31 +00001092 self.assertTrue(sys.stdout.getvalue().startswith(start))
1093 self.assertTrue(sys.stdout.getvalue().endswith(end))
1094 self.assertEquals(len(sys.stdout.getvalue()),
maruel@chromium.orgdd057f32010-09-20 19:33:31 +00001095 len(start) + len(end) + 7)
maruel@chromium.orgcb2985f2010-11-03 14:08:31 +00001096 sys.stdout.close()
msb@chromium.org5bde4852009-12-14 16:47:12 +00001097
msb@chromium.orge4af1ab2010-01-13 21:26:09 +00001098 def testUpdateNotGit(self):
1099 if not self.enabled:
1100 return
1101 options = self.Options()
1102 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1103 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001104 git_path = join(self.base_path, '.git')
maruel@chromium.orgba551772010-02-03 18:21:42 +00001105 rename(git_path, git_path + 'foo')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001106 exception = ('\n____ . at refs/heads/master\n'
1107 '\tPath is not a git repo. No .git dir.\n'
1108 '\tTo resolve:\n'
1109 '\t\trm -rf .\n'
1110 '\tAnd run gclient sync again\n')
msb@chromium.orge4af1ab2010-01-13 21:26:09 +00001111 self.assertRaisesError(exception, scm.update, options, (), [])
1112
msb@chromium.org0f282062009-11-06 20:14:02 +00001113 def testRevinfo(self):
1114 if not self.enabled:
1115 return
1116 options = self.Options()
1117 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1118 relpath=self.relpath)
1119 rev_info = scm.revinfo(options, (), None)
1120 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458')
1121
msb@chromium.orge28e4982009-09-25 20:51:45 +00001122
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001123class ManagedGitWrapperTestCaseMox(BaseTestCase):
1124 class OptionsObject(object):
1125 def __init__(self, verbose=False, revision=None, force=False):
1126 self.verbose = verbose
1127 self.revision = revision
1128 self.deps_os = None
1129 self.force = force
1130 self.reset = False
1131 self.nohooks = False
1132 # TODO(maruel): Test --jobs > 1.
1133 self.jobs = 1
1134
1135 def Options(self, *args, **kwargs):
1136 return self.OptionsObject(*args, **kwargs)
1137
1138 def setUp(self):
1139 BaseTestCase.setUp(self)
1140 self.fake_hash_1 = 't0ta11yf4k3'
1141 self.fake_hash_2 = '3v3nf4k3r'
1142 self.url = 'git://foo'
1143 self.root_dir = '/tmp'
1144 self.relpath = 'fake'
1145 self.base_path = os.path.join(self.root_dir, self.relpath)
1146
1147 def tearDown(self):
1148 BaseTestCase.tearDown(self)
1149
1150 def testGetUsableRevGit(self):
1151 # pylint: disable=E1101
1152 options = self.Options(verbose=True)
1153
1154 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True)
1155 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1
1156 ).AndReturn(True)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001157
1158 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
1159 gclient_scm.scm.GIT.IsGitSvn(cwd=self.base_path).MultipleTimes(
1160 ).AndReturn(False)
1161
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001162 gclient_scm.scm.os.path.isdir(self.base_path).AndReturn(True)
1163
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001164 self.mox.ReplayAll()
1165
1166 git_scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1167 relpath=self.relpath)
1168 # A [fake] git sha1 with a git repo should work (this is in the case that
1169 # the LKGR gets flipped to git sha1's some day).
1170 self.assertEquals(git_scm.GetUsableRev(self.fake_hash_1, options),
1171 self.fake_hash_1)
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001172 # An SVN rev with an existing purely git repo should raise an exception.
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001173 self.assertRaises(gclient_scm.gclient_utils.Error,
1174 git_scm.GetUsableRev, '1', options)
1175
1176 def testGetUsableRevGitSvn(self):
1177 # pylint: disable=E1101
1178 options = self.Options()
1179 too_big = str(1e7)
1180
1181 # Pretend like the git-svn repo's HEAD is at r2.
1182 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'GetGitSvnHeadRev', True)
1183 gclient_scm.scm.GIT.GetGitSvnHeadRev(cwd=self.base_path).MultipleTimes(
1184 ).AndReturn(2)
1185
1186 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'GetSha1ForSvnRev', True)
1187 # r1 -> first fake hash, r3 -> second fake hash.
1188 gclient_scm.scm.GIT.GetSha1ForSvnRev(cwd=self.base_path, rev='1'
1189 ).AndReturn(self.fake_hash_1)
1190 gclient_scm.scm.GIT.GetSha1ForSvnRev(cwd=self.base_path, rev='3'
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001191 ).MultipleTimes().AndReturn(self.fake_hash_2)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001192
1193 # Ensure that we call git svn fetch if our LKGR is > the git-svn HEAD rev.
1194 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'Capture', True)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001195 gclient_scm.scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
1196 cwd=self.base_path).AndReturn('blah')
1197 gclient_scm.scm.GIT.Capture(['fetch'], cwd=self.base_path)
1198 gclient_scm.scm.GIT.Capture(['svn', 'fetch'], cwd=self.base_path)
1199 error = subprocess2.CalledProcessError(1, 'cmd', '/cwd', 'stdout', 'stderr')
1200 gclient_scm.scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
1201 cwd=self.base_path).AndRaise(error)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001202 gclient_scm.scm.GIT.Capture(['svn', 'fetch'], cwd=self.base_path)
1203
1204 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
1205 gclient_scm.scm.GIT.IsGitSvn(cwd=self.base_path).MultipleTimes(
1206 ).AndReturn(True)
1207
1208 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True)
1209 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1
1210 ).AndReturn(True)
1211 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=too_big
1212 ).AndReturn(False)
1213
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001214 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
1215 gclient_scm.os.path.isdir(self.base_path).MultipleTimes().AndReturn(True)
1216
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001217 self.mox.ReplayAll()
1218
1219 git_svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
1220 relpath=self.relpath)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001221 # Without an existing checkout, this should fail.
1222 # TODO(dbeam) Fix this. http://crbug.com/109184
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001223 self.assertRaises(gclient_scm.gclient_utils.Error,
1224 git_svn_scm.GetUsableRev, '1', options)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001225 # Given an SVN revision with a git-svn checkout, it should be translated to
1226 # a git sha1 and be usable.
1227 self.assertEquals(git_svn_scm.GetUsableRev('1', options),
1228 self.fake_hash_1)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001229 # Our fake HEAD rev is r2, so this should call git fetch and git svn fetch
1230 # to get more revs (pymox will complain if this doesn't happen). We mock an
1231 # optimized checkout the first time, so this run should call git fetch.
1232 self.assertEquals(git_svn_scm.GetUsableRev('3', options),
1233 self.fake_hash_2)
1234 # The time we pretend we're not optimized, so no git fetch should fire.
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001235 self.assertEquals(git_svn_scm.GetUsableRev('3', options),
1236 self.fake_hash_2)
1237 # Given a git sha1 with a git-svn checkout, it should be used as is.
1238 self.assertEquals(git_svn_scm.GetUsableRev(self.fake_hash_1, options),
1239 self.fake_hash_1)
1240 # We currently check for seemingly valid SVN revisions by assuming 6 digit
1241 # numbers, so assure that numeric revs >= 1000000 don't work.
1242 self.assertRaises(gclient_scm.gclient_utils.Error,
1243 git_svn_scm.GetUsableRev, too_big, options)
1244
1245
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001246class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
1247 def testUpdateCheckout(self):
1248 if not self.enabled:
1249 return
1250 options = self.Options(verbose=True)
1251 root_dir = gclient_scm.os.path.realpath(tempfile.mkdtemp())
1252 relpath = 'foo'
1253 base_path = join(root_dir, relpath)
1254 url = join(self.base_path, '.git')
1255 try:
1256 scm = gclient_scm.CreateSCM(url=url, root_dir=root_dir,
1257 relpath=relpath)
1258 file_list = []
1259 options.revision = 'unmanaged'
1260 scm.update(options, (), file_list)
1261 self.assertEquals(len(file_list), 2)
1262 self.assert_(gclient_scm.os.path.isfile(join(base_path, 'a')))
1263 self.assertEquals(scm.revinfo(options, (), None),
1264 '069c602044c5388d2d15c3f875b057c852003458')
1265 finally:
1266 rmtree(root_dir)
1267 msg1 = (
1268 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +00001269 "________ running 'git clone --progress -b master --verbose %s %s'"
1270 " in '%s'\n"
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001271 "Initialized empty Git repository in %s\n") % (
1272 join(self.root_dir, '.', '.git'),
1273 join(root_dir, 'foo'),
1274 root_dir,
1275 join(gclient_scm.os.path.realpath(root_dir), 'foo', '.git') + '/')
1276 msg2 = (
1277 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +00001278 "________ running 'git clone --progress -b master --verbose %s %s'"
1279 " in '%s'\n"
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001280 "Cloning into %s...\ndone.\n") % (
1281 join(self.root_dir, '.', '.git'),
1282 join(root_dir, 'foo'),
1283 root_dir,
1284 join(gclient_scm.os.path.realpath(root_dir), 'foo'))
1285 out = sys.stdout.getvalue()
1286 sys.stdout.close()
1287 sys.stdout = self._old_stdout
1288 self.assertTrue(out in (msg1, msg2), (out, msg1, msg2))
1289
1290 def testUpdateUpdate(self):
1291 if not self.enabled:
1292 return
1293 options = self.Options()
1294 expected_file_list = []
1295 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1296 relpath=self.relpath)
1297 file_list = []
1298 options.revision = 'unmanaged'
1299 scm.update(options, (), file_list)
1300 self.assertEquals(file_list, expected_file_list)
1301 self.assertEquals(scm.revinfo(options, (), None),
1302 '069c602044c5388d2d15c3f875b057c852003458')
1303 self.checkstdout('________ unmanaged solution; skipping .\n')
1304
1305
msb@chromium.orge28e4982009-09-25 20:51:45 +00001306if __name__ == '__main__':
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001307 if '-v' in sys.argv:
1308 logging.basicConfig(
1309 level=logging.DEBUG,
1310 format='%(asctime).19s %(levelname)s %(filename)s:'
1311 '%(lineno)s %(message)s')
msb@chromium.orge28e4982009-09-25 20:51:45 +00001312 unittest.main()
1313
1314# vim: ts=2:sw=2:tw=80:et: