Move goldfish local image methods to a new file
This commit moves methods from goldfish_local_image_local_instance to a
new file. Their functionalities are not changed. Remote host goldfish
will use the methods to process images.
Test: acloud-dev create -vv --local-instance --local-image \
--local-system-image --local-boot-image
Test: acloud-dev create -vv --local-instance --local-image \
--local-system-image \
out/target/product/generic_x86_64/system.img \
--local-boot-image \
out/target/product/generic_x86_64/boot-5.10.img \
--avd-type goldfish
Bug: 185094559
Change-Id: I069a0388f38b0b6653bf3306ae5745cd26ccd4a8
diff --git a/create/create_common.py b/create/create_common.py
index 9771fc7..cf1145c 100644
--- a/create/create_common.py
+++ b/create/create_common.py
@@ -65,6 +65,18 @@
return args_dict
+def GetNonEmptyEnvVars(*variable_names):
+ """Get non-empty environment variables.
+
+ Args:
+ variable_names: Strings, the variable names.
+
+ Returns:
+ List of strings, the variable values that are defined and not empty.
+ """
+ return list(filter(None, (os.environ.get(v) for v in variable_names)))
+
+
def GetCvdHostPackage(package_path=None):
"""Get cvd host package path.
@@ -85,11 +97,8 @@
return package_path
raise errors.GetCvdLocalHostPackageError(
"The cvd host package path (%s) doesn't exist." % package_path)
- dirs_to_check = list(
- filter(None, [
- os.environ.get(constants.ENV_ANDROID_SOONG_HOST_OUT),
- os.environ.get(constants.ENV_ANDROID_HOST_OUT)
- ]))
+ dirs_to_check = GetNonEmptyEnvVars(constants.ENV_ANDROID_SOONG_HOST_OUT,
+ constants.ENV_ANDROID_HOST_OUT)
dist_dir = utils.GetDistDir()
if dist_dir:
dirs_to_check.append(dist_dir)
diff --git a/create/create_common_test.py b/create/create_common_test.py
index 247750f..2503532 100644
--- a/create/create_common_test.py
+++ b/create/create_common_test.py
@@ -67,6 +67,14 @@
result_dict = create_common.ParseKeyValuePairArgs(args_str)
self.assertTrue(expected_dict == result_dict)
+ def testGetNonEmptyEnvVars(self):
+ """Test GetNonEmptyEnvVars."""
+ with mock.patch.dict("acloud.internal.lib.utils.os.environ",
+ {"A": "", "B": "b"},
+ clear=True):
+ self.assertEqual(
+ ["b"], create_common.GetNonEmptyEnvVars("A", "B", "C"))
+
def testGetCvdHostPackage(self):
"""test GetCvdHostPackage."""
# Can't find the cvd host package
diff --git a/create/goldfish_local_image_local_instance.py b/create/goldfish_local_image_local_instance.py
index a8a33b8..6971a79 100644
--- a/create/goldfish_local_image_local_instance.py
+++ b/create/goldfish_local_image_local_instance.py
@@ -46,6 +46,7 @@
from acloud.create import base_avd_create
from acloud.create import create_common
from acloud.internal import constants
+from acloud.internal.lib import goldfish_image
from acloud.internal.lib import ota_tools
from acloud.internal.lib import utils
from acloud.list import instance
@@ -58,26 +59,12 @@
_EMULATOR_BIN_NAME = "emulator"
_EMULATOR_BIN_DIR_NAMES = ("bin64", "qemu")
_SDK_REPO_EMULATOR_DIR_NAME = "emulator"
-_SYSTEM_IMAGE_NAME = "system.img"
-_SYSTEM_QEMU_IMAGE_NAME = "system-qemu.img"
# The pattern corresponds to the officially released GKI (Generic Kernel
# Image). The names are boot-<kernel version>.img. Emulator has no boot.img.
_BOOT_IMAGE_NAME_PATTERN = r"boot-[\d.]+\.img"
_SYSTEM_IMAGE_NAME_PATTERN = r"system\.img"
-# File names in an unpacked boot image.
-_UNPACK_DIR_NAME = "unpacked_boot_img"
-_UNPACKED_KERNEL_IMAGE_NAME = "kernel"
-_UNPACKED_RAMDISK_IMAGE_NAME = "ramdisk"
-# File names in a build environment or an SDK repository. They follow the
-# search order of emulator.
-_DISK_IMAGE_NAMES = (_SYSTEM_QEMU_IMAGE_NAME, _SYSTEM_IMAGE_NAME)
-_KERNEL_IMAGE_NAMES = ("kernel-ranchu", "kernel-ranchu-64", "kernel")
-_RAMDISK_IMAGE_NAMES = ("ramdisk-qemu.img", "ramdisk.img")
_NON_MIXED_BACKUP_IMAGE_EXT = ".bak-non-mixed"
_BUILD_PROP_FILE_NAME = "build.prop"
-_MISC_INFO_FILE_NAME = "misc_info.txt"
-_SYSTEM_QEMU_CONFIG_FILE_NAME = "system-qemu-config.txt"
-
# Timeout
_DEFAULT_EMULATOR_TIMEOUT_SECS = 150
_EMULATOR_TIMEOUT_ERROR = "Emulator did not boot within %(timeout)d secs."
@@ -187,11 +174,14 @@
contain required files.
errors.CheckPathError if OTA tools are not found.
"""
- emulator_path = self._FindEmulatorBinary(avd_spec.local_tool_dirs)
+ emulator_path = self._FindEmulatorBinary(
+ avd_spec.local_tool_dirs +
+ create_common.GetNonEmptyEnvVars(
+ constants.ENV_ANDROID_EMULATOR_PREBUILTS))
image_dir = self._FindImageDir(avd_spec.local_image_dir)
# Validate the input dir.
- self._FindFileByNames(image_dir, _DISK_IMAGE_NAMES)
+ goldfish_image.FindDiskImage(image_dir)
# TODO(b/141898893): In Android build environment, emulator gets build
# information from $ANDROID_PRODUCT_OUT/system/build.prop.
@@ -230,115 +220,6 @@
return result_report
@staticmethod
- def _FindFileByNames(parent_dir, names):
- """Find file under a directory by names.
-
- Args:
- parent_dir: The directory to find the file in.
- names: A list of file names.
-
- Returns:
- The path to the first existing file in the list.
-
- Raises:
- errors.GetLocalImageError if none of the files exist.
- """
- for name in names:
- path = os.path.join(parent_dir, name)
- if os.path.isfile(path):
- return path
- raise errors.GetLocalImageError("No %s in %s." %
- (", ".join(names), parent_dir))
-
- @staticmethod
- def _FindKernelImagesInBootImage(boot_image_path, instance_dir, ota):
- """Unpack a boot image and find kernel images.
-
- Args:
- boot_image_path: The path to the boot image.
- instance_dir: The directory where the boot image is unpacked.
- ota: An instance of ota_tools.OtaTools.
-
- Returns:
- The kernel image path and the ramdisk image path.
-
- Raises:
- errors.GetLocalImageError if any image is not found.
- """
- unpack_dir = os.path.join(instance_dir, _UNPACK_DIR_NAME)
- if os.path.exists(unpack_dir):
- shutil.rmtree(unpack_dir)
-
- ota.UnpackBootImg(unpack_dir, boot_image_path)
-
- kernel_path = os.path.join(unpack_dir, _UNPACKED_KERNEL_IMAGE_NAME)
- ramdisk_path = os.path.join(unpack_dir, _UNPACKED_RAMDISK_IMAGE_NAME)
- if not os.path.isfile(kernel_path):
- raise errors.GetLocalImageError("No kernel in %s." %
- boot_image_path)
- if not os.path.isfile(ramdisk_path):
- raise errors.GetLocalImageError("No ramdisk in %s." %
- boot_image_path)
- return kernel_path, ramdisk_path
-
- @staticmethod
- def _MixRamdiskImages(output_path, original_ramdisk_path,
- boot_ramdisk_path):
- """Mix an emulator ramdisk and a boot ramdisk.
-
- An emulator ramdisk consists of a boot ramdisk and a vendor ramdisk.
- This method overlays a new boot ramdisk on the emulator ramdisk by
- concatenating them.
-
- Args:
- output_path: The path to the output ramdisk.
- original_ramdisk_path: The path to the emulator ramdisk.
- boot_ramdisk_path: The path to the boot ramdisk.
- """
- with open(output_path, "wb") as mixed_ramdisk:
- with open(original_ramdisk_path, "rb") as ramdisk:
- shutil.copyfileobj(ramdisk, mixed_ramdisk)
- with open(boot_ramdisk_path, "rb") as ramdisk:
- shutil.copyfileobj(ramdisk, mixed_ramdisk)
-
- @staticmethod
- def _MixImages(output_dir, image_dir, system_image_path, ota):
- """Mix emulator images and a system image into a disk image.
-
- Args:
- output_dir: The path to the output directory.
- image_dir: The input directory that provides images except
- system.img.
- system_image_path: The path to the system image.
- ota: An instance of ota_tools.OtaTools.
-
- Returns:
- The path to the mixed disk image in output_dir.
- """
- # Create the super image.
- mixed_super_image_path = os.path.join(output_dir, "mixed_super.img")
- ota.BuildSuperImage(
- mixed_super_image_path,
- os.path.join(image_dir, _MISC_INFO_FILE_NAME),
- lambda partition: ota_tools.GetImageForPartition(
- partition, image_dir, system=system_image_path))
-
- # Create the vbmeta image.
- disabled_vbmeta_image_path = os.path.join(output_dir,
- "disabled_vbmeta.img")
- ota.MakeDisabledVbmetaImage(disabled_vbmeta_image_path)
-
- # Create the disk image.
- disk_image = os.path.join(output_dir, "mixed_disk.img")
- ota.MkCombinedImg(
- disk_image,
- os.path.join(image_dir, _SYSTEM_QEMU_CONFIG_FILE_NAME),
- lambda partition: ota_tools.GetImageForPartition(
- partition, image_dir, super=mixed_super_image_path,
- vbmeta=disabled_vbmeta_image_path))
- return disk_image
-
- @staticmethod
def _FindEmulatorBinary(search_paths):
"""Find emulator binary in the directories.
@@ -369,14 +250,6 @@
emulator_dir = sdk_repo_dir
break
- # Find in build environment.
- if not emulator_dir:
- prebuilt_emulator_dir = os.environ.get(
- constants.ENV_ANDROID_EMULATOR_PREBUILTS)
- if (prebuilt_emulator_dir and os.path.isfile(
- os.path.join(prebuilt_emulator_dir, _EMULATOR_BIN_NAME))):
- emulator_dir = prebuilt_emulator_dir
-
if not emulator_dir:
raise errors.GetSdkRepoPackageError(_MISSING_EMULATOR_MSG)
@@ -482,7 +355,8 @@
new_image: The path to the new image.
image_dir: The directory containing system-qemu.img.
"""
- system_qemu_img = os.path.join(image_dir, _SYSTEM_QEMU_IMAGE_NAME)
+ system_qemu_img = os.path.join(image_dir,
+ goldfish_image.SYSTEM_QEMU_IMAGE_NAME)
if os.path.exists(system_qemu_img):
system_qemu_img_bak = system_qemu_img + _NON_MIXED_BACKUP_IMAGE_EXT
if not os.path.exists(system_qemu_img_bak):
@@ -491,7 +365,8 @@
# preserved. The user can restore it by renaming the backup to
# system-qemu.img.
logger.info("Rename %s to %s%s.",
- system_qemu_img, _SYSTEM_QEMU_IMAGE_NAME,
+ system_qemu_img,
+ goldfish_image.SYSTEM_QEMU_IMAGE_NAME,
_NON_MIXED_BACKUP_IMAGE_EXT)
os.rename(system_qemu_img, system_qemu_img_bak)
else:
@@ -531,24 +406,14 @@
boot_image_path = None
if boot_image_path:
- kernel_path, boot_ramdisk_path = self._FindKernelImagesInBootImage(
- boot_image_path, instance_dir,
- ota_tools.FindOtaTools(tool_dirs))
- # The ramdisk unpacked from the boot image does not include
- # emulator's kernel modules. The ramdisk in the original image
- # directory contains the modules. This method mixes the two
- # ramdisks.
- mixed_ramdisk_path = os.path.join(instance_dir, "mixed_ramdisk")
- original_ramdisk_path = self._FindFileByNames(
- self._FindImageDir(image_dir), _RAMDISK_IMAGE_NAMES)
- self._MixRamdiskImages(mixed_ramdisk_path, original_ramdisk_path,
- boot_ramdisk_path)
- return kernel_path, mixed_ramdisk_path
+ return goldfish_image.MixWithBootImage(
+ os.path.join(instance_dir, "mix_kernel"),
+ self._FindImageDir(image_dir),
+ boot_image_path, ota_tools.FindOtaTools(tool_dirs))
# Find kernel and ramdisk images built for emulator.
kernel_dir = self._FindImageDir(kernel_search_path)
- kernel_path = self._FindFileByNames(kernel_dir, _KERNEL_IMAGE_NAMES)
- ramdisk_path = self._FindFileByNames(kernel_dir, _RAMDISK_IMAGE_NAMES)
+ kernel_path, ramdisk_path = goldfish_image.FindKernelImages(kernel_dir)
logger.info("Found kernel and ramdisk: %s %s",
kernel_path, ramdisk_path)
return kernel_path, ramdisk_path
@@ -571,27 +436,25 @@
if not avd_spec.autoconnect:
args.append("-no-window")
+ ota_tools_search_paths = (
+ avd_spec.local_tool_dirs +
+ create_common.GetNonEmptyEnvVars(
+ constants.ENV_ANDROID_SOONG_HOST_OUT,
+ constants.ENV_ANDROID_HOST_OUT))
+
if avd_spec.local_kernel_image:
kernel_path, ramdisk_path = self._FindAndMixKernelImages(
avd_spec.local_kernel_image, avd_spec.local_image_dir,
- avd_spec.local_tool_dirs, instance_dir)
+ ota_tools_search_paths, instance_dir)
args.extend(("-kernel", kernel_path, "-ramdisk", ramdisk_path))
if avd_spec.local_system_image:
- mixed_image_dir = os.path.join(instance_dir, "mixed_images")
- if os.path.exists(mixed_image_dir):
- shutil.rmtree(mixed_image_dir)
- os.mkdir(mixed_image_dir)
-
image_dir = self._FindImageDir(avd_spec.local_image_dir)
-
- system_image_path = create_common.FindLocalImage(
- avd_spec.local_system_image, _SYSTEM_IMAGE_NAME_PATTERN)
-
- ota = ota_tools.FindOtaTools(avd_spec.local_tool_dirs)
-
- mixed_image = self._MixImages(mixed_image_dir, image_dir,
- system_image_path, ota)
+ mixed_image = goldfish_image.MixWithSystemImage(
+ os.path.join(instance_dir, "mix_disk"), image_dir,
+ create_common.FindLocalImage(avd_spec.local_system_image,
+ _SYSTEM_IMAGE_NAME_PATTERN),
+ ota_tools.FindOtaTools(ota_tools_search_paths))
# TODO(b/142228085): Use -system instead of modifying image_dir.
self._ReplaceSystemQemuImg(mixed_image, image_dir)
diff --git a/create/goldfish_local_image_local_instance_test.py b/create/goldfish_local_image_local_instance_test.py
index db4cf6c..2b37bc4 100644
--- a/create/goldfish_local_image_local_instance_test.py
+++ b/create/goldfish_local_image_local_instance_test.py
@@ -69,6 +69,21 @@
with open(path, "w") as _:
pass
+ def _MockMixWithSystemImage(self, output_dir, *_args):
+ """Mock goldfish_image.MixWithSystemImage."""
+ self.assertEqual(os.path.join(self._instance_dir, "mix_disk"),
+ output_dir)
+ output_path = os.path.join(output_dir, "mixed_disk.img")
+ self._CreateEmptyFile(output_path)
+ return output_path
+
+ def _MockMixWithBootImage(self, output_dir, *_args):
+ """Mock goldfish_image.MixWithBootImage."""
+ self.assertEqual(os.path.join(self._instance_dir, "mix_kernel"),
+ output_dir)
+ return (os.path.join(output_dir, "kernel"),
+ os.path.join(output_dir, "ramdisk"))
+
def _MockPopen(self, *_args, **_kwargs):
self._emulator_is_running = True
return self._mock_proc
@@ -87,7 +102,8 @@
raise ValueError("Unexpected arguments " + str(args))
- def _SetUpMocks(self, mock_popen, mock_utils, mock_instance):
+ def _SetUpMocks(self, mock_popen, mock_utils, mock_instance,
+ mock_gf_image=None):
mock_utils.IsSupportedPlatform.return_value = True
mock_adb_tools = mock.Mock(side_effect=self._MockEmuCommand)
@@ -107,6 +123,13 @@
mock_popen.side_effect = self._MockPopen
+ if mock_gf_image:
+ mock_gf_image.SYSTEM_QEMU_IMAGE_NAME = "system-qemu.img"
+ mock_gf_image.MixWithSystemImage.side_effect = (
+ self._MockMixWithSystemImage)
+ mock_gf_image.MixWithBootImage.side_effect = (
+ self._MockMixWithBootImage)
+
def _CreateMockAvdSpec(self, local_instance_id, autoconnect=True,
boot_timeout_secs=None, gpu=None,
local_instance_dir=None, local_kernel_image=None,
@@ -301,18 +324,15 @@
@mock.patch("acloud.create.goldfish_local_image_local_instance."
"subprocess.Popen")
@mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools")
- def testCreateAVDWithMixedImages(self, mock_ota_tools, mock_popen,
- mock_utils, mock_instance):
+ @mock.patch("acloud.create.goldfish_local_image_local_instance."
+ "goldfish_image")
+ def testCreateAVDWithMixedImages(self, mock_gf_image, mock_ota_tools,
+ mock_popen, mock_utils, mock_instance):
"""Test _CreateAVD with mixed images and SDK repository files."""
- mock_ota_tools_object = mock.Mock()
- mock_ota_tools.FindOtaTools.return_value = mock_ota_tools_object
- mock_ota_tools_object.MkCombinedImg.side_effect = (
- lambda out_path, _conf, _get_img: self._CreateEmptyFile(out_path))
+ self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_image)
- self._SetUpMocks(mock_popen, mock_utils, mock_instance)
-
- self._CreateEmptyFile(os.path.join(self._image_dir, "x86",
- "system.img"))
+ system_image_path = os.path.join(self._image_dir, "x86", "system.img")
+ self._CreateEmptyFile(system_image_path)
self._CreateEmptyFile(os.path.join(self._image_dir, "x86", "system",
"build.prop"))
@@ -320,8 +340,7 @@
local_instance_id=3,
gpu="auto",
autoconnect=False,
- local_system_image=os.path.join(self._image_dir, "x86",
- "system.img"),
+ local_system_image=system_image_path,
local_tool_dirs=[self._tool_dir])
with mock.patch.dict("acloud.create."
@@ -336,18 +355,11 @@
self.assertTrue(os.path.isdir(self._instance_dir))
- mock_ota_tools.FindOtaTools.assert_called_with([self._tool_dir])
+ mock_ota_tools.FindOtaTools.assert_called_once_with([self._tool_dir])
- mock_ota_tools_object.BuildSuperImage.assert_called_once()
- self.assertEqual(mock_ota_tools_object.BuildSuperImage.call_args[0][1],
- os.path.join(self._image_dir, "x86", "misc_info.txt"))
-
- mock_ota_tools_object.MakeDisabledVbmetaImage.assert_called_once()
-
- mock_ota_tools_object.MkCombinedImg.assert_called_once()
- self.assertEqual(
- mock_ota_tools_object.MkCombinedImg.call_args[0][1],
- os.path.join(self._image_dir, "x86", "system-qemu-config.txt"))
+ mock_gf_image.MixWithSystemImage.assert_called_once_with(
+ mock.ANY, os.path.join(self._image_dir, "x86"), system_image_path,
+ mock_ota_tools.FindOtaTools.return_value)
mock_utils.SetExecutable.assert_called_with(self._emulator_path)
mock_popen.assert_called_once()
@@ -365,35 +377,19 @@
@mock.patch("acloud.create.goldfish_local_image_local_instance."
"subprocess.Popen")
@mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools")
- def testCreateAVDWithBootImage(self, mock_ota_tools, mock_popen,
- mock_utils, mock_instance):
+ @mock.patch("acloud.create.goldfish_local_image_local_instance."
+ "goldfish_image")
+ def testCreateAVDWithBootImage(self, mock_gf_image, mock_ota_tools,
+ mock_popen, mock_utils, mock_instance):
"""Test _CreateAVD with a boot image and SDK repository files."""
- mock_ota_tools_object = mock.Mock()
- mock_ota_tools.FindOtaTools.return_value = mock_ota_tools_object
+ self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_image)
- unpack_dir = os.path.join(self._instance_dir, "unpacked_boot_img")
+ image_subdir = os.path.join(self._image_dir, "x86")
boot_image_path = os.path.join(self._temp_dir, "kernel_images",
"boot-5.10.img")
-
- def _MockUnpackBootImg(out_dir, boot_img):
- self.assertEqual(unpack_dir, out_dir)
- self.assertEqual(boot_image_path, boot_img)
- self._CreateEmptyFile(os.path.join(out_dir, "kernel"))
- with open(os.path.join(out_dir, "ramdisk"), "w") as ramdisk:
- ramdisk.write("test")
-
- mock_ota_tools_object.UnpackBootImg.side_effect = _MockUnpackBootImg
-
- self._SetUpMocks(mock_popen, mock_utils, mock_instance)
-
self._CreateEmptyFile(boot_image_path)
- self._CreateEmptyFile(os.path.join(self._image_dir, "x86",
- "system.img"))
- self._CreateEmptyFile(os.path.join(self._image_dir, "x86",
- "build.prop"))
- with open(os.path.join(self._image_dir, "x86", "ramdisk.img"),
- "w") as ramdisk:
- ramdisk.write("unit")
+ self._CreateEmptyFile(os.path.join(image_subdir, "system.img"))
+ self._CreateEmptyFile(os.path.join(image_subdir, "build.prop"))
mock_avd_spec = self._CreateMockAvdSpec(
local_instance_id=3,
@@ -408,18 +404,18 @@
self.assertEqual(report.data.get("devices"),
self._EXPECTED_DEVICES_IN_REPORT)
- mock_ota_tools_object.UnpackBootImg.assert_called_once()
-
- mixed_ramdisk_path = os.path.join(self._instance_dir, "mixed_ramdisk")
- with open(mixed_ramdisk_path, "r") as mixed_ramdisk:
- self.assertEqual("unittest", mixed_ramdisk.read())
+ mock_gf_image.MixWithBootImage.assert_called_once_with(
+ mock.ANY, os.path.join(image_subdir), boot_image_path,
+ mock_ota_tools.FindOtaTools.return_value)
mock_popen.assert_called_once()
self.assertEqual(
mock_popen.call_args[0][0],
self._GetExpectedEmulatorArgs(
- "-kernel", os.path.join(unpack_dir, "kernel"),
- "-ramdisk", mixed_ramdisk_path))
+ "-kernel",
+ os.path.join(self._instance_dir, "mix_kernel", "kernel"),
+ "-ramdisk",
+ os.path.join(self._instance_dir, "mix_kernel", "ramdisk")))
# pylint: disable=protected-access
@mock.patch("acloud.create.goldfish_local_image_local_instance.instance."
@@ -428,16 +424,20 @@
@mock.patch("acloud.create.goldfish_local_image_local_instance."
"subprocess.Popen")
@mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools")
- def testCreateAVDWithKernelImages(self, mock_ota_tools, mock_popen,
- mock_utils, mock_instance):
+ @mock.patch("acloud.create.goldfish_local_image_local_instance."
+ "goldfish_image")
+ def testCreateAVDWithKernelImages(self, mock_gf_image, mock_ota_tools,
+ mock_popen, mock_utils, mock_instance):
"""Test _CreateAVD with kernel images and SDK repository files."""
- self._SetUpMocks(mock_popen, mock_utils, mock_instance)
+ self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_image)
- kernel_dir = os.path.join(self._temp_dir, "kernel_images")
- kernel_image_path = os.path.join(kernel_dir, "x86", "kernel-ranchu")
- ramdisk_image_path = os.path.join(kernel_dir, "x86", "ramdisk.img")
- self._CreateEmptyFile(kernel_image_path)
- self._CreateEmptyFile(ramdisk_image_path)
+ kernel_subdir = os.path.join(self._temp_dir, "kernel_images", "x86")
+ kernel_image_path = os.path.join(kernel_subdir, "kernel-ranchu")
+ ramdisk_image_path = os.path.join(kernel_subdir, "ramdisk.img")
+ mock_gf_image.FindKernelImages.return_value = (kernel_image_path,
+ ramdisk_image_path)
+
+ os.makedirs(kernel_subdir)
self._CreateEmptyFile(os.path.join(self._image_dir, "x86",
"system.img"))
self._CreateEmptyFile(os.path.join(self._image_dir, "x86",
@@ -445,7 +445,7 @@
mock_avd_spec = self._CreateMockAvdSpec(
local_instance_id=3,
- local_kernel_image=kernel_dir,
+ local_kernel_image=os.path.dirname(kernel_subdir),
local_tool_dirs=[self._tool_dir])
with mock.patch.dict("acloud.create."
@@ -457,6 +457,7 @@
self._EXPECTED_DEVICES_IN_REPORT)
mock_ota_tools.FindOtaTools.assert_not_called()
+ mock_gf_image.FindKernelImages.assert_called_once_with(kernel_subdir)
mock_popen.assert_called_once()
self.assertEqual(
@@ -472,25 +473,26 @@
@mock.patch("acloud.create.goldfish_local_image_local_instance."
"subprocess.Popen")
@mock.patch("acloud.create.goldfish_local_image_local_instance.ota_tools")
- def testCreateAVDWithMixedImageDirs(self, mock_ota_tools, mock_popen,
- mock_utils, mock_instance):
+ @mock.patch("acloud.create.goldfish_local_image_local_instance."
+ "goldfish_image")
+ def testCreateAVDWithMixedImageDirs(self, mock_gf_image, mock_ota_tools,
+ mock_popen, mock_utils, mock_instance):
"""Test _CreateAVD with mixed images in build environment."""
- mock_ota_tools_object = mock.Mock()
- mock_ota_tools.FindOtaTools.return_value = mock_ota_tools_object
- mock_ota_tools_object.MkCombinedImg.side_effect = (
- lambda out_path, _conf, _get_img: self._CreateEmptyFile(out_path))
+ self._SetUpMocks(mock_popen, mock_utils, mock_instance, mock_gf_image)
- self._SetUpMocks(mock_popen, mock_utils, mock_instance)
-
+ system_image_path = os.path.join(self._image_dir, "system.img")
+ self._CreateEmptyFile(system_image_path)
self._CreateEmptyFile(os.path.join(self._image_dir,
"system-qemu.img"))
- self._CreateEmptyFile(os.path.join(self._image_dir,
- "system.img"))
self._CreateEmptyFile(os.path.join(self._image_dir, "system",
"build.prop"))
mock_environ = {"ANDROID_EMULATOR_PREBUILTS":
- os.path.join(self._tool_dir, "emulator")}
+ os.path.join(self._tool_dir, "emulator"),
+ "ANDROID_HOST_OUT":
+ os.path.join(self._tool_dir, "host"),
+ "ANDROID_SOONG_HOST_OUT":
+ os.path.join(self._tool_dir, "soong")}
mock_avd_spec = self._CreateMockAvdSpec(
local_instance_id=3,
@@ -510,18 +512,13 @@
self.assertTrue(os.path.isdir(self._instance_dir))
- mock_ota_tools.FindOtaTools.assert_called_with([])
+ mock_ota_tools.FindOtaTools.assert_called_once_with([
+ os.path.join(self._tool_dir, "soong"),
+ os.path.join(self._tool_dir, "host")])
- mock_ota_tools_object.BuildSuperImage.assert_called_once()
- self.assertEqual(mock_ota_tools_object.BuildSuperImage.call_args[0][1],
- os.path.join(self._image_dir, "misc_info.txt"))
-
- mock_ota_tools_object.MakeDisabledVbmetaImage.assert_called_once()
-
- mock_ota_tools_object.MkCombinedImg.assert_called_once()
- self.assertEqual(
- mock_ota_tools_object.MkCombinedImg.call_args[0][1],
- os.path.join(self._image_dir, "system-qemu-config.txt"))
+ mock_gf_image.MixWithSystemImage.assert_called_once_with(
+ mock.ANY, self._image_dir, system_image_path,
+ mock_ota_tools.FindOtaTools.return_value)
mock_utils.SetExecutable.assert_called_with(self._emulator_path)
mock_popen.assert_called_once()
diff --git a/create/local_image_local_instance.py b/create/local_image_local_instance.py
index 32c5111..f538b2b 100644
--- a/create/local_image_local_instance.py
+++ b/create/local_image_local_instance.py
@@ -303,14 +303,6 @@
constants.CMD_LAUNCH_CVD)):
return search_path
- for env_host_out in [constants.ENV_ANDROID_SOONG_HOST_OUT,
- constants.ENV_ANDROID_HOST_OUT]:
- host_out_dir = os.environ.get(env_host_out)
- if (host_out_dir and
- os.path.isfile(os.path.join(host_out_dir, "bin",
- constants.CMD_LAUNCH_CVD))):
- return host_out_dir
-
raise errors.GetCvdLocalHostPackageError(
"CVD host binaries are not found. Please run `make hosttar`, or "
"set --local-tool to an extracted CVD host package.")
@@ -383,13 +375,17 @@
errors.CheckPathError if any artifact is not found.
"""
image_dir = os.path.abspath(avd_spec.local_image_dir)
- host_bins_path = self._FindCvdHostBinaries(avd_spec.local_tool_dirs)
+ tool_dirs = (avd_spec.local_tool_dirs +
+ create_common.GetNonEmptyEnvVars(
+ constants.ENV_ANDROID_SOONG_HOST_OUT,
+ constants.ENV_ANDROID_HOST_OUT))
+ host_bins_path = self._FindCvdHostBinaries(tool_dirs)
if avd_spec.local_system_image:
misc_info_path = self._FindMiscInfo(image_dir)
image_dir = self._FindImageDir(image_dir)
ota_tools_dir = os.path.abspath(
- ota_tools.FindOtaToolsDir(avd_spec.local_tool_dirs))
+ ota_tools.FindOtaToolsDir(tool_dirs))
system_image_path = create_common.FindLocalImage(
avd_spec.local_system_image, _SYSTEM_IMAGE_NAME_PATTERN)
else:
diff --git a/create/local_image_local_instance_test.py b/create/local_image_local_instance_test.py
index d30dda3..4476759 100644
--- a/create/local_image_local_instance_test.py
+++ b/create/local_image_local_instance_test.py
@@ -233,27 +233,16 @@
cvd_host_dir = "/unit/test"
mock_isfile.return_value = None
- with mock.patch.dict("acloud.internal.lib.ota_tools.os.environ",
- {"ANDROID_HOST_OUT": cvd_host_dir,
- "ANDROID_SOONG_HOST_OUT": cvd_host_dir}, clear=True):
- with self.assertRaises(errors.GetCvdLocalHostPackageError):
- self.local_image_local_instance._FindCvdHostBinaries(
- [cvd_host_dir])
+ with self.assertRaises(errors.GetCvdLocalHostPackageError):
+ self.local_image_local_instance._FindCvdHostBinaries(
+ [cvd_host_dir])
mock_isfile.side_effect = (
lambda path: path == "/unit/test/bin/launch_cvd")
- with mock.patch.dict("acloud.internal.lib.ota_tools.os.environ",
- {"ANDROID_HOST_OUT": cvd_host_dir,
- "ANDROID_SOONG_HOST_OUT": cvd_host_dir}, clear=True):
- path = self.local_image_local_instance._FindCvdHostBinaries([])
- self.assertEqual(path, cvd_host_dir)
-
- with mock.patch.dict("acloud.internal.lib.ota_tools.os.environ",
- dict(), clear=True):
- path = self.local_image_local_instance._FindCvdHostBinaries(
- [cvd_host_dir])
- self.assertEqual(path, cvd_host_dir)
+ path = self.local_image_local_instance._FindCvdHostBinaries(
+ [cvd_host_dir])
+ self.assertEqual(path, cvd_host_dir)
@staticmethod
def _CreateEmptyFile(path):
@@ -308,12 +297,13 @@
with mock.patch.dict("acloud.create.local_image_local_instance."
"os.environ",
- {"ANDROID_SOONG_HOST_OUT": cvd_dir},
+ {"ANDROID_SOONG_HOST_OUT": cvd_dir,
+ "ANDROID_HOST_OUT": "/cvd"},
clear=True):
paths = self.local_image_local_instance.GetImageArtifactsPath(
mock_avd_spec)
- mock_ota_tools.FindOtaToolsDir.assert_called_once()
+ mock_ota_tools.FindOtaToolsDir.assert_called_with([cvd_dir, "/cvd"])
self.assertEqual(paths,
(image_dir, cvd_dir, misc_info_path, cvd_dir,
system_image_path, boot_image_path))
@@ -343,10 +333,14 @@
local_system_image=system_image_path,
local_tool_dirs=[ota_tools_dir, cvd_dir])
- paths = self.local_image_local_instance.GetImageArtifactsPath(
- mock_avd_spec)
+ with mock.patch.dict("acloud.create.local_image_local_instance."
+ "os.environ",
+ clear=True):
+ paths = self.local_image_local_instance.GetImageArtifactsPath(
+ mock_avd_spec)
- mock_ota_tools.FindOtaToolsDir.assert_called_once()
+ mock_ota_tools.FindOtaToolsDir.assert_called_with(
+ [ota_tools_dir, cvd_dir])
self.assertEqual(paths,
(os.path.join(image_dir, "IMAGES"), cvd_dir,
misc_info_path, ota_tools_dir, system_image_path,
diff --git a/internal/lib/goldfish_image.py b/internal/lib/goldfish_image.py
new file mode 100644
index 0000000..bc11669
--- /dev/null
+++ b/internal/lib/goldfish_image.py
@@ -0,0 +1,208 @@
+# Copyright 2021 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Utility functions that process goldfish images."""
+
+import os
+import shutil
+
+from acloud import errors
+from acloud.internal.lib import ota_tools
+
+
+# File names under working directory.
+_UNPACK_DIR_NAME = "unpacked_boot_img"
+_MIXED_RAMDISK_IMAGE_NAME = "mixed_ramdisk"
+# File names in unpacked boot image.
+_UNPACKED_KERNEL_IMAGE_NAME = "kernel"
+_UNPACKED_RAMDISK_IMAGE_NAME = "ramdisk"
+# File names in a build environment or an SDK repository.
+SYSTEM_QEMU_IMAGE_NAME = "system-qemu.img"
+_SDK_REPO_SYSTEM_IMAGE_NAME = "system.img"
+_MISC_INFO_FILE_NAME = "misc_info.txt"
+_SYSTEM_QEMU_CONFIG_FILE_NAME = "system-qemu-config.txt"
+# File names in the search order of emulator.
+_DISK_IMAGE_NAMES = (SYSTEM_QEMU_IMAGE_NAME, _SDK_REPO_SYSTEM_IMAGE_NAME)
+_KERNEL_IMAGE_NAMES = ("kernel-ranchu", "kernel-ranchu-64", "kernel")
+_RAMDISK_IMAGE_NAMES = ("ramdisk-qemu.img", "ramdisk.img")
+
+
+def _FindFileByNames(parent_dir, names):
+ """Find file under a directory by names.
+
+ Args:
+ parent_dir: The directory to find the file in.
+ names: A list of file names.
+
+ Returns:
+ The path to the first existing file in the list.
+
+ Raises:
+ errors.GetLocalImageError if none of the files exist.
+ """
+ for name in names:
+ path = os.path.join(parent_dir, name)
+ if os.path.isfile(path):
+ return path
+ raise errors.GetLocalImageError("No %s in %s." %
+ (", ".join(names), parent_dir))
+
+
+def _UnpackBootImage(output_dir, boot_image_path, ota):
+ """Unpack a boot image and find kernel images.
+
+ Args:
+ output_dir: The directory where the boot image is unpacked.
+ boot_image_path: The path to the boot image.
+ ota: An instance of ota_tools.OtaTools.
+
+ Returns:
+ The kernel image path and the ramdisk image path.
+
+ Raises:
+ errors.GetLocalImageError if the kernel or the ramdisk is not found.
+ """
+ ota.UnpackBootImg(output_dir, boot_image_path)
+
+ kernel_path = os.path.join(output_dir, _UNPACKED_KERNEL_IMAGE_NAME)
+ ramdisk_path = os.path.join(output_dir, _UNPACKED_RAMDISK_IMAGE_NAME)
+ if not os.path.isfile(kernel_path):
+ raise errors.GetLocalImageError("No kernel in %s." % boot_image_path)
+ if not os.path.isfile(ramdisk_path):
+ raise errors.GetLocalImageError("No ramdisk in %s." % boot_image_path)
+ return kernel_path, ramdisk_path
+
+
+def _MixRamdiskImages(output_path, original_ramdisk_path,
+ boot_ramdisk_path):
+ """Mix an emulator ramdisk with a boot ramdisk.
+
+ An emulator ramdisk consists of a boot ramdisk and a vendor ramdisk.
+ This method overlays a new boot ramdisk on the emulator ramdisk by
+ concatenating them.
+
+ Args:
+ output_path: The path to the output ramdisk.
+ original_ramdisk_path: The path to the emulator ramdisk.
+ boot_ramdisk_path: The path to the boot ramdisk.
+ """
+ with open(output_path, "wb") as mixed_ramdisk:
+ with open(original_ramdisk_path, "rb") as ramdisk:
+ shutil.copyfileobj(ramdisk, mixed_ramdisk)
+ with open(boot_ramdisk_path, "rb") as ramdisk:
+ shutil.copyfileobj(ramdisk, mixed_ramdisk)
+
+
+def MixWithBootImage(output_dir, image_dir, boot_image_path, ota):
+ """Mix emulator kernel images with a boot image.
+
+ Args:
+ output_dir: The directory containing the output and intermediate files.
+ image_dir: The directory containing emulator kernel and ramdisk images.
+ boot_image_path: The path to the boot image.
+ ota: An instance of ota_tools.OtaTools.
+
+ Returns:
+ The paths to the kernel and ramdisk images in output_dir.
+
+ Raises:
+ errors.GetLocalImageError if any image is not found.
+ """
+ unpack_dir = os.path.join(output_dir, _UNPACK_DIR_NAME)
+ if os.path.exists(unpack_dir):
+ shutil.rmtree(unpack_dir)
+ os.makedirs(unpack_dir, exist_ok=True)
+
+ kernel_path, boot_ramdisk_path = _UnpackBootImage(
+ unpack_dir, boot_image_path, ota)
+ # The ramdisk unpacked from boot_image_path does not include emulator's
+ # kernel modules. The ramdisk in image_dir contains the modules. This
+ # method mixes the two ramdisks.
+ mixed_ramdisk_path = os.path.join(output_dir, _MIXED_RAMDISK_IMAGE_NAME)
+ original_ramdisk_path = _FindFileByNames(image_dir, _RAMDISK_IMAGE_NAMES)
+ _MixRamdiskImages(mixed_ramdisk_path, original_ramdisk_path,
+ boot_ramdisk_path)
+ return kernel_path, mixed_ramdisk_path
+
+
+def FindKernelImages(image_dir):
+ """Find emulator kernel images in a directory.
+
+ Args:
+ image_dir: The directory to find the images in.
+
+ Returns:
+ The paths to the kernel image and the ramdisk image.
+
+ Raises:
+ errors.GetLocalImageError if any image is not found.
+ """
+ return (_FindFileByNames(image_dir, _KERNEL_IMAGE_NAMES),
+ _FindFileByNames(image_dir, _RAMDISK_IMAGE_NAMES))
+
+
+def FindDiskImage(image_dir):
+ """Find an emulator disk image in a directory.
+
+ Args:
+ image_dir: The directory to find the image in.
+
+ Returns:
+ The path to the disk image.
+
+ Raises:
+ errors.GetLocalImageError if the image is not found.
+ """
+ return _FindFileByNames(image_dir, _DISK_IMAGE_NAMES)
+
+
+def MixWithSystemImage(output_dir, image_dir, system_image_path, ota):
+ """Mix emulator images and a system image into a disk image.
+
+ Args:
+ output_dir: The path to the output directory.
+ image_dir: The input directory that provides images except
+ system.img.
+ system_image_path: The path to the system image.
+ ota: An instance of ota_tools.OtaTools.
+
+ Returns:
+ The path to the mixed disk image in output_dir.
+
+ Raises:
+ errors.GetLocalImageError if any required file is not found.
+ """
+ os.makedirs(output_dir, exist_ok=True)
+
+ # Create the super image.
+ mixed_super_image_path = os.path.join(output_dir, "mixed_super.img")
+ ota.BuildSuperImage(
+ mixed_super_image_path,
+ _FindFileByNames(image_dir, [_MISC_INFO_FILE_NAME]),
+ lambda partition: ota_tools.GetImageForPartition(
+ partition, image_dir, system=system_image_path))
+
+ # Create the vbmeta image.
+ vbmeta_image_path = os.path.join(output_dir, "disabled_vbmeta.img")
+ ota.MakeDisabledVbmetaImage(vbmeta_image_path)
+
+ # Create the disk image.
+ disk_image = os.path.join(output_dir, "mixed_disk.img")
+ ota.MkCombinedImg(
+ disk_image,
+ _FindFileByNames(image_dir, [_SYSTEM_QEMU_CONFIG_FILE_NAME]),
+ lambda partition: ota_tools.GetImageForPartition(
+ partition, image_dir, super=mixed_super_image_path,
+ vbmeta=vbmeta_image_path))
+ return disk_image
diff --git a/internal/lib/goldfish_image_test.py b/internal/lib/goldfish_image_test.py
new file mode 100644
index 0000000..2244d57
--- /dev/null
+++ b/internal/lib/goldfish_image_test.py
@@ -0,0 +1,151 @@
+#!/usr/bin/env python3
+#
+# Copyright 2021 - The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+"""Unit tests for goldfish_image."""
+
+import os
+import shutil
+import tempfile
+import unittest
+
+from unittest import mock
+
+from acloud import errors
+from acloud.internal.lib import goldfish_image
+
+
+class GoldfishImageTest(unittest.TestCase):
+ """Test functions in goldfish_image."""
+
+ @staticmethod
+ def _CreateEmptyFile(path):
+ os.makedirs(os.path.dirname(path), exist_ok=True)
+ with open(path, "w"):
+ pass
+
+ def setUp(self):
+ """Create the temporary directory."""
+ self._temp_dir = tempfile.mkdtemp("goldfish_image_test")
+
+ def tearDown(self):
+ """Delete the temporary directory."""
+ shutil.rmtree(self._temp_dir)
+
+ def testMixWithBootImage(self):
+ """Test MixWithBootImage."""
+ boot_image_path = os.path.join(self._temp_dir, "boot.img")
+ image_dir = os.path.join(self._temp_dir, "image_dir")
+ self._CreateEmptyFile(boot_image_path)
+ os.makedirs(image_dir)
+ with open(os.path.join(image_dir, "ramdisk-qemu.img"), "w") as ramdisk:
+ ramdisk.write("original")
+ mix_dir = os.path.join(self._temp_dir, "mix_kernel")
+ unpack_dir = os.path.join(mix_dir, "unpacked_boot_img")
+
+ def _MockUnpackBootImg(out_dir, boot_img):
+ self.assertEqual(unpack_dir, out_dir)
+ self.assertEqual(boot_image_path, boot_img)
+ self._CreateEmptyFile(os.path.join(out_dir, "kernel"))
+ with open(os.path.join(out_dir, "ramdisk"), "w") as ramdisk:
+ ramdisk.write("boot")
+
+ mock_ota = mock.Mock()
+ mock_ota.UnpackBootImg.side_effect = _MockUnpackBootImg
+
+ kernel_path, ramdisk_path = goldfish_image.MixWithBootImage(
+ mix_dir, image_dir, boot_image_path, mock_ota)
+
+ mock_ota.UnpackBootImg.assert_called_with(unpack_dir, boot_image_path)
+ self.assertEqual(os.path.join(unpack_dir, "kernel"), kernel_path)
+ self.assertEqual(os.path.join(mix_dir, "mixed_ramdisk"), ramdisk_path)
+ with open(ramdisk_path, "r") as ramdisk:
+ self.assertEqual("originalboot", ramdisk.read())
+
+ def testFindKernelImage(self):
+ """Test FindKernelImage."""
+ with self.assertRaises(errors.GetLocalImageError):
+ goldfish_image.FindKernelImages(self._temp_dir)
+
+ kernel_path = os.path.join(self._temp_dir, "kernel")
+ ramdisk_path = os.path.join(self._temp_dir, "ramdisk.img")
+ self._CreateEmptyFile(kernel_path)
+ self._CreateEmptyFile(ramdisk_path)
+ self.assertEqual((kernel_path, ramdisk_path),
+ goldfish_image.FindKernelImages(self._temp_dir))
+
+ kernel_path = os.path.join(self._temp_dir, "kernel-ranchu")
+ ramdisk_path = os.path.join(self._temp_dir, "ramdisk-qemu.img")
+ self._CreateEmptyFile(kernel_path)
+ self._CreateEmptyFile(ramdisk_path)
+ self.assertEqual((kernel_path, ramdisk_path),
+ goldfish_image.FindKernelImages(self._temp_dir))
+
+ def testFindDiskImage(self):
+ """Test FindDiskImage."""
+ with self.assertRaises(errors.GetLocalImageError):
+ goldfish_image.FindDiskImage(self._temp_dir)
+
+ disk_path = os.path.join(self._temp_dir, "system.img")
+ self._CreateEmptyFile(disk_path)
+ self.assertEqual(disk_path,
+ goldfish_image.FindDiskImage(self._temp_dir))
+
+ disk_path = os.path.join(self._temp_dir, "system-qemu.img")
+ self._CreateEmptyFile(disk_path)
+ self.assertEqual(disk_path,
+ goldfish_image.FindDiskImage(self._temp_dir))
+
+ def testMixWithSystemImage(self):
+ """Test MixWithSystemImage."""
+ mock_ota = mock.Mock()
+ mix_dir = os.path.join(self._temp_dir, "mix_disk")
+ image_dir = os.path.join(self._temp_dir, "image_dir")
+ misc_info_path = os.path.join(image_dir, "misc_info.txt")
+ qemu_config_path = os.path.join(image_dir, "system-qemu-config.txt")
+ system_image_path = os.path.join(self._temp_dir, "system.img")
+ vendor_image_path = os.path.join(image_dir, "vendor.img")
+ vbmeta_image_path = os.path.join(mix_dir, "disabled_vbmeta.img")
+ super_image_path = os.path.join(mix_dir, "mixed_super.img")
+ self._CreateEmptyFile(misc_info_path)
+ self._CreateEmptyFile(qemu_config_path)
+
+ disk_image = goldfish_image.MixWithSystemImage(
+ mix_dir, image_dir, system_image_path, mock_ota)
+
+ self.assertTrue(os.path.isdir(mix_dir))
+ self.assertEqual(os.path.join(mix_dir, "mixed_disk.img"), disk_image)
+
+ mock_ota.BuildSuperImage.assert_called_with(
+ os.path.join(mix_dir, "mixed_super.img"), misc_info_path, mock.ANY)
+ get_image = mock_ota.BuildSuperImage.call_args[0][2]
+ self._CreateEmptyFile(vendor_image_path)
+ self._CreateEmptyFile(system_image_path)
+ self.assertEqual(system_image_path, get_image("system"))
+ self.assertEqual(vendor_image_path, get_image("vendor"))
+
+ mock_ota.MakeDisabledVbmetaImage.assert_called_with(vbmeta_image_path)
+
+ mock_ota.MkCombinedImg.assert_called_with(
+ disk_image, qemu_config_path, mock.ANY)
+ get_image = mock_ota.MkCombinedImg.call_args[0][2]
+ self._CreateEmptyFile(vbmeta_image_path)
+ self._CreateEmptyFile(super_image_path)
+ self.assertEqual(vbmeta_image_path, get_image("vbmeta"))
+ self.assertEqual(super_image_path, get_image("super"))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/internal/lib/ota_tools.py b/internal/lib/ota_tools.py
index 45f1365..b4f347e 100644
--- a/internal/lib/ota_tools.py
+++ b/internal/lib/ota_tools.py
@@ -22,7 +22,6 @@
from acloud import errors
-from acloud.internal import constants
from acloud.internal.lib import utils
logger = logging.getLogger(__name__)
@@ -47,7 +46,7 @@
def FindOtaToolsDir(search_paths):
- """Find OTA tools directory in the search paths and in build environment.
+ """Find OTA tools directory in the search paths.
Args:
search_paths: List of paths, the directories to search for OTA tools.
@@ -62,20 +61,12 @@
if os.path.isfile(os.path.join(search_path, _BIN_DIR_NAME,
_BUILD_SUPER_IMAGE)):
return search_path
- for env_host_out in [constants.ENV_ANDROID_SOONG_HOST_OUT,
- constants.ENV_ANDROID_HOST_OUT]:
- host_out_dir = os.environ.get(env_host_out)
- if (host_out_dir and
- os.path.isfile(os.path.join(host_out_dir, _BIN_DIR_NAME,
- _BUILD_SUPER_IMAGE))):
- return host_out_dir
-
raise errors.CheckPathError(_MISSING_OTA_TOOLS_MSG %
{"tool_name": "OTA tool directory"})
def FindOtaTools(search_paths):
- """Find OTA tools in the search paths and in build environment.
+ """Find OTA tools in the search paths.
Args:
search_paths: List of paths, the directories to search for OTA tools.
diff --git a/internal/lib/ota_tools_test.py b/internal/lib/ota_tools_test.py
index 6f72170..7a2a024 100644
--- a/internal/lib/ota_tools_test.py
+++ b/internal/lib/ota_tools_test.py
@@ -126,27 +126,16 @@
"""Test FindOtaToolsDir and FindOtaTools."""
# CVD host package contains lpmake but not all tools.
self._CreateBinary("lpmake")
- with mock.patch.dict("acloud.internal.lib.ota_tools.os.environ",
- {"ANDROID_HOST_OUT": self._temp_dir,
- "ANDROID_SOONG_HOST_OUT": self._temp_dir},
- clear=True):
- with self.assertRaises(errors.CheckPathError):
- ota_tools.FindOtaToolsDir([self._temp_dir])
+ with self.assertRaises(errors.CheckPathError):
+ ota_tools.FindOtaToolsDir([self._temp_dir])
# The function identifies OTA tool directory by build_super_image.
self._CreateBinary("build_super_image")
- with mock.patch.dict("acloud.internal.lib.ota_tools.os.environ",
- dict(), clear=True):
- self.assertEqual(ota_tools.FindOtaToolsDir([self._temp_dir]),
- self._temp_dir)
-
- # ANDROID_HOST_OUT contains OTA tools in build environment.
- with mock.patch.dict("acloud.internal.lib.ota_tools.os.environ",
- {"ANDROID_HOST_OUT": self._temp_dir,
- "ANDROID_SOONG_HOST_OUT": self._temp_dir},
- clear=True):
- self.assertEqual(ota_tools.FindOtaTools([])._ota_tools_dir,
- self._temp_dir)
+ self.assertEqual(ota_tools.FindOtaToolsDir([self._temp_dir]),
+ self._temp_dir)
+ self.assertEqual(
+ ota_tools.FindOtaTools([self._temp_dir])._ota_tools_dir,
+ self._temp_dir)
def testGetImageForPartition(self):
"""Test GetImageForPartition."""