| # Copyright 2016 The Chromium OS 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 cros_mark_android_as_stable.py.""" |
| |
| from __future__ import print_function |
| |
| import mock |
| import os |
| |
| from chromite.cbuildbot import constants |
| from chromite.lib import cros_build_lib |
| from chromite.lib import cros_test_lib |
| from chromite.lib import git |
| from chromite.lib import gs |
| from chromite.lib import gs_unittest |
| from chromite.lib import osutils |
| from chromite.lib import portage_util |
| from chromite.scripts import cros_mark_android_as_stable |
| |
| |
| class _StubCommandResult(object): |
| """Helper for mocking RunCommand results.""" |
| def __init__(self, msg): |
| self.output = msg |
| |
| |
| class CrosMarkAndroidAsStable(cros_test_lib.MockTempDirTestCase): |
| """Tests for cros_mark_android_as_stable.""" |
| |
| unstable_data = 'KEYWORDS="~x86 ~arm"' |
| stable_data = 'KEYWORDS="x86 arm"' |
| |
| def setUp(self): |
| """Setup vars and create mock dir.""" |
| self.tmp_overlay = os.path.join(self.tempdir, 'chromiumos-overlay') |
| self.mock_android_dir = os.path.join(self.tmp_overlay, constants.ANDROID_CP) |
| |
| ebuild = os.path.join(self.mock_android_dir, |
| constants.ANDROID_PN + '-%s.ebuild') |
| self.unstable = ebuild % '9999' |
| self.old_version = '25' |
| self.old = ebuild % self.old_version |
| self.old2_version = '50' |
| self.old2 = ebuild % self.old2_version |
| self.new_version = '100' |
| self.new = ebuild % ('%s-r1' % self.new_version) |
| self.partial_new_version = '150' |
| self.not_new_version = '200' |
| |
| osutils.WriteFile(self.unstable, self.unstable_data, makedirs=True) |
| osutils.WriteFile(self.old, self.stable_data, makedirs=True) |
| osutils.WriteFile(self.old2, self.stable_data, makedirs=True) |
| |
| self.bucket_url = 'gs://u' |
| self.build_branch = 'x' |
| self.gs_mock = self.StartPatcher(gs_unittest.GSContextMock()) |
| |
| builds = { |
| 'ARM': [ |
| self.old_version, self.old2_version, self.new_version, |
| self.partial_new_version |
| ], |
| 'X86': [self.old_version, self.old2_version, self.new_version], |
| } |
| for build_type, builds in builds.iteritems(): |
| url = self.makeTargetUrl(constants.ANDROID_BUILD_TARGETS[build_type]) |
| builds = '\n'.join(os.path.join(url, version) for version in builds) |
| self.gs_mock.AddCmdResult(['ls', '--', url], output=builds) |
| |
| for version in [self.old_version, self.old2_version, self.new_version]: |
| for target in constants.ANDROID_BUILD_TARGETS.itervalues(): |
| self.setupMockBuild(target, version) |
| |
| self.setupMockBuild(constants.ANDROID_BUILD_TARGETS['ARM'], |
| self.partial_new_version) |
| self.setupMockBuild(constants.ANDROID_BUILD_TARGETS['X86'], |
| self.partial_new_version, False) |
| |
| for target in constants.ANDROID_BUILD_TARGETS.itervalues(): |
| self.setupMockBuild(target, self.not_new_version, False) |
| |
| def setupMockBuild(self, target, version, valid=True): |
| """Helper to mock a build.""" |
| url = self.makeUrl(target, version) |
| if valid: |
| subdir = os.path.join(url, self.makeSubpath(target, version)) |
| self.gs_mock.AddCmdResult(['ls', '--', url], output=subdir) |
| zipfile = os.path.join(subdir, 'file-%s.zip' % version) |
| self.gs_mock.AddCmdResult(['ls', '--', subdir], output=zipfile) |
| else: |
| def _RaiseGSNoSuchKey(*_args, **_kwargs): |
| raise gs.GSNoSuchKey('file does not exist') |
| self.gs_mock.AddCmdResult(['ls', '--', url], |
| side_effect=_RaiseGSNoSuchKey) |
| |
| def makeTargetUrl(self, target): |
| """Helper to return the url for a target.""" |
| return os.path.join(self.bucket_url, |
| '%s-%s' % (self.build_branch, target)) |
| |
| def makeUrl(self, target, version): |
| """Helper to return the url for a build.""" |
| return os.path.join(self.makeTargetUrl(target), version) |
| |
| def makeSubpath(self, target, version): |
| """Helper to return the subpath for a build.""" |
| return '%s%s' % (target, version) |
| |
| def testIsBuildIdValid(self): |
| """Test if checking if build valid.""" |
| subpaths = cros_mark_android_as_stable.IsBuildIdValid(self.bucket_url, |
| self.build_branch, |
| self.old_version) |
| self.assertTrue(subpaths) |
| self.assertEquals(len(subpaths), 2) |
| self.assertEquals(subpaths['ARM'], 'linux-minnie_cheets-userdebug25') |
| self.assertEquals(subpaths['X86'], 'linux-cheets_x86-userdebug25') |
| |
| subpaths = cros_mark_android_as_stable.IsBuildIdValid(self.bucket_url, |
| self.build_branch, |
| self.new_version) |
| self.assertTrue(subpaths) |
| self.assertEquals(len(subpaths), 2) |
| self.assertEquals(subpaths['ARM'], 'linux-minnie_cheets-userdebug100') |
| self.assertEquals(subpaths['X86'], 'linux-cheets_x86-userdebug100') |
| |
| subpaths = cros_mark_android_as_stable.IsBuildIdValid( |
| self.bucket_url, self.build_branch, self.partial_new_version) |
| self.assertEqual(subpaths, None) |
| |
| subpaths = cros_mark_android_as_stable.IsBuildIdValid(self.bucket_url, |
| self.build_branch, |
| self.not_new_version) |
| self.assertEqual(subpaths, None) |
| |
| def testFindAndroidCandidates(self): |
| """Test creation of stable ebuilds from mock dir.""" |
| (unstable, stable) = cros_mark_android_as_stable.FindAndroidCandidates( |
| self.mock_android_dir) |
| |
| stable_ebuild_paths = [x.ebuild_path for x in stable] |
| self.assertEqual(unstable.ebuild_path, self.unstable) |
| self.assertEqual(len(stable), 2) |
| self.assertIn(self.old, stable_ebuild_paths) |
| self.assertIn(self.old2, stable_ebuild_paths) |
| |
| def testGetLatestBuild(self): |
| """Test determination of latest build from gs bucket.""" |
| version, subpaths = cros_mark_android_as_stable.GetLatestBuild( |
| self.bucket_url, self.build_branch) |
| self.assertEqual(version, self.new_version) |
| self.assertTrue(subpaths) |
| self.assertEquals(len(subpaths), 2) |
| self.assertEquals(subpaths['ARM'], 'linux-minnie_cheets-userdebug100') |
| self.assertEquals(subpaths['X86'], 'linux-cheets_x86-userdebug100') |
| |
| def testGetAndroidRevisionListLink(self): |
| """Test generation of revision diff list.""" |
| old_ebuild = portage_util.EBuild(self.old) |
| old2_ebuild = portage_util.EBuild(self.old2) |
| link = cros_mark_android_as_stable.GetAndroidRevisionListLink( |
| self.build_branch, old_ebuild, old2_ebuild) |
| self.assertEqual(link, ('http://android-build-uber.corp.google.com/' |
| 'repo.html?last_bid=25&bid=50&branch=x')) |
| |
| def testMarkAndroidEBuildAsStable(self): |
| """Test updating of ebuild.""" |
| self.PatchObject(cros_build_lib, 'RunCommand') |
| git_mock = self.PatchObject(git, 'RunGit') |
| commit_mock = self.PatchObject(portage_util.EBuild, 'CommitChange') |
| stable_candidate = portage_util.EBuild(self.old2) |
| unstable = portage_util.EBuild(self.unstable) |
| android_version = self.new_version |
| package_dir = self.mock_android_dir |
| subpaths_dict = { |
| 'ARM': 'linux-minnie_cheets-userdebug100', |
| 'X86': 'linux-cheets_x86-userdebug100', |
| } |
| version_atom = cros_mark_android_as_stable.MarkAndroidEBuildAsStable( |
| stable_candidate, unstable, constants.ANDROID_PN, |
| android_version, subpaths_dict, package_dir, |
| self.build_branch) |
| git_mock.assert_has_calls([ |
| mock.call(package_dir, ['add', self.new]), |
| mock.call(package_dir, ['add', 'Manifest']), |
| ]) |
| commit_mock.assert_call(mock.call('latest', package_dir)) |
| self.assertEqual(version_atom, |
| '%s-%s-r1' % (constants.ANDROID_CP, self.new_version)) |