blob: 08ea7d8be1e7b9afd2792b7a415c8f34b1c675f2 [file] [log] [blame]
# Copyright (c) 2012 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 the deploy_chrome script."""
from __future__ import print_function
import datetime
import mock
from chromite.lib import cros_test_lib
from chromite.lib import gs
from chromite.lib import gs_unittest
from chromite.lib import purge_lib
# pylint: disable=W0212
class TestHelperMethods(cros_test_lib.TestCase):
"""Main tests."""
def testKnownCases(self):
"""The stats upload path."""
CASES = (
('cros/factory-veyron-7505.B', '7505'),
('origin/factory-2723.14.B', '2723.14'),
('remote/firmware-falco_peppy-4389.B', '4389'),
('factory-veyron-7505.B', '7505'),
('factory-2723.14.B', '2723.14'),
('firmware-falco_peppy-4389.B', '4389'),
)
for branch, expected in CASES:
self.assertEqual(purge_lib.ParseBranchName(branch), expected)
def testListRemoteBranches(self):
branches = purge_lib.ListRemoteBranches()
# We know there are more than 300 remote branches for chromite.
self.assertGreater(len(branches), 300)
def testProtectedBranchVersions(self):
branch_names = [
'cros/factory-veyron-7505.B',
'origin/factory-2723.14.B',
'remote/firmware-falco_peppy-4389.B',
]
branch_versions = purge_lib.ProtectedBranchVersions(branch_names)
# We know there are more than 100 firmware/factory branches.
self.assertEqual(branch_versions, ['7505', '2723.14', '4389'])
def testProtectedBranchVersionsLive(self):
branches = purge_lib.ListRemoteBranches()
branch_versions = purge_lib.ProtectedBranchVersions(branches)
# We know there are more than 100 firmware/factory branches.
self.assertGreater(len(branch_versions), 100)
# cros/firmware-snow-2695.90.B is a known branch. Ensure it's listed.
self.assertIn('2695.90', branch_versions)
def testParseChromeosReleasesBuildUri(self):
"""Test parseChromeosReleasesBuildUri."""
self.assertEqual(
purge_lib.ParseChromeosReleasesBuildUri(
'gs://chromeos-releases/canary-channel/duck/6652.0.0/'),
'6652.0.0')
def testVersionBranchMatch(self):
"""Test versionBranchMatch."""
self.assertTrue(purge_lib.VersionBranchMatch('1.2.3', '1'))
self.assertTrue(purge_lib.VersionBranchMatch('1.2.3', '1.2'))
self.assertTrue(purge_lib.VersionBranchMatch('1.2.357', '1.2'))
self.assertFalse(purge_lib.VersionBranchMatch('12.24.37', '1.2'))
self.assertFalse(purge_lib.VersionBranchMatch('1.0.0', '1'))
self.assertFalse(purge_lib.VersionBranchMatch('1.2.0', '1.2'))
def testInBranches(self):
"""Test versionBranchMatch."""
branches = ('1', '2.2', '5.3')
self.assertTrue(purge_lib.InBranches('1.2.3', branches))
self.assertTrue(purge_lib.InBranches('1.2.3', branches))
self.assertTrue(purge_lib.InBranches('1.2.357', branches))
self.assertTrue(purge_lib.InBranches('5.3.23', branches))
self.assertFalse(purge_lib.InBranches('12.24.37', branches))
self.assertFalse(purge_lib.InBranches('1.0.0', branches))
self.assertFalse(purge_lib.InBranches('2.1.0', branches))
self.assertFalse(purge_lib.InBranches('5.3.0', branches))
class TestBucketSearches(gs_unittest.AbstractGSContextTest):
"""Test GS interactions in purge_lib."""
def setUp(self):
self.maxDiff = None
self.expireDate = datetime.datetime.now()
self.preExpire = self.expireDate + datetime.timedelta(minutes=5)
self.postExpire = self.expireDate - datetime.timedelta(minutes=5)
self.file_no_timestamp = gs.GSListResult(
'gs://chromeos-releases/canary-channel/plain_file',
None, None, None, None)
self.file_with_timestamp = self.mockResult(
'gs://chromeos-releases/canary-channel/plain_file')
self.directory = self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/')
def mockResult(self, url, expired=True):
if url.endswith('/'):
creation_time = None
else:
creation_time = self.postExpire if expired else self.preExpire
return gs.GSListResult(
content_length=0,
creation_time=creation_time,
url=url,
generation=0,
metageneration=0)
def patchSafeList(self):
listResults = {
'gs://chromeos-image-archive/': [
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/'),
self.mockResult(
'gs://chromeos-image-archive/trybot-foo-paladin/'),
self.mockResult(
'gs://chromeos-image-archive/foo-factory/'),
self.mockResult(
'gs://chromeos-image-archive/trybot-foo-factory/'),
self.mockResult(
'gs://chromeos-image-archive/foo-firmware/'),
self.mockResult(
'gs://chromeos-image-archive/trybot-foo-firmware/'),
self.mockResult(
'gs://chromeos-image-archive/bar-firmware/'),
self.mockResult(
'gs://chromeos-image-archive/trybot-whirlwind-test-ap/'),
self.mockResult(
'gs://chromeos-image-archive/trybot-stumpy-test-ap/'),
],
'gs://chromeos-image-archive/foo-paladin/': [
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/plain_file'),
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/1.2.3/'),
],
'gs://chromeos-image-archive/foo-paladin/1.2.3/**': [
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/1.2.3/a'),
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/1.2.3/b'),
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/1.2.3/nested/c'),
],
'gs://chromeos-image-archive/trybot-foo-paladin/': [
],
'gs://chromeos-image-archive/foo-factory/': [
],
'gs://chromeos-image-archive/trybot-foo-factory/': [
],
'gs://chromeos-image-archive/trybot-foo-firmware/': [
],
'gs://chromeos-releases/': [
self.mockResult(
'gs://chromeos-releases/stable-channel/'),
self.mockResult(
'gs://chromeos-releases/beta-channel/'),
self.mockResult(
'gs://chromeos-releases/dev-channel/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/'),
self.mockResult(
'gs://chromeos-releases/logs/'),
self.mockResult(
'gs://chromeos-releases/top-level-file'),
],
'gs://chromeos-releases/canary-channel/': [
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/plain_file'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/'),
],
'gs://chromeos-releases/canary-channel/plain_file': [
self.mockResult(
'gs://chromeos-releases/canary-channel/plain_file'),
],
'gs://chromeos-releases/canary-channel/arkham/': [
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/6301.0.0/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/6301.1.0/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/7023.0.0/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/noparse/'),
],
'gs://chromeos-releases/canary-channel/arkham/6301.0.0/**': [
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/6301.0.0/a'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/6301.0.0/b'),
],
'gs://chromeos-releases/canary-channel/arkham/7023.0.0/**': [
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/7023.0.0/a'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/7023.0.0/b'),
],
'gs://chromeos-releases/canary-channel/arkham/noparse/**': [
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/noparse/a'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/noparse/b'),
],
'gs://chromeos-releases/canary-channel/x86-alex/': [
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.4/'),
],
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/**': [
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/a'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/b',
expired=False),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/'
'nest/deep'),
],
'gs://chromeos-releases/canary-channel/x86-alex/1.2.4/**': [
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.4/a'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.4/b'),
],
}
self.PatchObject(purge_lib, 'SafeList',
side_effect=lambda _, url: listResults[url])
def testLocateChromeosReleasesProtectedPrefixes(self):
"""Test locateChromeosReleasesProtectedPrefixes."""
protected_versions = ('6301', '7000.2')
self.patchSafeList()
result = purge_lib.LocateChromeosReleasesProtectedPrefixes(
self.ctx, protected_versions)
self.assertEqual(result, [
'gs://chromeos-releases/Attic',
'gs://chromeos-releases/stable-channel',
'gs://chromeos-releases/beta-channel',
'gs://chromeos-releases/dev-channel',
'gs://chromeos-releases/logs',
'gs://chromeos-releases/tobesigned',
'gs://chromeos-releases/canary-channel/arkham/6301.1.0/',
])
def testLocateChromeosImageArchiveProtectedPrefixes(self):
self.patchSafeList()
result = purge_lib.LocateChromeosImageArchiveProtectedPrefixes(self.ctx)
self.assertEqual(result, [
'gs://chromeos-image-archive/foo-firmware/',
'gs://chromeos-image-archive/bar-firmware/',
'gs://chromeos-image-archive/trybot-whirlwind-test-ap/',
'gs://chromeos-image-archive/trybot-stumpy-test-ap/',
])
def testProduceFilteredCandidatesArchive(self):
protected_prefixes = (
'gs://chromeos-image-archive/foo-firmware',
'gs://chromeos-image-archive/bar-firmware',
'gs://chromeos-image-archive/trybot-whirlwind-test-ap/',
'gs://chromeos-image-archive/trybot-stumpy-test-ap/',
)
self.patchSafeList()
result = purge_lib.ProduceFilteredCandidates(
self.ctx, 'gs://chromeos-image-archive/', protected_prefixes, 2)
self.assertEqual(list(result), [
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/plain_file'),
self.mockResult(
'gs://chromeos-image-archive/foo-paladin/1.2.3/'),
])
def testProduceFilteredCandidatesReleases(self):
protected_prefixes = (
'gs://chromeos-releases/Attic',
'gs://chromeos-releases/stable-channel',
'gs://chromeos-releases/beta-channel',
'gs://chromeos-releases/dev-channel',
'gs://chromeos-releases/logs',
'gs://chromeos-releases/tobesigned',
'gs://chromeos-releases/canary-channel/arkham/6301.1.0/',
'gs://chromeos-releases/canary-channel/auron/6301.18.0/',
)
self.patchSafeList()
result = purge_lib.ProduceFilteredCandidates(
self.ctx, 'gs://chromeos-releases/', protected_prefixes, 3)
self.assertEqual(list(result), [
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/6301.0.0/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/7023.0.0/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/arkham/noparse/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/plain_file'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.4/'),
self.mockResult(
'gs://chromeos-releases/top-level-file'),
])
def testExpand(self):
self.patchSafeList()
result = purge_lib.Expand(self.ctx, self.file_no_timestamp)
self.assertEqual(result, [self.file_with_timestamp])
result = purge_lib.Expand(self.ctx, self.file_with_timestamp)
self.assertEqual(result, [self.file_with_timestamp])
result = purge_lib.Expand(self.ctx, self.directory)
self.assertEqual(result, [
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/a'),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/b',
expired=False),
self.mockResult(
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/nest/deep'),
])
def testExpire(self):
# Dryrun, move nothing.
purge_lib.Expire(self.ctx, dryrun=True, url='gs://foo/bar')
purge_lib.Expire(self.ctx, dryrun=True,
url='gs://chromeos-releases/deep/nested/file')
self.assertEqual(self.gs_mock.call_args_list, [])
# Really move stuff.
purge_lib.Expire(self.ctx, dryrun=False, url='gs://foo/bar')
purge_lib.Expire(self.ctx, dryrun=False,
url='gs://chromeos-releases/deep/nested/file')
self.assertEqual(self.gs_mock.call_args_list, [
mock.call(self.ctx, [
'mv', '--', 'gs://foo/bar', 'gs://foo-backup/bar',
]),
mock.call(self.ctx, [
'mv', '--', 'gs://chromeos-releases/deep/nested/file',
'gs://chromeos-releases-backup/deep/nested/file',
]),
])
def testExpireAndExpandDryrun(self):
self.patchSafeList()
purge_lib.ExpandAndExpire(self.ctx, True, self.expireDate,
self.file_no_timestamp)
purge_lib.ExpandAndExpire(self.ctx, True, self.expireDate,
self.file_with_timestamp)
purge_lib.ExpandAndExpire(self.ctx, True, self.expireDate,
self.directory)
self.assertEqual(self.gs_mock.call_args_list, [])
def testExpireAndExpandNoTimestamp(self):
self.patchSafeList()
# File with no timestamp.
purge_lib.ExpandAndExpire(self.ctx, False, self.expireDate,
self.file_no_timestamp)
self.assertEqual(self.gs_mock.call_args_list, [
mock.call(self.ctx, [
'mv', '--',
'gs://chromeos-releases/canary-channel/plain_file',
'gs://chromeos-releases-backup/canary-channel/plain_file',
]),
])
def testExpireAndExpandWithTimestamp(self):
self.patchSafeList()
# File with timestamp.
purge_lib.ExpandAndExpire(self.ctx, False, self.expireDate,
self.file_with_timestamp)
self.assertEqual(self.gs_mock.call_args_list, [
mock.call(self.ctx, [
'mv', '--',
'gs://chromeos-releases/canary-channel/plain_file',
'gs://chromeos-releases-backup/canary-channel/plain_file',
]),
])
def testExpireAndExpandDirectory(self):
self.patchSafeList()
purge_lib.ExpandAndExpire(self.ctx, False, self.expireDate,
self.directory)
self.assertEqual(self.gs_mock.call_args_list, [
mock.call(self.ctx, [
'mv', '--',
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/a',
'gs://chromeos-releases-backup/canary-channel/x86-alex/1.2.3/a',
]),
mock.call(self.ctx, [
'mv', '--',
'gs://chromeos-releases/canary-channel/x86-alex/1.2.3/nest/deep',
'gs://chromeos-releases-backup/canary-channel/x86-alex/1.2.3/'
'nest/deep',
]),
])