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