2 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 """Unittests for remote_try.py."""
8 from __future__ import print_function
18 sys.path.insert(0, constants.SOURCE_ROOT)
19 from chromite.lib import cros_build_lib
20 from chromite.lib import cros_test_lib
21 from chromite.lib import git
22 from chromite.cbuildbot import remote_try
23 from chromite.cbuildbot import repository
24 from chromite.scripts import cbuildbot
26 class RemoteTryJobMock(remote_try.RemoteTryJob):
27 """Helper for Mocking out a RemoteTryJob."""
29 # pylint: disable=W0212,R0904,E1101
30 class RemoteTryTests(cros_test_lib.MoxTempDirTestCase):
31 """Test cases related to remote try jobs."""
33 PATCHES = ('5555', '6666')
34 BOTS = ('x86-generic-paladin', 'arm-generic-paladin')
37 self.parser = cbuildbot._CreateParser()
38 args = ['-r', '/tmp/test_build1', '-g', '5555', '-g',
40 args.extend(self.BOTS)
41 self.options, args = cbuildbot._ParseCommandLine(self.parser, args)
42 self.options.cache_dir = self.tempdir
43 self.checkout_dir = os.path.join(self.tempdir, 'test_checkout')
44 self.int_mirror, self.ext_mirror = None, None
46 def _RunGitSingleOutput(self, cwd, cmd):
47 result = git.RunGit(cwd, cmd)
48 out_lines = result.output.split()
49 self.assertEqual(len(out_lines), 1)
52 def _GetNewestFile(self, dirname, basehash):
53 newhash = git.GetGitRepoRevision(dirname)
54 self.assertNotEqual(basehash, newhash)
55 cmd = ['log', '--format=%H', '%s..' % basehash]
56 # Make sure we have a single commit.
57 self._RunGitSingleOutput(dirname, cmd)
58 cmd = ['diff', '--name-only', 'HEAD^']
59 # Make sure only one file per commit.
60 return self._RunGitSingleOutput(dirname, cmd)
62 def _SubmitJob(self, checkout_dir, job, version=None):
63 """Returns the path to the tryjob description."""
64 self.assertTrue(isinstance(job, RemoteTryJobMock))
65 basehash = git.GetGitRepoRevision(job.repo_url)
66 if version is not None:
67 self._SetMirrorVersion(version)
68 job.Submit(workdir=checkout_dir, dryrun=True)
69 # Get the file that was just created.
70 created_file = self._GetNewestFile(checkout_dir, basehash)
71 return os.path.join(checkout_dir, created_file)
73 def _SetupMirrors(self):
74 mirror = os.path.join(self.tempdir, 'tryjobs_mirror')
76 url = '%s/%s' % (constants.EXTERNAL_GOB_URL, 'chromiumos/tryjobs')
77 repository.CloneGitRepo(mirror, url,
79 self.ext_mirror = mirror
80 mirror = os.path.join(self.tempdir, 'tryjobs_int_mirror')
82 repository.CloneGitRepo(mirror, self.ext_mirror, reference=self.ext_mirror,
85 self.int_mirror = mirror
86 RemoteTryJobMock.EXTERNAL_URL = self.ext_mirror
87 RemoteTryJobMock.INTERNAL_URL = self.int_mirror
88 self._SetMirrorVersion(remote_try.RemoteTryJob.TRYJOB_FORMAT_VERSION, True)
90 def _SetMirrorVersion(self, version, only_if_missing=False):
91 for path in (self.ext_mirror, self.int_mirror):
92 vpath = os.path.join(path, remote_try.RemoteTryJob.TRYJOB_FORMAT_FILE)
93 if os.path.exists(vpath) and only_if_missing:
95 # Get ourselves a working dir.
96 tmp_repo = os.path.join(self.tempdir, 'tmp-repo')
97 git.RunGit(self.tempdir, ['clone', path, tmp_repo])
98 vpath = os.path.join(tmp_repo, remote_try.RemoteTryJob.TRYJOB_FORMAT_FILE)
99 with open(vpath, 'w') as f:
100 f.write(str(version))
101 git.RunGit(tmp_repo, ['add', vpath])
102 git.RunGit(tmp_repo, ['commit', '-m', 'setting version to %s' % version])
103 git.RunGit(tmp_repo, ['push', path, 'master:master'])
104 shutil.rmtree(tmp_repo)
106 def _CreateJob(self, mirror=True):
107 job_class = remote_try.RemoteTryJob
109 job_class = RemoteTryJobMock
112 job = job_class(self.options, self.BOTS, [])
115 def testJobTimestamp(self):
116 """Verify jobs have unique names."""
117 def submit_helper(dirname):
118 work_dir = os.path.join(self.tempdir, dirname)
119 return os.path.basename(self._SubmitJob(work_dir, job))
121 self.mox.StubOutWithMock(repository, 'IsARepoRoot')
122 repository.IsARepoRoot(mox.IgnoreArg()).AndReturn(False)
124 job = self._CreateJob()
126 file1 = submit_helper('test1')
127 # Tryjob file names are based on timestamp, so delay one second to avoid two
128 # jobfiles having the same name.
130 file2 = submit_helper('test2')
131 self.assertNotEqual(file1, file2)
133 def testSimpleTryJob(self, version=None):
134 """Test that a tryjob spec file is created and pushed properly."""
135 self.mox.StubOutWithMock(repository, 'IsARepoRoot')
136 repository.IsARepoRoot(mox.IgnoreArg()).AndReturn(True)
137 self.mox.StubOutWithMock(repository, 'IsInternalRepoCheckout')
138 repository.IsInternalRepoCheckout(mox.IgnoreArg()).AndReturn(False)
142 os.environ["GIT_AUTHOR_EMAIL"] = "Elmer Fudd <efudd@google.com>"
143 os.environ["GIT_COMMITTER_EMAIL"] = "Elmer Fudd <efudd@google.com>"
144 job = self._CreateJob()
146 os.environ.pop("GIT_AUTHOR_EMAIL", None)
147 os.environ.pop("GIT_COMMITTER_EMAIL", None)
148 created_file = self._SubmitJob(self.checkout_dir, job, version=version)
149 with open(created_file, 'rb') as job_desc_file:
150 values = json.load(job_desc_file)
152 self.assertTrue('efudd@google.com' in values['email'][0])
154 for patch in self.PATCHES:
155 self.assertTrue(patch in values['extra_args'],
156 msg="expected patch %s in args %s" %
157 (patch, values['extra_args']))
159 self.assertTrue(set(self.BOTS).issubset(values['bot']))
161 remote_url = cros_build_lib.RunCommand(
162 ['git', 'config', 'remote.origin.url'], redirect_stdout=True,
163 cwd=self.checkout_dir).output.strip()
164 self.assertEqual(remote_url, self.ext_mirror)
166 def testClientVersionAwareness(self):
168 remote_try.ChromiteUpgradeNeeded,
169 self.testSimpleTryJob,
170 version=remote_try.RemoteTryJob.TRYJOB_FORMAT_VERSION + 1)
172 def testInternalTryJob(self):
173 """Verify internal tryjobs are pushed properly."""
174 self.mox.StubOutWithMock(repository, 'IsARepoRoot')
175 repository.IsARepoRoot(mox.IgnoreArg()).AndReturn(True)
176 self.mox.StubOutWithMock(repository, 'IsInternalRepoCheckout')
177 repository.IsInternalRepoCheckout(mox.IgnoreArg()).AndReturn(True)
180 job = self._CreateJob()
181 self._SubmitJob(self.checkout_dir, job)
183 remote_url = cros_build_lib.RunCommand(
184 ['git', 'config', 'remote.origin.url'], redirect_stdout=True,
185 cwd=self.checkout_dir).output.strip()
186 self.assertEqual(remote_url, self.int_mirror)
188 def testBareTryJob(self):
189 """Verify submitting a tryjob from just a chromite checkout works."""
190 self.mox.StubOutWithMock(repository, 'IsARepoRoot')
191 repository.IsARepoRoot(mox.IgnoreArg()).AndReturn(False)
192 self.mox.StubOutWithMock(repository, 'IsInternalRepoCheckout')
195 job = self._CreateJob(mirror=False)
196 self.assertEqual(job.repo_url, remote_try.RemoteTryJob.EXTERNAL_URL)
199 if __name__ == '__main__':