blob: 3ced217ee20d909e940b254105c2dc06669d0b2a [file] [log] [blame]
Mike Frysinger0e2cb7a2019-08-20 17:04:52 -04001#!/usr/bin/python2
Prathmesh Prabhu5f6b2332015-04-10 16:41:28 -07002import logging, mox, os, shutil, tempfile, unittest, utils
3
4# This makes autotest_lib imports available.
5import common
beepsd9153b52013-01-23 20:52:46 -08006from autotest_lib.client.common_lib import revision_control
7
8
beeps98365d82013-02-20 20:08:07 -08009class GitRepoManager(object):
beepsd9153b52013-01-23 20:52:46 -080010 """
11 A wrapper for GitRepo.
12 """
13 commit_hash = None
14 commit_msg = None
15 repodir = None
16 git_repo_manager = None
17
18
19 def __init__(self, master_repo=None):
20 """
21 Setup self.git_repo_manager.
22
23 If a master_repo is present clone it.
24 Otherwise create a directory in /tmp and init it.
25
26 @param master_repo: GitRepo representing master.
27 """
28 if master_repo is None:
29 self.repodir = tempfile.mktemp(suffix='master')
30 self._create_git_repo(self.repodir)
31 self.git_repo_manager = revision_control.GitRepo(
32 self.repodir,
33 self.repodir,
34 abs_work_tree=self.repodir)
Prathmesh Prabhuec841372015-06-05 17:29:33 -070035 self._setup_git_environment()
Prathmesh Prabhu5f6b2332015-04-10 16:41:28 -070036 # Create an initial commit. We really care about the common case
37 # where there exists a commit in the upstream repo.
38 self._edit('initial_commit_file', 'is_non_empty')
39 self.add()
40 self.commit('initial_commit')
beepsd9153b52013-01-23 20:52:46 -080041 else:
42 self.repodir = tempfile.mktemp(suffix='dependent')
43 self.git_repo_manager = revision_control.GitRepo(
44 self.repodir,
45 master_repo.repodir,
46 abs_work_tree=self.repodir)
47 self.git_repo_manager.clone()
Prathmesh Prabhuec841372015-06-05 17:29:33 -070048 self._setup_git_environment()
49
50
51 def _setup_git_environment(self):
52 """
53 Mock out basic git environment to keep tests deterministic.
54 """
Simran Basi4eb38782014-11-26 17:13:47 -080055 # Set user and email for the test git checkout.
56 self.git_repo_manager.gitcmd('config user.name Unittests')
57 self.git_repo_manager.gitcmd('config user.email utests@chromium.org')
beepsd9153b52013-01-23 20:52:46 -080058
59
60 def _edit(self, filename='foo', msg='bar'):
61 """
62 Write msg into a file in the repodir.
63
64 @param filename: Name of the file in current repo.
65 If none exists one will be created.
66 @param msg: A message to write into the file.
67 """
68 local_file_name = os.path.join(self.git_repo_manager.repodir,
69 filename)
70 with open(local_file_name, 'w') as f:
71 f.write(msg)
72
73
74 def _create_git_repo(self, repodir):
75 """
76 Init a new git repository.
77
78 @param repodir: directory for repo.
79 """
beeps98365d82013-02-20 20:08:07 -080080 logging.info('initializing git repo in: %s', repodir)
beepsd9153b52013-01-23 20:52:46 -080081 gitcmd = 'git init %s' % repodir
82 rv = utils.run(gitcmd)
83 if rv.exit_status != 0:
84 logging.error(rv.stderr)
Prathmesh Prabhuec841372015-06-05 17:29:33 -070085 raise revision_control.revision_control.GitError(gitcmd + 'failed')
beepsd9153b52013-01-23 20:52:46 -080086
87
88 def add(self):
89 """
90 Add all unadded files in repodir to repo.
91 """
92 rv = self.git_repo_manager.gitcmd('add .')
93 if rv.exit_status != 0:
94 logging.error(rv.stderr)
95 raise revision_control.GitError('Unable to add files to repo', rv)
96
97
98 def commit(self, msg='default'):
99 """
100 Commit changes to repo with the supplied commit msg.
101 Also updates commit_hash with the hash for this commit.
102
103 @param msg: A message that goes with the commit.
104 """
105 self.git_repo_manager.commit(msg)
106 self.commit_hash = self.git_repo_manager.get_latest_commit_hash()
107
108
109 def get_master_tot(self):
110 """
111 Get everything from masters TOT squashing local changes.
112 If the dependent repo is empty pull from master.
113 """
Prathmesh Prabhu5f6b2332015-04-10 16:41:28 -0700114 self.git_repo_manager.reinit_repo_at('master')
beepsd9153b52013-01-23 20:52:46 -0800115 self.commit_hash = self.git_repo_manager.get_latest_commit_hash()
116
117
beeps98365d82013-02-20 20:08:07 -0800118class RevisionControlUnittest(mox.MoxTestBase):
beepsd9153b52013-01-23 20:52:46 -0800119 """
120 A unittest to exercise build_externals.py's usage
121 of revision_control.py's Git wrappers.
122 """
123 master_repo=None
124 dependent_repo=None
125
126 def setUp(self):
127 """
128 Create a master repo and clone it into a dependent repo.
129 """
beeps98365d82013-02-20 20:08:07 -0800130 super(RevisionControlUnittest, self).setUp()
131 self.master_repo = GitRepoManager()
132 self.dependent_repo = GitRepoManager(self.master_repo)
beepsd9153b52013-01-23 20:52:46 -0800133
134
135 def tearDown(self):
136 """
137 Delete temporary directories.
138 """
139 shutil.rmtree(self.master_repo.repodir)
140 shutil.rmtree(self.dependent_repo.repodir)
beeps98365d82013-02-20 20:08:07 -0800141 super(RevisionControlUnittest, self).tearDown()
beepsd9153b52013-01-23 20:52:46 -0800142
143
beeps98365d82013-02-20 20:08:07 -0800144 def testCommit(self):
beepsd9153b52013-01-23 20:52:46 -0800145 """
146 Test add, commit, pull, clone.
147 """
148 self.master_repo._edit()
149 self.master_repo.add()
150 self.master_repo.commit()
151 self.dependent_repo.get_master_tot()
beepsaae3f1c2013-03-19 15:49:14 -0700152 self.assertEquals(self.dependent_repo.commit_hash,
153 self.master_repo.commit_hash,
154 msg=(("hashes don't match after clone, master and dependent repo"
155 "out of sync: %r != %r") %
156 (self.dependent_repo.commit_hash,
157 self.master_repo.commit_hash)))
158
159 self.master_repo._edit(msg='foobar')
160 self.master_repo.commit()
161 self.dependent_repo.get_master_tot()
162 self.assertEquals(self.dependent_repo.commit_hash,
163 self.master_repo.commit_hash,
164 msg=(("hashes don't match after pull, master and dependent repo"
165 "out of sync: %r != %r") %
166 (self.dependent_repo.commit_hash,
167 self.master_repo.commit_hash)))
beeps98365d82013-02-20 20:08:07 -0800168
169
170 def testGitUrlClone(self):
171 """
172 Test that git clone raises a ValueError if giturl is unset.
173 """
174 self.dependent_repo.git_repo_manager._giturl = None
beeps98365d82013-02-20 20:08:07 -0800175 self.assertRaises(ValueError,
Prathmesh Prabhu5f6b2332015-04-10 16:41:28 -0700176 self.dependent_repo.git_repo_manager.clone)
beeps98365d82013-02-20 20:08:07 -0800177
178
179 def testGitUrlPull(self):
180 """
181 Test that git pull raises a ValueError if giturl is unset.
182 """
183 self.dependent_repo.git_repo_manager._giturl = None
beeps98365d82013-02-20 20:08:07 -0800184 self.assertRaises(ValueError,
Prathmesh Prabhu5f6b2332015-04-10 16:41:28 -0700185 self.dependent_repo.git_repo_manager.pull)
beeps98365d82013-02-20 20:08:07 -0800186
187
188 def testGitUrlFetch(self):
189 """
190 Test that git fetch raises a ValueError if giturl is unset.
191 """
192 self.dependent_repo.git_repo_manager._giturl = None
beeps98365d82013-02-20 20:08:07 -0800193 self.assertRaises(ValueError,
Prathmesh Prabhu5f6b2332015-04-10 16:41:28 -0700194 self.dependent_repo.git_repo_manager.fetch_remote)
195
196
197if __name__ == '__main__':
198 unittest.main()