| #!/usr/bin/env python |
| # Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Unit tests for scm.py.""" |
| |
| import logging |
| import os |
| import sys |
| import unittest |
| |
| sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) |
| |
| from testing_support import fake_repos |
| from testing_support.super_mox import SuperMoxTestBase |
| |
| import scm |
| import subprocess2 |
| |
| |
| # Access to a protected member XXX of a client class |
| # pylint: disable=W0212 |
| |
| |
| class BaseTestCase(SuperMoxTestBase): |
| # Like unittest's assertRaises, but checks for Gclient.Error. |
| def assertRaisesError(self, msg, fn, *args, **kwargs): |
| try: |
| fn(*args, **kwargs) |
| except scm.gclient_utils.Error, e: |
| self.assertEquals(e.args[0], msg) |
| else: |
| self.fail('%s not raised' % msg) |
| |
| |
| class BaseSCMTestCase(BaseTestCase): |
| def setUp(self): |
| BaseTestCase.setUp(self) |
| self.mox.StubOutWithMock(scm.gclient_utils, 'CheckCallAndFilter') |
| self.mox.StubOutWithMock(scm.gclient_utils, 'CheckCallAndFilterAndHeader') |
| self.mox.StubOutWithMock(subprocess2, 'Popen') |
| self.mox.StubOutWithMock(subprocess2, 'communicate') |
| |
| |
| class RootTestCase(BaseSCMTestCase): |
| def testMembersChanged(self): |
| self.mox.ReplayAll() |
| members = [ |
| 'cStringIO', |
| 'determine_scm', |
| 'ElementTree', |
| 'gclient_utils', |
| 'GenFakeDiff', |
| 'GetCasedPath', |
| 'GIT', |
| 'glob', |
| 'logging', |
| 'only_int', |
| 'os', |
| 're', |
| 'subprocess2', |
| 'SVN', |
| 'sys', |
| 'tempfile', |
| 'time', |
| 'ValidateEmail', |
| ] |
| # If this test fails, you should add the relevant test. |
| self.compareMembers(scm, members) |
| |
| |
| class GitWrapperTestCase(BaseSCMTestCase): |
| def testMembersChanged(self): |
| members = [ |
| 'ApplyEnvVars', |
| 'AssertVersion', |
| 'Capture', |
| 'CaptureStatus', |
| 'CleanupDir', |
| 'current_version', |
| 'FetchUpstreamTuple', |
| 'GenerateDiff', |
| 'GetBlessedSha1ForSvnRev', |
| 'GetBranch', |
| 'GetBranchRef', |
| 'GetCheckoutRoot', |
| 'GetDifferentFiles', |
| 'GetEmail', |
| 'GetGitDir', |
| 'GetGitSvnHeadRev', |
| 'GetPatchName', |
| 'GetSha1ForSvnRev', |
| 'GetSVNBranch', |
| 'GetUpstreamBranch', |
| 'IsDirectoryVersioned', |
| 'IsGitSvn', |
| 'IsInsideWorkTree', |
| 'IsValidRevision', |
| 'IsWorkTreeDirty', |
| 'MatchSvnGlob', |
| 'ParseGitSvnSha1', |
| 'RefToRemoteRef', |
| 'ShortBranchName', |
| ] |
| # If this test fails, you should add the relevant test. |
| self.compareMembers(scm.GIT, members) |
| |
| def testGetEmail(self): |
| self.mox.StubOutWithMock(scm.GIT, 'Capture') |
| scm.GIT.Capture(['config', 'user.email'], cwd=self.root_dir |
| ).AndReturn('[email protected]') |
| self.mox.ReplayAll() |
| self.assertEqual(scm.GIT.GetEmail(self.root_dir), '[email protected]') |
| |
| def testMatchSvnGlob(self): |
| self.assertEquals(scm.GIT.MatchSvnGlob( |
| 'svn://svn.chromium.org/chrome/trunk/src', |
| 'svn://svn.chromium.org/chrome', |
| 'trunk/src:refs/remotes/origin/trunk', |
| False), 'refs/remotes/origin/trunk') |
| self.assertEquals(scm.GIT.MatchSvnGlob( |
| 'https://v8.googlecode.com/svn/branches/bleeding_edge', |
| 'https://v8.googlecode.com/svn', |
| 'branches/*:refs/remotes/*', |
| True), 'refs/remotes/bleeding_edge') |
| |
| def testRefToRemoteRefNoRemote(self): |
| refs = { |
| # local ref for upstream branch-head |
| 'refs/remotes/branch-heads/1234': ('refs/remotes/branch-heads/', |
| '1234'), |
| # upstream ref for branch-head |
| 'refs/branch-heads/1234': ('refs/remotes/branch-heads/', '1234'), |
| # could be either local or upstream ref, assumed to refer to |
| # upstream, but probably don't want to encourage refs like this. |
| 'branch-heads/1234': ('refs/remotes/branch-heads/', '1234'), |
| # actively discouraging refs like this, should prepend with 'refs/' |
| 'remotes/branch-heads/1234': None, |
| # might be non-"branch-heads" upstream branches, but can't resolve |
| # without knowing the remote. |
| 'refs/heads/1234': None, |
| 'heads/1234': None, |
| # underspecified, probably intended to refer to a local branch |
| '1234': None, |
| } |
| for k, v in refs.items(): |
| r = scm.GIT.RefToRemoteRef(k) |
| self.assertEqual(r, v, msg='%s -> %s, expected %s' % (k, r, v)) |
| |
| def testRefToRemoteRefWithRemote(self): |
| remote = 'origin' |
| refs = { |
| # This shouldn't be any different from the NoRemote() version. |
| 'refs/branch-heads/1234': ('refs/remotes/branch-heads/', '1234'), |
| # local refs for upstream branch |
| 'refs/remotes/%s/foobar' % remote: ('refs/remotes/%s/' % remote, |
| 'foobar'), |
| '%s/foobar' % remote: ('refs/remotes/%s/' % remote, 'foobar'), |
| # upstream ref for branch |
| 'refs/heads/foobar': ('refs/remotes/%s/' % remote, 'foobar'), |
| # could be either local or upstream ref, assumed to refer to |
| # upstream, but probably don't want to encourage refs like this. |
| 'heads/foobar': ('refs/remotes/%s/' % remote, 'foobar'), |
| # underspecified, probably intended to refer to a local branch |
| 'foobar': None, |
| } |
| for k, v in refs.items(): |
| r = scm.GIT.RefToRemoteRef(k, remote) |
| self.assertEqual(r, v, msg='%s -> %s, expected %s' % (k, r, v)) |
| |
| |
| class RealGitTest(fake_repos.FakeReposTestBase): |
| def setUp(self): |
| super(RealGitTest, self).setUp() |
| self.enabled = self.FAKE_REPOS.set_up_git() |
| if self.enabled: |
| self.clone_dir = scm.os.path.join(self.FAKE_REPOS.git_root, 'repo_1') |
| |
| def testIsValidRevision(self): |
| if not self.enabled: |
| return |
| # Sha1's are [0-9a-z]{32}, so starting with a 'z' or 'r' should always fail. |
| self.assertFalse(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='zebra')) |
| self.assertFalse(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='r123456')) |
| # Valid cases |
| first_rev = self.githash('repo_1', 1) |
| self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev=first_rev)) |
| self.assertTrue(scm.GIT.IsValidRevision(cwd=self.clone_dir, rev='HEAD')) |
| |
| |
| if __name__ == '__main__': |
| if '-v' in sys.argv: |
| logging.basicConfig(level=logging.DEBUG) |
| unittest.main() |
| |
| # vim: ts=2:sw=2:tw=80:et: |