xref: /aosp_15_r20/tools/acloud/internal/lib/goldfish_utils_test.py (revision 800a58d989c669b8eb8a71d8df53b1ba3d411444)
1*800a58d9SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*800a58d9SAndroid Build Coastguard Worker#
3*800a58d9SAndroid Build Coastguard Worker# Copyright 2021 - The Android Open Source Project
4*800a58d9SAndroid Build Coastguard Worker#
5*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*800a58d9SAndroid Build Coastguard Worker#
9*800a58d9SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*800a58d9SAndroid Build Coastguard Worker#
11*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*800a58d9SAndroid Build Coastguard Worker# limitations under the License.
16*800a58d9SAndroid Build Coastguard Worker
17*800a58d9SAndroid Build Coastguard Worker"""Unit tests for goldfish_utils."""
18*800a58d9SAndroid Build Coastguard Worker
19*800a58d9SAndroid Build Coastguard Workerimport os
20*800a58d9SAndroid Build Coastguard Workerimport shutil
21*800a58d9SAndroid Build Coastguard Workerimport tempfile
22*800a58d9SAndroid Build Coastguard Workerimport unittest
23*800a58d9SAndroid Build Coastguard Worker
24*800a58d9SAndroid Build Coastguard Workerfrom unittest import mock
25*800a58d9SAndroid Build Coastguard Worker
26*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors
27*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import goldfish_utils
28*800a58d9SAndroid Build Coastguard Worker
29*800a58d9SAndroid Build Coastguard Worker
30*800a58d9SAndroid Build Coastguard Workerclass GoldfishUtilsTest(unittest.TestCase):
31*800a58d9SAndroid Build Coastguard Worker    """Test functions in goldfish_utils."""
32*800a58d9SAndroid Build Coastguard Worker
33*800a58d9SAndroid Build Coastguard Worker    # Remote host instance name.
34*800a58d9SAndroid Build Coastguard Worker    _IP_ADDRESS = "192.0.2.1"
35*800a58d9SAndroid Build Coastguard Worker    _DOMAIN_NAME = "host.NAME-1234"
36*800a58d9SAndroid Build Coastguard Worker    _CONSOLE_PORT = 5554
37*800a58d9SAndroid Build Coastguard Worker    _BUILD_INFO = {"build_id": "123456",
38*800a58d9SAndroid Build Coastguard Worker                   "build_target": "sdk_phone_x86_64-userdebug"}
39*800a58d9SAndroid Build Coastguard Worker    _INSTANCE_NAME_WITH_IP = ("host-goldfish-192.0.2.1-5554-"
40*800a58d9SAndroid Build Coastguard Worker                              "123456-sdk_phone_x86_64-userdebug")
41*800a58d9SAndroid Build Coastguard Worker    _INSTANCE_NAME_WITH_DOMAIN = ("host-goldfish-host.NAME_1234-5554-"
42*800a58d9SAndroid Build Coastguard Worker                                  "123456-sdk_phone_x86_64-userdebug")
43*800a58d9SAndroid Build Coastguard Worker    _INSTANCE_NAME_WITHOUT_INFO = "host-goldfish-192.0.2.1-5554-userbuild"
44*800a58d9SAndroid Build Coastguard Worker    _INVALID_NAME = "host-192.0.2.1-123456-aosp_cf_x86_phone-userdebug"
45*800a58d9SAndroid Build Coastguard Worker
46*800a58d9SAndroid Build Coastguard Worker    @staticmethod
47*800a58d9SAndroid Build Coastguard Worker    def _CreateEmptyFile(path):
48*800a58d9SAndroid Build Coastguard Worker        os.makedirs(os.path.dirname(path), exist_ok=True)
49*800a58d9SAndroid Build Coastguard Worker        with open(path, "w"):
50*800a58d9SAndroid Build Coastguard Worker            pass
51*800a58d9SAndroid Build Coastguard Worker
52*800a58d9SAndroid Build Coastguard Worker    def setUp(self):
53*800a58d9SAndroid Build Coastguard Worker        """Create the temporary directory."""
54*800a58d9SAndroid Build Coastguard Worker        self._temp_dir = tempfile.mkdtemp("goldfish_utils_test")
55*800a58d9SAndroid Build Coastguard Worker
56*800a58d9SAndroid Build Coastguard Worker    def tearDown(self):
57*800a58d9SAndroid Build Coastguard Worker        """Delete the temporary directory."""
58*800a58d9SAndroid Build Coastguard Worker        shutil.rmtree(self._temp_dir)
59*800a58d9SAndroid Build Coastguard Worker
60*800a58d9SAndroid Build Coastguard Worker    def testMixWithBootImage(self):
61*800a58d9SAndroid Build Coastguard Worker        """Test MixWithBootImage."""
62*800a58d9SAndroid Build Coastguard Worker        boot_image_path = os.path.join(self._temp_dir, "boot.img")
63*800a58d9SAndroid Build Coastguard Worker        image_dir = os.path.join(self._temp_dir, "image_dir")
64*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(boot_image_path)
65*800a58d9SAndroid Build Coastguard Worker        os.makedirs(image_dir)
66*800a58d9SAndroid Build Coastguard Worker        with open(os.path.join(image_dir, "ramdisk-qemu.img"), "w") as ramdisk:
67*800a58d9SAndroid Build Coastguard Worker            ramdisk.write("original")
68*800a58d9SAndroid Build Coastguard Worker        mix_dir = os.path.join(self._temp_dir, "mix_kernel")
69*800a58d9SAndroid Build Coastguard Worker        unpack_dir = os.path.join(mix_dir, "unpacked_boot_img")
70*800a58d9SAndroid Build Coastguard Worker
71*800a58d9SAndroid Build Coastguard Worker        def _MockUnpackBootImg(out_dir, boot_img):
72*800a58d9SAndroid Build Coastguard Worker            self.assertEqual(unpack_dir, out_dir)
73*800a58d9SAndroid Build Coastguard Worker            self.assertEqual(boot_image_path, boot_img)
74*800a58d9SAndroid Build Coastguard Worker            self._CreateEmptyFile(os.path.join(out_dir, "kernel"))
75*800a58d9SAndroid Build Coastguard Worker            with open(os.path.join(out_dir, "ramdisk"), "w") as ramdisk:
76*800a58d9SAndroid Build Coastguard Worker                ramdisk.write("boot")
77*800a58d9SAndroid Build Coastguard Worker
78*800a58d9SAndroid Build Coastguard Worker        mock_ota = mock.Mock()
79*800a58d9SAndroid Build Coastguard Worker        mock_ota.UnpackBootImg.side_effect = _MockUnpackBootImg
80*800a58d9SAndroid Build Coastguard Worker
81*800a58d9SAndroid Build Coastguard Worker        kernel_path, ramdisk_path = goldfish_utils.MixWithBootImage(
82*800a58d9SAndroid Build Coastguard Worker            mix_dir, image_dir, boot_image_path, mock_ota)
83*800a58d9SAndroid Build Coastguard Worker
84*800a58d9SAndroid Build Coastguard Worker        mock_ota.UnpackBootImg.assert_called_with(unpack_dir, boot_image_path)
85*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(os.path.join(unpack_dir, "kernel"), kernel_path)
86*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(os.path.join(mix_dir, "mixed_ramdisk"), ramdisk_path)
87*800a58d9SAndroid Build Coastguard Worker        with open(ramdisk_path, "r") as ramdisk:
88*800a58d9SAndroid Build Coastguard Worker            self.assertEqual("originalboot", ramdisk.read())
89*800a58d9SAndroid Build Coastguard Worker
90*800a58d9SAndroid Build Coastguard Worker    def testFindKernelImage(self):
91*800a58d9SAndroid Build Coastguard Worker        """Test FindKernelImage."""
92*800a58d9SAndroid Build Coastguard Worker        with self.assertRaises(errors.GetLocalImageError):
93*800a58d9SAndroid Build Coastguard Worker            goldfish_utils.FindKernelImages(self._temp_dir)
94*800a58d9SAndroid Build Coastguard Worker
95*800a58d9SAndroid Build Coastguard Worker        kernel_path = os.path.join(self._temp_dir, "kernel")
96*800a58d9SAndroid Build Coastguard Worker        ramdisk_path = os.path.join(self._temp_dir, "ramdisk.img")
97*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(kernel_path)
98*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(ramdisk_path)
99*800a58d9SAndroid Build Coastguard Worker        self.assertEqual((kernel_path, ramdisk_path),
100*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.FindKernelImages(self._temp_dir))
101*800a58d9SAndroid Build Coastguard Worker
102*800a58d9SAndroid Build Coastguard Worker        kernel_path = os.path.join(self._temp_dir, "kernel-ranchu")
103*800a58d9SAndroid Build Coastguard Worker        ramdisk_path = os.path.join(self._temp_dir, "ramdisk-qemu.img")
104*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(kernel_path)
105*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(ramdisk_path)
106*800a58d9SAndroid Build Coastguard Worker        self.assertEqual((kernel_path, ramdisk_path),
107*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.FindKernelImages(self._temp_dir))
108*800a58d9SAndroid Build Coastguard Worker
109*800a58d9SAndroid Build Coastguard Worker    def testFindSystemDlkmImage(self):
110*800a58d9SAndroid Build Coastguard Worker        """Test FindSystemDlkmImage."""
111*800a58d9SAndroid Build Coastguard Worker        system_dlkm_image_path = os.path.join(self._temp_dir, "test.img")
112*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(system_dlkm_image_path)
113*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(
114*800a58d9SAndroid Build Coastguard Worker            system_dlkm_image_path,
115*800a58d9SAndroid Build Coastguard Worker            goldfish_utils.FindSystemDlkmImage(system_dlkm_image_path))
116*800a58d9SAndroid Build Coastguard Worker
117*800a58d9SAndroid Build Coastguard Worker        with self.assertRaises(errors.GetLocalImageError):
118*800a58d9SAndroid Build Coastguard Worker            goldfish_utils.FindSystemDlkmImage(self._temp_dir)
119*800a58d9SAndroid Build Coastguard Worker
120*800a58d9SAndroid Build Coastguard Worker        system_dlkm_image_path = os.path.join(self._temp_dir,
121*800a58d9SAndroid Build Coastguard Worker                                              "system_dlkm.img")
122*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(system_dlkm_image_path)
123*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(system_dlkm_image_path,
124*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.FindSystemDlkmImage(self._temp_dir))
125*800a58d9SAndroid Build Coastguard Worker
126*800a58d9SAndroid Build Coastguard Worker        system_dlkm_image_path = os.path.join(self._temp_dir,
127*800a58d9SAndroid Build Coastguard Worker                                              "system_dlkm.flatten.ext4.img")
128*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(system_dlkm_image_path)
129*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(system_dlkm_image_path,
130*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.FindSystemDlkmImage(self._temp_dir))
131*800a58d9SAndroid Build Coastguard Worker
132*800a58d9SAndroid Build Coastguard Worker    def testFindDiskImage(self):
133*800a58d9SAndroid Build Coastguard Worker        """Test FindDiskImage."""
134*800a58d9SAndroid Build Coastguard Worker        with self.assertRaises(errors.GetLocalImageError):
135*800a58d9SAndroid Build Coastguard Worker            goldfish_utils.FindDiskImage(self._temp_dir)
136*800a58d9SAndroid Build Coastguard Worker
137*800a58d9SAndroid Build Coastguard Worker        disk_path = os.path.join(self._temp_dir, "system.img")
138*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(disk_path)
139*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(disk_path,
140*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.FindDiskImage(self._temp_dir))
141*800a58d9SAndroid Build Coastguard Worker
142*800a58d9SAndroid Build Coastguard Worker        disk_path = os.path.join(self._temp_dir, "system-qemu.img")
143*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(disk_path)
144*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(disk_path,
145*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.FindDiskImage(self._temp_dir))
146*800a58d9SAndroid Build Coastguard Worker
147*800a58d9SAndroid Build Coastguard Worker    def testMixDiskImage(self):
148*800a58d9SAndroid Build Coastguard Worker        """Test MixDiskImage."""
149*800a58d9SAndroid Build Coastguard Worker        mock_ota = mock.Mock()
150*800a58d9SAndroid Build Coastguard Worker        mix_dir = os.path.join(self._temp_dir, "mix_disk")
151*800a58d9SAndroid Build Coastguard Worker        image_dir = os.path.join(self._temp_dir, "image_dir")
152*800a58d9SAndroid Build Coastguard Worker        misc_info_path = os.path.join(image_dir, "misc_info.txt")
153*800a58d9SAndroid Build Coastguard Worker        qemu_config_path = os.path.join(image_dir, "system-qemu-config.txt")
154*800a58d9SAndroid Build Coastguard Worker        system_image_path = os.path.join(self._temp_dir, "system.img")
155*800a58d9SAndroid Build Coastguard Worker        system_dlkm_image_path = os.path.join(self._temp_dir,
156*800a58d9SAndroid Build Coastguard Worker                                              "system_dlkm.img")
157*800a58d9SAndroid Build Coastguard Worker        vendor_image_path = os.path.join(image_dir, "vendor.img")
158*800a58d9SAndroid Build Coastguard Worker        vbmeta_image_path = os.path.join(mix_dir, "disabled_vbmeta.img")
159*800a58d9SAndroid Build Coastguard Worker        super_image_path = os.path.join(mix_dir, "mixed_super.img")
160*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(misc_info_path)
161*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(qemu_config_path)
162*800a58d9SAndroid Build Coastguard Worker
163*800a58d9SAndroid Build Coastguard Worker        disk_image = goldfish_utils.MixDiskImage(
164*800a58d9SAndroid Build Coastguard Worker            mix_dir, image_dir, system_image_path, system_dlkm_image_path,
165*800a58d9SAndroid Build Coastguard Worker            mock_ota)
166*800a58d9SAndroid Build Coastguard Worker
167*800a58d9SAndroid Build Coastguard Worker        self.assertTrue(os.path.isdir(mix_dir))
168*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(os.path.join(mix_dir, "mixed_disk.img"), disk_image)
169*800a58d9SAndroid Build Coastguard Worker
170*800a58d9SAndroid Build Coastguard Worker        mock_ota.BuildSuperImage.assert_called_with(
171*800a58d9SAndroid Build Coastguard Worker            os.path.join(mix_dir, "mixed_super.img"), misc_info_path, mock.ANY)
172*800a58d9SAndroid Build Coastguard Worker        get_image = mock_ota.BuildSuperImage.call_args[0][2]
173*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(vendor_image_path)
174*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(system_image_path)
175*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(system_dlkm_image_path)
176*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(system_image_path, get_image("system"))
177*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(system_dlkm_image_path, get_image("system_dlkm"))
178*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(vendor_image_path, get_image("vendor"))
179*800a58d9SAndroid Build Coastguard Worker
180*800a58d9SAndroid Build Coastguard Worker        mock_ota.MakeDisabledVbmetaImage.assert_called_with(vbmeta_image_path)
181*800a58d9SAndroid Build Coastguard Worker
182*800a58d9SAndroid Build Coastguard Worker        mock_ota.MkCombinedImg.assert_called_with(
183*800a58d9SAndroid Build Coastguard Worker            disk_image, qemu_config_path, mock.ANY)
184*800a58d9SAndroid Build Coastguard Worker        get_image = mock_ota.MkCombinedImg.call_args[0][2]
185*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(vbmeta_image_path)
186*800a58d9SAndroid Build Coastguard Worker        self._CreateEmptyFile(super_image_path)
187*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(vbmeta_image_path, get_image("vbmeta"))
188*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(super_image_path, get_image("super"))
189*800a58d9SAndroid Build Coastguard Worker
190*800a58d9SAndroid Build Coastguard Worker    def testParseRemoteHostConsoleAddress(self):
191*800a58d9SAndroid Build Coastguard Worker        """Test ParseRemoteHostConsoleAddress."""
192*800a58d9SAndroid Build Coastguard Worker        console_addr = goldfish_utils.ParseRemoteHostConsoleAddress(
193*800a58d9SAndroid Build Coastguard Worker            self._INSTANCE_NAME_WITH_IP)
194*800a58d9SAndroid Build Coastguard Worker        self.assertEqual((self._IP_ADDRESS, self._CONSOLE_PORT), console_addr)
195*800a58d9SAndroid Build Coastguard Worker
196*800a58d9SAndroid Build Coastguard Worker        console_addr = goldfish_utils.ParseRemoteHostConsoleAddress(
197*800a58d9SAndroid Build Coastguard Worker            self._INSTANCE_NAME_WITH_DOMAIN)
198*800a58d9SAndroid Build Coastguard Worker        self.assertEqual((self._DOMAIN_NAME, self._CONSOLE_PORT), console_addr)
199*800a58d9SAndroid Build Coastguard Worker
200*800a58d9SAndroid Build Coastguard Worker        console_addr = goldfish_utils.ParseRemoteHostConsoleAddress(
201*800a58d9SAndroid Build Coastguard Worker            self._INVALID_NAME)
202*800a58d9SAndroid Build Coastguard Worker        self.assertIsNone(console_addr)
203*800a58d9SAndroid Build Coastguard Worker
204*800a58d9SAndroid Build Coastguard Worker    def testFormatInstanceName(self):
205*800a58d9SAndroid Build Coastguard Worker        """Test FormatRemoteHostInstanceName."""
206*800a58d9SAndroid Build Coastguard Worker        instance_name = goldfish_utils.FormatRemoteHostInstanceName(
207*800a58d9SAndroid Build Coastguard Worker            self._IP_ADDRESS, self._CONSOLE_PORT, self._BUILD_INFO)
208*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(self._INSTANCE_NAME_WITH_IP, instance_name)
209*800a58d9SAndroid Build Coastguard Worker
210*800a58d9SAndroid Build Coastguard Worker        instance_name = goldfish_utils.FormatRemoteHostInstanceName(
211*800a58d9SAndroid Build Coastguard Worker            self._DOMAIN_NAME, self._CONSOLE_PORT, self._BUILD_INFO)
212*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(self._INSTANCE_NAME_WITH_DOMAIN, instance_name)
213*800a58d9SAndroid Build Coastguard Worker
214*800a58d9SAndroid Build Coastguard Worker        instance_name = goldfish_utils.FormatRemoteHostInstanceName(
215*800a58d9SAndroid Build Coastguard Worker            self._IP_ADDRESS, self._CONSOLE_PORT, {})
216*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(self._INSTANCE_NAME_WITHOUT_INFO, instance_name)
217*800a58d9SAndroid Build Coastguard Worker
218*800a58d9SAndroid Build Coastguard Worker    def testConvertAvdSpecToArgs(self):
219*800a58d9SAndroid Build Coastguard Worker        """Test ConvertAvdSpecToArgs."""
220*800a58d9SAndroid Build Coastguard Worker        hw_property = {
221*800a58d9SAndroid Build Coastguard Worker            "cpu": "2",
222*800a58d9SAndroid Build Coastguard Worker            "x_res": "1270",
223*800a58d9SAndroid Build Coastguard Worker            "y_res": "700",
224*800a58d9SAndroid Build Coastguard Worker            "memory": "2048",
225*800a58d9SAndroid Build Coastguard Worker            "disk": "4096"
226*800a58d9SAndroid Build Coastguard Worker        }
227*800a58d9SAndroid Build Coastguard Worker        mock_spec = mock.Mock(hw_customize=True, gpu='off',
228*800a58d9SAndroid Build Coastguard Worker                              hw_property=hw_property)
229*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(["-gpu", "off", "-cores", "2", "-skin", "1270x700",
230*800a58d9SAndroid Build Coastguard Worker                          "-memory", "2048", "-partition-size", "4096"],
231*800a58d9SAndroid Build Coastguard Worker                         goldfish_utils.ConvertAvdSpecToArgs(mock_spec))
232*800a58d9SAndroid Build Coastguard Worker
233*800a58d9SAndroid Build Coastguard Worker        mock_spec = mock.Mock(hw_customize=True, gpu=None, hw_property={})
234*800a58d9SAndroid Build Coastguard Worker        self.assertEqual([], goldfish_utils.ConvertAvdSpecToArgs(mock_spec))
235*800a58d9SAndroid Build Coastguard Worker
236*800a58d9SAndroid Build Coastguard Worker
237*800a58d9SAndroid Build Coastguard Workerif __name__ == "__main__":
238*800a58d9SAndroid Build Coastguard Worker    unittest.main()
239