Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / cbuildbot / manifest_version_unittest.py
1 #!/usr/bin/python
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.
5
6 """Unittests for manifest_version. Needs to be run inside of chroot."""
7
8 from __future__ import print_function
9
10 import mox
11 import os
12 import sys
13 import tempfile
14
15 import constants
16 if __name__ == '__main__':
17   sys.path.insert(0, constants.SOURCE_ROOT)
18
19 from chromite.cbuildbot import failures_lib
20 from chromite.cbuildbot import manifest_version
21 from chromite.cbuildbot import repository
22 from chromite.lib import cros_build_lib_unittest
23 from chromite.lib import git
24 from chromite.lib import cros_test_lib
25 from chromite.lib import osutils
26
27 # pylint: disable=W0212,R0904
28 FAKE_VERSION = """
29 CHROMEOS_BUILD=%(build_number)s
30 CHROMEOS_BRANCH=%(branch_build_number)s
31 CHROMEOS_PATCH=%(patch_number)s
32 CHROME_BRANCH=%(chrome_branch)s
33 """
34
35 FAKE_VERSION_STRING = '1.2.3'
36 FAKE_VERSION_STRING_NEXT = '1.2.4'
37 CHROME_BRANCH = '13'
38
39 # Use the chromite repo to actually test git changes.
40 GIT_TEST_PATH = 'chromite'
41
42 MOCK_BUILD_ID = 162345
43
44 class HelperMethodsTest(cros_test_lib.TempDirTestCase):
45   """Test methods associated with methods not in a class."""
46
47   def testCreateSymlink(self):
48     """Tests that we can create symlinks and remove a previous one."""
49     srcfile = os.path.join(self.tempdir, 'src')
50     osutils.Touch(srcfile)
51     other_dir = os.path.join(self.tempdir, 'other_dir')
52     os.makedirs(other_dir)
53     destfile = os.path.join(other_dir, 'dest')
54
55     manifest_version.CreateSymlink(srcfile, destfile)
56     self.assertTrue(os.path.lexists(destfile),
57                     'Unable to create symlink to %s' % destfile)
58
59
60 class VersionInfoTest(cros_test_lib.MoxTempDirTestCase):
61   """Test methods testing methods in VersionInfo class."""
62
63   @classmethod
64   def WriteFakeVersionFile(cls, version_file, version=None, chrome_branch=None):
65     """Helper method to write a version file from specified version number."""
66     if version is None:
67       version = FAKE_VERSION_STRING
68     if chrome_branch is None:
69       chrome_branch = CHROME_BRANCH
70
71     osutils.SafeMakedirs(os.path.split(version_file)[0])
72     info = manifest_version.VersionInfo(version, chrome_branch)
73     osutils.WriteFile(version_file, FAKE_VERSION % info.__dict__)
74
75   @classmethod
76   def CreateFakeVersionFile(cls, tmpdir, version=None, chrome_branch=None):
77     """Helper method to create a version file from specified version number."""
78     version_file = tempfile.mktemp(dir=tmpdir)
79     cls.WriteFakeVersionFile(version_file, version=version,
80                              chrome_branch=chrome_branch)
81     return version_file
82
83   def testLoadFromFile(self):
84     """Tests whether we can load from a version file."""
85     version_file = self.CreateFakeVersionFile(self.tempdir)
86     info = manifest_version.VersionInfo(version_file=version_file)
87     self.assertEqual(info.VersionString(), FAKE_VERSION_STRING)
88
89   def testLoadFromRepo(self):
90     """Tests whether we can load from a source repo."""
91     version_file = os.path.join(self.tempdir, constants.VERSION_FILE)
92     self.WriteFakeVersionFile(version_file)
93     info = manifest_version.VersionInfo.from_repo(self.tempdir)
94     self.assertEqual(info.VersionString(), FAKE_VERSION_STRING)
95
96   def testLoadFromString(self):
97     """Tests whether we can load from a string."""
98     info = manifest_version.VersionInfo(FAKE_VERSION_STRING, CHROME_BRANCH)
99     self.assertEqual(info.VersionString(), FAKE_VERSION_STRING)
100
101   def CommonTestIncrementVersion(self, incr_type, version, chrome_branch=None):
102     """Common test increment.  Returns path to new incremented file."""
103     message = 'Incrementing cuz I sed so'
104     self.mox.StubOutWithMock(git, 'CreateBranch')
105     self.mox.StubOutWithMock(manifest_version, '_PushGitChanges')
106     self.mox.StubOutWithMock(git, 'CleanAndCheckoutUpstream')
107
108     git.CreateBranch(self.tempdir, manifest_version.PUSH_BRANCH)
109
110     version_file = self.CreateFakeVersionFile(
111         self.tempdir, version=version, chrome_branch=chrome_branch)
112
113     manifest_version._PushGitChanges(self.tempdir, message, dry_run=False,
114                                      push_to=None)
115
116     git.CleanAndCheckoutUpstream(self.tempdir)
117     self.mox.ReplayAll()
118     info = manifest_version.VersionInfo(version_file=version_file,
119                                         incr_type=incr_type)
120     info.IncrementVersion()
121     info.UpdateVersionFile(message, dry_run=False)
122     self.mox.VerifyAll()
123     return version_file
124
125   def testIncrementVersionPatch(self):
126     """Tests whether we can increment a version file by patch number."""
127     version_file = self.CommonTestIncrementVersion('branch', '1.2.3')
128     new_info = manifest_version.VersionInfo(version_file=version_file,
129                                             incr_type='branch')
130     self.assertEqual(new_info.VersionString(), '1.2.4')
131
132   def testIncrementVersionBranch(self):
133     """Tests whether we can increment a version file by branch number."""
134     version_file = self.CommonTestIncrementVersion('branch', '1.2.0')
135     new_info = manifest_version.VersionInfo(version_file=version_file,
136                                             incr_type='branch')
137     self.assertEqual(new_info.VersionString(), '1.3.0')
138
139   def testIncrementVersionBuild(self):
140     """Tests whether we can increment a version file by build number."""
141     version_file = self.CommonTestIncrementVersion('build', '1.0.0')
142     new_info = manifest_version.VersionInfo(version_file=version_file,
143                                             incr_type='build')
144     self.assertEqual(new_info.VersionString(), '2.0.0')
145
146   def testIncrementVersionChrome(self):
147     """Tests whether we can increment the chrome version."""
148     version_file = self.CommonTestIncrementVersion(
149         'chrome_branch', version='1.0.0', chrome_branch='29')
150     new_info = manifest_version.VersionInfo(version_file=version_file)
151     self.assertEqual(new_info.VersionString(), '2.0.0')
152     self.assertEqual(new_info.chrome_branch, '30')
153
154
155 class BuildSpecsManagerTest(cros_test_lib.MoxTempDirTestCase,
156                             cros_test_lib.MockTestCase):
157   """Tests for the BuildSpecs manager."""
158
159   def setUp(self):
160     os.makedirs(os.path.join(self.tempdir, '.repo'))
161     self.source_repo = 'ssh://source/repo'
162     self.manifest_repo = 'ssh://manifest/repo'
163     self.version_file = 'version-file.sh'
164     self.branch = 'master'
165     self.build_names = ['x86-generic-paladin']
166     self.incr_type = 'branch'
167
168     repo = repository.RepoRepository(
169       self.source_repo, self.tempdir, self.branch)
170     self.manager = manifest_version.BuildSpecsManager(
171       repo, self.manifest_repo, self.build_names, self.incr_type, False,
172       branch=self.branch, dry_run=True)
173
174     # Change default to something we clean up.
175     self.tmpmandir = os.path.join(self.tempdir, 'man')
176     osutils.SafeMakedirs(self.tmpmandir)
177     self.manager.manifest_dir = self.tmpmandir
178     # Shorten the sleep between attempts.
179     self.manager.SLEEP_TIMEOUT = 1
180
181   def testPublishManifestCommitMessageWithBuildId(self):
182     """Tests that PublishManifest writes a build id."""
183     expected_message = ('Automatic: Start x86-generic-paladin master 1\n'
184                         'CrOS-Build-Id: %s' % MOCK_BUILD_ID)
185     self.mox.StubOutWithMock(self.manager, 'PushSpecChanges')
186
187     info = manifest_version.VersionInfo(
188         FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='branch')
189
190     # Create a fake manifest file.
191     m = os.path.join(self.tmpmandir, '1.xml')
192     osutils.Touch(m)
193     self.manager.InitializeManifestVariables(info)
194
195     self.manager.PushSpecChanges(expected_message)
196
197     self.mox.ReplayAll()
198     self.manager.PublishManifest(m, '1', build_id=MOCK_BUILD_ID)
199     self.mox.VerifyAll()
200
201   def testPublishManifestCommitMessageWithNegativeBuildId(self):
202     """Tests that PublishManifest doesn't write a negative build_id"""
203     expected_message = 'Automatic: Start x86-generic-paladin master 1'
204     self.mox.StubOutWithMock(self.manager, 'PushSpecChanges')
205
206     info = manifest_version.VersionInfo(
207         FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='branch')
208
209     # Create a fake manifest file.
210     m = os.path.join(self.tmpmandir, '1.xml')
211     osutils.Touch(m)
212     self.manager.InitializeManifestVariables(info)
213
214     self.manager.PushSpecChanges(expected_message)
215
216     self.mox.ReplayAll()
217     self.manager.PublishManifest(m, '1', build_id=-1)
218     self.mox.VerifyAll()
219
220   def testPublishManifestCommitMessageWithNoneBuildId(self):
221     """Tests that PublishManifest doesn't write a non-existant build_id"""
222     expected_message = 'Automatic: Start x86-generic-paladin master 1'
223     self.mox.StubOutWithMock(self.manager, 'PushSpecChanges')
224
225     info = manifest_version.VersionInfo(
226         FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='branch')
227
228     # Create a fake manifest file.
229     m = os.path.join(self.tmpmandir, '1.xml')
230     osutils.Touch(m)
231     self.manager.InitializeManifestVariables(info)
232
233     self.manager.PushSpecChanges(expected_message)
234
235     self.mox.ReplayAll()
236     self.manager.PublishManifest(m, '1')
237     self.mox.VerifyAll()
238
239   def testLoadSpecs(self):
240     """Tests whether we can load specs correctly."""
241     info = manifest_version.VersionInfo(
242         FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='branch')
243     mpath = os.path.join(self.manager.manifest_dir, 'buildspecs', CHROME_BRANCH)
244     m1, m2, m3, m4 = [os.path.join(mpath, '1.2.%d.xml' % x)
245                       for x in [2,3,4,5]]
246     for_build = os.path.join(self.manager.manifest_dir, 'build-name',
247                              self.build_names[0])
248
249     # Create fake buildspecs.
250     osutils.SafeMakedirs(os.path.join(mpath))
251     for m in [m1, m2, m3, m4]:
252       osutils.Touch(m)
253
254     # Fake BuilderStatus with status MISSING.
255     missing = manifest_version.BuilderStatus(
256         manifest_version.BuilderStatus.STATUS_MISSING, None)
257
258     # Fail 1, pass 2, leave 3,4 unprocessed.
259     manifest_version.CreateSymlink(m1, os.path.join(
260         for_build, 'fail', CHROME_BRANCH, os.path.basename(m1)))
261     manifest_version.CreateSymlink(m1, os.path.join(
262         for_build, 'pass', CHROME_BRANCH, os.path.basename(m2)))
263     self.mox.StubOutWithMock(self.manager, 'GetBuildStatus')
264     self.manager.GetBuildStatus(self.build_names[0], '1.2.5').AndReturn(missing)
265     self.mox.ReplayAll()
266     self.manager.InitializeManifestVariables(info)
267     self.mox.VerifyAll()
268     self.assertEqual(self.manager.latest_unprocessed, '1.2.5')
269
270   def testLatestSpecFromDir(self):
271     """Tests whether we can get sorted specs correctly from a directory."""
272     self.mox.StubOutWithMock(repository, 'CloneGitRepo')
273     info = manifest_version.VersionInfo(
274         '99.1.2', CHROME_BRANCH, incr_type='branch')
275
276     specs_dir = os.path.join(self.manager.manifest_dir, 'buildspecs',
277                              CHROME_BRANCH)
278     m1, m2, m3, m4 = [os.path.join(specs_dir, x)
279                       for x in ['100.0.0.xml', '99.3.3.xml', '99.1.10.xml',
280                                 '99.1.5.xml']]
281
282     # Create fake buildspecs.
283     osutils.SafeMakedirs(specs_dir)
284     for m in [m1, m2, m3, m4]:
285       osutils.Touch(m)
286
287     self.mox.ReplayAll()
288     spec = self.manager._LatestSpecFromDir(info, specs_dir)
289     self.mox.VerifyAll()
290     # Should be the latest on the 99.1 branch.
291     self.assertEqual(spec, '99.1.10')
292
293   def testGetNextVersionNoIncrement(self):
294     """Tests whether we can get the next version to be built correctly.
295
296     Tests without pre-existing version in manifest dir.
297     """
298     info = manifest_version.VersionInfo(
299         FAKE_VERSION_STRING, CHROME_BRANCH, incr_type='branch')
300
301     self.manager.latest = None
302     self.mox.ReplayAll()
303     version = self.manager.GetNextVersion(info)
304     self.mox.VerifyAll()
305     self.assertEqual(FAKE_VERSION_STRING, version)
306
307   def testGetNextVersionIncrement(self):
308     """Tests that we create a new version if a previous one exists."""
309     self.mox.StubOutWithMock(manifest_version.VersionInfo, 'UpdateVersionFile')
310     version_file = VersionInfoTest.CreateFakeVersionFile(self.tempdir)
311     info = manifest_version.VersionInfo(version_file=version_file,
312                                         incr_type='branch')
313     info.UpdateVersionFile(
314         'Automatic: %s - Updating to a new version number from %s' % (
315             self.build_names[0], FAKE_VERSION_STRING), dry_run=True)
316
317     self.manager.latest = FAKE_VERSION_STRING
318     self.mox.ReplayAll()
319     version = self.manager.GetNextVersion(info)
320     self.mox.VerifyAll()
321     self.assertEqual(FAKE_VERSION_STRING_NEXT, version)
322
323   def testGetNextBuildSpec(self):
324     """End-to-end test of updating the manifest."""
325     my_info = manifest_version.VersionInfo('1.2.3', chrome_branch='4')
326     self.PatchObject(manifest_version.BuildSpecsManager,
327                      'GetCurrentVersionInfo', return_value=my_info)
328     self.PatchObject(repository.RepoRepository, 'Sync')
329     self.PatchObject(repository.RepoRepository, 'ExportManifest',
330                      return_value='<manifest />')
331     rc = self.StartPatcher(cros_build_lib_unittest.RunCommandMock())
332     rc.SetDefaultCmdResult()
333
334     self.mox.ReplayAll()
335     self.manager.GetNextBuildSpec(retries=0)
336     self.manager.UpdateStatus({self.build_names[0]: True})
337     self.mox.VerifyAll()
338
339   def testUnpickleBuildStatus(self):
340     """Tests that _UnpickleBuildStatus returns the correct values."""
341     failed_msg = failures_lib.BuildFailureMessage(
342         'you failed', ['traceback'], True, 'taco', 'bot')
343     failed_input_status = manifest_version.BuilderStatus(
344         manifest_version.BuilderStatus.STATUS_FAILED, failed_msg)
345     passed_input_status = manifest_version.BuilderStatus(
346         manifest_version.BuilderStatus.STATUS_PASSED, None)
347
348     failed_output_status = self.manager._UnpickleBuildStatus(
349         failed_input_status.AsPickledDict())
350     passed_output_status = self.manager._UnpickleBuildStatus(
351         passed_input_status.AsPickledDict())
352     empty_string_status = self.manager._UnpickleBuildStatus('')
353
354     self.assertEqual(failed_input_status.AsFlatDict(),
355                 failed_output_status.AsFlatDict())
356     self.assertEqual(passed_input_status.AsFlatDict(),
357                 passed_output_status.AsFlatDict())
358     self.assertTrue(empty_string_status.Failed())
359
360   def _GetBuildersStatus(self, builders, status_runs):
361     """Test a call to BuildSpecsManager.GetBuildersStatus.
362
363     Args:
364       builders: List of builders to get status for.
365       status_runs: List of dictionaries of expected build and status.
366     """
367     self.mox.StubOutWithMock(manifest_version.BuildSpecsManager,
368                              'GetSlaveStatusesFromCIDB')
369     self.mox.StubOutWithMock(manifest_version.BuildSpecsManager,
370                              'GetBuildStatus')
371     for status_dict in status_runs:
372       manifest_version.BuildSpecsManager.GetSlaveStatusesFromCIDB(
373           mox.IgnoreArg()).AndReturn(status_dict)
374
375     final_status_dict = status_runs[-1]
376     for builder in builders:
377       status = manifest_version.BuilderStatus(
378           final_status_dict.get(builder), None)
379       manifest_version.BuildSpecsManager.GetBuildStatus(
380           builder, mox.IgnoreArg()).AndReturn(status)
381
382     self.mox.ReplayAll()
383     statuses = self.manager.GetBuildersStatus(mox.IgnoreArg, builders)
384     self.mox.VerifyAll()
385     return statuses
386
387   def testGetBuildersStatusBothFinished(self):
388     """Tests GetBuilderStatus where both builds have finished."""
389     status_runs = [{'build1': manifest_version.BuilderStatus.STATUS_FAILED,
390                     'build2': manifest_version.BuilderStatus.STATUS_PASSED}]
391     statuses = self._GetBuildersStatus(['build1', 'build2'], status_runs)
392     self.assertTrue(statuses['build1'].Failed())
393     self.assertTrue(statuses['build2'].Passed())
394
395   def testGetBuildersStatusLoop(self):
396     """Tests GetBuilderStatus where builds are inflight."""
397     status_runs = [{'build1': manifest_version.BuilderStatus.STATUS_INFLIGHT,
398                     'build2': manifest_version.BuilderStatus.STATUS_MISSING},
399                    {'build1': manifest_version.BuilderStatus.STATUS_FAILED,
400                     'build2': manifest_version.BuilderStatus.STATUS_INFLIGHT},
401                    {'build1': manifest_version.BuilderStatus.STATUS_FAILED,
402                     'build2': manifest_version.BuilderStatus.STATUS_PASSED}]
403     statuses = self._GetBuildersStatus(['build1', 'build2'], status_runs)
404     self.assertTrue(statuses['build1'].Failed())
405     self.assertTrue(statuses['build2'].Passed())
406
407
408 if __name__ == '__main__':
409   cros_test_lib.main()