blob: af11fd60d7a4186e741da9ee5a38ebf246d5b6a7 [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.
"""Image API unittests."""
import errno
import glob
import os
from pathlib import Path
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 dlc_lib
from chromite.lib import image_lib
from chromite.lib import osutils
from chromite.lib import portage_util
from chromite.lib import sysroot_lib
from chromite.lib.parser import package_info
from chromite.service import image
class BuildImageTest(
cros_test_lib.RunCommandTempDirTestCase, cros_test_lib.LoggingTestCase
):
"""Build Image tests."""
def setUp(self):
osutils.Touch(
os.path.join(self.tempdir, image.PARALLEL_EMERGE_STATUS_FILE_NAME)
)
self.PatchObject(
osutils.TempDir, "__enter__", return_value=self.tempdir
)
self.PatchObject(portage_util, "GetBoardUseFlags", return_value="")
self.PatchObject(
chromeos_version,
"VersionInfo",
return_value=chromeos_version.VersionInfo(
version_string="1.2.3", chrome_branch="4"
),
)
self.config = image.BuildConfig(
build_root=self.tempdir / "build",
output_root=self.tempdir / "output",
replace=True,
build_attempt=1,
)
(
self.build_dir,
self.output_dir,
self.image_dir,
) = image_lib.CreateBuildDir(
self.config.build_root,
self.config.output_root,
"4",
"1.2.3",
"board",
"latest",
replace=True,
build_attempt=1,
)
self.MoveDir_mock = self.PatchObject(osutils, "MoveDirContents")
def testBuildBoardHandling(self):
"""Test the argument handling."""
# No board should raise an error.
with self.assertRaises(image.InvalidArgumentError):
image.Build(None, [constants.IMAGE_TYPE_BASE])
with self.assertRaises(image.InvalidArgumentError):
image.Build("", [constants.IMAGE_TYPE_BASE])
def testBuildImageTypes(self):
"""Test the image type handling."""
result = image.Build("board", [])
assert result.all_built and not result.build_run
# Should be using the argument when passed.
image.Build("board", [constants.IMAGE_TYPE_DEV], config=self.config)
self.assertCommandContains(
[constants.IMAGE_TYPE_TO_NAME[constants.IMAGE_TYPE_DEV]]
)
# Multiple should all be passed.
multi = [
constants.IMAGE_TYPE_BASE,
constants.IMAGE_TYPE_DEV,
constants.IMAGE_TYPE_TEST,
]
image.Build("board", multi, config=self.config)
for x in multi:
self.assertCommandContains([constants.IMAGE_TYPE_TO_NAME[x]])
# Building RECOVERY only should cause base to be built.
image.Build(
"board", [constants.IMAGE_TYPE_RECOVERY], config=self.config
)
self.assertCommandContains(
[constants.IMAGE_TYPE_TO_NAME[constants.IMAGE_TYPE_BASE]]
)
def testInvalidBuildImageTypes(self):
"""Test the image type handling with invalid input."""
build_result = image.Build(
"board", [constants.IMAGE_TYPE_BASE, constants.FACTORY_IMAGE_BIN]
)
self.assertEqual(build_result.return_code, errno.EINVAL)
def testClearShadowLocks(self):
"""Test that stale shadow-utils locks are cleared."""
clear_shadow_locks_mock = self.PatchObject(
cros_build_lib, "ClearShadowLocks"
)
test_board = "board"
image.Build(test_board, [constants.IMAGE_TYPE_BASE])
clear_shadow_locks_mock.assert_called_once_with(
build_target_lib.get_default_sysroot_path(test_board)
)
def testBuildDir(self):
"""Test the case if build directory exists."""
config = image.BuildConfig(
build_root=self.tempdir / "build",
output_root=self.tempdir / "build",
)
build_result = image.Build(
"board", [constants.IMAGE_TYPE_DEV], config=config
)
build_result = image.Build(
"board", [constants.IMAGE_TYPE_DEV], config=config
)
self.assertEqual(build_result.return_code, errno.EEXIST)
def testDlcCommand(self):
"""Test if DLC installation is called."""
image.Build("board", [constants.IMAGE_TYPE_DEV], config=self.config)
self.assertCommandContains(
[
"build_dlc",
"--sysroot",
build_target_lib.get_default_sysroot_path("board"),
"--install-root-dir",
self.output_dir / "dlc",
"--board",
"board",
]
)
def testMoveDir(self):
"""Test if MoveDirContents is called."""
image.Build("board", [constants.IMAGE_TYPE_DEV], config=self.config)
self.MoveDir_mock.assert_called_once_with(
self.build_dir,
self.output_dir,
remove_from_dir=True,
allow_nonempty=True,
)
def testSummary(self):
"""Test if summary text is printed correctly."""
base_image_path = os.path.relpath(
self.output_dir / constants.BASE_IMAGE_BIN
)
dev_image_path = os.path.relpath(
self.output_dir / constants.DEV_IMAGE_BIN
)
test_image_path = os.path.relpath(
self.output_dir / constants.TEST_IMAGE_BIN
)
with cros_test_lib.LoggingCapturer() as logs:
image.Build(
"board",
[
constants.IMAGE_TYPE_BASE,
constants.IMAGE_TYPE_DEV,
constants.IMAGE_TYPE_TEST,
],
config=self.config,
)
# pylint: disable=protected-access
# Base Image summary text.
self.AssertLogsContain(
logs,
(
f"{image._IMAGE_TYPE_DESCRIPTION[constants.BASE_IMAGE_BIN]}"
f" image created as {constants.BASE_IMAGE_BIN}"
),
)
self.AssertLogsContain(logs, f"cros flash usb:// {base_image_path}")
self.AssertLogsContain(
logs, f"cros flash ${{DUT_IP}} {base_image_path}"
)
self.AssertLogsContain(
logs,
f"cros_vm --start --image-path={base_image_path} --board=board",
inverted=True,
)
# Dev Image summary text.
self.AssertLogsContain(
logs,
(
f"{image._IMAGE_TYPE_DESCRIPTION[constants.DEV_IMAGE_BIN]} "
f"image created as {constants.DEV_IMAGE_BIN}"
),
)
self.AssertLogsContain(logs, f"cros flash usb:// {dev_image_path}")
self.AssertLogsContain(
logs, f"cros flash ${{DUT_IP}} {dev_image_path}"
)
self.AssertLogsContain(
logs,
f"cros_vm --start --image-path={dev_image_path} --board=board",
)
# Test Image summary text.
self.AssertLogsContain(
logs,
(
f"{image._IMAGE_TYPE_DESCRIPTION[constants.TEST_IMAGE_BIN]}"
f" image created as {constants.TEST_IMAGE_BIN}"
),
)
self.AssertLogsContain(logs, f"cros flash usb:// {test_image_path}")
self.AssertLogsContain(
logs, f"cros flash ${{DUT_IP}} {test_image_path}"
)
self.AssertLogsContain(
logs,
f"cros_vm --start --image-path={test_image_path} --board=board",
)
class BuildImageCommandTest(cros_test_lib.MockTestCase):
"""BuildConfig tests."""
def testBuildImageCommand(self):
"""GetArguments tests."""
cmd = image.GetBuildImageCommand(
image.BuildConfig(), [constants.BASE_IMAGE_BIN], "testBoard"
)
expected = {
constants.CROSUTILS_DIR / "build_image.sh",
"--script-is-run-only-by-chromite-and-not-users",
"--board",
"testBoard",
}
self.assertTrue(expected.issubset(set(cmd)))
# Make sure each arg produces the correct argument individually.
cmd = image.GetBuildImageCommand(
image.BuildConfig(builder_path="test_builder_path"),
[constants.BASE_IMAGE_BIN],
"testBoard",
)
expected = {
"--builder_path",
"testBoard",
}
self.assertTrue(expected.issubset(set(cmd)))
# disk_layout
cmd = image.GetBuildImageCommand(
image.BuildConfig(disk_layout="disk"),
[constants.BASE_IMAGE_BIN],
"testBoard",
)
expected = {
"--disk_layout",
"disk",
}
self.assertTrue(expected.issubset(set(cmd)))
# enable_rootfs_verification
self.assertIn(
"--noenable_rootfs_verification",
image.GetBuildImageCommand(
image.BuildConfig(enable_rootfs_verification=False),
[constants.BASE_IMAGE_BIN],
"testBoard",
),
)
# adjust_partition
cmd = image.GetBuildImageCommand(
image.BuildConfig(adjust_partition="ROOT-A:+1G"),
[constants.BASE_IMAGE_BIN],
"testBoard",
)
expected = {
"--adjust_part",
"ROOT-A:+1G",
}
self.assertTrue(expected.issubset(set(cmd)))
# boot_args
config = image.BuildConfig(boot_args="initrd")
cmd = image.GetBuildImageCommand(
config, [constants.BASE_IMAGE_BIN], "testBoard"
)
expected = {
"--boot_args",
"initrd",
}
self.assertTrue(expected.issubset(set(cmd)))
cmd = image.GetBuildImageCommand(
config, [constants.FACTORY_IMAGE_BIN], "testBoard"
)
expected = {
"--boot_args",
"initrd cros_factory_install",
}
self.assertTrue(expected.issubset(set(cmd)))
# enable_bootcache
config = image.BuildConfig(enable_bootcache=True)
self.assertIn(
"--enable_bootcache",
image.GetBuildImageCommand(
config, [constants.BASE_IMAGE_BIN], "testBoard"
),
)
self.assertNotIn(
"--enable_bootcache",
image.GetBuildImageCommand(
config, [constants.FACTORY_IMAGE_BIN], "testBoard"
),
)
# enable_serial
cmd = image.GetBuildImageCommand(
image.BuildConfig(enable_serial="ttyS1"),
[constants.BASE_IMAGE_BIN],
"testBoard",
)
expected = {
"--enable_serial",
"ttyS1",
}
self.assertTrue(expected.issubset(set(cmd)))
# kernel_loglevel
cmd = image.GetBuildImageCommand(
image.BuildConfig(kernel_loglevel=4),
[constants.BASE_IMAGE_BIN],
"testBoard",
)
expected = {
"--loglevel",
"4",
}
self.assertTrue(expected.issubset(set(cmd)))
# jobs
cmd = image.GetBuildImageCommand(
image.BuildConfig(jobs=40), [constants.BASE_IMAGE_BIN], "testBoard"
)
expected = {
"--jobs",
"40",
}
self.assertTrue(expected.issubset(set(cmd)))
# image_name
config = image.BuildConfig()
for image_name in constants.IMAGE_NAME_TO_TYPE.keys():
self.assertIn(
image_name,
image.GetBuildImageCommand(config, [image_name], "testBoard"),
)
class CreateVmTest(cros_test_lib.RunCommandTestCase):
"""Create VM tests."""
def setUp(self):
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
def testNoBoardFails(self):
"""Should fail when not given a valid board-ish value."""
with self.assertRaises(AssertionError):
image.CreateVm("")
def testBoardArgument(self):
"""Test the board argument."""
image.CreateVm("board")
self.assertCommandContains(["--board", "board"])
def testTestImage(self):
"""Test the application of the --test_image argument."""
image.CreateVm("board", is_test=True)
self.assertCommandContains(["--test_image"])
def testNonTestImage(self):
"""Test the non-application of the --test_image argument."""
image.CreateVm("board", is_test=False)
self.assertCommandContains(["--test_image"], expected=False)
def testDiskLayout(self):
"""Test the application of the --disk_layout argument."""
image.CreateVm("board", disk_layout="5000PB")
self.assertCommandContains(["--disk_layout", "5000PB"])
def testCommandError(self):
"""Test handling of an error when running the command."""
self.rc.SetDefaultCmdResult(returncode=1)
with self.assertRaises(image.ImageToVmError):
image.CreateVm("board")
def testResultPath(self):
"""Test the path building."""
self.PatchObject(image_lib, "GetLatestImageLink", return_value="/tmp")
self.assertEqual(
os.path.join("/tmp", constants.VM_IMAGE_BIN),
image.CreateVm("board"),
)
class CopyBaseToRecoveryTest(cros_test_lib.MockTempDirTestCase):
"""Tests the CopyBaseToRecovery method."""
def setUp(self):
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
self.PatchObject(Path, "exists", return_value=True)
self.base_image = self.tempdir / constants.BASE_IMAGE_BIN
self.recovery_image = self.tempdir / constants.RECOVERY_IMAGE_BIN
def testCopyRecoveryImage(self):
self.base_image.touch()
result = image.CopyBaseToRecovery("board", self.base_image)
self.assertEqual(result.return_code, 0)
self.assertEqual(
result.images[constants.IMAGE_TYPE_RECOVERY], self.recovery_image
)
self.assertExists(self.recovery_image)
def testCopyRecoveryImageInvalid(self):
result = image.CopyBaseToRecovery("board", self.base_image)
self.assertNotEqual(result.return_code, 0)
self.assertNotExists(self.recovery_image)
class BuildRecoveryTest(cros_test_lib.RunCommandTestCase):
"""Create recovery image tests."""
def setUp(self):
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
def testNoBoardFails(self):
"""Should fail when not given a valid board-ish value."""
with self.assertRaises(image.InvalidArgumentError):
image.BuildRecoveryImage("")
def testBoardArgument(self):
"""Test the board argument."""
image.BuildRecoveryImage("board")
self.assertCommandContains(["--board", "board"])
class ImageTestTest(cros_test_lib.RunCommandTempDirTestCase):
"""Image Test tests."""
def setUp(self):
"""Setup the filesystem."""
self.board = "board"
self.chroot_container = os.path.join(self.tempdir, "outside")
self.outside_result_dir = os.path.join(self.chroot_container, "results")
self.inside_result_dir_inside = "/inside/results_inside"
self.inside_result_dir_outside = os.path.join(
self.chroot_container, "inside/results_inside"
)
self.image_dir_inside = "/inside/build/board/latest"
self.image_dir_outside = os.path.join(
self.chroot_container, "inside/build/board/latest"
)
D = cros_test_lib.Directory
filesystem = (
D(
"outside",
(
D("results", ()),
D(
"inside",
(
D("results_inside", ()),
D(
"build",
(
D(
"board",
(
D(
"latest",
(
"%s.bin"
% constants.BASE_IMAGE_NAME,
),
),
),
),
),
),
),
),
),
),
)
cros_test_lib.CreateOnDiskHierarchy(self.tempdir, filesystem)
def testTestFailsInvalidArguments(self):
"""Test invalid arguments are correctly failed."""
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
with self.assertRaises(image.InvalidArgumentError):
image.Test(None, None)
with self.assertRaises(image.InvalidArgumentError):
image.Test("", "")
with self.assertRaises(image.InvalidArgumentError):
image.Test(None, self.outside_result_dir)
with self.assertRaises(image.InvalidArgumentError):
image.Test(self.board, None)
with self.assertRaises(image.ChrootError):
image.Test(self.board, self.outside_result_dir)
def testTestInsideChrootAllProvided(self):
"""Test behavior when inside the chroot and all paths provided."""
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
image.Test(
self.board, self.outside_result_dir, image_dir=self.image_dir_inside
)
# Inside chroot shouldn't need to do any path manipulations, so we
# should see exactly what we called it with.
self.assertCommandContains(
[
"--board",
self.board,
"--test_results_root",
self.outside_result_dir,
self.image_dir_inside,
]
)
def testTestInsideChrootNoImageDir(self):
"""Test image dir generation inside the chroot."""
mocked_dir = "/foo/bar"
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=True)
self.PatchObject(
image_lib, "GetLatestImageLink", return_value=mocked_dir
)
image.Test(self.board, self.outside_result_dir)
self.assertCommandContains(
[
"--board",
self.board,
"--test_results_root",
self.outside_result_dir,
mocked_dir,
]
)
class TestCreateFactoryImageZip(cros_test_lib.MockTempDirTestCase):
"""Unittests for create_factory_image_zip."""
def setUp(self):
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
# Create a chroot_path.
self.chroot_path = os.path.join(self.tempdir, "chroot_dir")
self.out_path = self.tempdir / "out_dir"
self.chroot = chroot_lib.Chroot(
path=self.chroot_path, out_path=self.out_path
)
self.sysroot_path = os.path.join("build", "target")
self.sysroot = sysroot_lib.Sysroot(path=self.sysroot_path)
# Create appropriate sysroot structure.
osutils.SafeMakedirs(self.chroot.full_path(self.sysroot_path))
factory_bundle_path = self.chroot.full_path(
self.sysroot.path, "usr", "local", "factory", "bundle"
)
osutils.SafeMakedirs(factory_bundle_path)
osutils.Touch(os.path.join(factory_bundle_path, "bundle_foo"))
# Create factory shim directory.
self.factory_shim_path = os.path.join(self.tempdir, "factory_shim_dir")
osutils.SafeMakedirs(self.factory_shim_path)
osutils.Touch(
os.path.join(self.factory_shim_path, "factory_install.bin")
)
osutils.Touch(os.path.join(self.factory_shim_path, "partition"))
osutils.SafeMakedirs(os.path.join(self.factory_shim_path, "netboot"))
osutils.Touch(os.path.join(self.factory_shim_path, "netboot", "bar"))
# Create output dir.
self.output_dir = os.path.join(self.tempdir, "output_dir")
osutils.SafeMakedirs(self.output_dir)
def test(self):
"""create_factory_image_zip calls cbuildbot/commands correctly."""
version = "1.2.3.4"
output_file = image.create_factory_image_zip(
self.chroot,
self.sysroot,
Path(self.factory_shim_path),
version,
self.output_dir,
)
# Check that all expected files are present.
zip_contents = cros_build_lib.run(
["zipinfo", "-1", output_file], cwd=self.output_dir, stdout=True
)
zip_files = sorted(
zip_contents.stdout.decode("UTF-8").strip().split("\n")
)
expected_files = sorted(
[
"factory_shim_dir/netboot/",
"factory_shim_dir/netboot/bar",
"factory_shim_dir/factory_install.bin",
"factory_shim_dir/partition",
"bundle_foo",
"BUILD_VERSION",
]
)
self.assertListEqual(zip_files, expected_files)
# Check contents of BUILD_VERSION.
cmd = ["unzip", "-p", output_file, "BUILD_VERSION"]
version_file = cros_build_lib.run(cmd, cwd=self.output_dir, stdout=True)
self.assertEqual(version_file.stdout.decode("UTF-8").strip(), version)
class TestCreateStrippedPackagesTar(cros_test_lib.MockTempDirTestCase):
"""Unittests for create_stripped_packages_tar."""
def setUp(self):
self.PatchObject(cros_build_lib, "IsInsideChroot", return_value=False)
# Create a chroot_path.
self.chroot_path = os.path.join(self.tempdir, "chroot_dir")
self.out_path = self.tempdir / "out_dir"
self.chroot = chroot_lib.Chroot(
path=self.chroot_path, out_path=self.out_path
)
# Create build target.
self.build_target = build_target_lib.BuildTarget(
"target", build_root="/build/target"
)
# Create output dir.
self.output_dir = os.path.join(self.tempdir, "output_dir")
osutils.SafeMakedirs(self.output_dir)
def test(self):
"""Test generation of stripped package tarball using globs."""
self.PatchObject(
portage_util,
"FindPackageNameMatches",
side_effect=[
[package_info.SplitCPV("chromeos-base/chrome-1-r0")],
[
package_info.SplitCPV("sys-kernel/kernel-1-r0"),
package_info.SplitCPV("sys-kernel/kernel-2-r0"),
],
],
)
# Drop "stripped packages".
pkg_dir = self.chroot.full_path(
self.build_target.root, "stripped-packages"
)
osutils.Touch(
os.path.join(pkg_dir, "chromeos-base", "chrome-1-r0.tbz2"),
makedirs=True,
)
sys_kernel = os.path.join(pkg_dir, "sys-kernel")
osutils.Touch(
os.path.join(sys_kernel, "kernel-1-r0.tbz2"), makedirs=True
)
osutils.Touch(
os.path.join(sys_kernel, "kernel-1-r01.tbz2"), makedirs=True
)
osutils.Touch(
os.path.join(sys_kernel, "kernel-2-r0.tbz1"), makedirs=True
)
osutils.Touch(
os.path.join(sys_kernel, "kernel-2-r0.tbz2"), makedirs=True
)
stripped_files_list = [
os.path.join(
"stripped-packages", "chromeos-base", "chrome-1-r0.tbz2"
),
os.path.join("stripped-packages", "sys-kernel", "kernel-1-r0.tbz2"),
os.path.join("stripped-packages", "sys-kernel", "kernel-2-r0.tbz2"),
]
tar_mock = self.PatchObject(cros_build_lib, "CreateTarball")
rc = self.StartPatcher(cros_test_lib.RunCommandMock())
rc.SetDefaultCmdResult()
image.create_stripped_packages_tar(
self.chroot, self.build_target, self.output_dir
)
tar_mock.assert_called_once_with(
tarball_path=os.path.join(self.output_dir, "stripped-packages.tar"),
cwd=self.chroot.full_path(self.build_target.root),
compression=cros_build_lib.CompressionType.NONE,
chroot=self.chroot,
inputs=stripped_files_list,
)
class TestCreateNetbootKernel(cros_test_lib.MockTempDirTestCase):
"""Unittests for create_netboot_kernel."""
def test(self):
"""Test netboot kernel creation."""
board = "atlas"
image_dir = "/path/to/factory_install/"
rc = self.StartPatcher(cros_test_lib.RunCommandMock())
rc.SetDefaultCmdResult()
image.create_netboot_kernel(board, image_dir)
rc.assertCommandContains(
[
"./make_netboot.sh",
f"--board={board}",
f"--image_dir={image_dir}",
]
)
class TestCreateImageScriptsArchive(cros_test_lib.MockTempDirTestCase):
"""Unittests for create_image_scripts_archive."""
def test(self):
"""Test image scripts archive creation."""
build_target = build_target_lib.BuildTarget(
"target",
)
output_dir = "/path/to/output/dir/"
image_dir = self.tempdir
self.PatchObject(
image_lib, "GetLatestImageLink", return_value=str(image_dir)
)
glob_mock = self.PatchObject(
glob,
"glob",
return_value=[
os.path.join(image_dir, "bar.sh"),
os.path.join(image_dir, "baz.sh"),
],
)
tar_mock = self.PatchObject(cros_build_lib, "CreateTarball")
image.create_image_scripts_archive(build_target, output_dir)
glob_mock.assert_called_once()
tar_mock.assert_called_once_with(
os.path.join(output_dir, "image_scripts.tar.xz"),
str(image_dir),
inputs=["bar.sh", "baz.sh"],
)
class TestCopyDlcImages(cros_test_lib.MockTempDirTestCase):
"""Unittests for copy_dlc_image."""
def touchDlc(
self,
dlc_id: str,
dlc_package: str = dlc_lib.DLC_PACKAGE,
dlc_artifact: str = dlc_lib.DLC_IMAGE,
dlc_build_dir: str = dlc_lib.DLC_BUILD_DIR,
metadata: bool = True,
):
"""Touches the DLC artifact with the given args.
Args:
dlc_id: The DLC ID.
dlc_package: The DLC package.
dlc_artifact: The DLC artifact.
dlc_build_dir: The DLC build dir.
metadata: True to create metadata.
"""
build_dir = os.path.join(self.tempdir, dlc_build_dir)
osutils.Touch(
os.path.join(build_dir, dlc_id, dlc_package, dlc_artifact),
makedirs=True,
)
if metadata:
osutils.Touch(
os.path.join(
build_dir,
dlc_id,
dlc_package,
dlc_lib.DLC_TMP_META_DIR,
dlc_lib.IMAGELOADER_JSON,
),
makedirs=True,
)
def testOnlyLegacyDLCs(self):
"""Test copy of DLC artifacts for legacy."""
good_dlc_ids = ("dlc-a", "dlc-b")
for dlc_id in good_dlc_ids:
self.touchDlc(dlc_id)
self.touchDlc(dlc_id, dlc_artifact="foobar-file")
dlc_bad_id = "dlc_bad_id"
self.touchDlc(dlc_bad_id)
dlc_bad_package = "dlc-bad-package"
self.touchDlc(dlc_bad_package, dlc_package="packit")
dlc_bad_artifact = "dlc-bad-artifact"
self.touchDlc(dlc_bad_artifact, dlc_artifact="some-file")
dlc_bad_artifact_with_dir = "dlc-bad-artifact-with-dir"
self.touchDlc(
dlc_bad_artifact_with_dir, dlc_artifact="some-dir/some-file"
)
output_path = os.path.join(self.tempdir, "_output")
dst_paths = image.copy_dlc_image(self.tempdir, output_path)
self.assertEqual(len(dst_paths), 2)
# pylint: disable=unsubscriptable-object
path = dst_paths[0]
self.assertEqual(sorted(os.listdir(path)), list(good_dlc_ids))
self.assertEqual(os.path.basename(path), dlc_lib.DLC_DIR)
for dlc_id in good_dlc_ids:
self.assertTrue(
os.path.exists(
os.path.join(
path, dlc_id, dlc_lib.DLC_PACKAGE, dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_id, dlc_lib.DLC_PACKAGE, "foobar-file"
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_id, dlc_lib.DLC_PACKAGE, dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(path, dlc_bad_package, "packit", dlc_lib.DLC_IMAGE)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_artifact, dlc_lib.DLC_PACKAGE, "some-file"
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path,
dlc_bad_artifact_with_dir,
dlc_lib.DLC_PACKAGE,
"some-dir/some-file",
)
)
)
def testOnlyScaledDLCs(self):
"""Test copy of DLC artifacts for only scaled."""
good_dlc_ids = ("dlc-a", "dlc-b")
for dlc_id in good_dlc_ids:
self.touchDlc(dlc_id, dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED)
dlc_bad_id = "dlc_bad_id"
self.touchDlc(dlc_bad_id, dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED)
dlc_bad_package = "dlc-bad-package"
self.touchDlc(
dlc_bad_package,
dlc_package="packit",
dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED,
)
dlc_bad_artifact = "dlc-bad-artifact"
self.touchDlc(
dlc_bad_artifact,
dlc_artifact="some-file",
dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED,
)
dlc_bad_artifact_with_dir = "dlc-bad-artifact-with-dir"
self.touchDlc(
dlc_bad_artifact_with_dir,
dlc_artifact="some-dir/some-file",
dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED,
)
dst_paths = image.copy_dlc_image(self.tempdir, self.tempdir)
self.assertEqual(len(dst_paths), 2)
# pylint: disable=unsubscriptable-object
path = dst_paths[0]
self.assertEqual(sorted(os.listdir(path)), list(good_dlc_ids))
self.assertEqual(os.path.basename(path), dlc_lib.DLC_DIR_SCALED)
for dlc_id in good_dlc_ids:
self.assertTrue(
os.path.exists(
os.path.join(
path, dlc_id, dlc_lib.DLC_PACKAGE, dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_id, dlc_lib.DLC_PACKAGE, "foobar-file"
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_id, dlc_lib.DLC_PACKAGE, dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(path, dlc_bad_package, "packit", dlc_lib.DLC_IMAGE)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_artifact, dlc_lib.DLC_PACKAGE, "some-file"
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path,
dlc_bad_artifact_with_dir,
dlc_lib.DLC_PACKAGE,
"some-dir/some-file",
)
)
)
def testAllDLCs(self):
"""Test copy of DLC artifacts of all types."""
good_dlc_ids = ("dlc-a", "dlc-b")
for dlc_id in good_dlc_ids:
self.touchDlc(dlc_id)
self.touchDlc(dlc_id, dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED)
dlc_bad_id = "dlc_bad_id"
self.touchDlc(dlc_bad_id)
self.touchDlc(dlc_bad_id, dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED)
dlc_bad_package = "dlc-bad-package"
self.touchDlc(dlc_bad_package, dlc_package="packit")
self.touchDlc(
dlc_bad_package,
dlc_package="packit",
dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED,
)
dlc_bad_artifact = "dlc-bad-artifact"
self.touchDlc(dlc_bad_artifact, dlc_artifact="some-file")
self.touchDlc(
dlc_bad_artifact,
dlc_artifact="some-file",
dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED,
)
dlc_bad_artifact_with_dir = "dlc-bad-artifact-with-dir"
self.touchDlc(
dlc_bad_artifact_with_dir, dlc_artifact="some-dir/some-file"
)
self.touchDlc(
dlc_bad_artifact_with_dir,
dlc_artifact="some-dir/some-file",
dlc_build_dir=dlc_lib.DLC_BUILD_DIR_SCALED,
)
dst_paths = image.copy_dlc_image(self.tempdir, self.tempdir)
self.assertEqual(len(dst_paths), 4)
# pylint: disable=unsubscriptable-object
path0 = dst_paths[0]
self.assertEqual(sorted(os.listdir(path0)), list(good_dlc_ids))
self.assertEqual(os.path.basename(path0), dlc_lib.DLC_DIR)
# pylint: disable=unsubscriptable-object
path1 = dst_paths[2]
self.assertEqual(sorted(os.listdir(path1)), list(good_dlc_ids))
self.assertEqual(os.path.basename(path1), dlc_lib.DLC_DIR_SCALED)
for data_path in (dst_paths[1], dst_paths[3]):
for dlc_id in good_dlc_ids:
self.assertTrue(
os.path.exists(
os.path.join(
data_path,
dlc_id,
dlc_lib.DLC_PACKAGE,
dlc_lib.IMAGELOADER_JSON,
)
)
)
# Even bad ones that have metadata should copy over.
self.assertFalse(
os.path.exists(
os.path.join(
data_path,
dlc_bad_id,
dlc_lib.DLC_PACKAGE,
dlc_lib.IMAGELOADER_JSON,
)
)
)
for path in (path0, path1):
for dlc_id in good_dlc_ids:
self.assertTrue(
os.path.exists(
os.path.join(
path, dlc_id, dlc_lib.DLC_PACKAGE, dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_id, dlc_lib.DLC_PACKAGE, "foobar-file"
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_id, dlc_lib.DLC_PACKAGE, dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_package, "packit", dlc_lib.DLC_IMAGE
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path, dlc_bad_artifact, dlc_lib.DLC_PACKAGE, "some-file"
)
)
)
self.assertFalse(
os.path.exists(
os.path.join(
path,
dlc_bad_artifact_with_dir,
dlc_lib.DLC_PACKAGE,
"some-dir/some-file",
)
)
)