| OLD | NEW |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Unit tests for scm.py.""" | 6 """Unit tests for scm.py.""" |
| 7 | 7 |
| 8 import logging | 8 import logging |
| 9 import os | 9 import os |
| 10 import sys | 10 import sys |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 return | 182 return |
| 183 # Sha1's are [0-9a-z]{32}, so starting with a 'z' or 'r' should always fail. | 183 # Sha1's are [0-9a-z]{32}, so starting with a 'z' or 'r' should always fail. |
| 184 self.assertFalse(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='zebra')) | 184 self.assertFalse(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='zebra')) |
| 185 self.assertFalse(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='r123456')) | 185 self.assertFalse(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='r123456')) |
| 186 # Valid cases | 186 # Valid cases |
| 187 first_rev = self.githash('repo_1', 1) | 187 first_rev = self.githash('repo_1', 1) |
| 188 self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev=first_rev)) | 188 self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev=first_rev)) |
| 189 self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='HEAD')) | 189 self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='HEAD')) |
| 190 | 190 |
| 191 | 191 |
| 192 class RealGitSvnTest(fake_repos.FakeReposTestBase): | |
| 193 def setUp(self): | |
| 194 super(RealGitSvnTest, self).setUp() | |
| 195 self.enabled = self.FAKE_REPOS.set_up_git() and self.FAKE_REPOS.set_up_svn() | |
| 196 if self.enabled: | |
| 197 self.tree_name = 'git-svn' | |
| 198 self.svn_url = scm.os.path.join(self.FAKE_REPOS.svn_base, 'trunk') | |
| 199 self.clone_dir = scm.os.path.join(self.FAKE_REPOS.git_root, | |
| 200 self.tree_name) | |
| 201 scm.os.makedirs(self.clone_dir) | |
| 202 self._capture(['svn', 'clone', '-q', '-q', self.svn_url, self.clone_dir]) | |
| 203 # git rev-list gives revisions in reverse chronological order. | |
| 204 hashes = reversed(self._capture(['rev-list', 'HEAD']).splitlines()) | |
| 205 # We insert a null value at 0 to do 1-based indexing, not 0-based, as SVN | |
| 206 # revisions are 1-based (i.e. they start at r1, not r0). | |
| 207 self.git_hashes = ([None] + list(hashes)) | |
| 208 | |
| 209 def tearDown(self): | |
| 210 scm.gclient_utils.rmtree(self.clone_dir) | |
| 211 | |
| 212 def _capture(self, cmd, **kwargs): | |
| 213 kwargs.setdefault('cwd', self.clone_dir) | |
| 214 return scm.GIT.Capture(cmd, **kwargs) | |
| 215 | |
| 216 def testGetGitSvnHeadRev(self): | |
| 217 if not self.enabled: | |
| 218 return | |
| 219 self.assertEquals(scm.GIT.GetGitSvnHeadRev(cwd=self.clone_dir), 2) | |
| 220 self._capture(['reset', '--hard', 'HEAD^']) | |
| 221 self.assertEquals(scm.GIT.GetGitSvnHeadRev(cwd=self.clone_dir), 1) | |
| 222 | |
| 223 def testIsGitSvn(self): | |
| 224 if not self.enabled: | |
| 225 return | |
| 226 # Git-svn | |
| 227 self.assertTrue(scm.GIT.IsGitSvn(self.clone_dir)) | |
| 228 # Pure git | |
| 229 git_dir = scm.os.path.join(self.FAKE_REPOS.git_root, 'repo_1') | |
| 230 self.assertFalse(scm.GIT.IsGitSvn(git_dir)) | |
| 231 # Pure svn | |
| 232 svn_dir = scm.os.path.join(self.FAKE_REPOS.svn_checkout, 'trunk') | |
| 233 self.assertFalse(scm.GIT.IsGitSvn(svn_dir)) | |
| 234 | |
| 235 def testParseGitSvnSha1(self): | |
| 236 test_sha1 = 'a5c63ce8671922e5c59c0dea49ef4f9d4a3020c9' | |
| 237 expected_output = test_sha1 + '\n' | |
| 238 # Cygwin git-svn 1.7.9 prints extra escape sequences when run under | |
| 239 # TERM=xterm | |
| 240 cygwin_output = test_sha1 + '\n\033[?1034h' | |
| 241 | |
| 242 self.assertEquals(scm.GIT.ParseGitSvnSha1(expected_output), test_sha1) | |
| 243 self.assertEquals(scm.GIT.ParseGitSvnSha1(cygwin_output), test_sha1) | |
| 244 | |
| 245 def testGetGetSha1ForSvnRev(self): | |
| 246 if not self.enabled: | |
| 247 return | |
| 248 self.assertEquals(scm.GIT.GetSha1ForSvnRev(cwd=self.clone_dir, rev=1), | |
| 249 self.git_hashes[1]) | |
| 250 self.assertEquals(scm.GIT.GetSha1ForSvnRev(cwd=self.clone_dir, rev=2), | |
| 251 self.git_hashes[2]) | |
| 252 | |
| 253 | |
| 254 class SVNTestCase(BaseSCMTestCase): | |
| 255 def setUp(self): | |
| 256 BaseSCMTestCase.setUp(self) | |
| 257 self.mox.StubOutWithMock(scm.SVN, 'Capture') | |
| 258 self.url = self.SvnUrl() | |
| 259 | |
| 260 def testMembersChanged(self): | |
| 261 self.mox.ReplayAll() | |
| 262 members = [ | |
| 263 'AssertVersion', | |
| 264 'Capture', | |
| 265 'CaptureLocalInfo', | |
| 266 'CaptureRemoteInfo', | |
| 267 'CaptureRevision', | |
| 268 'CaptureStatus', | |
| 269 'current_version', | |
| 270 'GenerateDiff', | |
| 271 'GetCheckoutRoot', | |
| 272 'GetEmail', | |
| 273 'GetFileProperty', | |
| 274 'IsMoved', | |
| 275 'IsMovedInfo', | |
| 276 'IsValidRevision', | |
| 277 'ReadSimpleAuth', | |
| 278 'Revert', | |
| 279 'RunAndGetFileList', | |
| 280 ] | |
| 281 # If this test fails, you should add the relevant test. | |
| 282 self.compareMembers(scm.SVN, members) | |
| 283 | |
| 284 def testGetCheckoutRoot(self): | |
| 285 # pylint: disable=E1103 | |
| 286 self.mox.StubOutWithMock(scm.SVN, '_CaptureInfo') | |
| 287 self.mox.StubOutWithMock(scm, 'GetCasedPath') | |
| 288 scm.os.path.abspath = lambda x: x | |
| 289 scm.GetCasedPath = lambda x: x | |
| 290 scm.SVN._CaptureInfo([], self.root_dir + '/foo/bar').AndReturn({ | |
| 291 'Repository Root': 'svn://svn.chromium.org/chrome', | |
| 292 'URL': 'svn://svn.chromium.org/chrome/trunk/src', | |
| 293 }) | |
| 294 scm.SVN._CaptureInfo([], self.root_dir + '/foo').AndReturn({ | |
| 295 'Repository Root': 'svn://svn.chromium.org/chrome', | |
| 296 'URL': 'svn://svn.chromium.org/chrome/trunk', | |
| 297 }) | |
| 298 scm.SVN._CaptureInfo([], self.root_dir).AndReturn({ | |
| 299 'Repository Root': 'svn://svn.chromium.org/chrome', | |
| 300 'URL': 'svn://svn.chromium.org/chrome/trunk/tools/commit-queue/workdir', | |
| 301 }) | |
| 302 self.mox.ReplayAll() | |
| 303 self.assertEquals(scm.SVN.GetCheckoutRoot(self.root_dir + '/foo/bar'), | |
| 304 self.root_dir + '/foo') | |
| 305 | |
| 306 def testGetFileInfo(self): | |
| 307 xml_text = r"""<?xml version="1.0"?> | |
| 308 <info> | |
| 309 <entry kind="file" path="%s" revision="14628"> | |
| 310 <url>http://src.chromium.org/svn/trunk/src/chrome/app/d</url> | |
| 311 <repository><root>http://src.chromium.org/svn</root></repository> | |
| 312 <wc-info> | |
| 313 <schedule>add</schedule> | |
| 314 <depth>infinity</depth> | |
| 315 <copy-from-url>http://src.chromium.org/svn/trunk/src/chrome/app/DEPS</copy-from-
url> | |
| 316 <copy-from-rev>14628</copy-from-rev> | |
| 317 <checksum>369f59057ba0e6d9017e28f8bdfb1f43</checksum> | |
| 318 </wc-info> | |
| 319 </entry> | |
| 320 </info> | |
| 321 """ % self.url | |
| 322 scm.SVN.Capture(['info', '--xml', self.url], None).AndReturn(xml_text) | |
| 323 expected = { | |
| 324 'URL': 'http://src.chromium.org/svn/trunk/src/chrome/app/d', | |
| 325 'UUID': None, | |
| 326 'Repository Root': 'http://src.chromium.org/svn', | |
| 327 'Schedule': 'add', | |
| 328 'Copied From URL': | |
| 329 'http://src.chromium.org/svn/trunk/src/chrome/app/DEPS', | |
| 330 'Copied From Rev': '14628', | |
| 331 'Path': self.url, | |
| 332 'Revision': 14628, | |
| 333 'Node Kind': 'file', | |
| 334 } | |
| 335 self.mox.ReplayAll() | |
| 336 file_info = scm.SVN._CaptureInfo([self.url], None) | |
| 337 self.assertEquals(sorted(file_info.items()), sorted(expected.items())) | |
| 338 | |
| 339 def testCaptureInfo(self): | |
| 340 xml_text = """<?xml version="1.0"?> | |
| 341 <info> | |
| 342 <entry | |
| 343 kind="dir" | |
| 344 path="." | |
| 345 revision="35"> | |
| 346 <url>%s</url> | |
| 347 <repository> | |
| 348 <root>%s</root> | |
| 349 <uuid>7b9385f5-0452-0410-af26-ad4892b7a1fb</uuid> | |
| 350 </repository> | |
| 351 <wc-info> | |
| 352 <schedule>normal</schedule> | |
| 353 <depth>infinity</depth> | |
| 354 </wc-info> | |
| 355 <commit | |
| 356 revision="35"> | |
| 357 <author>maruel</author> | |
| 358 <date>2008-12-04T20:12:19.685120Z</date> | |
| 359 </commit> | |
| 360 </entry> | |
| 361 </info> | |
| 362 """ % (self.url, self.root_dir) | |
| 363 scm.SVN.Capture(['info', '--xml', self.url], None).AndReturn(xml_text) | |
| 364 self.mox.ReplayAll() | |
| 365 file_info = scm.SVN._CaptureInfo([self.url], None) | |
| 366 expected = { | |
| 367 'URL': self.url, | |
| 368 'UUID': '7b9385f5-0452-0410-af26-ad4892b7a1fb', | |
| 369 'Revision': 35, | |
| 370 'Repository Root': self.root_dir, | |
| 371 'Schedule': 'normal', | |
| 372 'Copied From URL': None, | |
| 373 'Copied From Rev': None, | |
| 374 'Path': '.', | |
| 375 'Node Kind': 'directory', | |
| 376 } | |
| 377 self.assertEqual(file_info, expected) | |
| 378 | |
| 379 def testCaptureStatus(self): | |
| 380 text = r"""<?xml version="1.0"?> | |
| 381 <status> | |
| 382 <target path="."> | |
| 383 <entry path="unversionned_file.txt"> | |
| 384 <wc-status props="none" item="unversioned"></wc-status> | |
| 385 </entry> | |
| 386 <entry path="build\internal\essential.vsprops"> | |
| 387 <wc-status props="normal" item="modified" revision="14628"> | |
| 388 <commit revision="13818"> | |
| 389 <author>ajwong@chromium.org</author> | |
| 390 <date>2009-04-16T00:42:06.872358Z</date> | |
| 391 </commit> | |
| 392 </wc-status> | |
| 393 </entry> | |
| 394 <entry path="chrome\app\d"> | |
| 395 <wc-status props="none" copied="true" tree-conflicted="true" item="added"> | |
| 396 </wc-status> | |
| 397 </entry> | |
| 398 <entry path="chrome\app\DEPS"> | |
| 399 <wc-status props="modified" item="modified" revision="14628"> | |
| 400 <commit revision="1279"> | |
| 401 <author>brettw@google.com</author> | |
| 402 <date>2008-08-23T17:16:42.090152Z</date> | |
| 403 </commit> | |
| 404 </wc-status> | |
| 405 </entry> | |
| 406 <entry path="scripts\master\factory\gclient_factory.py"> | |
| 407 <wc-status props="normal" item="conflicted" revision="14725"> | |
| 408 <commit revision="14633"> | |
| 409 <author>nsylvain@chromium.org</author> | |
| 410 <date>2009-04-27T19:37:17.977400Z</date> | |
| 411 </commit> | |
| 412 </wc-status> | |
| 413 </entry> | |
| 414 </target> | |
| 415 </status> | |
| 416 """ | |
| 417 scm.SVN.Capture(['status', '--xml'], '.').AndReturn(text) | |
| 418 | |
| 419 self.mox.ReplayAll() | |
| 420 info = scm.SVN.CaptureStatus(None, '.') | |
| 421 expected = [ | |
| 422 ('? ', 'unversionned_file.txt'), | |
| 423 ('M ', 'build\\internal\\essential.vsprops'), | |
| 424 ('A + ', 'chrome\\app\\d'), | |
| 425 ('MM ', 'chrome\\app\\DEPS'), | |
| 426 ('C ', 'scripts\\master\\factory\\gclient_factory.py'), | |
| 427 ] | |
| 428 self.assertEquals(sorted(info), sorted(expected)) | |
| 429 | |
| 430 def testCaptureStatusEmpty(self): | |
| 431 text = r"""<?xml version="1.0"?> | |
| 432 <status> | |
| 433 <target | |
| 434 path="perf"> | |
| 435 </target> | |
| 436 </status>""" | |
| 437 scm.SVN.Capture(['status', '--xml'], None).AndReturn(text) | |
| 438 self.mox.ReplayAll() | |
| 439 info = scm.SVN.CaptureStatus(None, None) | |
| 440 self.assertEquals(info, []) | |
| 441 | |
| 442 | |
| 443 class RealSvnTest(fake_repos.FakeReposTestBase): | |
| 444 # Tests that work with a checkout. | |
| 445 def setUp(self): | |
| 446 super(RealSvnTest, self).setUp() | |
| 447 self.enabled = self.FAKE_REPOS.set_up_svn() | |
| 448 if self.enabled: | |
| 449 self.svn_root = scm.os.path.join(self.root_dir, 'base') | |
| 450 scm.SVN.Capture( | |
| 451 ['checkout', self.svn_base + 'trunk/third_party', 'base'], | |
| 452 cwd=self.root_dir) | |
| 453 self.tree = self.mangle_svn_tree(('trunk/third_party@-1', ''),) | |
| 454 | |
| 455 def _capture(self, cmd, **kwargs): | |
| 456 kwargs.setdefault('cwd', self.svn_root) | |
| 457 return scm.SVN.Capture(cmd, **kwargs) | |
| 458 | |
| 459 def testCheckout(self): | |
| 460 if not self.enabled: | |
| 461 return | |
| 462 # Checkout and verify the tree. | |
| 463 self.assertTree(self.tree, self.svn_root) | |
| 464 | |
| 465 def testIsValidRevision(self): | |
| 466 if not self.enabled: | |
| 467 return | |
| 468 url_at_rev = self.svn_base + 'trunk/third_party@%s' | |
| 469 # Invalid or non-existent. | |
| 470 self.assertFalse(scm.SVN.IsValidRevision('url://totally_invalid/trunk/foo')) | |
| 471 self.assertFalse(scm.SVN.IsValidRevision(url_at_rev % 0)) | |
| 472 self.assertFalse(scm.SVN.IsValidRevision(url_at_rev % 123)) | |
| 473 # Valid. | |
| 474 self.assertTrue(scm.SVN.IsValidRevision(url_at_rev % 1)) | |
| 475 self.assertTrue(scm.SVN.IsValidRevision(url_at_rev % 2)) | |
| 476 self.assertTrue(scm.SVN.IsValidRevision(url_at_rev % 'HEAD')) | |
| 477 | |
| 478 | |
| 479 if __name__ == '__main__': | 192 if __name__ == '__main__': |
| 480 if '-v' in sys.argv: | 193 if '-v' in sys.argv: |
| 481 logging.basicConfig(level=logging.DEBUG) | 194 logging.basicConfig(level=logging.DEBUG) |
| 482 unittest.main() | 195 unittest.main() |
| 483 | 196 |
| 484 # vim: ts=2:sw=2:tw=80:et: | 197 # vim: ts=2:sw=2:tw=80:et: |
| OLD | NEW |