blob: 81b40d0a5d2fd41631c823d8b9a702bf4a939b24 [file] [log] [blame]
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Packages service tests."""
import io
import json
import os
import re
from unittest import mock
import pytest
import chromite as cr
from chromite.lib import build_target_lib
from chromite.lib import chromeos_version
from chromite.lib import chroot_lib
from chromite.lib import constants
from chromite.lib import cros_build_lib
from chromite.lib import cros_test_lib
from chromite.lib import dependency_graph
from chromite.lib import depgraph
from chromite.lib import osutils
from chromite.lib import partial_mock
from chromite.lib import portage_util
from chromite.lib import uprev_lib
from chromite.lib.parser import package_info
from chromite.service import android
from chromite.service import dependency
from chromite.service import packages
D = cros_test_lib.Directory
class UprevAndroidTest(cros_test_lib.RunCommandTestCase):
"""Uprev android tests."""
def _mock_successful_uprev(self) -> None:
self.rc.AddCmdResult(
partial_mock.In("cros_mark_android_as_stable"),
stdout=(
'{"revved": true,'
' "android_atom": "android/android-1.0",'
' "modified_files": ["file1", "file2"]}'
),
)
def test_success(self) -> None:
"""Test successful run handling."""
self._mock_successful_uprev()
build_targets = [
build_target_lib.BuildTarget(t) for t in ["foo", "bar"]
]
result = packages.uprev_android(
"android/package", chroot_lib.Chroot(), build_targets=build_targets
)
self.assertCommandContains(
[
"cros_mark_android_as_stable",
"--android_package=android/package",
"--boards=foo bar",
]
)
self.assertCommandContains(["emerge-foo"])
self.assertCommandContains(["emerge-bar"])
self.assertTrue(result.revved)
self.assertEqual(result.android_atom, "android/android-1.0")
self.assertListEqual(result.modified_files, ["file1", "file2"])
def test_android_build_branch(self) -> None:
"""Test specifying android_build_branch option."""
self._mock_successful_uprev()
packages.uprev_android(
"android/package",
chroot_lib.Chroot(),
android_build_branch="android-build-branch",
)
self.assertCommandContains(
[
"cros_mark_android_as_stable",
"--android_package=android/package",
"--android_build_branch=android-build-branch",
]
)
def test_android_version(self) -> None:
"""Test specifying android_version option."""
self._mock_successful_uprev()
packages.uprev_android(
"android/package", chroot_lib.Chroot(), android_version="7123456"
)
self.assertCommandContains(
[
"cros_mark_android_as_stable",
"--android_package=android/package",
"--force_version=7123456",
]
)
def test_skip_commit(self) -> None:
"""Test specifying skip_commit option."""
self._mock_successful_uprev()
packages.uprev_android(
"android/package", chroot_lib.Chroot(), skip_commit=True
)
self.assertCommandContains(
[
"cros_mark_android_as_stable",
"--android_package=android/package",
"--skip_commit",
]
)
def test_no_uprev(self) -> None:
"""Test no uprev handling."""
self.rc.AddCmdResult(
partial_mock.In("cros_mark_android_as_stable"),
stdout='{"revved": false}',
)
build_targets = [
build_target_lib.BuildTarget(t) for t in ["foo", "bar"]
]
result = packages.uprev_android(
"android/package", chroot_lib.Chroot(), build_targets=build_targets
)
self.assertCommandContains(
["cros_mark_android_as_stable", "--boards=foo bar"]
)
self.assertCommandContains(["emerge-foo"], expected=False)
self.assertCommandContains(["emerge-bar"], expected=False)
self.assertFalse(result.revved)
def test_ignore_junk_in_stdout(self) -> None:
"""Test when stdout contains junk messages."""
self.rc.AddCmdResult(
partial_mock.In("cros_mark_android_as_stable"),
stdout='foo\nbar\n{"revved": false}\n',
)
result = packages.uprev_android("android/package", chroot_lib.Chroot())
self.assertFalse(result.revved)
class UprevAndroidLKGBTest(cros_test_lib.MockTestCase):
"""Tests for uprevving Android with LKGB."""
def test_registered_handlers(self) -> None:
"""Test that each Android package has an uprev handler registered."""
mock_handler = self.PatchObject(packages, "uprev_android_lkgb")
for android_package in android.GetAllAndroidPackages():
cpv = package_info.SplitCPV(
"chromeos-base/" + android_package, strict=False
)
build_targets = [build_target_lib.BuildTarget("foo")]
chroot = chroot_lib.Chroot()
packages.uprev_versioned_package(cpv, build_targets, [], chroot)
mock_handler.assert_called_once_with(
android_package, build_targets, chroot
)
mock_handler.reset_mock()
def test_success(self) -> None:
"""Test a successful uprev."""
self.PatchObject(android, "OVERLAY_DIR", new="overlay-dir")
self.PatchObject(
android, "ReadLKGB", return_value=dict(build_id="android-lkgb")
)
self.PatchObject(
packages,
"uprev_android",
return_value=packages.UprevAndroidResult(
revved=True,
android_atom="android-atom",
modified_files=["file1", "file2"],
),
)
result = packages.uprev_android_lkgb(
"android-package", [], chroot_lib.Chroot()
)
self.assertListEqual(
result.modified,
[
uprev_lib.UprevVersionedPackageModifications(
"android-lkgb",
[
os.path.join("overlay-dir", "file1"),
os.path.join("overlay-dir", "file2"),
],
)
],
)
def test_no_rev(self) -> None:
"""Test when nothing revved."""
self.PatchObject(
android, "ReadLKGB", return_value=dict(build_id="android-lkgb")
)
self.PatchObject(
packages,
"uprev_android",
return_value=packages.UprevAndroidResult(revved=False),
)
result = packages.uprev_android_lkgb(
"android-package", [], chroot_lib.Chroot()
)
self.assertListEqual(result.modified, [])
class UprevECUtilsTest(cros_test_lib.MockTestCase):
"""Tests for upreving ecutils."""
def test_success(self) -> None:
"""Test a successful uprev."""
def fakeRunTasks(func, inputs):
results = []
for args in inputs:
results.append(func(*args))
return results
self.PatchObject(
packages.uprev_lib.parallel,
"RunTasksInProcessPool",
side_effect=fakeRunTasks,
)
mock_devutils = mock.MagicMock(name="dev-utils")
mock_ecutils = mock.MagicMock(name="ec-utils")
mock_ecutilstest = mock.MagicMock(name="ec-utils-test")
self.PatchObject(
packages.uprev_lib.portage_util,
"GetOverlayEBuilds",
return_value=[
mock_devutils,
mock_ecutils,
mock_ecutilstest,
],
)
mock_overlay_mgr = mock.MagicMock(name="overlay-manager")
mock_overlay_mgr.modified_ebuilds = ["file1", "file2"]
self.PatchObject(
packages.uprev_lib,
"UprevOverlayManager",
return_value=mock_overlay_mgr,
)
for package in [
"chromeos-base/ec-devutils",
"chromeos-base/ec-utils",
"chromeos-base/ec-utils-test",
]:
cpv = package_info.SplitCPV(package, strict=False)
assert cpv is not None
build_targets = [build_target_lib.BuildTarget("foo")]
refs = [
uprev_lib.GitRef(
path="/platform/ec",
ref="main",
revision="123",
)
]
chroot = chroot_lib.Chroot()
result = packages.uprev_versioned_package(
cpv, build_targets, refs, chroot
)
self.assertEqual(1, len(result.modified))
self.assertEqual("123", result.modified[0].new_version)
self.assertListEqual(result.modified[0].files, ["file1", "file2"])
mock_overlay_mgr.uprev.assert_called_with(
package_list=[
package,
],
force=True,
)
class UprevBuildTargetsTest(cros_test_lib.RunCommandTestCase):
"""uprev_build_targets tests."""
def test_invalid_type_fails(self) -> None:
"""Test invalid type fails."""
with self.assertRaises(AssertionError):
packages.uprev_build_targets(
[build_target_lib.BuildTarget("foo")], "invalid"
)
def test_none_type_fails(self) -> None:
"""Test None type fails."""
with self.assertRaises(AssertionError):
packages.uprev_build_targets(
[build_target_lib.BuildTarget("foo")], None
)
class PatchEbuildVarsTest(cros_test_lib.MockTestCase):
"""patch_ebuild_vars test."""
def setUp(self) -> None:
self.mock_input = self.PatchObject(packages.fileinput, "input")
self.mock_stdout_write = self.PatchObject(packages.sys.stdout, "write")
self.ebuild_path = "/path/to/ebuild"
self.old_var_value = "R100-5678.0.123456789"
self.new_var_value = "R102-5678.0.234566789"
def test_patch_ebuild_vars_var_only(self) -> None:
"""patch_ebuild_vars changes ^var=value$."""
ebuild_contents = (
"This line does not change.\n"
'AFDO_PROFILE_VERSION="{var_value}"\n'
"\n"
"# The line with AFDO_PROFILE_VERSION is also unchanged."
)
# Ebuild contains old_var_value.
self.mock_input.return_value = io.StringIO(
ebuild_contents.format(var_value=self.old_var_value)
)
expected_calls = []
# Expect the line with new_var_value.
for line in io.StringIO(
ebuild_contents.format(var_value=self.new_var_value)
):
expected_calls.append(mock.call(line))
packages.patch_ebuild_vars(
self.ebuild_path, {"AFDO_PROFILE_VERSION": self.new_var_value}
)
self.mock_stdout_write.assert_has_calls(expected_calls)
def test_patch_ebuild_vars_ignore_export(self) -> None:
"""patch_ebuild_vars changes ^export var=value$ and keeps export."""
ebuild_contents = (
"This line does not change.\n"
'export AFDO_PROFILE_VERSION="{var_value}"\n'
"# This line is also unchanged."
)
# Ebuild contains old_var_value.
self.mock_input.return_value = io.StringIO(
ebuild_contents.format(var_value=self.old_var_value)
)
expected_calls = []
# Expect the line with new_var_value.
for line in io.StringIO(
ebuild_contents.format(var_value=self.new_var_value)
):
expected_calls.append(mock.call(line))
packages.patch_ebuild_vars(
self.ebuild_path, {"AFDO_PROFILE_VERSION": self.new_var_value}
)
self.mock_stdout_write.assert_has_calls(expected_calls)
def test_patch_ebuild_vars_partial_match(self) -> None:
"""patch_ebuild_vars ignores ^{prefix}var=value$."""
ebuild_contents = (
'This and the line below do not change.\nNEW_AFDO="{var_value}"'
)
# Ebuild contains old_var_value.
self.mock_input.return_value = io.StringIO(
ebuild_contents.format(var_value=self.old_var_value)
)
expected_calls = []
# Expect the line with UNCHANGED old_var_value.
for line in io.StringIO(
ebuild_contents.format(var_value=self.old_var_value)
):
expected_calls.append(mock.call(line))
# Note that the var name partially matches the ebuild var and hence it
# has to be ignored.
packages.patch_ebuild_vars(
self.ebuild_path, {"AFDO": self.new_var_value}
)
self.mock_stdout_write.assert_has_calls(expected_calls)
def test_patch_ebuild_vars_no_vars(self) -> None:
"""patch_ebuild_vars keeps ebuild intact if there are no vars."""
ebuild_contents = (
"This line does not change.\n"
"The line with AFDO_PROFILE_VERSION is also unchanged."
)
self.mock_input.return_value = io.StringIO(ebuild_contents)
expected_calls = []
for line in io.StringIO(ebuild_contents):
expected_calls.append(mock.call(line))
packages.patch_ebuild_vars(
self.ebuild_path, {"AFDO_PROFILE_VERSION": self.new_var_value}
)
self.mock_stdout_write.assert_has_calls(expected_calls)
class UprevsVersionedPackageTest(cros_test_lib.MockTestCase):
"""uprevs_versioned_package decorator test."""
@packages.uprevs_versioned_package("category/package")
def uprev_category_package(self, *args, **kwargs) -> None:
"""Registered function for testing."""
def test_calls_function(self) -> None:
"""Test calling a registered function."""
self.PatchObject(self, "uprev_category_package")
cpv = package_info.SplitCPV("category/package", strict=False)
packages.uprev_versioned_package(cpv, [], [], chroot_lib.Chroot())
# TODO(crbug/1065172): Invalid assertion that was previously mocked.
# patch.assert_called()
def test_unregistered_package(self) -> None:
"""Test calling with an unregistered package."""
cpv = package_info.SplitCPV("does-not/exist", strict=False)
with self.assertRaises(packages.UnknownPackageError):
packages.uprev_versioned_package(cpv, [], [], chroot_lib.Chroot())
class UprevEbuildFromPinTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests uprev_ebuild_from_pin function"""
package = "category/package"
version = "1.2.3"
new_version = "1.2.4"
ebuild_template = "package-%s-r1.ebuild"
ebuild = ebuild_template % version
unstable_ebuild = "package-9999.ebuild"
manifest = "Manifest"
def test_uprev_ebuild(self) -> None:
"""Tests uprev of ebuild with version path"""
file_layout = (
D(self.package, [self.ebuild, self.unstable_ebuild, self.manifest]),
)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout)
package_path = os.path.join(self.tempdir, self.package)
ebuild_path = os.path.join(package_path, self.ebuild)
self.WriteTempFile(ebuild_path, 'KEYWORDS="*"\n')
result = uprev_lib.uprev_ebuild_from_pin(
package_path, self.new_version, chroot=chroot_lib.Chroot()
)
self.assertEqual(
len(result.modified),
1,
"unexpected number of results: %s" % len(result.modified),
)
mod = result.modified[0]
self.assertEqual(
mod.new_version,
self.new_version + "-r1",
"unexpected version number: %s" % mod.new_version,
)
old_ebuild_path = os.path.join(
package_path, self.ebuild_template % self.version
)
new_ebuild_path = os.path.join(
package_path, self.ebuild_template % self.new_version
)
manifest_path = os.path.join(package_path, "Manifest")
expected_modified_files = [
old_ebuild_path,
new_ebuild_path,
manifest_path,
]
self.assertCountEqual(mod.files, expected_modified_files)
self.assertCommandContains(["ebuild", "manifest"])
def test_uprev_ebuild_same_version(self) -> None:
"""Tests uprev of ebuild with version path with unchanged version.
This should result in bumping the revision number.
"""
file_layout = (
D(self.package, [self.ebuild, self.unstable_ebuild, self.manifest]),
)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout)
package_path = os.path.join(self.tempdir, self.package)
ebuild_path = os.path.join(package_path, self.ebuild)
self.WriteTempFile(ebuild_path, 'KEYWORDS="*"\n')
result = uprev_lib.uprev_ebuild_from_pin(
package_path, self.version, chroot=chroot_lib.Chroot()
)
self.assertEqual(
len(result.modified),
1,
"unexpected number of results: %s" % len(result.modified),
)
mod = result.modified[0]
self.assertEqual(
mod.new_version,
self.version + "-r2",
"unexpected version number: %s" % mod.new_version,
)
old_ebuild_path = os.path.join(
package_path, self.ebuild_template % self.version
)
new_ebuild_path = os.path.join(
package_path, "package-%s-r2.ebuild" % self.version
)
manifest_path = os.path.join(package_path, "Manifest")
expected_modified_files = [
old_ebuild_path,
new_ebuild_path,
manifest_path,
]
self.assertCountEqual(mod.files, expected_modified_files)
self.assertCommandContains(["ebuild", "manifest"])
def test_no_ebuild(self) -> None:
"""Tests assertion is raised if package has no ebuilds"""
file_layout = (D(self.package, [self.manifest]),)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout)
package_path = os.path.join(self.tempdir, self.package)
with self.assertRaises(uprev_lib.EbuildUprevError):
uprev_lib.uprev_ebuild_from_pin(
package_path, self.new_version, chroot=chroot_lib.Chroot()
)
def test_multiple_stable_ebuilds(self) -> None:
"""Tests assertion is raised if multiple stable ebuilds are present"""
file_layout = (
D(
self.package,
[self.ebuild, self.ebuild_template % "1.2.1", self.manifest],
),
)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout)
package_path = os.path.join(self.tempdir, self.package)
ebuild_path = os.path.join(package_path, self.ebuild)
self.WriteTempFile(ebuild_path, 'KEYWORDS="*"\n')
ebuild_path = os.path.join(package_path, self.ebuild_template % "1.2.1")
self.WriteTempFile(ebuild_path, 'KEYWORDS="*"\n')
with self.assertRaises(uprev_lib.EbuildUprevError):
uprev_lib.uprev_ebuild_from_pin(
package_path, self.new_version, chroot=chroot_lib.Chroot()
)
def test_multiple_unstable_ebuilds(self) -> None:
"""Tests assertion is raised if multiple unstable ebuilds are present"""
file_layout = (
D(
self.package,
[self.ebuild, self.ebuild_template % "1.2.1", self.manifest],
),
)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, file_layout)
package_path = os.path.join(self.tempdir, self.package)
with self.assertRaises(uprev_lib.EbuildUprevError):
uprev_lib.uprev_ebuild_from_pin(
package_path, self.new_version, chroot=chroot_lib.Chroot()
)
class GetBestVisibleTest(cros_test_lib.MockTestCase):
"""get_best_visible tests."""
def test_empty_atom_fails(self) -> None:
"""Test empty atom raises an error."""
with self.assertRaises(AssertionError):
packages.get_best_visible("")
class HasPrebuiltTest(cros_test_lib.MockTestCase):
"""has_prebuilt tests."""
def test_empty_atom_fails(self) -> None:
"""Test an empty atom results in an error."""
with self.assertRaises(AssertionError):
packages.has_prebuilt("")
def test_use_flags(self) -> None:
"""Test use flags get propagated correctly."""
# We don't really care about the result, just the env handling.
patch = self.PatchObject(portage_util, "HasPrebuilt", return_value=True)
# Ignore any flags that may be in the environment.
self.PatchObject(os.environ, "get", return_value="")
packages.has_prebuilt("cat/pkg-1.2.3", useflags="useflag")
patch.assert_called_with(
"cat/pkg-1.2.3", board=None, extra_env={"USE": "useflag"}
)
def test_env_use_flags(self) -> None:
"""Test env use flags get propagated correctly with passed useflags."""
# We don't really care about the result, just the env handling.
patch = self.PatchObject(portage_util, "HasPrebuilt", return_value=True)
# Add some flags to the environment.
existing_flags = "already set flags"
self.PatchObject(os.environ, "get", return_value=existing_flags)
new_flags = "useflag"
packages.has_prebuilt("cat/pkg-1.2.3", useflags=new_flags)
expected = "%s %s" % (existing_flags, new_flags)
patch.assert_called_with(
"cat/pkg-1.2.3", board=None, extra_env={"USE": expected}
)
class AndroidVersionsTest(cros_test_lib.MockTestCase):
"""Tests getting android versions."""
def setUp(self) -> None:
package_result = [
"chromeos-base/android-container-nyc-4717008-r1",
"chromeos-base/update_engine-0.0.3-r3408",
]
self.PatchObject(
portage_util, "GetPackageDependencies", return_value=package_result
)
self.board = "board"
self.PatchObject(
portage_util,
"FindEbuildForBoardPackage",
return_value="chromeos-base/android-container-nyc",
)
FakeEnvironment = {
"ARM_TARGET": "3-linux-target",
}
self.PatchObject(
osutils, "SourceEnvironment", return_value=FakeEnvironment
)
# Clear the LRU cache for the function. We mock the function that
# provides the data this function processes to produce its result, so we
# need to clear it manually.
packages.determine_android_package.cache_clear()
def test_determine_android_version(self) -> None:
"""Tests that a valid android version is returned."""
version = packages.determine_android_version(self.board)
self.assertEqual(version, "4717008")
def test_determine_android_version_when_not_present(self) -> None:
"""Test None is returned for version when android is not present."""
package_result = ["chromeos-base/update_engine-0.0.3-r3408"]
self.PatchObject(
portage_util, "GetPackageDependencies", return_value=package_result
)
version = packages.determine_android_version(self.board)
self.assertEqual(version, None)
def test_determine_android_branch(self) -> None:
"""Tests that a valid android branch is returned."""
branch = packages.determine_android_branch(self.board)
self.assertEqual(branch, "3")
def test_determine_android_branch_64bit_targets(self) -> None:
"""Tests a valid android branch is returned with only 64bit targets."""
self.PatchObject(
osutils,
"SourceEnvironment",
return_value={"ARM64_TARGET": "3-linux-target"},
)
branch = packages.determine_android_branch(self.board)
self.assertEqual(branch, "3")
def test_determine_android_branch_when_not_present(self) -> None:
"""Tests a None is returned for branch when android is not present."""
package_result = ["chromeos-base/update_engine-0.0.3-r3408"]
self.PatchObject(
portage_util, "GetPackageDependencies", return_value=package_result
)
branch = packages.determine_android_branch(self.board)
self.assertEqual(branch, None)
def test_determine_android_target(self) -> None:
"""Tests that a valid android target is returned."""
target = packages.determine_android_target(self.board)
self.assertEqual(target, "cheets")
def test_determine_android_target_when_not_present(self) -> None:
"""Tests a None is returned for target when android is not present."""
package_result = ["chromeos-base/update_engine-0.0.3-r3408"]
self.PatchObject(
portage_util, "GetPackageDependencies", return_value=package_result
)
target = packages.determine_android_target(self.board)
self.assertEqual(target, None)
def test_determine_android_version_handle_exception(self) -> None:
"""Tests handling RunCommandError inside determine_android_version."""
# Mock what happens when portage returns that bubbles up (via
# RunCommand) inside portage_util.GetPackageDependencies.
self.PatchObject(
portage_util,
"GetPackageDependencies",
side_effect=cros_build_lib.RunCommandError("error"),
)
target = packages.determine_android_version(self.board)
self.assertEqual(target, None)
def test_determine_android_package_handle_exception(self) -> None:
"""Tests handling RunCommandError inside determine_android_package."""
# Mock what happens when portage returns that bubbles up (via
# RunCommand) inside portage_util.GetPackageDependencies.
self.PatchObject(
portage_util,
"GetPackageDependencies",
side_effect=cros_build_lib.RunCommandError("error"),
)
target = packages.determine_android_package(self.board)
self.assertEqual(target, None)
def test_determine_android_package_callers_handle_exception(self) -> None:
"""Tests RunCommandError caught by determine_android_package callers."""
# Mock what happens when portage returns that bubbles up (via
# RunCommand) inside portage_util.GetPackageDependencies.
self.PatchObject(
portage_util,
"GetPackageDependencies",
side_effect=cros_build_lib.RunCommandError("error"),
)
# Verify that target is None, as expected.
target = packages.determine_android_package(self.board)
self.assertEqual(target, None)
# determine_android_branch calls determine_android_package
branch = packages.determine_android_branch(self.board)
self.assertEqual(branch, None)
# determine_android_target calls determine_android_package
target = packages.determine_android_target(self.board)
self.assertEqual(target, None)
@pytest.mark.usefixtures("testcase_caplog", "testcase_monkeypatch")
class FindFingerprintsTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for find_fingerprints."""
def setUp(self) -> None:
self.board = "test-board"
# Create cheets-fingerprints.txt based on tempdir/src...
self.fingerprint_contents = (
"google/test-board/test-board_cheets"
":9/R99-12345.0.9999/123456:user/release-keys"
)
fingerprint_path = os.path.join(
self.tempdir,
"src/build/images/test-board/latest/cheets-fingerprint.txt",
)
self.chroot = chroot_lib.Chroot(
path=self.tempdir / "chroot", out_path=self.tempdir / "out"
)
osutils.WriteFile(
fingerprint_path, self.fingerprint_contents, makedirs=True
)
def test_find_fingerprints_with_test_path(self) -> None:
"""Tests get_firmware_versions with mocked output."""
self.monkeypatch.setattr(constants, "SOURCE_ROOT", self.tempdir)
build_target = build_target_lib.BuildTarget(self.board)
result = packages.find_fingerprints(build_target)
self.assertEqual(result, [self.fingerprint_contents])
self.assertIn("Reading fingerprint file", self.caplog.text)
def test_find_fingerprints(self) -> None:
"""Tests get_firmware_versions with mocked output."""
# Use board name whose path for fingerprint file does not exist.
# Verify that fingerprint file is not found and None is returned.
build_target = build_target_lib.BuildTarget("wrong-boardname")
self.monkeypatch.setattr(constants, "SOURCE_ROOT", self.tempdir)
result = packages.find_fingerprints(build_target)
self.assertEqual(result, [])
self.assertIn("Fingerprint file not found", self.caplog.text)
class GetAllFirmwareVersionsTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for get_firmware_versions."""
def setUp(self) -> None:
self.board = "test-board"
# pylint: disable=line-too-long
self.rc.SetDefaultCmdResult(
stdout="""
flashrom(8): 68935ee2fcfcffa47af81b966269cd2b */build/reef/usr/sbin/flashrom
ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, for GNU/Linux 2.6.32, BuildID[sha1]=e102cc98d45300b50088999d53775acbeff407dc, stripped
0.9.9 : bbb2d6a : Jul 28 2017 15:12:34 UTC
Model: reef
BIOS image: 1b535280fe688ac284d95276492b06f6 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/reef/image.bin
BIOS version: Google_Reef.9042.87.1
BIOS (RW) image: 0ef265eb8f2d228c09f75b011adbdcbb */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/reef/image.binrw
BIOS (RW) version: Google_Reef.9042.110.0
EC image: 2e8b4b5fa73cc5dbca4496de97a917a9 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/reef/ec.bin
EC version: reef_v1.1.5900-ab1ee51
EC (RW) version: reef_v1.1.5909-bd1f0c9
Model: pyro
BIOS image: 9e62447ebf22a724a4a835018ab6234e */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/pyro/image.bin
BIOS version: Google_Pyro.9042.87.1
BIOS (RW) image: 1897457303c85de99f3e98b2eaa0eccc */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/pyro/image.binrw
BIOS (RW) version: Google_Pyro.9042.110.0
EC image: 44b93ed591733519e752e05aa0529eb5 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/pyro/ec.bin
EC version: pyro_v1.1.5900-ab1ee51
EC (RW) version: pyro_v1.1.5909-bd1f0c9
Model: snappy
BIOS image: 3ab63ff080596bd7de4e7619f003bb64 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/snappy/image.bin
BIOS version: Google_Snappy.9042.110.0
EC image: c4db159e84428391d2ee25368c5fe5b6 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/snappy/ec.bin
EC version: snappy_v1.1.5909-bd1f0c9
Model: sand
BIOS image: 387da034a4f0a3f53e278ebfdcc2a412 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/sand/image.bin
BIOS version: Google_Sand.9042.110.0
EC image: 411562e0589dacec131f5fdfbe95a561 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/sand/ec.bin
EC version: sand_v1.1.5909-bd1f0c9
Model: electro
BIOS image: 1b535280fe688ac284d95276492b06f6 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/reef/image.bin
BIOS version: Google_Reef.9042.87.1
BIOS (RW) image: 0ef265eb8f2d228c09f75b011adbdcbb */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/reef/image.binrw
BIOS (RW) version: Google_Reef.9042.110.0
EC image: 2e8b4b5fa73cc5dbca4496de97a917a9 */build/reef/tmp/portage/chromeos-base/chromeos-firmware-reef-0.0.1-r79/temp/tmp7rHApL.pack_firmware-99001/models/reef/ec.bin
EC version: reef_v1.1.5900-ab1ee51
EC (RW) version: reef_v1.1.5909-bd1f0c9
Package Content:
612e7bb6ed1fb0a05abf2ebdc834c18b *./updater4.sh
0eafbee07282315829d0f42135ec7c0c *./gbb_utility
6074e3ca424cb30a67c378c1d9681f9c *./mosys
68935ee2fcfcffa47af81b966269cd2b *./flashrom
0eafbee07282315829d0f42135ec7c0c *./dump_fmap
490c95d6123c208d20d84d7c16857c7c *./crosfw.sh
60899148600b8673ddb711faa55aee40 *./common.sh
3c3a99346d1ca1273cbcd86c104851ff *./shflags
de7ce035e1f82a89f8909d888ee402c0 *./crosutil.sh
f9334372bdb9036ba09a6fd9bf30e7a2 *./crossystem
22257a8d5f0adc1f50a1916c3a4a35dd *./models/reef/ec.bin
faf12dbb7cdaf21ce153bdffb67841fd *./models/reef/bios.bin
c9bbb417b7921b85a7ed999ee42f550e *./models/reef/setvars.sh
29823d46f1ec1491ecacd7b830fd2686 *./models/pyro/ec.bin
2320463aba8b22eb5ea836f094d281b3 *./models/pyro/bios.bin
81614833ad77c9cd093360ba7bea76b8 *./models/pyro/setvars.sh
411562e0589dacec131f5fdfbe95a561 *./models/sand/ec.bin
387da034a4f0a3f53e278ebfdcc2a412 *./models/sand/bios.bin
fcd8cb0ac0e2ed6be220aaae435d43ff *./models/sand/setvars.sh
c4db159e84428391d2ee25368c5fe5b6 *./models/snappy/ec.bin
3ab63ff080596bd7de4e7619f003bb64 *./models/snappy/bios.bin
fe5d699f2e9e4a7de031497953313dbd *./models/snappy/setvars.sh
79aabd7cd8a215a54234c53d7bb2e6fb *./vpd
"""
)
# pylint: enable=line-too-long
def test_get_firmware_versions(self) -> None:
"""Tests get_firmware_versions with mocked output."""
build_target = build_target_lib.BuildTarget(self.board)
result = packages.get_all_firmware_versions(build_target)
self.assertEqual(len(result), 5)
self.assertEqual(
result["reef"],
packages.FirmwareVersions(
"reef",
"Google_Reef.9042.87.1",
"Google_Reef.9042.110.0",
"reef_v1.1.5900-ab1ee51",
"reef_v1.1.5909-bd1f0c9",
),
)
self.assertEqual(
result["pyro"],
packages.FirmwareVersions(
"pyro",
"Google_Pyro.9042.87.1",
"Google_Pyro.9042.110.0",
"pyro_v1.1.5900-ab1ee51",
"pyro_v1.1.5909-bd1f0c9",
),
)
self.assertEqual(
result["snappy"],
packages.FirmwareVersions(
"snappy",
"Google_Snappy.9042.110.0",
None,
"snappy_v1.1.5909-bd1f0c9",
None,
),
)
self.assertEqual(
result["sand"],
packages.FirmwareVersions(
"sand",
"Google_Sand.9042.110.0",
None,
"sand_v1.1.5909-bd1f0c9",
None,
),
)
self.assertEqual(
result["electro"],
packages.FirmwareVersions(
"electro",
"Google_Reef.9042.87.1",
"Google_Reef.9042.110.0",
"reef_v1.1.5900-ab1ee51",
"reef_v1.1.5909-bd1f0c9",
),
)
def test_get_firmware_versions_error(self) -> None:
"""Tests get_firmware_versions with no output."""
# Throw an exception when running the command.
self.rc.SetDefaultCmdResult(returncode=1)
build_target = build_target_lib.BuildTarget(self.board)
result = packages.get_all_firmware_versions(build_target)
self.assertEqual(result, {})
class GetFirmwareVersionsTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for get_firmware_versions."""
def setUp(self) -> None:
self.board = "test-board"
# pylint: disable=line-too-long
self.rc.SetDefaultCmdResult(
stdout="""
flashrom(8): a8f99c2e61e7dc09c4b25ef5a76ef692 */build/kevin/usr/sbin/flashrom
ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), statically linked, for GNU/Linux 2.d
0.9.4 : 860875a : Apr 10 2017 23:54:29 UTC
BIOS image: 6b5b855a0b8fd1657546d1402c15b206 *chromeos-firmware-kevin-0.0.1/.dist/kevin_fw_8785.178.0.n
BIOS version: Google_Kevin.8785.178.0
EC image: 1ebfa9518e6cac0558a80b7ab2f5b489 *chromeos-firmware-kevin-0.0.1/.dist/kevin_ec_8785.178.0.n
EC version:kevin_v1.10.184-459421c
Package Content:
a8f99c2e61e7dc09c4b25ef5a76ef692 *./flashrom
3c3a99346d1ca1273cbcd86c104851ff *./shflags
457a8dc8546764affc9700f8da328d23 *./dump_fmap
c392980ddb542639edf44a965a59361a *./updater5.sh
490c95d6123c208d20d84d7c16857c7c *./crosfw.sh
6b5b855a0b8fd1657546d1402c15b206 *./bios.bin
7b5bef0d2da90c23ff2e157250edf0fa *./crosutil.sh
d78722e4f1a0dc2d8c3d6b0bc7010ae3 *./crossystem
457a8dc8546764affc9700f8da328d23 *./gbb_utility
1ebfa9518e6cac0558a80b7ab2f5b489 *./ec.bin
c98ca54db130886142ad582a58e90ddc *./common.sh
5ba978bdec0f696f47f0f0de90936880 *./mosys
312e8ee6122057f2a246d7bcf1572f49 *./vpd
"""
)
# pylint: enable=line-too-long
def test_get_firmware_versions(self) -> None:
"""Tests get_firmware_versions with mocked output."""
build_target = build_target_lib.BuildTarget(self.board)
result = packages.get_firmware_versions(build_target)
versions = packages.FirmwareVersions(
None,
"Google_Kevin.8785.178.0",
None,
"kevin_v1.10.184-459421c",
None,
)
self.assertEqual(result, versions)
class DetermineKernelVersionTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for determine_kernel_version."""
def setUp(self) -> None:
self.board = "test-board"
self.build_target = build_target_lib.BuildTarget(self.board)
def test_determine_kernel_version(self) -> None:
"""Tests that a valid kernel version is returned."""
kernel_candidates = [
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
"sys-kernel/socfpga-kernel-4.20-r34",
]
self.PatchObject(
portage_util,
"GetFlattenedDepsForPackage",
return_value=kernel_candidates,
)
installed_pkgs = [
"sys-kernel/linux-firmware-0.0.1-r594",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"virtual/linux-sources-1-r30",
]
self.PatchObject(
portage_util,
"GetPackageDependencies",
return_value=installed_pkgs,
)
result = packages.determine_kernel_version(self.build_target)
self.assertEqual(result, "4.4.223-r2209")
def test_determine_kernel_version_ignores_exact_duplicates(self) -> None:
"""Tests that multiple results for candidates is ignored."""
# Depgraph is evaluated for version as well as revision, so graph will
# return all results twice.
kernel_candidates = [
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
"sys-kernel/socfpga-kernel-4.20-r34",
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
"sys-kernel/socfpga-kernel-4.20-r34",
]
self.PatchObject(
portage_util,
"GetFlattenedDepsForPackage",
return_value=kernel_candidates,
)
installed_pkgs = [
"sys-kernel/linux-firmware-0.0.1-r594",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"virtual/linux-sources-1-r30",
]
self.PatchObject(
portage_util,
"GetPackageDependencies",
return_value=installed_pkgs,
)
result = packages.determine_kernel_version(self.build_target)
self.assertEqual(result, "4.4.223-r2209")
def test_determine_kernel_version_ignores_virtual_package(self) -> None:
"""Tests that top-level package is ignored as potential kernel pkg."""
# Depgraph results include the named package at level 0 as well as its
# first-order dependencies, so verify that the virtual package is not
# included as a kernel package.
kernel_candidates = [
"virtual/linux-sources-1",
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
"sys-kernel/socfpga-kernel-4.20-r34",
"virtual/linux-sources-1-r30",
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
"sys-kernel/socfpga-kernel-4.20-r34",
]
self.PatchObject(
portage_util,
"GetFlattenedDepsForPackage",
return_value=kernel_candidates,
)
installed_pkgs = [
"sys-kernel/linux-firmware-0.0.1-r594",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"virtual/linux-sources-1-r30",
]
self.PatchObject(
portage_util,
"GetPackageDependencies",
return_value=installed_pkgs,
)
result = packages.determine_kernel_version(self.build_target)
self.assertEqual(result, "4.4.223-r2209")
def test_determine_kernel_version_too_many(self) -> None:
"""Tests that an exception is thrown with too many matching packages."""
package_result = [
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
"sys-kernel/socfpga-kernel-4.20-r34",
]
self.PatchObject(
portage_util,
"GetFlattenedDepsForPackage",
return_value=package_result,
)
installed_pkgs = [
"sys-kernel/linux-firmware-0.0.1-r594",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"virtual/linux-sources-1-r30",
]
self.PatchObject(
portage_util,
"GetPackageDependencies",
return_value=installed_pkgs,
)
with self.assertRaises(packages.KernelVersionError):
packages.determine_kernel_version(self.build_target)
def test_determine_kernel_version_no_kernel_match(self) -> None:
"""Tests that an exception is thrown with 0-sized intersection."""
package_result = [
"sys-kernel/chromeos-kernel-experimental-4.18_rc2-r23",
"sys-kernel/chromeos-kernel-4_4-4.4.223-r2209",
"sys-kernel/chromeos-kernel-5_15-5.15.65-r869",
"sys-kernel/upstream-kernel-next-9999",
]
self.PatchObject(
portage_util,
"GetFlattenedDepsForPackage",
return_value=package_result,
)
installed_pkgs = [
"sys-kernel/linux-firmware-0.0.1-r594",
"sys-kernel/socfpga-kernel-4.20-r34",
"virtual/linux-sources-1-r30",
]
self.PatchObject(
portage_util,
"GetPackageDependencies",
return_value=installed_pkgs,
)
with self.assertRaises(packages.KernelVersionError):
packages.determine_kernel_version(self.build_target)
def test_determine_kernel_version_exception(self) -> None:
"""Tests that portage_util exceptions result in returning empty str."""
self.PatchObject(
portage_util,
"GetFlattenedDepsForPackage",
side_effect=cros_build_lib.RunCommandError("error"),
)
result = packages.determine_kernel_version(self.build_target)
self.assertEqual(result, "")
class ChromeVersionsTest(cros_test_lib.MockTestCase):
"""Tests getting chrome version."""
def setUp(self) -> None:
self.build_target = build_target_lib.BuildTarget("board")
def test_determine_chrome_version(self) -> None:
"""Tests that a valid chrome version is returned."""
# Mock PortageqBestVisible to return a valid chrome version string.
r1_cpf = "chromeos-base/chromeos-chrome-78.0.3900.0_rc-r1"
r1_cpv = package_info.SplitCPV(r1_cpf)
self.PatchObject(
portage_util, "PortageqBestVisible", return_value=r1_cpv
)
chrome_version = packages.determine_package_version(
constants.CHROME_CP, self.build_target
)
version_numbers = chrome_version.split(".")
self.assertEqual(len(version_numbers), 4)
self.assertEqual(int(version_numbers[0]), 78)
def test_determine_chrome_version_handle_exception(self) -> None:
# Mock what happens when portage throws an exception that bubbles up
# (via RunCommand)inside portage_util.PortageqBestVisible.
self.PatchObject(
portage_util,
"PortageqBestVisible",
side_effect=cros_build_lib.RunCommandError("error"),
)
target = packages.determine_package_version(
constants.CHROME_CP, self.build_target
)
self.assertEqual(target, None)
class PlatformVersionsTest(cros_test_lib.MockTestCase):
"""Tests getting platform version."""
def test_determine_platform_version(self) -> None:
"""Test checking that a valid platform version is returned."""
platform_version = packages.determine_platform_version()
# The returned platform version is something like 12603.0.0.
version_string_list = platform_version.split(".")
self.assertEqual(len(version_string_list), 3)
# We don't want to check an exact version, but the first number should
# be non-zero.
self.assertGreaterEqual(int(version_string_list[0]), 1)
def test_determine_milestone_version(self) -> None:
"""Test checking that a valid milestone version is returned."""
milestone_version = packages.determine_milestone_version()
# Milestone version should be non-zero
self.assertGreaterEqual(int(milestone_version), 1)
def test_determine_full_version(self) -> None:
"""Test checking that a valid full version is returned."""
full_version = packages.determine_full_version()
pattern = r"^R(\d+)-(\d+.\d+.\d+(-rc\d+)*)"
m = re.match(pattern, full_version)
self.assertTrue(m)
milestone_version = m.group(1)
self.assertGreaterEqual(int(milestone_version), 1)
def test_versions_based_on_mock(self) -> None:
# Create a test version_info object, and then mock VersionInfo.from_repo
# return it.
test_platform_version = "12575.0.0"
test_chrome_branch = "75"
version_info_mock = chromeos_version.VersionInfo(test_platform_version)
version_info_mock.chrome_branch = test_chrome_branch
self.PatchObject(
chromeos_version.VersionInfo,
"from_repo",
return_value=version_info_mock,
)
test_full_version = (
"R" + test_chrome_branch + "-" + test_platform_version
)
platform_version = packages.determine_platform_version()
milestone_version = packages.determine_milestone_version()
full_version = packages.determine_full_version()
self.assertEqual(platform_version, test_platform_version)
self.assertEqual(milestone_version, test_chrome_branch)
self.assertEqual(full_version, test_full_version)
# Each of the columns in the following table is a separate dimension along
# which Chrome uprev test cases can vary in behavior. The full test space would
# be the Cartesian product of the possible values of each column.
# 'CHROME_EBUILD' refers to the relationship between the version of the existing
# Chrome ebuild vs. the requested uprev version. 'FOLLOWER_EBUILDS' refers to
# the same relationship but for the packages defined in OTHER_CHROME_PACKAGES.
# 'EBUILDS MODIFIED' refers to whether any of the existing 9999 ebuilds have
# modified contents relative to their corresponding stable ebuilds.
#
# CHROME_EBUILD FOLLOWER_EBUILDS EBUILDS_MODIFIED
#
# HIGHER HIGHER YES
# SAME SAME NO
# LOWER LOWER
# DOESN'T EXIST YET
# These test cases cover both CHROME & FOLLOWER ebuilds being identically
# higher, lower, or the same versions, with no modified ebuilds.
UPREV_VERSION_CASES = (
# Uprev.
pytest.param(
"80.0.8080.0",
"81.0.8181.0",
# One added and one deleted for chrome and each "other" package.
2 * (1 + len(constants.OTHER_CHROME_PACKAGES)),
False,
id="newer_chrome_version",
),
# Revbump.
pytest.param(
"80.0.8080.0",
"80.0.8080.0",
2,
True,
id="chrome_revbump",
),
# No files should be changed in these cases.
pytest.param(
"80.0.8080.0",
"80.0.8080.0",
0,
False,
id="same_chrome_version",
),
pytest.param(
"80.0.8080.0",
"79.0.7979.0",
0,
False,
id="older_chrome_version",
),
)
@pytest.mark.parametrize(
"old_version, new_version, expected_count, modify_unstable",
UPREV_VERSION_CASES,
)
def test_uprev_chrome_all_files_already_exist(
old_version,
new_version,
expected_count,
modify_unstable,
monkeypatch,
overlay_stack,
) -> None:
"""Test Chrome uprevs work as expected when all packages already exist."""
(overlay,) = overlay_stack(1)
monkeypatch.setattr(uprev_lib, "_CHROME_OVERLAY_PATH", overlay.path)
unstable_chrome = cr.test.Package(
"chromeos-base", "chromeos-chrome", version="9999", keywords="~*"
)
if modify_unstable:
# Add some field not set in stable.
unstable_chrome.depend = "foo/bar"
stable_chrome = cr.test.Package(
"chromeos-base", "chromeos-chrome", version=f"{old_version}_rc-r1"
)
overlay.add_package(unstable_chrome)
overlay.add_package(stable_chrome)
for pkg_str in constants.OTHER_CHROME_PACKAGES:
category, pkg_name = pkg_str.split("/")
unstable_pkg = cr.test.Package(
category, pkg_name, version="9999", keywords="~*"
)
stable_pkg = cr.test.Package(
category, pkg_name, version=f"{old_version}_rc-r1"
)
overlay.add_package(unstable_pkg)
overlay.add_package(stable_pkg)
git_refs = [
uprev_lib.GitRef(
path="/foo", ref=f"refs/tags/{new_version}", revision="stubcommit"
)
]
res = packages.uprev_chrome_from_ref(None, git_refs, None)
modified_file_count = sum(len(m.files) for m in res.modified)
assert modified_file_count == expected_count
@pytest.mark.usefixtures("testcase_monkeypatch")
class GetModelsTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for get_models."""
def setUp(self) -> None:
self.board = "test-board"
self.rc.SetDefaultCmdResult(stdout="pyro\nreef\nsnappy\n")
self.monkeypatch.setattr(constants, "SOURCE_ROOT", self.tempdir)
build_bin = os.path.join(
self.tempdir, constants.DEFAULT_CHROOT_DIR, "usr", "bin"
)
osutils.Touch(
os.path.join(build_bin, "cros_config_host"), makedirs=True
)
def testGetModels(self) -> None:
"""Test get_models."""
build_target = build_target_lib.BuildTarget(self.board)
result = packages.get_models(build_target)
self.assertEqual(result, ["pyro", "reef", "snappy"])
class GetKeyIdTest(cros_test_lib.MockTestCase):
"""Tests for get_key_id."""
def setUp(self) -> None:
self.board = "test-board"
self.build_target = build_target_lib.BuildTarget(self.board)
def testGetKeyId(self) -> None:
"""Test get_key_id when _run_cros_config_host returns a key."""
self.PatchObject(
packages, "_run_cros_config_host", return_value=["key"]
)
result = packages.get_key_id(self.build_target, "model")
self.assertEqual(result, "key")
def testGetKeyIdNoKey(self) -> None:
"""Test get_key_id when None should be returned."""
self.PatchObject(
packages, "_run_cros_config_host", return_value=["key1", "key2"]
)
result = packages.get_key_id(self.build_target, "model")
self.assertEqual(result, None)
class GetLatestVersionTest(cros_test_lib.TestCase):
"""Tests for get_latest_version_from_refs."""
def setUp(self) -> None:
self.prefix = "refs/tags/drivefs_"
# The tag ref template.
ref_tpl = self.prefix + "%s"
self.latest = "44.0.20"
self.versions = ["42.0.1", self.latest, "44.0.19", "39.0.15"]
self.latest_ref = uprev_lib.GitRef(
"/path", ref_tpl % self.latest, "abc123"
)
self.refs = [
uprev_lib.GitRef("/path", ref_tpl % v, "abc123")
for v in self.versions
]
def test_single_ref(self) -> None:
"""Test a single ref is supplied."""
# pylint: disable=protected-access
self.assertEqual(
self.latest,
packages._get_latest_version_from_refs(
self.prefix, [self.latest_ref]
),
)
def test_multiple_ref_versions(self) -> None:
"""Test multiple refs supplied."""
# pylint: disable=protected-access
self.assertEqual(
self.latest,
packages._get_latest_version_from_refs(self.prefix, self.refs),
)
def test_no_refs_returns_none(self) -> None:
"""Test no refs supplied."""
# pylint: disable=protected-access
self.assertEqual(
packages._get_latest_version_from_refs(self.prefix, []), None
)
def test_ref_prefix(self) -> None:
"""Test refs with a different prefix isn't used"""
# pylint: disable=protected-access
# Add refs/tags/foo_100.0.0 to the refs, which should be ignored in
# _get_latest_version_from_refs because the prefix doesn't match, even
# if its version number is larger.
refs = self.refs + [
uprev_lib.GitRef("/path", "refs/tags/foo_100.0.0", "abc123")
]
self.assertEqual(
self.latest,
packages._get_latest_version_from_refs(self.prefix, refs),
)
class NeedsChromeSourceTest(cros_test_lib.MockTestCase):
"""Tests for needs_chrome_source."""
def _build_graph(self, with_chrome: bool, with_followers: bool):
root = "/build/build_target"
foo_bar = package_info.parse("foo/bar-1")
chrome = package_info.parse(f"{constants.CHROME_CP}-1.2.3.4")
followers = [
package_info.parse(f"{pkg}-1.2.3.4")
for pkg in constants.OTHER_CHROME_PACKAGES
]
nodes = [dependency_graph.PackageNode(foo_bar, root)]
root_pkgs = ["foo/bar-1"]
if with_chrome:
nodes.append(dependency_graph.PackageNode(chrome, root))
root_pkgs.append(chrome.cpvr)
if with_followers:
nodes.extend(
[dependency_graph.PackageNode(f, root) for f in followers]
)
root_pkgs.extend([f.cpvr for f in followers])
return dependency_graph.DependencyGraph(nodes, root, root_pkgs)
def test_needs_all(self) -> None:
"""Verify we need source when we have no prebuilts."""
graph = self._build_graph(with_chrome=True, with_followers=True)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=False)
self.PatchObject(
packages,
"uprev_chrome",
return_value=uprev_lib.UprevVersionedPackageResult(),
)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target)
self.assertTrue(result.needs_chrome_source)
self.assertTrue(result.builds_chrome)
self.assertTrue(result.packages)
self.assertEqual(
len(result.packages), len(constants.OTHER_CHROME_PACKAGES) + 1
)
self.assertTrue(result.missing_chrome_prebuilt)
self.assertTrue(result.missing_follower_prebuilt)
self.assertFalse(result.local_uprev)
def test_needs_none(self) -> None:
"""Verify not building any chrome packages prevents needing it."""
graph = self._build_graph(with_chrome=False, with_followers=False)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=False)
self.PatchObject(
packages,
"uprev_chrome",
return_value=uprev_lib.UprevVersionedPackageResult(),
)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target)
self.assertFalse(result.needs_chrome_source)
self.assertFalse(result.builds_chrome)
self.assertFalse(result.packages)
self.assertFalse(result.missing_chrome_prebuilt)
self.assertFalse(result.missing_follower_prebuilt)
self.assertFalse(result.local_uprev)
def test_needs_chrome_only(self) -> None:
"""Verify only chrome triggers needs chrome source."""
graph = self._build_graph(with_chrome=True, with_followers=False)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=False)
self.PatchObject(
packages,
"uprev_chrome",
return_value=uprev_lib.UprevVersionedPackageResult(),
)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target)
self.assertTrue(result.needs_chrome_source)
self.assertTrue(result.builds_chrome)
self.assertTrue(result.packages)
self.assertEqual(
{p.atom for p in result.packages}, {constants.CHROME_CP}
)
self.assertTrue(result.missing_chrome_prebuilt)
self.assertFalse(result.missing_follower_prebuilt)
self.assertFalse(result.local_uprev)
def test_needs_followers_only(self) -> None:
"""Verify only chrome followers triggers needs chrome source."""
graph = self._build_graph(with_chrome=False, with_followers=True)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=False)
self.PatchObject(
packages,
"uprev_chrome",
return_value=uprev_lib.UprevVersionedPackageResult(),
)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target)
self.assertTrue(result.needs_chrome_source)
self.assertFalse(result.builds_chrome)
self.assertTrue(result.packages)
self.assertEqual(
{p.atom for p in result.packages},
set(constants.OTHER_CHROME_PACKAGES),
)
self.assertFalse(result.missing_chrome_prebuilt)
self.assertTrue(result.missing_follower_prebuilt)
self.assertFalse(result.local_uprev)
def test_has_prebuilts(self) -> None:
"""Test prebuilts prevent us from needing chrome source."""
graph = self._build_graph(with_chrome=True, with_followers=True)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=True)
self.PatchObject(
packages,
"uprev_chrome",
return_value=uprev_lib.UprevVersionedPackageResult(),
)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target)
self.assertFalse(result.needs_chrome_source)
self.assertTrue(result.builds_chrome)
self.assertFalse(result.packages)
self.assertFalse(result.missing_chrome_prebuilt)
self.assertFalse(result.missing_follower_prebuilt)
self.assertFalse(result.local_uprev)
def test_compile_source(self) -> None:
"""Test compile source ignores prebuilts."""
graph = self._build_graph(with_chrome=True, with_followers=True)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=True)
self.PatchObject(
packages,
"uprev_chrome",
return_value=uprev_lib.UprevVersionedPackageResult(),
)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target, compile_source=True)
self.assertTrue(result.needs_chrome_source)
self.assertTrue(result.builds_chrome)
self.assertTrue(result.packages)
self.assertEqual(
len(result.packages), len(constants.OTHER_CHROME_PACKAGES) + 1
)
self.assertTrue(result.missing_chrome_prebuilt)
self.assertTrue(result.missing_follower_prebuilt)
self.assertFalse(result.local_uprev)
def test_local_uprev(self) -> None:
"""Test compile source ignores prebuilts."""
graph = self._build_graph(with_chrome=True, with_followers=True)
self.PatchObject(
depgraph, "get_sysroot_dependency_graph", return_value=graph
)
self.PatchObject(packages, "has_prebuilt", return_value=False)
uprev_result = uprev_lib.UprevVersionedPackageResult()
uprev_result.add_result("1.2.3.4", ["/tmp/foo"])
self.PatchObject(packages, "uprev_chrome", return_value=uprev_result)
build_target = build_target_lib.BuildTarget("build_target")
result = packages.needs_chrome_source(build_target, compile_source=True)
self.assertTrue(result.needs_chrome_source)
self.assertTrue(result.builds_chrome)
self.assertTrue(result.packages)
self.assertEqual(
len(result.packages), len(constants.OTHER_CHROME_PACKAGES) + 1
)
self.assertTrue(result.missing_chrome_prebuilt)
self.assertTrue(result.missing_follower_prebuilt)
self.assertTrue(result.local_uprev)
class GetTargetVersionTest(cros_test_lib.RunCommandTestCase):
"""Tests for get_target_version."""
def setUp(self) -> None:
self.build_target = build_target_lib.BuildTarget("build_target")
def test_default_empty(self) -> None:
"""Default behavior with mostly stub empty data."""
def GetBuildDependency(sysroot_path, board, mock_packages):
assert sysroot_path == self.build_target.root
assert board == self.build_target.name
assert list(mock_packages) == [
package_info.parse(constants.TARGET_OS_PKG)
]
return {"package_deps": []}, {}
self.PatchObject(
dependency, "GetBuildDependency", side_effect=GetBuildDependency
)
ret = packages.get_target_versions(self.build_target)
assert ret.android_version is None
assert ret.android_branch is None
assert ret.android_target is None
assert ret.chrome_version is None
assert isinstance(ret.platform_version, str)
assert isinstance(ret.milestone_version, str)
assert isinstance(ret.full_version, str)
assert ret.lacros_version is None
class UprevDrivefsTest(cros_test_lib.MockTestCase):
"""Tests for uprev_drivefs."""
def setUp(self) -> None:
self.refs = [
uprev_lib.GitRef(
path="/chromeos/platform/drivefs-google3/",
ref="refs/tags/drivefs_45.0.2",
revision="123",
)
]
self.MOCK_DRIVEFS_EBUILD_PATH = "drivefs.45.0.2-r1.ebuild"
def revisionBumpOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.REVISION_BUMP, [ebuild_path]
)
def majorBumpOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.VERSION_BUMP, [ebuild_path]
)
def sameVersionOutcome(self):
return uprev_lib.UprevResult(uprev_lib.Outcome.SAME_VERSION_EXISTS)
def test_latest_version_returns_none(self) -> None:
"""Test no refs were supplied"""
output = packages.uprev_drivefs(None, [], chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_drivefs_uprev_fails(self) -> None:
"""Test a single ref is supplied."""
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[None, None],
)
output = packages.uprev_drivefs(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_same_version_exists(self) -> None:
"""Test the same version exists uprev should not happen."""
drivefs_outcome = self.sameVersionOutcome()
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[drivefs_outcome],
)
output = packages.uprev_drivefs(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_revision_bump_both_packages(self) -> None:
"""Test both packages uprev, should succeed."""
drivefs_outcome = self.revisionBumpOutcome(
self.MOCK_DRIVEFS_EBUILD_PATH
)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[drivefs_outcome],
)
output = packages.uprev_drivefs(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
def test_major_bump_both_packages(self) -> None:
"""Test both packages uprev, should succeed."""
drivefs_outcome = self.majorBumpOutcome(self.MOCK_DRIVEFS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[drivefs_outcome],
)
output = packages.uprev_drivefs(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
class UprevKernelAfdo(cros_test_lib.RunCommandTempDirTestCase):
"""Tests for uprev_kernel_afdo."""
def setUp(self) -> None:
# patch_ebuild_vars is tested separately.
self.mock_patch = self.PatchObject(packages, "patch_ebuild_vars")
self.PatchObject(constants, "SOURCE_ROOT", new=self.tempdir)
self.metadata_dir = os.path.join(
"src",
"third_party",
"toolchain-utils",
"afdo_metadata",
)
osutils.SafeMakedirs(os.path.join(self.tempdir, self.metadata_dir))
def test_uprev_kernel_afdo_version(self) -> None:
"""Test kernel afdo version uprev."""
json_files = {
"kernel_afdo.json": (
"{\n"
' "chromeos-kernel-5_4": {\n'
' "name": "R106-12345.0-0123456789"\n'
" }\n"
"}"
),
"kernel_arm_afdo.json": (
"{\n"
' "chromeos-kernel-5_15": {\n'
' "name": "R107-67890.0-0123456789"\n'
" }\n"
"}"
),
}
for f, contents in json_files.items():
self.WriteTempFile(os.path.join(self.metadata_dir, f), contents)
returned_output = packages.uprev_kernel_afdo(
None, [], chroot_lib.Chroot()
)
package_root = os.path.join(
constants.SOURCE_ROOT,
constants.CHROMIUMOS_OVERLAY_DIR,
"sys-kernel",
)
expect_result = [
uprev_lib.UprevVersionedPackageModifications(
new_version="R106-12345.0-0123456789",
files=[
os.path.join(
package_root,
"chromeos-kernel-5_4",
"chromeos-kernel-5_4-9999.ebuild",
),
os.path.join(
package_root, "chromeos-kernel-5_4", "Manifest"
),
],
),
uprev_lib.UprevVersionedPackageModifications(
new_version="R107-67890.0-0123456789",
files=[
os.path.join(
package_root,
"chromeos-kernel-5_15",
"chromeos-kernel-5_15-9999.ebuild",
),
os.path.join(
package_root, "chromeos-kernel-5_15", "Manifest"
),
],
),
]
self.assertTrue(returned_output.uprevved)
self.assertEqual(returned_output.modified, expect_result)
def test_uprev_kernel_afdo_empty_json(self) -> None:
"""Test kernel afdo version unchanged."""
json_files = {
"kernel_afdo.json": "{}",
"kernel_arm_afdo.json": "{}",
}
for f, contents in json_files.items():
self.WriteTempFile(os.path.join(self.metadata_dir, f), contents)
returned_output = packages.uprev_kernel_afdo(
None, [], chroot_lib.Chroot()
)
self.assertFalse(returned_output.uprevved)
def test_uprev_kernel_afdo_empty_file(self) -> None:
"""Test malformed json raises."""
json_files = {
"kernel_afdo.json": "",
"kernel_arm_afdo.json": "",
}
for f, contents in json_files.items():
self.WriteTempFile(os.path.join(self.metadata_dir, f), contents)
with self.assertRaisesRegex(
json.decoder.JSONDecodeError, "Expecting value"
):
packages.uprev_kernel_afdo(None, [], chroot_lib.Chroot())
def test_uprev_kernel_afdo_manifest_raises(self) -> None:
"""Test manifest update raises."""
json_files = {
"kernel_afdo.json": (
"{\n"
' "chromeos-kernel-5_4": {\n'
' "name": "R106-12345.0-0123456789"\n'
" }\n"
"}"
),
}
for f, contents in json_files.items():
self.WriteTempFile(os.path.join(self.metadata_dir, f), contents)
# run() raises exception.
self.rc.SetDefaultCmdResult(
side_effect=cros_build_lib.RunCommandError("error")
)
with self.assertRaises(uprev_lib.EbuildManifestError):
packages.uprev_kernel_afdo(None, [], chroot_lib.Chroot())
# TODO(chenghaoyang): Shouldn't use uprev_workon_ebuild_to_version.
class UprevPerfettoTest(cros_test_lib.MockTestCase):
"""Tests for uprev_perfetto."""
def setUp(self) -> None:
self.refs = [
uprev_lib.GitRef(path="/foo", ref="refs/tags/v12.0", revision="123")
]
self.MOCK_PERFETTO_EBUILD_PATH = "perfetto-12.0-r1.ebuild"
self.MOCK_PERFETTO_PROTO_EBUILD_PATH = "perfetto-protos-12.0-r1.ebuild"
def revisionBumpOutcome(self):
return [
uprev_lib.UprevResult(
uprev_lib.Outcome.REVISION_BUMP,
[self.MOCK_PERFETTO_EBUILD_PATH],
),
uprev_lib.UprevResult(
uprev_lib.Outcome.REVISION_BUMP,
[self.MOCK_PERFETTO_PROTO_EBUILD_PATH],
),
]
def majorBumpOutcome(self):
return [
uprev_lib.UprevResult(
uprev_lib.Outcome.VERSION_BUMP, [self.MOCK_PERFETTO_EBUILD_PATH]
),
uprev_lib.UprevResult(
uprev_lib.Outcome.VERSION_BUMP,
[self.MOCK_PERFETTO_PROTO_EBUILD_PATH],
),
]
def newerVersionOutcome(self):
return uprev_lib.UprevResult(uprev_lib.Outcome.NEWER_VERSION_EXISTS)
def sameVersionOutcome(self):
return uprev_lib.UprevResult(uprev_lib.Outcome.SAME_VERSION_EXISTS)
def test_latest_version_returns_none(self) -> None:
"""Test no refs were supplied"""
output = packages.uprev_perfetto(None, [], chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_perfetto_uprev_fails(self) -> None:
"""Test a single ref is supplied."""
self.PatchObject(
uprev_lib, "uprev_workon_ebuild_to_version", side_effect=[None]
)
output = packages.uprev_perfetto(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_newer_version_exists(self) -> None:
"""Test the newer version exists uprev should not happen."""
perfetto_outcome = self.newerVersionOutcome()
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[perfetto_outcome],
)
output = packages.uprev_perfetto(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_same_version_exists(self) -> None:
"""Test the same version exists uprev should not happen."""
perfetto_outcome = self.sameVersionOutcome()
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[perfetto_outcome],
)
output = packages.uprev_perfetto(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_revision_bump_perfetto_package(self) -> None:
"""Test perfetto package uprev."""
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=self.revisionBumpOutcome(),
)
output = packages.uprev_perfetto(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
self.assertEqual(
output.modified[0].files, [self.MOCK_PERFETTO_EBUILD_PATH]
)
self.assertEqual(
output.modified[1].files, [self.MOCK_PERFETTO_PROTO_EBUILD_PATH]
)
def test_major_bump_perfetto_package(self) -> None:
"""Test perfetto package uprev."""
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=self.majorBumpOutcome(),
)
output = packages.uprev_perfetto(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
self.assertEqual(
output.modified[0].files, [self.MOCK_PERFETTO_EBUILD_PATH]
)
self.assertEqual(
output.modified[1].files, [self.MOCK_PERFETTO_PROTO_EBUILD_PATH]
)
def test_revision_bump_trunk(self) -> None:
"""Test revision bump on receiving non-versioned trunk refs."""
refs = [
uprev_lib.GitRef(
path="/foo", ref="refs/heads/main", revision="0123456789abcdef"
)
]
self.PatchObject(
uprev_lib, "get_stable_ebuild_version", return_value="12.0"
)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=self.revisionBumpOutcome(),
)
output = packages.uprev_perfetto(None, refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
self.assertEqual(
output.modified[0].files, [self.MOCK_PERFETTO_EBUILD_PATH]
)
self.assertEqual(output.modified[0].new_version, "12.0-012345678")
self.assertEqual(
output.modified[1].files, [self.MOCK_PERFETTO_PROTO_EBUILD_PATH]
)
self.assertEqual(output.modified[1].new_version, "12.0-012345678")
class UprevLacrosTest(cros_test_lib.MockTestCase):
"""Tests for uprev_lacros"""
def setUp(self) -> None:
self.refs = [
uprev_lib.GitRef(
path="/lacros", ref="refs/heads/main", revision="123.456.789.0"
)
]
self.MOCK_LACROS_EBUILD_PATH = "chromeos-lacros-123.456.789.0-r1.ebuild"
def revisionBumpOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.REVISION_BUMP, [ebuild_path]
)
def majorBumpOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.VERSION_BUMP, [ebuild_path]
)
def newerVersionOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.NEWER_VERSION_EXISTS, [ebuild_path]
)
def sameVersionOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.SAME_VERSION_EXISTS, [ebuild_path]
)
def newEbuildCreatedOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.NEW_EBUILD_CREATED, [ebuild_path]
)
def test_lacros_uprev_fails(self) -> None:
"""Test a lacros package uprev with no triggers"""
self.PatchObject(
uprev_lib, "uprev_workon_ebuild_to_version", side_effect=[None]
)
with self.assertRaises(IndexError):
packages.uprev_lacros(None, [], chroot_lib.Chroot())
def test_lacros_uprev_revision_bump(self) -> None:
"""Test lacros package uprev."""
lacros_outcome = self.revisionBumpOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
def test_lacros_uprev_version_bump(self) -> None:
"""Test lacros package uprev."""
lacros_outcome = self.majorBumpOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
def test_lacros_uprev_new_ebuild_created(self) -> None:
"""Test lacros package uprev."""
lacros_outcome = self.newEbuildCreatedOutcome(
self.MOCK_LACROS_EBUILD_PATH
)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros(None, self.refs, chroot_lib.Chroot())
self.assertTrue(output.uprevved)
def test_lacros_uprev_newer_version_exist(self) -> None:
"""Test the newer version exists uprev should not happen."""
lacros_outcome = self.newerVersionOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
def test_lacros_uprev_same_version_exist(self) -> None:
"""Test the same version exists uprev should not happen."""
lacros_outcome = self.sameVersionOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros(None, self.refs, chroot_lib.Chroot())
self.assertFalse(output.uprevved)
class UprevLacrosInParallelTest(cros_test_lib.MockTestCase):
"""Tests for uprev_lacros"""
def setUp(self) -> None:
self.refs = [
uprev_lib.GitRef(
path="/lacros", revision="abc123", ref="refs/tags/123.456.789.0"
)
]
self.MOCK_LACROS_EBUILD_PATH = "chromeos-lacros-123.456.789.0-r1.ebuild"
def revisionBumpOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.REVISION_BUMP, [ebuild_path]
)
def majorBumpOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.VERSION_BUMP, [ebuild_path]
)
def newerVersionOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.NEWER_VERSION_EXISTS, [ebuild_path]
)
def sameVersionOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.SAME_VERSION_EXISTS, [ebuild_path]
)
def newEbuildCreatedOutcome(self, ebuild_path):
return uprev_lib.UprevResult(
uprev_lib.Outcome.NEW_EBUILD_CREATED, [ebuild_path]
)
def test_lacros_uprev_fails(self) -> None:
"""Test a lacros package uprev with no triggers"""
self.PatchObject(
uprev_lib, "uprev_workon_ebuild_to_version", side_effect=[None]
)
with self.assertRaises(uprev_lib.NoRefsError):
packages.uprev_lacros_in_parallel(None, [], chroot_lib.Chroot())
def test_lacros_uprev_revision_bump(self) -> None:
"""Test lacros package uprev."""
lacros_outcome = self.revisionBumpOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros_in_parallel(
None, self.refs, chroot_lib.Chroot()
)
self.assertTrue(output.uprevved)
def test_lacros_uprev_version_bump(self) -> None:
"""Test lacros package uprev."""
lacros_outcome = self.majorBumpOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros_in_parallel(
None, self.refs, chroot_lib.Chroot()
)
self.assertTrue(output.uprevved)
def test_lacros_uprev_new_ebuild_created(self) -> None:
"""Test lacros package uprev."""
lacros_outcome = self.newEbuildCreatedOutcome(
self.MOCK_LACROS_EBUILD_PATH
)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros_in_parallel(
None, self.refs, chroot_lib.Chroot()
)
self.assertTrue(output.uprevved)
def test_lacros_uprev_newer_version_exist(self) -> None:
"""Test the newer version exists uprev should not happen."""
lacros_outcome = self.newerVersionOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros_in_parallel(
None, self.refs, chroot_lib.Chroot()
)
self.assertFalse(output.uprevved)
def test_lacros_uprev_same_version_exist(self) -> None:
"""Test the same version exists uprev should not happen."""
lacros_outcome = self.sameVersionOutcome(self.MOCK_LACROS_EBUILD_PATH)
self.PatchObject(
uprev_lib,
"uprev_workon_ebuild_to_version",
side_effect=[lacros_outcome],
)
output = packages.uprev_lacros_in_parallel(
None, self.refs, chroot_lib.Chroot()
)
self.assertFalse(output.uprevved)
class UprevStarbaseArtifactsTest(cros_test_lib.RunCommandTempDirTestCase):
"""Tests of uprev of starbase artifacts ebuild."""
simple_name = "apps"
component = "chromeos-base"
package_name = f"starbase-{simple_name}"
version = "2.4.6"
revision = "111"
tarfile_name = f"starbase_{simple_name}_tarfile.tar.zst"
tarfile_hash = "42"
ebuild_name_format = f"starbase-{simple_name}-%s%s.ebuild"
rev0_ebuild_name = ebuild_name_format % (version, "")
old_ebuild_name = ebuild_name_format % (version, f"-r{revision}")
ebuild_content_format = """# Buildable ebuild
foo
bar
baz
SRC_URI="${DISTFILES}/%s"
zab
rab
oof
"""
manifest_content = f"DIST {tarfile_name} 7 BLAH 123 SHA512 42"
def test_uprev(self) -> None:
"""Test that the ebuild is modified and uprevved."""
# Create ebuild directory.
directory_tree = (
D(
self.component,
[
D(
self.package_name,
[
self.rev0_ebuild_name,
self.old_ebuild_name,
"Manifest",
],
),
],
),
)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, directory_tree)
package_path = os.path.join(
self.tempdir, self.component, self.package_name
)
old_ebuild_content = self.ebuild_content_format % "to-be-clobbered"
rev0_ebuild_path = os.path.join(package_path, self.rev0_ebuild_name)
old_ebuild_path = os.path.join(package_path, self.old_ebuild_name)
# Create mock ebuild to be uprevved.
self.WriteTempFile(rev0_ebuild_path, old_ebuild_content)
version_id = "20230101-r42-rc123"
manifest_path = os.path.join(package_path, "Manifest")
self.WriteTempFile(manifest_path, self.manifest_content)
# Run the function under test.
modified = packages.starbase_find_and_uprev(
self.tarfile_name,
self.tarfile_hash,
self.component,
self.package_name,
version_id,
self.tempdir,
chroot_lib.Chroot(),
)
# Check that the expected files were modified.
new_rev = f"-r{str(int(self.revision) + 1)}"
new_ebuild_name = self.ebuild_name_format % (self.version, new_rev)
new_ebuild_path = os.path.join(package_path, new_ebuild_name)
self.assertEqual(modified[0], manifest_path)
self.assertEqual(modified[1], rev0_ebuild_path)
self.assertEqual(modified[2], old_ebuild_path)
self.assertEqual(modified[3], new_ebuild_path)
tarfile_path = f"starbase-artifacts-{version_id}/{self.tarfile_name}"
# Check that the new ebuild file contains the expected content.
new_ebuild_content = self.ebuild_content_format % tarfile_path
found_content = osutils.ReadFile(new_ebuild_path)
self.assertEqual(new_ebuild_content, found_content)