@ -17,10 +17,13 @@ import shutil
import sys
import tempfile
import unittest
from unittest import mock
sys . path . insert ( 0 , os . path . dirname ( os . path . dirname ( os . path . abspath ( __file__ ) ) ) )
import scm_mock
import metrics
import metrics_utils
# We have to disable monitoring before importing git_cl.
@ -84,33 +87,6 @@ class ChangelistMock(object):
return ( ' origin ' , ' refs/remotes/origin/main ' )
class GitMocks ( object ) :
def __init__ ( self , config = None , branchref = None ) :
self . branchref = branchref or ' refs/heads/main '
self . config = config or { }
def GetBranchRef ( self , _root ) :
return self . branchref
def NewBranch ( self , branchref ) :
self . branchref = branchref
def GetConfig ( self , root , key , default = None ) :
if root != ' ' :
key = ' %s : %s ' % ( root , key )
return self . config . get ( key , default )
def SetConfig ( self , root , key , value = None ) :
if root != ' ' :
key = ' %s : %s ' % ( root , key )
if value :
self . config [ key ] = value
return
if key not in self . config :
raise CERR1
del self . config [ key ]
class WatchlistsMock ( object ) :
def __init__ ( self , _ ) :
pass
@ -654,14 +630,9 @@ class TestGitCl(unittest.TestCase):
lambda * a : self . _mocked_call ( ' ValidAccounts ' , * a ) ) . start ( )
mock . patch ( ' sys.exit ' , side_effect = SystemExitMock ) . start ( )
mock . patch ( ' git_cl.Settings.GetRoot ' , return_value = ' ' ) . start ( )
self . mockGit = GitMocks ( )
mock . patch ( ' scm.GIT.GetBranchRef ' , self . mockGit . GetBranchRef ) . start ( )
mock . patch ( ' scm.GIT.GetConfig ' , self . mockGit . GetConfig ) . start ( )
scm_mock . GIT ( self )
mock . patch ( ' scm.GIT.ResolveCommit ' , return_value = ' hash ' ) . start ( )
mock . patch ( ' scm.GIT.IsValidRevision ' , return_value = True ) . start ( )
mock . patch ( ' scm.GIT.SetConfig ' , self . mockGit . SetConfig ) . start ( )
mock . patch ( ' git_new_branch.create_new_branch ' ,
self . mockGit . NewBranch ) . start ( )
mock . patch ( ' scm.GIT.FetchUpstreamTuple ' ,
return_value = ( ' origin ' , ' refs/heads/main ' ) ) . start ( )
mock . patch ( ' scm.GIT.CaptureStatus ' ,
@ -864,7 +835,8 @@ class TestGitCl(unittest.TestCase):
calls = [ ]
if squash_mode in ( ' override_squash ' , ' override_nosquash ' ) :
self . mockGit . config [ ' gerrit.override-squash-uploads ' ] = (
scm . GIT . SetConfig (
' ' , ' gerrit.override-squash-uploads ' ,
' true ' if squash_mode == ' override_squash ' else ' false ' )
if not git_footers . get_footer_change_id ( description ) and not squash :
@ -1244,12 +1216,12 @@ class TestGitCl(unittest.TestCase):
' gclient_utils.AskForData ' ,
lambda prompt : self . _mocked_call ( ' ask_for_data ' , prompt ) ) . start ( )
self . mockGit . config [ ' gerrit.host ' ] = ' true '
self . mockGit . config [ ' branch.main.gerritissue ' ] = ( str ( issue )
if issue else None )
self . mockGit . config [ ' remote.origin.url ' ] = (
' https:// %s .googlesource.com/my/repo ' % short_hostname )
self . mockGit . config [ ' user.email ' ] = ' owner@example.com '
scm . GIT . SetConfig ( ' ' , ' gerrit.host ' , ' true ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' ,
( str ( issue ) if issue else None ) )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
f ' https:// { short_hostname } .googlesource.com/my/repo ' )
scm . GIT . SetConfig ( ' ' , ' user.email ' , ' owner@example.com ' )
self . calls = [ ]
if squash_mode == " override_nosquash " :
@ -1421,8 +1393,8 @@ class TestGitCl(unittest.TestCase):
mockUploadAllPrecheck . return_value = ( cls , True )
upstream_gerrit_commit = ' upstream-commit '
self . mockGit . config [
' branch.upstream-branch.gerritsquashhash ' ] = upstream_gerrit_commit
scm . GIT . SetConfig ( ' ' , ' branch.upstream-branch.gerritsquashhash ' ,
upstream_gerrit_commit )
reviewers = [ ]
ccs = [ ]
@ -1730,13 +1702,13 @@ class TestGitCl(unittest.TestCase):
# (so no LAST_UPLOAD_HASH_CONIFG_KEY)
# Case 4: upstream2's last_upload is behind upstream3's base_commit
self . mockGit . config [ ' branch.upstream2. %s ' %
git_cl . LAST_UPLOAD_HASH_CONFIG_KEY ] = ' commit2.3 '
key = f ' branch.upstream2. { git_cl . LAST_UPLOAD_HASH_CONFIG_KEY } '
scm . GIT . SetConfig ( ' ' , key , ' commit2.3 ' )
mockIsAncestor . side_effect = [ True ]
# Case 3: upstream1's last_upload matches upstream2's base_commit
self . mockGit . config [ ' branch.upstream1. %s ' %
git_cl . LAST_UPLOAD_HASH_CONFIG_KEY ] = ' commit1.5 '
key = f ' branch.upstream1. { git_cl . LAST_UPLOAD_HASH_CONFIG_KEY } '
scm . GIT . SetConfig ( ' ' , key , ' commit1.5 ' )
cls , cherry_pick = git_cl . _UploadAllPrecheck ( options , orig_args )
self . assertFalse ( cherry_pick )
@ -1858,8 +1830,8 @@ class TestGitCl(unittest.TestCase):
mockGitGetBranchConfigValue . return_value = None
# Case 5: current's base_commit is behind upstream3's last_upload.
self . mockGit . config [ ' branch.upstream3. %s ' %
git_cl . LAST_UPLOAD_HASH_CONFIG_KEY ] = ' commit3.7 '
key = f ' branch.upstream3. { git_cl . LAST_UPLOAD_HASH_CONFIG_KEY } '
scm . GIT . SetConfig ( ' ' , key , ' commit3.7 ' )
mockIsAncestor . side_effect = [ False , True ]
with self . assertRaises ( SystemExitMock ) :
options = optparse . Values ( )
@ -1904,8 +1876,8 @@ class TestGitCl(unittest.TestCase):
mockIsAncestor . return_value = True
# Give upstream3 a last upload hash
self . mockGit . config [ ' branch.upstream3. %s ' %
git_cl . LAST_UPLOAD_HASH_CONFIG_KEY ] = ' commit3.4 '
key = f ' branch.upstream3. { git_cl . LAST_UPLOAD_HASH_CONFIG_KEY } '
scm . GIT . SetConfig ( ' ' , key , ' commit3.4 ' )
# end commits
mockRunGit . return_value = ' commit4 '
@ -2391,8 +2363,8 @@ class TestGitCl(unittest.TestCase):
def _patch_common ( self , git_short_host = ' chromium ' ) :
mock . patch ( ' scm.GIT.ResolveCommit ' , return_value = ' deadbeef ' ) . start ( )
self . mockGit . config [ ' remote.origin.url ' ] = (
' https:// %s .googlesource.com/my/repo ' % git_short_host )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
f ' https:// { git_short_host } .googlesource.com/my/repo ' )
gerrit_util . GetChangeDetail . return_value = {
' current_revision ' : ' 7777777777 ' ,
' revisions ' : {
@ -2505,8 +2477,8 @@ class TestGitCl(unittest.TestCase):
side_effect = gerrit_util . GerritError ( 404 , ' ' ) )
@mock.patch ( ' sys.stderr ' , io . StringIO ( ) )
def test_patch_gerrit_not_exists ( self , * _mocks ) :
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/my/repo ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/my/repo ' )
with self . assertRaises ( SystemExitMock ) :
self . assertEqual ( 1 , git_cl . main ( [ ' patch ' , ' 123456 ' ] ) )
self . assertEqual (
@ -2550,8 +2522,8 @@ class TestGitCl(unittest.TestCase):
mock . patch (
' git_cl.gerrit_util.CookiesAuthenticator ' ,
CookiesAuthenticatorMockFactory ( hosts_with_creds = auth ) ) . start ( )
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/my/repo ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/my/repo ' )
cl = git_cl . Changelist ( )
cl . branch = ' main '
cl . branchref = ' refs/heads/main '
@ -2594,12 +2566,12 @@ class TestGitCl(unittest.TestCase):
self . assertIsNone ( cl . EnsureAuthenticated ( force = False ) )
def test_gerrit_ensure_authenticated_skipped ( self ) :
self . mockGit . config [ ' gerrit.skip-ensure-authenticated ' ] = ' true '
scm . GIT . SetConfig ( ' ' , ' gerrit.skip-ensure-authenticated ' , ' true ' )
cl = self . _test_gerrit_ensure_authenticated_common ( auth = { } )
self . assertIsNone ( cl . EnsureAuthenticated ( force = False ) )
def test_gerrit_ensure_authenticated_sso ( self ) :
self . mockGit . config [ ' remote.origin.url ' ] = ' sso://repo '
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' , ' sso://repo ' )
mock . patch (
' git_cl.gerrit_util.CookiesAuthenticator ' ,
@ -2629,7 +2601,7 @@ class TestGitCl(unittest.TestCase):
self . assertTrue ( ' Bearer ' in conn . req_headers [ ' Authorization ' ] )
def test_gerrit_ensure_authenticated_non_https_sso ( self ) :
self . mockGit . config [ ' remote.origin.url ' ] = ' custom-scheme://repo '
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' , ' custom-scheme://repo ' )
self . calls = [
( ( ' logging.warning ' ,
' Ignoring branch %(branch)s with non-https remote '
@ -2650,8 +2622,8 @@ class TestGitCl(unittest.TestCase):
self . assertIsNone ( cl . EnsureAuthenticated ( force = False ) )
def test_gerrit_ensure_authenticated_non_url ( self ) :
self . mockGit . config [ ' remote.origin.url ' ] = (
' git@somehost.example:foo/bar.git ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' git@somehost.example:foo/bar.git ' )
self . calls = [
( ( ' logging.error ' ,
' Remote " %(remote)s " for branch " %(branch)s " points to " %(url)s " , '
@ -2673,11 +2645,11 @@ class TestGitCl(unittest.TestCase):
self . assertIsNone ( cl . EnsureAuthenticated ( force = False ) )
def _cmd_set_commit_gerrit_common ( self , vote , notify = None ) :
self . mockGit . config [ ' branch.main.gerritissue ' ] = ' 123 '
self . mockGit . config [ ' branch.main.gerritserver ' ] = (
' https://chromium-review.googlesource.com ' )
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/infra/infra ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' , ' 123 ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritserver ' ,
' https://chromium-review.googlesource.com ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/infra/infra ' )
self . calls = [
( ( ' SetReview ' , ' chromium-review.googlesource.com ' ,
' infra %2F infra~123 ' , None , {
@ -2732,8 +2704,8 @@ class TestGitCl(unittest.TestCase):
self . assertEqual ( git_cl . main ( [ ' set-close ' , ' --issue ' , ' 1 ' ] ) , 0 )
def test_description ( self ) :
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/my/repo ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/my/repo ' )
gerrit_util . GetChangeDetail . return_value = {
' current_revision ' : ' sha1 ' ,
' revisions ' : {
@ -2783,7 +2755,7 @@ class TestGitCl(unittest.TestCase):
UpdateDescription ) . start ( )
mock . patch ( ' git_cl.gclient_utils.RunEditor ' , RunEditor ) . start ( )
self . mockGit . config [ ' branch.main.gerritissue ' ] = ' 123 '
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' , ' 123 ' )
self . assertEqual ( 0 , git_cl . main ( [ ' description ' ] ) )
def test_description_does_not_append_bug_line_if_fixed_is_present ( self ) :
@ -2803,7 +2775,7 @@ class TestGitCl(unittest.TestCase):
lambda * args : current_desc ) . start ( )
mock . patch ( ' git_cl.gclient_utils.RunEditor ' , RunEditor ) . start ( )
self . mockGit . config [ ' branch.main.gerritissue ' ] = ' 123 '
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' , ' 123 ' )
self . assertEqual ( 0 , git_cl . main ( [ ' description ' ] ) )
def test_description_set_stdin ( self ) :
@ -2950,20 +2922,20 @@ class TestGitCl(unittest.TestCase):
' archived/ {issue} - {branch} ' ] ) )
def test_cmd_issue_erase_existing ( self ) :
self . mockGit . config [ ' branch.main.gerritissue ' ] = ' 123 '
self . mockGit . config [ ' branch.main.gerritserver ' ] = (
' https://chromium-review.googlesource.com ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' , ' 123 ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritserver ' ,
' https://chromium-review.googlesource.com ' )
self . calls = [
( ( [ ' git ' , ' log ' , ' -1 ' , ' --format= % B ' ] , ) , ' This is a description ' ) ,
]
self . assertEqual ( 0 , git_cl . main ( [ ' issue ' , ' 0 ' ] ) )
self . assert NotIn( ' branch.main.gerritissue ' , self . mockGit . config )
self . assert NotIn( ' branch.main.gerritserver ' , self . mockGit . config )
self . assert IsNone( scm . GIT . GetConfig ( ' root ' , ' branch.main.gerritissue ' ) )
self . assert IsNone( scm . GIT . GetConfig ( ' root ' , ' branch.main.gerritserver ' ) )
def test_cmd_issue_erase_existing_with_change_id ( self ) :
self . mockGit . config [ ' branch.main.gerritissue ' ] = ' 123 '
self . mockGit . config [ ' branch.main.gerritserver ' ] = (
' https://chromium-review.googlesource.com ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' , ' 123 ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritserver ' ,
' https://chromium-review.googlesource.com ' )
mock . patch (
' git_cl.Changelist.FetchDescription ' ,
lambda _ : ' This is a description \n \n Change-Id: Ideadbeef ' ) . start ( )
@ -2974,15 +2946,15 @@ class TestGitCl(unittest.TestCase):
' This is a description \n ' ] , ) , ' ' ) ,
]
self . assertEqual ( 0 , git_cl . main ( [ ' issue ' , ' 0 ' ] ) )
self . assert NotIn( ' branch.main.gerritissue ' , self . mockGit . config )
self . assert NotIn( ' branch.main.gerritserver ' , self . mockGit . config )
self . assert IsNone( scm . GIT . GetConfig ( ' root ' , ' branch.main.gerritissue ' ) )
self . assert IsNone( scm . GIT . GetConfig ( ' root ' , ' branch.main.gerritserver ' ) )
def test_cmd_issue_json ( self ) :
self . mockGit . config [ ' branch.main.gerritissue ' ] = ' 123 '
self . mockGit . config [ ' branch.main.gerritserver ' ] = (
' https://chromium-review.googlesource.com ' )
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/chromium/src ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritissue ' , ' 123 ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritserver ' ,
' https://chromium-review.googlesource.com ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/chromium/src ' )
self . calls = [ (
(
' write_json ' ,
@ -3046,9 +3018,9 @@ class TestGitCl(unittest.TestCase):
cl . _GerritCommitMsgHookCheck ( offer_removal = True )
def test_GerritCmdLand ( self ) :
self . mockGit . config [ ' branch.main.gerritsquashhash ' ] = ' deadbeaf '
self . mockGit . config [ ' branch.main.gerritserver ' ] = (
' chromium-review.googlesource.com ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritsquashhash ' , ' deadbeaf ' )
scm . GIT . SetConfig ( ' ' , ' branch.main.gerritserver ' ,
' chromium-review.googlesource.com ' )
self . calls + = [
( ( [ ' git ' , ' diff ' , ' deadbeaf ' ] , ) , ' ' ) , # No diff.
]
@ -3222,9 +3194,9 @@ class TestGitCl(unittest.TestCase):
sys . stdout . getvalue ( ) )
def test_git_cl_comment_add_gerrit ( self ) :
self . mockGit . branchref = None
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/infra/infra ' )
git_new_branch . create_new_branch ( None ) # hits mock from scm_mock.GIT.
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/infra/infra ' )
self . calls = [
( ( ' SetReview ' , ' chromium-review.googlesource.com ' ,
' infra %2F infra~10 ' , ' msg ' , None , None , None ) , None ) ,
@ -3233,8 +3205,8 @@ class TestGitCl(unittest.TestCase):
@mock.patch ( ' git_cl.Changelist.GetBranch ' , return_value = ' foo ' )
def test_git_cl_comments_fetch_gerrit ( self , * _mocks ) :
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/infra/infra ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/infra/infra ' )
gerrit_util . GetChangeDetail . return_value = {
' owner ' : {
' email ' : ' owner@example.com '
@ -3388,8 +3360,8 @@ class TestGitCl(unittest.TestCase):
# git cl comments also fetches robot comments (which are considered a
# type of autogenerated comment), and unlike other types of comments,
# only robot comments from the latest patchset are shown.
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://x.googlesource.com/infra/infra ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://x.googlesource.com/infra/infra ' )
gerrit_util . GetChangeDetail . return_value = {
' owner ' : {
' email ' : ' owner@example.com '
@ -3505,8 +3477,8 @@ class TestGitCl(unittest.TestCase):
mock . patch ( ' os.path.isdir ' , selective_os_path_isdir_mock ) . start ( )
url = ' https://chromium.googlesource.com/my/repo '
self . mockGit . config [ ' remote.origin.url ' ] = ( ' /cache/this-dir-exists ' )
self . mockGit . config [ ' /cache/this-dir-exists:remote.origin.url ' ] = ( url )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' , ' /cache/this-dir-exists ' )
scm . GIT . SetConfig ( ' /cache/this-dir-exists ' , ' remote.origin.url ' , url )
self . calls = [
( ( ' os.path.isdir ' , ' /cache/this-dir-exists ' ) , True ) ,
]
@ -3526,8 +3498,8 @@ class TestGitCl(unittest.TestCase):
mock . patch ( ' logging.error ' ,
lambda * a : self . _mocked_call ( ' logging.error ' , * a ) ) . start ( )
self . mockGit . config [ ' remote.origin.url ' ] = (
' /cache/this-dir-doesnt-exist ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' /cache/this-dir-doesnt-exist ' )
self . calls = [
( ( ' os.path.isdir ' , ' /cache/this-dir-doesnt-exist ' ) , False ) ,
( ( ' logging.error ' ,
@ -3553,7 +3525,7 @@ class TestGitCl(unittest.TestCase):
mock . patch ( ' logging.error ' ,
lambda * a : self . _mocked_call ( ' logging.error ' , * a ) ) . start ( )
self . mockGit . config [ ' remote.origin.url ' ] = ( ' /cache/this-dir-exists ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' , ' /cache/this-dir-exists ' )
self . calls = [
( ( ' os.path.isdir ' , ' /cache/this-dir-exists ' ) , True ) ,
( ( ' logging.error ' ,
@ -3570,8 +3542,8 @@ class TestGitCl(unittest.TestCase):
self . assertIsNone ( cl . GetRemoteUrl ( ) )
def test_gerrit_change_identifier_with_project ( self ) :
self . mockGit . config [ ' remote.origin.url ' ] = (
' https://chromium.googlesource.com/a/my/repo.git/ ' )
scm . GIT . SetConfig ( ' ' , ' remote.origin.url ' ,
' https://chromium.googlesource.com/a/my/repo.git/ ' )
cl = git_cl . Changelist ( issue = 123456 )
self . assertEqual ( cl . _GerritChangeIdentifier ( ) , ' my %2F repo~123456 ' )
@ -3641,11 +3613,10 @@ class ChangelistTest(unittest.TestCase):
return_value = ' project ' ) . start ( )
mock . patch ( ' sys.exit ' , side_effect = SystemExitMock ) . start ( )
scm_mock . GIT ( self )
self . addCleanup ( mock . patch . stopall )
self . temp_count = 0
self . mockGit = GitMocks ( )
mock . patch ( ' scm.GIT.GetConfig ' , self . mockGit . GetConfig ) . start ( )
mock . patch ( ' scm.GIT.SetConfig ' , self . mockGit . SetConfig ) . start ( )
gerrit_util . _Authenticator . _resolved = None
def testRunHook ( self ) :
@ -4238,10 +4209,10 @@ class ChangelistTest(unittest.TestCase):
cl . PostUploadUpdates ( options , new_upload , ' 12345 ' )
mockSetPatchset . assert_called_once_with ( 3 )
self . assertEqual (
self . mockGit . config [ ' root:branch.current-branch.gerritsquashhash ' ] ,
scm . GIT . GetConfig ( ' root ' , ' branch.current-branch.gerritsquashhash ' ) ,
new_upload . commit_to_push )
self . assertEqual (
self . mockGit . config [ ' root:branch.current-branch.last-upload-hash ' ] ,
scm . GIT . GetConfig ( ' root ' , ' branch.current-branch.last-upload-hash ' ) ,
new_upload . new_last_uploaded_commit )
mockAddReviewers . assert_called_once_with ( ' chromium ' ,