blob: e41f4f0b01f68c39413b179a21705c98a7ef7c72 [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.org98e69452012-02-16 16:36:43 +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)
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000360 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000361
msb@chromium.orge28e4982009-09-25 20:51:45 +0000362 # Checkout or update.
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000363 dotted_path = join(self.base_path, '.')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000364 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000365
366 # Verify no locked files.
367 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
368
msb@chromium.orge28e4982009-09-25 20:51:45 +0000369 # Cheat a bit here.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000370 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
371 ).AndReturn(file_info)
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000372
373 # _AddAdditionalUpdateFlags()
374 gclient_scm.scm.SVN.Capture(['--version'], None
375 ).AndReturn('svn, version 1.5.1 (r32289)')
376
msb@chromium.orge28e4982009-09-25 20:51:45 +0000377 additional_args = []
378 if options.manually_grab_svn_rev:
379 additional_args = ['--revision', str(file_info['Revision'])]
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000380 additional_args.extend(['--force', '--ignore-externals'])
msb@chromium.orge28e4982009-09-25 20:51:45 +0000381 files_list = []
maruel@chromium.org5aeb7dd2009-11-17 18:09:01 +0000382 gclient_scm.scm.SVN.RunAndGetFileList(
maruel@chromium.org03807072010-08-16 17:18:44 +0000383 options.verbose,
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000384 ['update', self.base_path] + additional_args,
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000385 cwd=self.root_dir, file_list=files_list)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000386
387 self.mox.ReplayAll()
388 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
389 relpath=self.relpath)
390 scm.update(options, (), files_list)
391
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000392 def testUpdateReset(self):
393 options = self.Options(verbose=True)
394 options.reset = True
395 file_info = {
396 'Repository Root': 'blah',
397 'URL': self.url,
398 'UUID': 'ABC',
399 'Revision': 42,
400 }
401 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
402 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
403 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
404
405 # Checkout or update.
406 dotted_path = join(self.base_path, '.')
407 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
408
409 # Create an untracked file and directory.
410 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
411 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
412
413 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
414 ).AndReturn(file_info)
415
416 self.mox.ReplayAll()
417 files_list = []
418 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
419 relpath=self.relpath)
420 scm.update(options, (), files_list)
421 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
422
423 def testUpdateResetDeleteUnversionedTrees(self):
424 options = self.Options(verbose=True)
425 options.reset = True
426 options.delete_unversioned_trees = True
427
428 file_info = {
429 'Repository Root': 'blah',
430 'URL': self.url,
431 'UUID': 'ABC',
432 'Revision': 42,
433 }
434 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
435 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
436 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
437
438 # Checkout or update.
439 dotted_path = join(self.base_path, '.')
440 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
441
442 # Create an untracked file and directory.
443 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path
444 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
445
446 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
447 ).AndReturn(file_info)
448
449 # Confirm that the untracked file is removed.
450 gclient_scm.scm.SVN.CaptureStatus(None, self.base_path
451 ).AndReturn([['? ', 'dir'], ['? ', 'file']])
452 gclient_scm.os.path.isdir(join(self.base_path, 'dir')).AndReturn(True)
453 gclient_scm.os.path.isdir(join(self.base_path, 'file')).AndReturn(False)
454 gclient_scm.os.path.islink(join(self.base_path, 'dir')).AndReturn(False)
455 gclient_scm.gclient_utils.RemoveDirectory(join(self.base_path, 'dir'))
456
457 self.mox.ReplayAll()
458 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
459 relpath=self.relpath)
460 files_list = []
461 scm.update(options, (), files_list)
462 self.checkstdout(
463 ('\n_____ %s at 42\n'
464 '\n_____ removing unversioned directory dir\n') % self.relpath)
465
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000466 def testUpdateSingleCheckout(self):
467 options = self.Options(verbose=True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000468 file_info = {
469 'URL': self.url,
470 'Revision': 42,
471 }
tony@chromium.org57564662010-04-14 02:35:12 +0000472
473 # Checks to make sure that we support svn co --depth.
474 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000475 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000476 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000477 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
478 gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(False)
tony@chromium.org57564662010-04-14 02:35:12 +0000479
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000480 # Verify no locked files.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000481 dotted_path = join(self.base_path, '.')
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000482 gclient_scm.scm.SVN.CaptureStatus(None, dotted_path).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000483
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000484 # When checking out a single file, we issue an svn checkout and svn update.
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000485 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000486 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000487 ['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000488 always=True,
489 cwd=self.root_dir)
490 gclient_scm.scm.SVN.RunAndGetFileList(
491 options.verbose,
492 ['update', 'DEPS', '--ignore-externals'],
493 cwd=self.base_path,
494 file_list=files_list)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000495
496 # Now we fall back on scm.update().
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000497 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
498 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
499 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000500 gclient_scm.scm.SVN._CaptureInfo([], dotted_path).AndReturn(file_info)
501 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
502 ).AndReturn(file_info)
tony@chromium.org57564662010-04-14 02:35:12 +0000503
504 self.mox.ReplayAll()
505 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
506 relpath=self.relpath)
507 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000508 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
tony@chromium.org57564662010-04-14 02:35:12 +0000509
510 def testUpdateSingleCheckoutSVN14(self):
511 options = self.Options(verbose=True)
tony@chromium.org57564662010-04-14 02:35:12 +0000512
513 # Checks to make sure that we support svn co --depth.
514 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000515 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000516 ).AndReturn('svn, version 1.4.4 (r25188)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000517 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
tony@chromium.org57564662010-04-14 02:35:12 +0000518
519 # When checking out a single file with svn 1.4, we use svn export
520 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000521 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000522 ['svn', 'export', join(self.url, 'DEPS'), join(self.base_path, 'DEPS')],
maruel@chromium.org77e4eca2010-09-21 13:23:07 +0000523 always=True, cwd=self.root_dir)
tony@chromium.org57564662010-04-14 02:35:12 +0000524
525 self.mox.ReplayAll()
526 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
527 relpath=self.relpath)
528 scm.updatesingle(options, ['DEPS'], files_list)
529
530 def testUpdateSingleCheckoutSVNUpgrade(self):
531 options = self.Options(verbose=True)
tony@chromium.org57564662010-04-14 02:35:12 +0000532 file_info = {
533 'URL': self.url,
534 'Revision': 42,
535 }
536
537 # Checks to make sure that we support svn co --depth.
538 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000539 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000540 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000541 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(False)
tony@chromium.org57564662010-04-14 02:35:12 +0000542 # If DEPS already exists, assume we're upgrading from svn1.4, so delete
543 # the old DEPS file.
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000544 gclient_scm.os.path.exists(join(self.base_path, 'DEPS')).AndReturn(True)
545 gclient_scm.os.remove(join(self.base_path, 'DEPS'))
tony@chromium.org57564662010-04-14 02:35:12 +0000546
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000547 # Verify no locked files.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000548 gclient_scm.scm.SVN.CaptureStatus(
549 None, join(self.base_path, '.')).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000550
tony@chromium.org57564662010-04-14 02:35:12 +0000551 # When checking out a single file, we issue an svn checkout and svn update.
552 files_list = self.mox.CreateMockAnything()
maruel@chromium.org669600d2010-09-01 19:06:31 +0000553 gclient_scm.gclient_utils.CheckCallAndFilterAndHeader(
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000554 ['svn', 'checkout', '--depth', 'empty', self.url, self.base_path],
maruel@chromium.orgce117f62011-01-17 20:04:25 +0000555 always=True,
556 cwd=self.root_dir)
557 gclient_scm.scm.SVN.RunAndGetFileList(
558 options.verbose,
559 ['update', 'DEPS', '--ignore-externals'],
560 cwd=self.base_path,
561 file_list=files_list)
tony@chromium.org57564662010-04-14 02:35:12 +0000562
563 # Now we fall back on scm.update().
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000564 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
565 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
566 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000567 gclient_scm.scm.SVN._CaptureInfo(
568 [], join(self.base_path, ".")).AndReturn(file_info)
569 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
570 ).AndReturn(file_info)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000571
572 self.mox.ReplayAll()
573 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
574 relpath=self.relpath)
575 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000576 self.checkstdout(
577 ('\n_____ %s at 42\n' % self.relpath))
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000578
579 def testUpdateSingleUpdate(self):
580 options = self.Options(verbose=True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000581 file_info = {
582 'URL': self.url,
583 'Revision': 42,
584 }
tony@chromium.org57564662010-04-14 02:35:12 +0000585 # Checks to make sure that we support svn co --depth.
586 gclient_scm.scm.SVN.current_version = None
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000587 gclient_scm.scm.SVN.Capture(['--version'], None
tony@chromium.org57564662010-04-14 02:35:12 +0000588 ).AndReturn('svn, version 1.5.1 (r32289)')
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000589 gclient_scm.os.path.exists(join(self.base_path, '.svn')).AndReturn(True)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000590
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000591 # Verify no locked files.
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000592 gclient_scm.scm.SVN.CaptureStatus(None, join(self.base_path, '.')
593 ).AndReturn([])
maruel@chromium.orge407c9a2010-08-09 19:11:37 +0000594
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000595 # Now we fall back on scm.update().
596 files_list = self.mox.CreateMockAnything()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000597 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
598 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(False)
599 gclient_scm.os.path.exists(self.base_path).AndReturn(True)
maruel@chromium.orgd579fcf2011-12-13 20:36:03 +0000600 gclient_scm.scm.SVN._CaptureInfo(
601 [], join(self.base_path, '.')).AndReturn(file_info)
602 gclient_scm.scm.SVN._CaptureInfo([file_info['URL']], None
603 ).AndReturn(file_info)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000604
605 self.mox.ReplayAll()
606 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
607 relpath=self.relpath)
608 scm.updatesingle(options, ['DEPS'], files_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000609 self.checkstdout('\n_____ %s at 42\n' % self.relpath)
tony@chromium.org4b5b1772010-04-08 01:52:56 +0000610
msb@chromium.orge28e4982009-09-25 20:51:45 +0000611 def testUpdateGit(self):
612 options = self.Options(verbose=True)
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000613 file_path = gclient_scm.os.path.join(self.root_dir, self.relpath, '.git')
614 gclient_scm.os.path.exists(file_path).AndReturn(True)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000615
616 self.mox.ReplayAll()
617 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
618 relpath=self.relpath)
619 file_list = []
620 scm.update(options, self.args, file_list)
maruel@chromium.org54019f32010-09-09 13:50:11 +0000621 self.checkstdout(
622 ('________ found .git directory; skipping %s\n' % self.relpath))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000623
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000624 def testUpdateHg(self):
625 options = self.Options(verbose=True)
626 gclient_scm.os.path.exists(join(self.base_path, '.git')).AndReturn(False)
627 gclient_scm.os.path.exists(join(self.base_path, '.hg')).AndReturn(True)
628
629 self.mox.ReplayAll()
630 scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
631 relpath=self.relpath)
632 file_list = []
633 scm.update(options, self.args, file_list)
634 self.checkstdout(
635 ('________ found .hg directory; skipping %s\n' % self.relpath))
636
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +0000637 def testGetUsableRevSVN(self):
638 # pylint: disable=E1101
639 options = self.Options(verbose=True)
640
641 # Mock SVN revision validity checking.
642 self.mox.StubOutWithMock(
643 gclient_scm.scm.SVN, 'IsValidRevision', True)
644 gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 1)
645 ).AndReturn(True)
646 gclient_scm.scm.SVN.IsValidRevision(url='%s@%s' % (self.url, 'fake')
647 ).AndReturn(False)
648
649 self.mox.ReplayAll()
650
651 svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir)
652 # With an SVN checkout, 1 an example of a valid usable rev.
653 self.assertEquals(svn_scm.GetUsableRev(1, options), 1)
654 # With an SVN checkout, a fake or unknown rev should raise an excpetion.
655 self.assertRaises(gclient_scm.gclient_utils.Error,
656 svn_scm.GetUsableRev, 'fake', options)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000657
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +0000658class BaseGitWrapperTestCase(GCBaseTestCase, StdoutCheck, TestCaseUtils,
659 unittest.TestCase):
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000660 """This class doesn't use pymox."""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000661 class OptionsObject(object):
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000662 def __init__(self, verbose=False, revision=None):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000663 self.verbose = verbose
664 self.revision = revision
665 self.manually_grab_svn_rev = True
666 self.deps_os = None
667 self.force = False
davemoore@chromium.org8bf27312010-02-19 17:29:44 +0000668 self.reset = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000669 self.nohooks = False
bauerb@chromium.org4dd09372011-07-22 14:41:51 +0000670 self.merge = False
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000671 self.delete_unversioned_trees = False
msb@chromium.orge28e4982009-09-25 20:51:45 +0000672
673 sample_git_import = """blob
674mark :1
675data 6
676Hello
677
678blob
679mark :2
680data 4
681Bye
682
683reset refs/heads/master
684commit refs/heads/master
685mark :3
686author Bob <bob@example.com> 1253744361 -0700
687committer Bob <bob@example.com> 1253744361 -0700
688data 8
689A and B
690M 100644 :1 a
691M 100644 :2 b
692
693blob
694mark :4
695data 10
696Hello
697You
698
699blob
700mark :5
701data 8
702Bye
703You
704
705commit refs/heads/origin
706mark :6
707author Alice <alice@example.com> 1253744424 -0700
708committer Alice <alice@example.com> 1253744424 -0700
709data 13
710Personalized
711from :3
712M 100644 :4 a
713M 100644 :5 b
714
715reset refs/heads/master
716from :3
717"""
msb@chromium.orge28e4982009-09-25 20:51:45 +0000718 def Options(self, *args, **kwargs):
maruel@chromium.org8071c282010-09-20 19:44:19 +0000719 return self.OptionsObject(*args, **kwargs)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000720
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000721 @staticmethod
722 def CreateGitRepo(git_import, path):
maruel@chromium.orgd5800f12009-11-12 20:03:43 +0000723 """Do it for real."""
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000724 try:
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000725 Popen(['git', 'init', '-q'], stdout=PIPE, stderr=STDOUT,
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000726 cwd=path).communicate()
727 except OSError:
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000728 # git is not available, skip this test.
729 return False
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000730 Popen(['git', 'fast-import', '--quiet'], stdin=PIPE, stdout=PIPE,
731 stderr=STDOUT, cwd=path).communicate(input=git_import)
732 Popen(['git', 'checkout', '-q'], stdout=PIPE, stderr=STDOUT,
733 cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000734 Popen(['git', 'remote', 'add', '-f', 'origin', '.'], stdout=PIPE,
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000735 stderr=STDOUT, cwd=path).communicate()
736 Popen(['git', 'checkout', '-b', 'new', 'origin/master', '-q'], stdout=PIPE,
737 stderr=STDOUT, cwd=path).communicate()
738 Popen(['git', 'push', 'origin', 'origin/origin:origin/master', '-q'],
739 stdout=PIPE, stderr=STDOUT, cwd=path).communicate()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +0000740 Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE,
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000741 stderr=STDOUT, cwd=path).communicate()
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000742 return True
msb@chromium.orge28e4982009-09-25 20:51:45 +0000743
msb@chromium.orge28e4982009-09-25 20:51:45 +0000744 def setUp(self):
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000745 TestCaseUtils.setUp(self)
746 unittest.TestCase.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000747 self.url = 'git://foo'
748 self.root_dir = tempfile.mkdtemp()
749 self.relpath = '.'
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000750 self.base_path = join(self.root_dir, self.relpath)
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000751 self.enabled = self.CreateGitRepo(self.sample_git_import, self.base_path)
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000752 StdoutCheck.setUp(self)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000753
754 def tearDown(self):
maruel@chromium.orgdd057f32010-09-20 19:33:31 +0000755 StdoutCheck.tearDown(self)
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000756 TestCaseUtils.tearDown(self)
757 unittest.TestCase.tearDown(self)
maruel@chromium.orgba551772010-02-03 18:21:42 +0000758 rmtree(self.root_dir)
msb@chromium.orge28e4982009-09-25 20:51:45 +0000759
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +0000760class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
msb@chromium.orge28e4982009-09-25 20:51:45 +0000761 def testDir(self):
762 members = [
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +0000763 'FullUrlForRelativeUrl',
764 'GetRevisionDate',
765 'GetUsableRev',
766 'RunCommand',
767 'cleanup',
768 'diff',
769 'pack',
770 'relpath',
771 'revert',
772 'revinfo',
773 'runhooks',
774 'status',
775 'update',
776 'url',
msb@chromium.orge28e4982009-09-25 20:51:45 +0000777 ]
778
779 # If you add a member, be sure to add the relevant test!
780 self.compareMembers(gclient_scm.CreateSCM(url=self.url), members)
781
782 def testRevertMissing(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000783 if not self.enabled:
784 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000785 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000786 file_path = join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000787 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
788 relpath=self.relpath)
789 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000790 scm.update(options, None, file_list)
791 gclient_scm.os.remove(file_path)
792 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000793 scm.revert(options, self.args, file_list)
794 self.assertEquals(file_list, [file_path])
795 file_list = []
796 scm.diff(options, self.args, file_list)
797 self.assertEquals(file_list, [])
szager@google.com85d3e3a2011-10-07 17:12:00 +0000798 expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000799 'Fast-forward\n a | 1 +\n b | 1 +\n'
800 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000801 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
szager@google.com85d3e3a2011-10-07 17:12:00 +0000802 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.')
803 self.assertTrue(sys.stdout.getvalue().startswith(expectation))
804 sys.stdout.close()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000805
806 def testRevertNone(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000807 if not self.enabled:
808 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000809 options = self.Options()
810 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
811 relpath=self.relpath)
812 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000813 scm.update(options, None, file_list)
814 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000815 scm.revert(options, self.args, file_list)
816 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000817 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000818 'a7142dc9f0009350b96a11f372b6ea658592aa95')
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000819 self.checkstdout(
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000820 ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
821 'Fast-forward\n a | 1 +\n b | 1 +\n'
822 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000823 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
824 'HEAD is now at a7142dc Personalized\n') %
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000825 join(self.root_dir, '.'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000826
827 def testRevertModified(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000828 if not self.enabled:
829 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000830 options = self.Options()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000831 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
832 relpath=self.relpath)
833 file_list = []
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000834 scm.update(options, None, file_list)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000835 file_path = join(self.base_path, 'a')
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000836 open(file_path, 'a').writelines('touched\n')
837 file_list = []
msb@chromium.orge28e4982009-09-25 20:51:45 +0000838 scm.revert(options, self.args, file_list)
839 self.assertEquals(file_list, [file_path])
840 file_list = []
841 scm.diff(options, self.args, file_list)
842 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000843 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000844 'a7142dc9f0009350b96a11f372b6ea658592aa95')
szager@google.com85d3e3a2011-10-07 17:12:00 +0000845 expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000846 'Fast-forward\n a | 1 +\n b | 1 +\n'
847 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000848 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
szager@google.com85d3e3a2011-10-07 17:12:00 +0000849 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.')
850 self.assertTrue(sys.stdout.getvalue().startswith(expectation))
851 sys.stdout.close()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000852
853 def testRevertNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000854 if not self.enabled:
855 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000856 options = self.Options()
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000857 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
858 relpath=self.relpath)
859 file_list = []
860 scm.update(options, None, file_list)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000861 file_path = join(self.base_path, 'c')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000862 f = open(file_path, 'w')
863 f.writelines('new\n')
864 f.close()
maruel@chromium.org8ef5f542009-11-12 02:05:02 +0000865 Popen(['git', 'add', 'c'], stdout=PIPE,
866 stderr=STDOUT, cwd=self.base_path).communicate()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000867 file_list = []
868 scm.revert(options, self.args, file_list)
869 self.assertEquals(file_list, [file_path])
870 file_list = []
871 scm.diff(options, self.args, file_list)
872 self.assertEquals(file_list, [])
msb@chromium.org0f282062009-11-06 20:14:02 +0000873 self.assertEquals(scm.revinfo(options, self.args, None),
nasser@codeaurora.orgb2b46312010-04-30 20:58:03 +0000874 'a7142dc9f0009350b96a11f372b6ea658592aa95')
szager@google.com85d3e3a2011-10-07 17:12:00 +0000875 expectation = ('\n_____ . at refs/heads/master\nUpdating 069c602..a7142dc\n'
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000876 'Fast-forward\n a | 1 +\n b | 1 +\n'
877 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n\n'
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000878 '________ running \'git reset --hard origin/master\' in \'%s\'\n'
szager@google.com85d3e3a2011-10-07 17:12:00 +0000879 'HEAD is now at a7142dc Personalized\n') % join(self.root_dir, '.')
880 self.assertTrue(sys.stdout.getvalue().startswith(expectation))
881 sys.stdout.close()
msb@chromium.orge28e4982009-09-25 20:51:45 +0000882
883 def testStatusNew(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000884 if not self.enabled:
885 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000886 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000887 file_path = join(self.base_path, 'a')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000888 open(file_path, 'a').writelines('touched\n')
889 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
890 relpath=self.relpath)
891 file_list = []
892 scm.status(options, self.args, file_list)
893 self.assertEquals(file_list, [file_path])
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000894 self.checkstdout(
895 ('\n________ running \'git diff --name-status '
896 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\n') %
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000897 join(self.root_dir, '.'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000898
899 def testStatus2New(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000900 if not self.enabled:
901 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000902 options = self.Options()
903 expected_file_list = []
904 for f in ['a', 'b']:
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +0000905 file_path = join(self.base_path, f)
906 open(file_path, 'a').writelines('touched\n')
907 expected_file_list.extend([file_path])
msb@chromium.orge28e4982009-09-25 20:51:45 +0000908 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
909 relpath=self.relpath)
910 file_list = []
911 scm.status(options, self.args, file_list)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000912 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000913 self.assertEquals(sorted(file_list), expected_file_list)
maruel@chromium.org389d6de2010-09-09 14:14:37 +0000914 self.checkstdout(
915 ('\n________ running \'git diff --name-status '
916 '069c602044c5388d2d15c3f875b057c852003458\' in \'%s\'\nM\ta\nM\tb\n') %
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000917 join(self.root_dir, '.'))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000918
919 def testUpdateCheckout(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000920 if not self.enabled:
921 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000922 options = self.Options(verbose=True)
dpranke@chromium.org330f5342011-03-13 02:56:43 +0000923 root_dir = gclient_scm.os.path.realpath(tempfile.mkdtemp())
msb@chromium.orge28e4982009-09-25 20:51:45 +0000924 relpath = 'foo'
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000925 base_path = join(root_dir, relpath)
926 url = join(self.base_path, '.git')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000927 try:
928 scm = gclient_scm.CreateSCM(url=url, root_dir=root_dir,
929 relpath=relpath)
930 file_list = []
931 scm.update(options, (), file_list)
932 self.assertEquals(len(file_list), 2)
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000933 self.assert_(gclient_scm.os.path.isfile(join(base_path, 'a')))
msb@chromium.org0f282062009-11-06 20:14:02 +0000934 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000935 '069c602044c5388d2d15c3f875b057c852003458')
936 finally:
maruel@chromium.orgba551772010-02-03 18:21:42 +0000937 rmtree(root_dir)
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000938 msg1 = (
939 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +0000940 "________ running 'git clone --progress -b master --verbose %s %s' "
941 "in '%s'\n"
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000942 "Initialized empty Git repository in %s\n") % (
943 join(self.root_dir, '.', '.git'),
944 join(root_dir, 'foo'),
945 root_dir,
946 join(gclient_scm.os.path.realpath(root_dir), 'foo', '.git') + '/')
947 msg2 = (
948 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +0000949 "________ running 'git clone --progress -b master --verbose %s %s'"
950 " in '%s'\n"
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000951 "Cloning into %s...\ndone.\n") % (
952 join(self.root_dir, '.', '.git'),
953 join(root_dir, 'foo'),
954 root_dir,
955 join(gclient_scm.os.path.realpath(root_dir), 'foo'))
956 out = sys.stdout.getvalue()
957 sys.stdout.close()
dpranke@chromium.org330f5342011-03-13 02:56:43 +0000958 sys.stdout = self._old_stdout
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +0000959 self.assertTrue(out in (msg1, msg2), (out, msg1, msg2))
msb@chromium.orge28e4982009-09-25 20:51:45 +0000960
961 def testUpdateUpdate(self):
maruel@chromium.orgea6c2c52009-10-09 20:38:14 +0000962 if not self.enabled:
963 return
msb@chromium.orge28e4982009-09-25 20:51:45 +0000964 options = self.Options()
maruel@chromium.org795a8c12010-10-05 19:54:29 +0000965 expected_file_list = [join(self.base_path, x) for x in ['a', 'b']]
msb@chromium.orge28e4982009-09-25 20:51:45 +0000966 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
967 relpath=self.relpath)
968 file_list = []
969 scm.update(options, (), file_list)
msb@chromium.org0f282062009-11-06 20:14:02 +0000970 self.assertEquals(file_list, expected_file_list)
971 self.assertEquals(scm.revinfo(options, (), None),
msb@chromium.orge28e4982009-09-25 20:51:45 +0000972 'a7142dc9f0009350b96a11f372b6ea658592aa95')
maruel@chromium.orgad80e3b2010-09-09 14:18:28 +0000973 self.checkstdout(
974 '\n_____ . at refs/heads/master\n'
975 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
976 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n')
msb@chromium.orge28e4982009-09-25 20:51:45 +0000977
steveblock@chromium.org98e69452012-02-16 16:36:43 +0000978 def testUpdateReset(self):
979 if not self.enabled:
980 return
981 options = self.Options()
982 options.reset = True
983
984 dir_path = join(self.base_path, 'c')
985 os.mkdir(dir_path)
986 open(join(dir_path, 'nested'), 'w').writelines('new\n')
987
988 file_path = join(self.base_path, 'file')
989 open(file_path, 'w').writelines('new\n')
990
991 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
992 relpath=self.relpath)
993 file_list = []
994 scm.update(options, (), file_list)
995 self.assert_(gclient_scm.os.path.isdir(dir_path))
996 self.assert_(gclient_scm.os.path.isfile(file_path))
997 self.checkstdout(
998 '\n________ running \'git reset --hard HEAD\' in \'%s\''
999 '\nHEAD is now at 069c602 A and B\n'
1000 '\n_____ . at refs/heads/master\n'
1001 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
1002 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n'
1003 % join(self.root_dir, '.'))
1004
1005 def testUpdateResetDeleteUnversionedTrees(self):
1006 if not self.enabled:
1007 return
1008 options = self.Options()
1009 options.reset = True
1010 options.delete_unversioned_trees = True
1011
1012 dir_path = join(self.base_path, 'dir')
1013 os.mkdir(dir_path)
1014 open(join(dir_path, 'nested'), 'w').writelines('new\n')
1015
1016 file_path = join(self.base_path, 'file')
1017 open(file_path, 'w').writelines('new\n')
1018
1019 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1020 relpath=self.relpath)
1021 file_list = []
1022 scm.update(options, (), file_list)
1023 self.assert_(not gclient_scm.os.path.isdir(dir_path))
1024 self.assert_(gclient_scm.os.path.isfile(file_path))
1025 self.checkstdout(
1026 '\n________ running \'git reset --hard HEAD\' in \'%s\''
1027 '\nHEAD is now at 069c602 A and B\n'
1028 '\n_____ . at refs/heads/master\n'
1029 'Updating 069c602..a7142dc\nFast-forward\n a | 1 +\n b | 1 +\n'
1030 ' 2 files changed, 2 insertions(+), 0 deletions(-)\n\n'
1031 '\n_____ removing unversioned directory dir/\n' % join(self.root_dir,
1032 '.'))
1033
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +00001034 def testUpdateUnstagedConflict(self):
1035 if not self.enabled:
1036 return
1037 options = self.Options()
1038 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1039 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001040 file_path = join(self.base_path, 'b')
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00001041 open(file_path, 'w').writelines('conflict\n')
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001042 try:
1043 scm.update(options, (), [])
1044 self.fail()
maruel@chromium.orgfae707b2011-09-15 18:57:58 +00001045 except (gclient_scm.gclient_utils.Error, subprocess2.CalledProcessError):
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001046 # The exact exception text varies across git versions so it's not worth
1047 # verifying it. It's fine as long as it throws.
1048 pass
1049 # Manually flush stdout since we can't verify it's content accurately across
1050 # git versions.
1051 sys.stdout.getvalue()
1052 sys.stdout.close()
nasser@codeaurora.orgd90ba3f2010-02-23 14:42:57 +00001053
msb@chromium.org5bde4852009-12-14 16:47:12 +00001054 def testUpdateConflict(self):
1055 if not self.enabled:
1056 return
1057 options = self.Options()
1058 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1059 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001060 file_path = join(self.base_path, 'b')
maruel@chromium.orgbf38a7e2010-12-14 18:15:54 +00001061 open(file_path, 'w').writelines('conflict\n')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001062 scm._Run(['commit', '-am', 'test'], options)
1063 __builtin__.raw_input = lambda x: 'y'
1064 exception = ('Conflict while rebasing this branch.\n'
1065 'Fix the conflict and run gclient again.\n'
1066 'See \'man git-rebase\' for details.\n')
msb@chromium.org5bde4852009-12-14 16:47:12 +00001067 self.assertRaisesError(exception, scm.update, options, (), [])
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001068 exception = ('\n____ . at refs/heads/master\n'
1069 '\tYou have unstaged changes.\n'
1070 '\tPlease commit, stash, or reset.\n')
msb@chromium.org5bde4852009-12-14 16:47:12 +00001071 self.assertRaisesError(exception, scm.update, options, (), [])
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001072 # The hash always changes. Use a cheap trick.
1073 start = ('\n________ running \'git commit -am test\' in \'%s\'\n'
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001074 '[new ') % join(self.root_dir, '.')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001075 end = ('] test\n 1 files changed, 1 insertions(+), '
1076 '1 deletions(-)\n\n_____ . at refs/heads/master\n'
1077 'Attempting rebase onto refs/remotes/origin/master...\n')
maruel@chromium.orgcb2985f2010-11-03 14:08:31 +00001078 self.assertTrue(sys.stdout.getvalue().startswith(start))
1079 self.assertTrue(sys.stdout.getvalue().endswith(end))
1080 self.assertEquals(len(sys.stdout.getvalue()),
maruel@chromium.orgdd057f32010-09-20 19:33:31 +00001081 len(start) + len(end) + 7)
maruel@chromium.orgcb2985f2010-11-03 14:08:31 +00001082 sys.stdout.close()
msb@chromium.org5bde4852009-12-14 16:47:12 +00001083
msb@chromium.orge4af1ab2010-01-13 21:26:09 +00001084 def testUpdateNotGit(self):
1085 if not self.enabled:
1086 return
1087 options = self.Options()
1088 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1089 relpath=self.relpath)
maruel@chromium.org795a8c12010-10-05 19:54:29 +00001090 git_path = join(self.base_path, '.git')
maruel@chromium.orgba551772010-02-03 18:21:42 +00001091 rename(git_path, git_path + 'foo')
maruel@chromium.org389d6de2010-09-09 14:14:37 +00001092 exception = ('\n____ . at refs/heads/master\n'
1093 '\tPath is not a git repo. No .git dir.\n'
1094 '\tTo resolve:\n'
1095 '\t\trm -rf .\n'
1096 '\tAnd run gclient sync again\n')
msb@chromium.orge4af1ab2010-01-13 21:26:09 +00001097 self.assertRaisesError(exception, scm.update, options, (), [])
1098
msb@chromium.org0f282062009-11-06 20:14:02 +00001099 def testRevinfo(self):
1100 if not self.enabled:
1101 return
1102 options = self.Options()
1103 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1104 relpath=self.relpath)
1105 rev_info = scm.revinfo(options, (), None)
1106 self.assertEquals(rev_info, '069c602044c5388d2d15c3f875b057c852003458')
1107
msb@chromium.orge28e4982009-09-25 20:51:45 +00001108
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001109class ManagedGitWrapperTestCaseMox(BaseTestCase):
1110 class OptionsObject(object):
1111 def __init__(self, verbose=False, revision=None, force=False):
1112 self.verbose = verbose
1113 self.revision = revision
1114 self.deps_os = None
1115 self.force = force
1116 self.reset = False
1117 self.nohooks = False
1118 # TODO(maruel): Test --jobs > 1.
1119 self.jobs = 1
1120
1121 def Options(self, *args, **kwargs):
1122 return self.OptionsObject(*args, **kwargs)
1123
1124 def setUp(self):
1125 BaseTestCase.setUp(self)
1126 self.fake_hash_1 = 't0ta11yf4k3'
1127 self.fake_hash_2 = '3v3nf4k3r'
1128 self.url = 'git://foo'
1129 self.root_dir = '/tmp'
1130 self.relpath = 'fake'
1131 self.base_path = os.path.join(self.root_dir, self.relpath)
1132
1133 def tearDown(self):
1134 BaseTestCase.tearDown(self)
1135
1136 def testGetUsableRevGit(self):
1137 # pylint: disable=E1101
1138 options = self.Options(verbose=True)
1139
1140 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True)
1141 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1
1142 ).AndReturn(True)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001143
1144 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
1145 gclient_scm.scm.GIT.IsGitSvn(cwd=self.base_path).MultipleTimes(
1146 ).AndReturn(False)
1147
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001148 gclient_scm.scm.os.path.isdir(self.base_path).AndReturn(True)
1149
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001150 self.mox.ReplayAll()
1151
1152 git_scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1153 relpath=self.relpath)
1154 # A [fake] git sha1 with a git repo should work (this is in the case that
1155 # the LKGR gets flipped to git sha1's some day).
1156 self.assertEquals(git_scm.GetUsableRev(self.fake_hash_1, options),
1157 self.fake_hash_1)
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001158 # An SVN rev with an existing purely git repo should raise an exception.
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001159 self.assertRaises(gclient_scm.gclient_utils.Error,
1160 git_scm.GetUsableRev, '1', options)
1161
1162 def testGetUsableRevGitSvn(self):
1163 # pylint: disable=E1101
1164 options = self.Options()
1165 too_big = str(1e7)
1166
1167 # Pretend like the git-svn repo's HEAD is at r2.
1168 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'GetGitSvnHeadRev', True)
1169 gclient_scm.scm.GIT.GetGitSvnHeadRev(cwd=self.base_path).MultipleTimes(
1170 ).AndReturn(2)
1171
1172 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'GetSha1ForSvnRev', True)
1173 # r1 -> first fake hash, r3 -> second fake hash.
1174 gclient_scm.scm.GIT.GetSha1ForSvnRev(cwd=self.base_path, rev='1'
1175 ).AndReturn(self.fake_hash_1)
1176 gclient_scm.scm.GIT.GetSha1ForSvnRev(cwd=self.base_path, rev='3'
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001177 ).MultipleTimes().AndReturn(self.fake_hash_2)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001178
1179 # Ensure that we call git svn fetch if our LKGR is > the git-svn HEAD rev.
1180 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'Capture', True)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001181 gclient_scm.scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
1182 cwd=self.base_path).AndReturn('blah')
1183 gclient_scm.scm.GIT.Capture(['fetch'], cwd=self.base_path)
1184 gclient_scm.scm.GIT.Capture(['svn', 'fetch'], cwd=self.base_path)
1185 error = subprocess2.CalledProcessError(1, 'cmd', '/cwd', 'stdout', 'stderr')
1186 gclient_scm.scm.GIT.Capture(['config', '--get', 'svn-remote.svn.fetch'],
1187 cwd=self.base_path).AndRaise(error)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001188 gclient_scm.scm.GIT.Capture(['svn', 'fetch'], cwd=self.base_path)
1189
1190 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsGitSvn', True)
1191 gclient_scm.scm.GIT.IsGitSvn(cwd=self.base_path).MultipleTimes(
1192 ).AndReturn(True)
1193
1194 self.mox.StubOutWithMock(gclient_scm.scm.GIT, 'IsValidRevision', True)
1195 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=self.fake_hash_1
1196 ).AndReturn(True)
1197 gclient_scm.scm.GIT.IsValidRevision(cwd=self.base_path, rev=too_big
1198 ).AndReturn(False)
1199
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001200 gclient_scm.os.path.isdir(self.base_path).AndReturn(False)
1201 gclient_scm.os.path.isdir(self.base_path).MultipleTimes().AndReturn(True)
1202
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001203 self.mox.ReplayAll()
1204
1205 git_svn_scm = self._scm_wrapper(url=self.url, root_dir=self.root_dir,
1206 relpath=self.relpath)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001207 # Without an existing checkout, this should fail.
1208 # TODO(dbeam) Fix this. http://crbug.com/109184
dbeam@chromium.org051c88b2011-12-22 00:23:03 +00001209 self.assertRaises(gclient_scm.gclient_utils.Error,
1210 git_svn_scm.GetUsableRev, '1', options)
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001211 # Given an SVN revision with a git-svn checkout, it should be translated to
1212 # a git sha1 and be usable.
1213 self.assertEquals(git_svn_scm.GetUsableRev('1', options),
1214 self.fake_hash_1)
dbeam@chromium.org2a75fdb2012-02-15 01:32:57 +00001215 # Our fake HEAD rev is r2, so this should call git fetch and git svn fetch
1216 # to get more revs (pymox will complain if this doesn't happen). We mock an
1217 # optimized checkout the first time, so this run should call git fetch.
1218 self.assertEquals(git_svn_scm.GetUsableRev('3', options),
1219 self.fake_hash_2)
1220 # The time we pretend we're not optimized, so no git fetch should fire.
dbeam@chromium.orge5d1e612011-12-19 19:49:19 +00001221 self.assertEquals(git_svn_scm.GetUsableRev('3', options),
1222 self.fake_hash_2)
1223 # Given a git sha1 with a git-svn checkout, it should be used as is.
1224 self.assertEquals(git_svn_scm.GetUsableRev(self.fake_hash_1, options),
1225 self.fake_hash_1)
1226 # We currently check for seemingly valid SVN revisions by assuming 6 digit
1227 # numbers, so assure that numeric revs >= 1000000 don't work.
1228 self.assertRaises(gclient_scm.gclient_utils.Error,
1229 git_svn_scm.GetUsableRev, too_big, options)
1230
1231
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001232class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
1233 def testUpdateCheckout(self):
1234 if not self.enabled:
1235 return
1236 options = self.Options(verbose=True)
1237 root_dir = gclient_scm.os.path.realpath(tempfile.mkdtemp())
1238 relpath = 'foo'
1239 base_path = join(root_dir, relpath)
1240 url = join(self.base_path, '.git')
1241 try:
1242 scm = gclient_scm.CreateSCM(url=url, root_dir=root_dir,
1243 relpath=relpath)
1244 file_list = []
1245 options.revision = 'unmanaged'
1246 scm.update(options, (), file_list)
1247 self.assertEquals(len(file_list), 2)
1248 self.assert_(gclient_scm.os.path.isfile(join(base_path, 'a')))
1249 self.assertEquals(scm.revinfo(options, (), None),
1250 '069c602044c5388d2d15c3f875b057c852003458')
1251 finally:
1252 rmtree(root_dir)
1253 msg1 = (
1254 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +00001255 "________ running 'git clone --progress -b master --verbose %s %s'"
1256 " in '%s'\n"
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001257 "Initialized empty Git repository in %s\n") % (
1258 join(self.root_dir, '.', '.git'),
1259 join(root_dir, 'foo'),
1260 root_dir,
1261 join(gclient_scm.os.path.realpath(root_dir), 'foo', '.git') + '/')
1262 msg2 = (
1263 "\n_____ foo at refs/heads/master\n\n"
szager@google.com85d3e3a2011-10-07 17:12:00 +00001264 "________ running 'git clone --progress -b master --verbose %s %s'"
1265 " in '%s'\n"
cmp@chromium.orgeb2756d2011-09-20 20:17:51 +00001266 "Cloning into %s...\ndone.\n") % (
1267 join(self.root_dir, '.', '.git'),
1268 join(root_dir, 'foo'),
1269 root_dir,
1270 join(gclient_scm.os.path.realpath(root_dir), 'foo'))
1271 out = sys.stdout.getvalue()
1272 sys.stdout.close()
1273 sys.stdout = self._old_stdout
1274 self.assertTrue(out in (msg1, msg2), (out, msg1, msg2))
1275
1276 def testUpdateUpdate(self):
1277 if not self.enabled:
1278 return
1279 options = self.Options()
1280 expected_file_list = []
1281 scm = gclient_scm.CreateSCM(url=self.url, root_dir=self.root_dir,
1282 relpath=self.relpath)
1283 file_list = []
1284 options.revision = 'unmanaged'
1285 scm.update(options, (), file_list)
1286 self.assertEquals(file_list, expected_file_list)
1287 self.assertEquals(scm.revinfo(options, (), None),
1288 '069c602044c5388d2d15c3f875b057c852003458')
1289 self.checkstdout('________ unmanaged solution; skipping .\n')
1290
1291
msb@chromium.orge28e4982009-09-25 20:51:45 +00001292if __name__ == '__main__':
maruel@chromium.orgcdbecc42011-02-09 04:31:47 +00001293 if '-v' in sys.argv:
1294 logging.basicConfig(
1295 level=logging.DEBUG,
1296 format='%(asctime).19s %(levelname)s %(filename)s:'
1297 '%(lineno)s %(message)s')
msb@chromium.orge28e4982009-09-25 20:51:45 +00001298 unittest.main()
1299
1300# vim: ts=2:sw=2:tw=80:et: