1*800a58d9SAndroid Build Coastguard Worker# Copyright 2022 - The Android Open Source Project 2*800a58d9SAndroid Build Coastguard Worker# 3*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 4*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 5*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at 6*800a58d9SAndroid Build Coastguard Worker# 7*800a58d9SAndroid Build Coastguard Worker# http://www.apache.org/licenses/LICENSE-2.0 8*800a58d9SAndroid Build Coastguard Worker# 9*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software 10*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS, 11*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and 13*800a58d9SAndroid Build Coastguard Worker# limitations under the License. 14*800a58d9SAndroid Build Coastguard Worker 15*800a58d9SAndroid Build Coastguard Worker"""Tests for cvd_utils.""" 16*800a58d9SAndroid Build Coastguard Worker 17*800a58d9SAndroid Build Coastguard Workerimport os 18*800a58d9SAndroid Build Coastguard Workerimport subprocess 19*800a58d9SAndroid Build Coastguard Workerimport tempfile 20*800a58d9SAndroid Build Coastguard Workerimport unittest 21*800a58d9SAndroid Build Coastguard Workerfrom unittest import mock 22*800a58d9SAndroid Build Coastguard Workerimport zipfile 23*800a58d9SAndroid Build Coastguard Worker 24*800a58d9SAndroid Build Coastguard Workerfrom acloud import errors 25*800a58d9SAndroid Build Coastguard Workerfrom acloud.create import create_common 26*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants 27*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import cvd_utils 28*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import driver_test_lib 29*800a58d9SAndroid Build Coastguard Worker 30*800a58d9SAndroid Build Coastguard Worker 31*800a58d9SAndroid Build Coastguard Worker# pylint: disable=too-many-public-methods 32*800a58d9SAndroid Build Coastguard Workerclass CvdUtilsTest(driver_test_lib.BaseDriverTest): 33*800a58d9SAndroid Build Coastguard Worker """Test the functions in cvd_utils.""" 34*800a58d9SAndroid Build Coastguard Worker 35*800a58d9SAndroid Build Coastguard Worker # Remote host instance name. 36*800a58d9SAndroid Build Coastguard Worker _PRODUCT_NAME = "aosp_cf_x86_64_phone" 37*800a58d9SAndroid Build Coastguard Worker _BUILD_ID = "2263051" 38*800a58d9SAndroid Build Coastguard Worker _REMOTE_HOSTNAME_1 = "192.0.2.1" 39*800a58d9SAndroid Build Coastguard Worker _REMOTE_HOSTNAME_2 = "host.NAME-1234" 40*800a58d9SAndroid Build Coastguard Worker _REMOTE_HOST_INSTANCE_NAME_1 = ( 41*800a58d9SAndroid Build Coastguard Worker "host-192.0.2.1-1-2263051-aosp_cf_x86_64_phone") 42*800a58d9SAndroid Build Coastguard Worker _REMOTE_HOST_INSTANCE_NAME_2 = ( 43*800a58d9SAndroid Build Coastguard Worker "host-host.NAME_1234-2-2263051-aosp_cf_x86_64_phone") 44*800a58d9SAndroid Build Coastguard Worker 45*800a58d9SAndroid Build Coastguard Worker def testGetAdbPorts(self): 46*800a58d9SAndroid Build Coastguard Worker """Test GetAdbPorts.""" 47*800a58d9SAndroid Build Coastguard Worker self.assertEqual([6520], cvd_utils.GetAdbPorts(None, None)) 48*800a58d9SAndroid Build Coastguard Worker self.assertEqual([6520], cvd_utils.GetAdbPorts(1, 1)) 49*800a58d9SAndroid Build Coastguard Worker self.assertEqual([6521, 6522], cvd_utils.GetAdbPorts(2, 2)) 50*800a58d9SAndroid Build Coastguard Worker 51*800a58d9SAndroid Build Coastguard Worker def testGetVncPorts(self): 52*800a58d9SAndroid Build Coastguard Worker """Test GetVncPorts.""" 53*800a58d9SAndroid Build Coastguard Worker self.assertEqual([6444], cvd_utils.GetVncPorts(None, None)) 54*800a58d9SAndroid Build Coastguard Worker self.assertEqual([6444], cvd_utils.GetVncPorts(1, 1)) 55*800a58d9SAndroid Build Coastguard Worker self.assertEqual([6445, 6446], cvd_utils.GetVncPorts(2, 2)) 56*800a58d9SAndroid Build Coastguard Worker 57*800a58d9SAndroid Build Coastguard Worker def testExtractTargetFilesZip(self): 58*800a58d9SAndroid Build Coastguard Worker """Test ExtractTargetFilesZip.""" 59*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory() as temp_dir: 60*800a58d9SAndroid Build Coastguard Worker zip_path = os.path.join(temp_dir, "in.zip") 61*800a58d9SAndroid Build Coastguard Worker output_dir = os.path.join(temp_dir, "out") 62*800a58d9SAndroid Build Coastguard Worker with zipfile.ZipFile(zip_path, "w") as zip_file: 63*800a58d9SAndroid Build Coastguard Worker for entry in ["IMAGES/", "META/", "test.img", 64*800a58d9SAndroid Build Coastguard Worker "IMAGES/system.img", "IMAGES/system.map", 65*800a58d9SAndroid Build Coastguard Worker "IMAGES/bootloader", "IMAGES/kernel", 66*800a58d9SAndroid Build Coastguard Worker "META/misc_info.txt"]: 67*800a58d9SAndroid Build Coastguard Worker zip_file.writestr(entry, "") 68*800a58d9SAndroid Build Coastguard Worker cvd_utils.ExtractTargetFilesZip(zip_path, output_dir) 69*800a58d9SAndroid Build Coastguard Worker 70*800a58d9SAndroid Build Coastguard Worker self.assertEqual(["IMAGES", "META"], 71*800a58d9SAndroid Build Coastguard Worker sorted(os.listdir(output_dir))) 72*800a58d9SAndroid Build Coastguard Worker self.assertEqual( 73*800a58d9SAndroid Build Coastguard Worker ["bootloader", "kernel", "system.img"], 74*800a58d9SAndroid Build Coastguard Worker sorted(os.listdir(os.path.join(output_dir, "IMAGES")))) 75*800a58d9SAndroid Build Coastguard Worker self.assertEqual(["misc_info.txt"], 76*800a58d9SAndroid Build Coastguard Worker os.listdir(os.path.join(output_dir, "META"))) 77*800a58d9SAndroid Build Coastguard Worker 78*800a58d9SAndroid Build Coastguard Worker @staticmethod 79*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.os.path.isdir", 80*800a58d9SAndroid Build Coastguard Worker return_value=False) 81*800a58d9SAndroid Build Coastguard Worker def testUploadImageZip(_mock_isdir): 82*800a58d9SAndroid Build Coastguard Worker """Test UploadArtifacts with image zip.""" 83*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 84*800a58d9SAndroid Build Coastguard Worker cvd_utils.UploadArtifacts(mock_ssh, "dir", "/mock/img.zip", 85*800a58d9SAndroid Build Coastguard Worker "/mock/cvd.tar.gz") 86*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_any_call("/usr/bin/install_zip.sh dir < " 87*800a58d9SAndroid Build Coastguard Worker "/mock/img.zip") 88*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_any_call("tar -xzf - -C dir < /mock/cvd.tar.gz") 89*800a58d9SAndroid Build Coastguard Worker 90*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.glob") 91*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.os.path.isdir") 92*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.ssh.ShellCmdWithRetry") 93*800a58d9SAndroid Build Coastguard Worker def testUploadImageDir(self, mock_shell, mock_isdir, mock_glob): 94*800a58d9SAndroid Build Coastguard Worker """Test UploadArtifacts with image directory.""" 95*800a58d9SAndroid Build Coastguard Worker mock_isdir.side_effect = lambda path: path != "/mock/cvd.tar.gz" 96*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 97*800a58d9SAndroid Build Coastguard Worker mock_ssh.GetBaseCmd.return_value = "/mock/ssh" 98*800a58d9SAndroid Build Coastguard Worker expected_image_shell_cmd = ("tar -cf - --lzop -S -C local/dir " 99*800a58d9SAndroid Build Coastguard Worker "super.img bootloader kernel android-info.txt | " 100*800a58d9SAndroid Build Coastguard Worker "/mock/ssh -- " 101*800a58d9SAndroid Build Coastguard Worker "tar -xf - --lzop -S -C remote/dir") 102*800a58d9SAndroid Build Coastguard Worker expected_target_files_shell_cmd = expected_image_shell_cmd.replace( 103*800a58d9SAndroid Build Coastguard Worker "local/dir", "local/dir/IMAGES") 104*800a58d9SAndroid Build Coastguard Worker expected_cvd_tar_ssh_cmd = "tar -xzf - -C remote/dir < /mock/cvd.tar.gz" 105*800a58d9SAndroid Build Coastguard Worker expected_cvd_dir_shell_cmd = ("tar -cf - --lzop -S -C /mock/cvd . | " 106*800a58d9SAndroid Build Coastguard Worker "/mock/ssh -- " 107*800a58d9SAndroid Build Coastguard Worker "tar -xf - --lzop -S -C remote/dir") 108*800a58d9SAndroid Build Coastguard Worker 109*800a58d9SAndroid Build Coastguard Worker # Test with cvd directory. 110*800a58d9SAndroid Build Coastguard Worker mock_open = mock.mock_open(read_data="super.img\nbootloader\nkernel") 111*800a58d9SAndroid Build Coastguard Worker with mock.patch("acloud.internal.lib.cvd_utils.open", mock_open): 112*800a58d9SAndroid Build Coastguard Worker cvd_utils.UploadArtifacts(mock_ssh, "remote/dir","local/dir", 113*800a58d9SAndroid Build Coastguard Worker "/mock/cvd") 114*800a58d9SAndroid Build Coastguard Worker mock_open.assert_called_with("local/dir/required_images", "r", 115*800a58d9SAndroid Build Coastguard Worker encoding="utf-8") 116*800a58d9SAndroid Build Coastguard Worker mock_glob.glob.assert_called_once_with("local/dir/*.img") 117*800a58d9SAndroid Build Coastguard Worker mock_shell.assert_has_calls([mock.call(expected_image_shell_cmd), 118*800a58d9SAndroid Build Coastguard Worker mock.call(expected_cvd_dir_shell_cmd)]) 119*800a58d9SAndroid Build Coastguard Worker 120*800a58d9SAndroid Build Coastguard Worker # Test with required_images file. 121*800a58d9SAndroid Build Coastguard Worker mock_glob.glob.reset_mock() 122*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 123*800a58d9SAndroid Build Coastguard Worker mock_shell.reset_mock() 124*800a58d9SAndroid Build Coastguard Worker mock_open = mock.mock_open(read_data="super.img\nbootloader\nkernel") 125*800a58d9SAndroid Build Coastguard Worker with mock.patch("acloud.internal.lib.cvd_utils.open", mock_open): 126*800a58d9SAndroid Build Coastguard Worker cvd_utils.UploadArtifacts(mock_ssh, "remote/dir","local/dir", 127*800a58d9SAndroid Build Coastguard Worker "/mock/cvd.tar.gz") 128*800a58d9SAndroid Build Coastguard Worker mock_open.assert_called_with("local/dir/required_images", "r", 129*800a58d9SAndroid Build Coastguard Worker encoding="utf-8") 130*800a58d9SAndroid Build Coastguard Worker mock_glob.glob.assert_called_once_with("local/dir/*.img") 131*800a58d9SAndroid Build Coastguard Worker mock_shell.assert_called_with(expected_image_shell_cmd) 132*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with(expected_cvd_tar_ssh_cmd) 133*800a58d9SAndroid Build Coastguard Worker 134*800a58d9SAndroid Build Coastguard Worker # Test with target files directory and glob. 135*800a58d9SAndroid Build Coastguard Worker mock_glob.glob.reset_mock() 136*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 137*800a58d9SAndroid Build Coastguard Worker mock_shell.reset_mock() 138*800a58d9SAndroid Build Coastguard Worker mock_glob.glob.side_effect = ( 139*800a58d9SAndroid Build Coastguard Worker lambda path: [path.replace("*", "super")] if 140*800a58d9SAndroid Build Coastguard Worker path.startswith("local/dir/IMAGES") else []) 141*800a58d9SAndroid Build Coastguard Worker with mock.patch("acloud.internal.lib.cvd_utils.open", 142*800a58d9SAndroid Build Coastguard Worker side_effect=IOError("file does not exist")): 143*800a58d9SAndroid Build Coastguard Worker cvd_utils.UploadArtifacts(mock_ssh, "remote/dir", "local/dir", 144*800a58d9SAndroid Build Coastguard Worker "/mock/cvd.tar.gz") 145*800a58d9SAndroid Build Coastguard Worker self.assertGreater(mock_glob.glob.call_count, 2) 146*800a58d9SAndroid Build Coastguard Worker mock_shell.assert_called_with(expected_target_files_shell_cmd) 147*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with(expected_cvd_tar_ssh_cmd) 148*800a58d9SAndroid Build Coastguard Worker 149*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.create_common") 150*800a58d9SAndroid Build Coastguard Worker def testUploadBootImages(self, mock_create_common): 151*800a58d9SAndroid Build Coastguard Worker """Test FindBootImages and UploadExtraImages.""" 152*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 153*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as image_dir: 154*800a58d9SAndroid Build Coastguard Worker mock_create_common.FindBootImage.return_value = "boot.img" 155*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(image_dir, "vendor_boot.img")) 156*800a58d9SAndroid Build Coastguard Worker 157*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock(local_kernel_image="boot.img", 158*800a58d9SAndroid Build Coastguard Worker local_system_image=None, 159*800a58d9SAndroid Build Coastguard Worker local_system_dlkm_image=None, 160*800a58d9SAndroid Build Coastguard Worker local_vendor_image=None, 161*800a58d9SAndroid Build Coastguard Worker local_vendor_boot_image=None) 162*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 163*800a58d9SAndroid Build Coastguard Worker None) 164*800a58d9SAndroid Build Coastguard Worker self.assertEqual([("-boot_image", "dir/acloud_image/boot.img")], 165*800a58d9SAndroid Build Coastguard Worker args) 166*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once_with("mkdir -p dir/acloud_image") 167*800a58d9SAndroid Build Coastguard Worker mock_ssh.ScpPushFile.assert_called_once_with( 168*800a58d9SAndroid Build Coastguard Worker "boot.img", "dir/acloud_image/boot.img") 169*800a58d9SAndroid Build Coastguard Worker 170*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 171*800a58d9SAndroid Build Coastguard Worker mock_avd_spec.local_kernel_image = image_dir 172*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 173*800a58d9SAndroid Build Coastguard Worker None) 174*800a58d9SAndroid Build Coastguard Worker self.assertEqual( 175*800a58d9SAndroid Build Coastguard Worker [("-boot_image", "dir/acloud_image/boot.img"), 176*800a58d9SAndroid Build Coastguard Worker ("-vendor_boot_image", "dir/acloud_image/vendor_boot.img")], 177*800a58d9SAndroid Build Coastguard Worker args) 178*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once() 179*800a58d9SAndroid Build Coastguard Worker self.assertEqual(2, mock_ssh.ScpPushFile.call_count) 180*800a58d9SAndroid Build Coastguard Worker 181*800a58d9SAndroid Build Coastguard Worker def testUploadKernelImages(self): 182*800a58d9SAndroid Build Coastguard Worker """Test FindKernelImages and UploadExtraImages.""" 183*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 184*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as image_dir: 185*800a58d9SAndroid Build Coastguard Worker kernel_image_path = os.path.join(image_dir, "Image") 186*800a58d9SAndroid Build Coastguard Worker self.CreateFile(kernel_image_path) 187*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(image_dir, "initramfs.img")) 188*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(image_dir, "boot.img")) 189*800a58d9SAndroid Build Coastguard Worker 190*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock(local_kernel_image=kernel_image_path, 191*800a58d9SAndroid Build Coastguard Worker local_system_image=None, 192*800a58d9SAndroid Build Coastguard Worker local_system_dlkm_image=None, 193*800a58d9SAndroid Build Coastguard Worker local_vendor_image=None, 194*800a58d9SAndroid Build Coastguard Worker local_vendor_boot_image=None) 195*800a58d9SAndroid Build Coastguard Worker with self.assertRaises(errors.GetLocalImageError): 196*800a58d9SAndroid Build Coastguard Worker cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 197*800a58d9SAndroid Build Coastguard Worker None) 198*800a58d9SAndroid Build Coastguard Worker 199*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 200*800a58d9SAndroid Build Coastguard Worker mock_avd_spec.local_kernel_image = image_dir 201*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 202*800a58d9SAndroid Build Coastguard Worker None) 203*800a58d9SAndroid Build Coastguard Worker self.assertEqual( 204*800a58d9SAndroid Build Coastguard Worker [("-kernel_path", "dir/acloud_image/kernel"), 205*800a58d9SAndroid Build Coastguard Worker ("-initramfs_path", "dir/acloud_image/initramfs.img")], 206*800a58d9SAndroid Build Coastguard Worker args) 207*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once() 208*800a58d9SAndroid Build Coastguard Worker self.assertEqual(2, mock_ssh.ScpPushFile.call_count) 209*800a58d9SAndroid Build Coastguard Worker 210*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.ota_tools.FindOtaTools") 211*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.ssh.ShellCmdWithRetry") 212*800a58d9SAndroid Build Coastguard Worker def testUploadSuperImage(self, mock_shell, mock_find_ota_tools): 213*800a58d9SAndroid Build Coastguard Worker """Test UploadExtraImages.""" 214*800a58d9SAndroid Build Coastguard Worker self.Patch(create_common, "GetNonEmptyEnvVars", return_value=[]) 215*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 216*800a58d9SAndroid Build Coastguard Worker mock_ota_tools_object = mock.Mock() 217*800a58d9SAndroid Build Coastguard Worker mock_find_ota_tools.return_value = mock_ota_tools_object 218*800a58d9SAndroid Build Coastguard Worker 219*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as temp_dir: 220*800a58d9SAndroid Build Coastguard Worker target_files_dir = os.path.join(temp_dir, "target_files") 221*800a58d9SAndroid Build Coastguard Worker extra_image_dir = os.path.join(temp_dir, "extra") 222*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock(local_kernel_image=None, 223*800a58d9SAndroid Build Coastguard Worker local_system_image=extra_image_dir, 224*800a58d9SAndroid Build Coastguard Worker local_system_dlkm_image=extra_image_dir, 225*800a58d9SAndroid Build Coastguard Worker local_vendor_image=extra_image_dir, 226*800a58d9SAndroid Build Coastguard Worker local_vendor_boot_image=None, 227*800a58d9SAndroid Build Coastguard Worker local_tool_dirs=[]) 228*800a58d9SAndroid Build Coastguard Worker self.CreateFile( 229*800a58d9SAndroid Build Coastguard Worker os.path.join(target_files_dir, "IMAGES", "boot.img")) 230*800a58d9SAndroid Build Coastguard Worker self.CreateFile( 231*800a58d9SAndroid Build Coastguard Worker os.path.join(target_files_dir, "META", "misc_info.txt")) 232*800a58d9SAndroid Build Coastguard Worker for image_name in ["system.img", "system_dlkm.img", "vendor.img", 233*800a58d9SAndroid Build Coastguard Worker "vendor_dlkm.img", "odm.img", "odm_dlkm.img"]: 234*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(extra_image_dir, image_name)) 235*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 236*800a58d9SAndroid Build Coastguard Worker target_files_dir) 237*800a58d9SAndroid Build Coastguard Worker 238*800a58d9SAndroid Build Coastguard Worker self.assertEqual( 239*800a58d9SAndroid Build Coastguard Worker [("-super_image", "dir/acloud_image/super.img"), 240*800a58d9SAndroid Build Coastguard Worker ("-vbmeta_image", "dir/acloud_image/vbmeta.img")], 241*800a58d9SAndroid Build Coastguard Worker args) 242*800a58d9SAndroid Build Coastguard Worker mock_find_ota_tools.assert_called_once_with([]) 243*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once_with("mkdir -p dir/acloud_image") 244*800a58d9SAndroid Build Coastguard Worker # Super image 245*800a58d9SAndroid Build Coastguard Worker mock_shell.assert_called_once() 246*800a58d9SAndroid Build Coastguard Worker upload_args = mock_shell.call_args[0] 247*800a58d9SAndroid Build Coastguard Worker self.assertEqual(1, len(upload_args)) 248*800a58d9SAndroid Build Coastguard Worker self.assertIn(" super.img", upload_args[0]) 249*800a58d9SAndroid Build Coastguard Worker self.assertIn("dir/acloud_image", upload_args[0]) 250*800a58d9SAndroid Build Coastguard Worker mock_ota_tools_object.MixSuperImage.assert_called_once_with( 251*800a58d9SAndroid Build Coastguard Worker mock.ANY, mock.ANY, os.path.join(target_files_dir, "IMAGES"), 252*800a58d9SAndroid Build Coastguard Worker system_image=os.path.join(extra_image_dir, "system.img"), 253*800a58d9SAndroid Build Coastguard Worker system_ext_image=None, 254*800a58d9SAndroid Build Coastguard Worker product_image=None, 255*800a58d9SAndroid Build Coastguard Worker system_dlkm_image=os.path.join(extra_image_dir, "system_dlkm.img"), 256*800a58d9SAndroid Build Coastguard Worker vendor_image=os.path.join(extra_image_dir, "vendor.img"), 257*800a58d9SAndroid Build Coastguard Worker vendor_dlkm_image=os.path.join(extra_image_dir, "vendor_dlkm.img"), 258*800a58d9SAndroid Build Coastguard Worker odm_image=os.path.join(extra_image_dir, "odm.img"), 259*800a58d9SAndroid Build Coastguard Worker odm_dlkm_image=os.path.join(extra_image_dir, "odm_dlkm.img")) 260*800a58d9SAndroid Build Coastguard Worker # vbmeta image 261*800a58d9SAndroid Build Coastguard Worker mock_ota_tools_object.MakeDisabledVbmetaImage.assert_called_once() 262*800a58d9SAndroid Build Coastguard Worker mock_ssh.ScpPushFile.assert_called_once_with( 263*800a58d9SAndroid Build Coastguard Worker mock.ANY, "dir/acloud_image/vbmeta.img") 264*800a58d9SAndroid Build Coastguard Worker 265*800a58d9SAndroid Build Coastguard Worker 266*800a58d9SAndroid Build Coastguard Worker def testUploadVendorBootImages(self): 267*800a58d9SAndroid Build Coastguard Worker """Test UploadExtraImages.""" 268*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 269*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as image_dir: 270*800a58d9SAndroid Build Coastguard Worker vendor_boot_image_path = os.path.join(image_dir, 271*800a58d9SAndroid Build Coastguard Worker "vendor_boot-debug_test.img") 272*800a58d9SAndroid Build Coastguard Worker self.CreateFile(vendor_boot_image_path) 273*800a58d9SAndroid Build Coastguard Worker 274*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock( 275*800a58d9SAndroid Build Coastguard Worker local_kernel_image=None, 276*800a58d9SAndroid Build Coastguard Worker local_system_image=None, 277*800a58d9SAndroid Build Coastguard Worker local_system_dlkm_image=None, 278*800a58d9SAndroid Build Coastguard Worker local_vendor_image=None, 279*800a58d9SAndroid Build Coastguard Worker local_vendor_boot_image=vendor_boot_image_path) 280*800a58d9SAndroid Build Coastguard Worker 281*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 282*800a58d9SAndroid Build Coastguard Worker None) 283*800a58d9SAndroid Build Coastguard Worker self.assertEqual( 284*800a58d9SAndroid Build Coastguard Worker [("-vendor_boot_image", "dir/acloud_image/vendor_boot.img")], 285*800a58d9SAndroid Build Coastguard Worker args) 286*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once() 287*800a58d9SAndroid Build Coastguard Worker mock_ssh.ScpPushFile.assert_called_once_with( 288*800a58d9SAndroid Build Coastguard Worker mock.ANY, "dir/acloud_image/vendor_boot.img") 289*800a58d9SAndroid Build Coastguard Worker 290*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 291*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(image_dir, "vendor_boot.img")) 292*800a58d9SAndroid Build Coastguard Worker mock_avd_spec.local_vendor_boot_image = image_dir 293*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.UploadExtraImages(mock_ssh, "dir", mock_avd_spec, 294*800a58d9SAndroid Build Coastguard Worker None) 295*800a58d9SAndroid Build Coastguard Worker self.assertEqual( 296*800a58d9SAndroid Build Coastguard Worker [("-vendor_boot_image", "dir/acloud_image/vendor_boot.img")], 297*800a58d9SAndroid Build Coastguard Worker args) 298*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once() 299*800a58d9SAndroid Build Coastguard Worker mock_ssh.ScpPushFile.assert_called_once_with( 300*800a58d9SAndroid Build Coastguard Worker mock.ANY, "dir/acloud_image/vendor_boot.img") 301*800a58d9SAndroid Build Coastguard Worker 302*800a58d9SAndroid Build Coastguard Worker 303*800a58d9SAndroid Build Coastguard Worker def testCleanUpRemoteCvd(self): 304*800a58d9SAndroid Build Coastguard Worker """Test CleanUpRemoteCvd.""" 305*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 306*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = ["", "", ""] 307*800a58d9SAndroid Build Coastguard Worker cvd_utils.CleanUpRemoteCvd(mock_ssh, "dir", raise_error=True) 308*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_has_calls([ 309*800a58d9SAndroid Build Coastguard Worker mock.call("'readlink -n -e dir/image_dir_link || true'"), 310*800a58d9SAndroid Build Coastguard Worker mock.call("'HOME=$HOME/dir dir/bin/stop_cvd'"), 311*800a58d9SAndroid Build Coastguard Worker mock.call("'rm -rf dir/*'")]) 312*800a58d9SAndroid Build Coastguard Worker 313*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 314*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = ["img_dir", "", "", ""] 315*800a58d9SAndroid Build Coastguard Worker cvd_utils.CleanUpRemoteCvd(mock_ssh, "dir", raise_error=True) 316*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_has_calls([ 317*800a58d9SAndroid Build Coastguard Worker mock.call("'readlink -n -e dir/image_dir_link || true'"), 318*800a58d9SAndroid Build Coastguard Worker mock.call("'mkdir -p img_dir && flock img_dir.lock -c '\"'\"'" 319*800a58d9SAndroid Build Coastguard Worker "rm -f dir/image_dir_link && " 320*800a58d9SAndroid Build Coastguard Worker "expr $(test -s img_dir.lock && " 321*800a58d9SAndroid Build Coastguard Worker "cat img_dir.lock || echo 1) - 1 > img_dir.lock || " 322*800a58d9SAndroid Build Coastguard Worker "rm -rf img_dir img_dir.lock'\"'\"''"), 323*800a58d9SAndroid Build Coastguard Worker mock.call("'HOME=$HOME/dir dir/bin/stop_cvd'"), 324*800a58d9SAndroid Build Coastguard Worker mock.call("'rm -rf dir/*'")]) 325*800a58d9SAndroid Build Coastguard Worker 326*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 327*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = [ 328*800a58d9SAndroid Build Coastguard Worker "", 329*800a58d9SAndroid Build Coastguard Worker subprocess.CalledProcessError(cmd="should raise", returncode=1)] 330*800a58d9SAndroid Build Coastguard Worker with self.assertRaises(subprocess.CalledProcessError): 331*800a58d9SAndroid Build Coastguard Worker cvd_utils.CleanUpRemoteCvd(mock_ssh, "dir", raise_error=True) 332*800a58d9SAndroid Build Coastguard Worker 333*800a58d9SAndroid Build Coastguard Worker mock_ssh.reset_mock() 334*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = [ 335*800a58d9SAndroid Build Coastguard Worker "", 336*800a58d9SAndroid Build Coastguard Worker subprocess.CalledProcessError(cmd="should ignore", returncode=1), 337*800a58d9SAndroid Build Coastguard Worker None] 338*800a58d9SAndroid Build Coastguard Worker cvd_utils.CleanUpRemoteCvd(mock_ssh, "dir", raise_error=False) 339*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_any_call("'HOME=$HOME/dir dir/bin/stop_cvd'", 340*800a58d9SAndroid Build Coastguard Worker retry=0) 341*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_any_call("'rm -rf dir/*'") 342*800a58d9SAndroid Build Coastguard Worker 343*800a58d9SAndroid Build Coastguard Worker def testGetRemoteHostBaseDir(self): 344*800a58d9SAndroid Build Coastguard Worker """Test GetRemoteHostBaseDir.""" 345*800a58d9SAndroid Build Coastguard Worker self.assertEqual("acloud_cf_1", cvd_utils.GetRemoteHostBaseDir(None)) 346*800a58d9SAndroid Build Coastguard Worker self.assertEqual("acloud_cf_2", cvd_utils.GetRemoteHostBaseDir(2)) 347*800a58d9SAndroid Build Coastguard Worker 348*800a58d9SAndroid Build Coastguard Worker def testFormatRemoteHostInstanceName(self): 349*800a58d9SAndroid Build Coastguard Worker """Test FormatRemoteHostInstanceName.""" 350*800a58d9SAndroid Build Coastguard Worker name = cvd_utils.FormatRemoteHostInstanceName( 351*800a58d9SAndroid Build Coastguard Worker self._REMOTE_HOSTNAME_1, None, self._BUILD_ID, self._PRODUCT_NAME) 352*800a58d9SAndroid Build Coastguard Worker self.assertEqual(name, self._REMOTE_HOST_INSTANCE_NAME_1) 353*800a58d9SAndroid Build Coastguard Worker 354*800a58d9SAndroid Build Coastguard Worker name = cvd_utils.FormatRemoteHostInstanceName( 355*800a58d9SAndroid Build Coastguard Worker self._REMOTE_HOSTNAME_2, 2, self._BUILD_ID, self._PRODUCT_NAME) 356*800a58d9SAndroid Build Coastguard Worker self.assertEqual(name, self._REMOTE_HOST_INSTANCE_NAME_2) 357*800a58d9SAndroid Build Coastguard Worker 358*800a58d9SAndroid Build Coastguard Worker def testParseRemoteHostAddress(self): 359*800a58d9SAndroid Build Coastguard Worker """Test ParseRemoteHostAddress.""" 360*800a58d9SAndroid Build Coastguard Worker result = cvd_utils.ParseRemoteHostAddress( 361*800a58d9SAndroid Build Coastguard Worker self._REMOTE_HOST_INSTANCE_NAME_1) 362*800a58d9SAndroid Build Coastguard Worker self.assertEqual(result, (self._REMOTE_HOSTNAME_1, "acloud_cf_1")) 363*800a58d9SAndroid Build Coastguard Worker 364*800a58d9SAndroid Build Coastguard Worker result = cvd_utils.ParseRemoteHostAddress( 365*800a58d9SAndroid Build Coastguard Worker self._REMOTE_HOST_INSTANCE_NAME_2) 366*800a58d9SAndroid Build Coastguard Worker self.assertEqual(result, (self._REMOTE_HOSTNAME_2, "acloud_cf_2")) 367*800a58d9SAndroid Build Coastguard Worker 368*800a58d9SAndroid Build Coastguard Worker result = cvd_utils.ParseRemoteHostAddress( 369*800a58d9SAndroid Build Coastguard Worker "host-goldfish-192.0.2.1-5554-123456-sdk_x86_64-sdk") 370*800a58d9SAndroid Build Coastguard Worker self.assertIsNone(result) 371*800a58d9SAndroid Build Coastguard Worker 372*800a58d9SAndroid Build Coastguard Worker # pylint: disable=protected-access 373*800a58d9SAndroid Build Coastguard Worker def testRemoteImageDirLink(self): 374*800a58d9SAndroid Build Coastguard Worker """Test PrepareRemoteImageDirLink and _DeleteRemoteImageDirLink.""" 375*800a58d9SAndroid Build Coastguard Worker self.assertEqual(os.path, cvd_utils.remote_path) 376*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as temp_dir: 377*800a58d9SAndroid Build Coastguard Worker env = os.environ.copy() 378*800a58d9SAndroid Build Coastguard Worker env["HOME"] = temp_dir 379*800a58d9SAndroid Build Coastguard Worker # Execute the commands locally. 380*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 381*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = lambda cmd: subprocess.check_output( 382*800a58d9SAndroid Build Coastguard Worker "sh -c " + cmd, shell=True, cwd=temp_dir, env=env 383*800a58d9SAndroid Build Coastguard Worker ).decode("utf-8") 384*800a58d9SAndroid Build Coastguard Worker # Relative paths under temp_dir. 385*800a58d9SAndroid Build Coastguard Worker base_dir_name_1 = "acloud_cf_1" 386*800a58d9SAndroid Build Coastguard Worker base_dir_name_2 = "acloud_cf_2" 387*800a58d9SAndroid Build Coastguard Worker image_dir_name = "test/img" 388*800a58d9SAndroid Build Coastguard Worker rel_ref_cnt_path = "test/img.lock" 389*800a58d9SAndroid Build Coastguard Worker # Absolute paths. 390*800a58d9SAndroid Build Coastguard Worker image_dir = os.path.join(temp_dir, image_dir_name) 391*800a58d9SAndroid Build Coastguard Worker ref_cnt_path = os.path.join(temp_dir, rel_ref_cnt_path) 392*800a58d9SAndroid Build Coastguard Worker link_path_1 = os.path.join(temp_dir, base_dir_name_1, 393*800a58d9SAndroid Build Coastguard Worker "image_dir_link") 394*800a58d9SAndroid Build Coastguard Worker link_path_2 = os.path.join(temp_dir, base_dir_name_2, 395*800a58d9SAndroid Build Coastguard Worker "image_dir_link") 396*800a58d9SAndroid Build Coastguard Worker # Delete non-existing directories. 397*800a58d9SAndroid Build Coastguard Worker cvd_utils._DeleteRemoteImageDirLink(mock_ssh, base_dir_name_1) 398*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with( 399*800a58d9SAndroid Build Coastguard Worker f"'readlink -n -e {base_dir_name_1}/image_dir_link || true'") 400*800a58d9SAndroid Build Coastguard Worker self.assertFalse( 401*800a58d9SAndroid Build Coastguard Worker os.path.exists(os.path.join(temp_dir, base_dir_name_1))) 402*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.exists(image_dir)) 403*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.exists(ref_cnt_path)) 404*800a58d9SAndroid Build Coastguard Worker # Prepare the first base dir. 405*800a58d9SAndroid Build Coastguard Worker cvd_utils.PrepareRemoteImageDirLink(mock_ssh, base_dir_name_1, 406*800a58d9SAndroid Build Coastguard Worker image_dir_name) 407*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with( 408*800a58d9SAndroid Build Coastguard Worker f"'mkdir -p {image_dir_name} && flock {rel_ref_cnt_path} -c " 409*800a58d9SAndroid Build Coastguard Worker f"'\"'\"'mkdir -p {base_dir_name_1} {image_dir_name} && " 410*800a58d9SAndroid Build Coastguard Worker f"ln -s -r {image_dir_name} " 411*800a58d9SAndroid Build Coastguard Worker f"{base_dir_name_1}/image_dir_link && " 412*800a58d9SAndroid Build Coastguard Worker f"expr $(test -s {rel_ref_cnt_path} && " 413*800a58d9SAndroid Build Coastguard Worker f"cat {rel_ref_cnt_path} || echo 0) + 1 > " 414*800a58d9SAndroid Build Coastguard Worker f"{rel_ref_cnt_path}'\"'\"''") 415*800a58d9SAndroid Build Coastguard Worker self.assertTrue(os.path.islink(link_path_1)) 416*800a58d9SAndroid Build Coastguard Worker self.assertEqual("../test/img", os.readlink(link_path_1)) 417*800a58d9SAndroid Build Coastguard Worker self.assertTrue(os.path.isfile(ref_cnt_path)) 418*800a58d9SAndroid Build Coastguard Worker with open(ref_cnt_path, "r", encoding="utf-8") as ref_cnt_file: 419*800a58d9SAndroid Build Coastguard Worker self.assertEqual("1\n", ref_cnt_file.read()) 420*800a58d9SAndroid Build Coastguard Worker # Prepare the second base dir. 421*800a58d9SAndroid Build Coastguard Worker cvd_utils.PrepareRemoteImageDirLink(mock_ssh, base_dir_name_2, 422*800a58d9SAndroid Build Coastguard Worker image_dir_name) 423*800a58d9SAndroid Build Coastguard Worker self.assertTrue(os.path.islink(link_path_2)) 424*800a58d9SAndroid Build Coastguard Worker self.assertEqual("../test/img", os.readlink(link_path_2)) 425*800a58d9SAndroid Build Coastguard Worker self.assertTrue(os.path.isfile(ref_cnt_path)) 426*800a58d9SAndroid Build Coastguard Worker with open(ref_cnt_path, "r", encoding="utf-8") as ref_cnt_file: 427*800a58d9SAndroid Build Coastguard Worker self.assertEqual("2\n", ref_cnt_file.read()) 428*800a58d9SAndroid Build Coastguard Worker # Delete the first base dir. 429*800a58d9SAndroid Build Coastguard Worker cvd_utils._DeleteRemoteImageDirLink(mock_ssh, base_dir_name_1) 430*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.lexists(link_path_1)) 431*800a58d9SAndroid Build Coastguard Worker self.assertTrue(os.path.isfile(ref_cnt_path)) 432*800a58d9SAndroid Build Coastguard Worker with open(ref_cnt_path, "r", encoding="utf-8") as ref_cnt_file: 433*800a58d9SAndroid Build Coastguard Worker self.assertEqual("1\n", ref_cnt_file.read()) 434*800a58d9SAndroid Build Coastguard Worker # Delete the second base dir. 435*800a58d9SAndroid Build Coastguard Worker cvd_utils._DeleteRemoteImageDirLink(mock_ssh, base_dir_name_2) 436*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.lexists(link_path_2)) 437*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.exists(image_dir)) 438*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.exists(ref_cnt_path)) 439*800a58d9SAndroid Build Coastguard Worker 440*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.utils.PollAndWait") 441*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.utils.time.time", 442*800a58d9SAndroid Build Coastguard Worker return_value=90.0) 443*800a58d9SAndroid Build Coastguard Worker def testLoadRemoteImageArgs(self, _mock_time, mock_poll_and_wait): 444*800a58d9SAndroid Build Coastguard Worker """Test LoadRemoteImageArgs.""" 445*800a58d9SAndroid Build Coastguard Worker deadline = 99.9 446*800a58d9SAndroid Build Coastguard Worker self.assertEqual(os.path, cvd_utils.remote_path) 447*800a58d9SAndroid Build Coastguard Worker 448*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as temp_dir: 449*800a58d9SAndroid Build Coastguard Worker env = os.environ.copy() 450*800a58d9SAndroid Build Coastguard Worker env["HOME"] = temp_dir 451*800a58d9SAndroid Build Coastguard Worker # Execute the commands locally. 452*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 453*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = lambda cmd: subprocess.check_output( 454*800a58d9SAndroid Build Coastguard Worker "sh -c " + cmd, shell=True, cwd=temp_dir, env=env, text=True) 455*800a58d9SAndroid Build Coastguard Worker mock_poll_and_wait.side_effect = lambda func, **kwargs: func() 456*800a58d9SAndroid Build Coastguard Worker 457*800a58d9SAndroid Build Coastguard Worker timestamp_path = os.path.join(temp_dir, "timestamp.txt") 458*800a58d9SAndroid Build Coastguard Worker args_path = os.path.join(temp_dir, "args.txt") 459*800a58d9SAndroid Build Coastguard Worker 460*800a58d9SAndroid Build Coastguard Worker # Test with an uninitialized directory. 461*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.LoadRemoteImageArgs( 462*800a58d9SAndroid Build Coastguard Worker mock_ssh, timestamp_path, args_path, deadline) 463*800a58d9SAndroid Build Coastguard Worker 464*800a58d9SAndroid Build Coastguard Worker self.assertIsNone(args) 465*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_once() 466*800a58d9SAndroid Build Coastguard Worker with open(timestamp_path, "r", encoding="utf-8") as timestamp_file: 467*800a58d9SAndroid Build Coastguard Worker timestamp = timestamp_file.read().strip() 468*800a58d9SAndroid Build Coastguard Worker self.assertRegex(timestamp, r"\d+", 469*800a58d9SAndroid Build Coastguard Worker f"Invalid timestamp: {timestamp}") 470*800a58d9SAndroid Build Coastguard Worker self.assertFalse(os.path.exists(args_path)) 471*800a58d9SAndroid Build Coastguard Worker 472*800a58d9SAndroid Build Coastguard Worker # Test with an initialized directory and the uploader times out. 473*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.reset_mock() 474*800a58d9SAndroid Build Coastguard Worker 475*800a58d9SAndroid Build Coastguard Worker with self.assertRaises(errors.CreateError): 476*800a58d9SAndroid Build Coastguard Worker cvd_utils.LoadRemoteImageArgs( 477*800a58d9SAndroid Build Coastguard Worker mock_ssh, timestamp_path, args_path, deadline) 478*800a58d9SAndroid Build Coastguard Worker 479*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_has_calls([ 480*800a58d9SAndroid Build Coastguard Worker mock.call(f"'flock {timestamp_path} -c '\"'\"'" 481*800a58d9SAndroid Build Coastguard Worker f"test -s {timestamp_path} && " 482*800a58d9SAndroid Build Coastguard Worker f"cat {timestamp_path} || " 483*800a58d9SAndroid Build Coastguard Worker f"expr $(date +%s) + 9 > {timestamp_path}'\"'\"''"), 484*800a58d9SAndroid Build Coastguard Worker mock.call(f"'flock {args_path} -c '\"'\"'" 485*800a58d9SAndroid Build Coastguard Worker f"test -s {args_path} -o " 486*800a58d9SAndroid Build Coastguard Worker f"{timestamp} -le $(date +%s) || " 487*800a58d9SAndroid Build Coastguard Worker "echo wait...'\"'\"''"), 488*800a58d9SAndroid Build Coastguard Worker mock.call(f"'flock {args_path} -c '\"'\"'" 489*800a58d9SAndroid Build Coastguard Worker f"cat {args_path}'\"'\"''") 490*800a58d9SAndroid Build Coastguard Worker ]) 491*800a58d9SAndroid Build Coastguard Worker with open(timestamp_path, "r", encoding="utf-8") as timestamp_file: 492*800a58d9SAndroid Build Coastguard Worker self.assertEqual(timestamp_file.read().strip(), timestamp) 493*800a58d9SAndroid Build Coastguard Worker self.assertEqual(os.path.getsize(args_path), 0) 494*800a58d9SAndroid Build Coastguard Worker 495*800a58d9SAndroid Build Coastguard Worker # Test with an initialized directory. 496*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.reset_mock() 497*800a58d9SAndroid Build Coastguard Worker self.CreateFile(args_path, b'[["arg", "1"]]') 498*800a58d9SAndroid Build Coastguard Worker 499*800a58d9SAndroid Build Coastguard Worker args = cvd_utils.LoadRemoteImageArgs( 500*800a58d9SAndroid Build Coastguard Worker mock_ssh, timestamp_path, args_path, deadline) 501*800a58d9SAndroid Build Coastguard Worker 502*800a58d9SAndroid Build Coastguard Worker self.assertEqual(args, [["arg", "1"]]) 503*800a58d9SAndroid Build Coastguard Worker self.assertEqual(mock_ssh.Run.call_count, 3) 504*800a58d9SAndroid Build Coastguard Worker 505*800a58d9SAndroid Build Coastguard Worker def testSaveRemoteImageArgs(self): 506*800a58d9SAndroid Build Coastguard Worker """Test SaveRemoteImageArgs.""" 507*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory(prefix="cvd_utils") as temp_dir: 508*800a58d9SAndroid Build Coastguard Worker env = os.environ.copy() 509*800a58d9SAndroid Build Coastguard Worker env["HOME"] = temp_dir 510*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 511*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = lambda cmd: subprocess.check_call( 512*800a58d9SAndroid Build Coastguard Worker "sh -c " + cmd, shell=True, cwd=temp_dir, env=env, text=True) 513*800a58d9SAndroid Build Coastguard Worker args_path = os.path.join(temp_dir, "args.txt") 514*800a58d9SAndroid Build Coastguard Worker 515*800a58d9SAndroid Build Coastguard Worker cvd_utils.SaveRemoteImageArgs(mock_ssh, args_path, [("arg", "1")]) 516*800a58d9SAndroid Build Coastguard Worker 517*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with( 518*800a58d9SAndroid Build Coastguard Worker f"'flock {args_path} -c '\"'\"'" 519*800a58d9SAndroid Build Coastguard Worker f"""echo '"'"'"'"'"'"'"'"'[["arg", "1"]]'"'"'"'"'"'"'"'"' > """ 520*800a58d9SAndroid Build Coastguard Worker f"{args_path}'\"'\"''") 521*800a58d9SAndroid Build Coastguard Worker with open(args_path, "r", encoding="utf-8") as args_file: 522*800a58d9SAndroid Build Coastguard Worker self.assertEqual(args_file.read().strip(), '[["arg", "1"]]') 523*800a58d9SAndroid Build Coastguard Worker 524*800a58d9SAndroid Build Coastguard Worker def testGetConfigFromRemoteAndroidInfo(self): 525*800a58d9SAndroid Build Coastguard Worker """Test GetConfigFromRemoteAndroidInfo.""" 526*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 527*800a58d9SAndroid Build Coastguard Worker mock_ssh.GetCmdOutput.return_value = "require board=vsoc_x86_64\n" 528*800a58d9SAndroid Build Coastguard Worker config = cvd_utils.GetConfigFromRemoteAndroidInfo(mock_ssh, ".") 529*800a58d9SAndroid Build Coastguard Worker mock_ssh.GetCmdOutput.assert_called_with("cat ./android-info.txt") 530*800a58d9SAndroid Build Coastguard Worker self.assertIsNone(config) 531*800a58d9SAndroid Build Coastguard Worker 532*800a58d9SAndroid Build Coastguard Worker mock_ssh.GetCmdOutput.return_value += "config=phone\n" 533*800a58d9SAndroid Build Coastguard Worker config = cvd_utils.GetConfigFromRemoteAndroidInfo(mock_ssh, ".") 534*800a58d9SAndroid Build Coastguard Worker self.assertEqual(config, "phone") 535*800a58d9SAndroid Build Coastguard Worker 536*800a58d9SAndroid Build Coastguard Worker def testGetRemoteLaunchCvdCmd(self): 537*800a58d9SAndroid Build Coastguard Worker """Test GetRemoteLaunchCvdCmd.""" 538*800a58d9SAndroid Build Coastguard Worker # Minimum arguments 539*800a58d9SAndroid Build Coastguard Worker mock_cfg = mock.Mock(extra_data_disk_size_gb=0) 540*800a58d9SAndroid Build Coastguard Worker hw_property = { 541*800a58d9SAndroid Build Coastguard Worker constants.HW_X_RES: "1080", 542*800a58d9SAndroid Build Coastguard Worker constants.HW_Y_RES: "1920", 543*800a58d9SAndroid Build Coastguard Worker constants.HW_ALIAS_DPI: "240"} 544*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock( 545*800a58d9SAndroid Build Coastguard Worker spec=[], 546*800a58d9SAndroid Build Coastguard Worker cfg=mock_cfg, 547*800a58d9SAndroid Build Coastguard Worker hw_customize=False, 548*800a58d9SAndroid Build Coastguard Worker hw_property=hw_property, 549*800a58d9SAndroid Build Coastguard Worker connect_webrtc=False, 550*800a58d9SAndroid Build Coastguard Worker connect_vnc=False, 551*800a58d9SAndroid Build Coastguard Worker openwrt=False, 552*800a58d9SAndroid Build Coastguard Worker num_avds_per_instance=1, 553*800a58d9SAndroid Build Coastguard Worker base_instance_num=0, 554*800a58d9SAndroid Build Coastguard Worker launch_args="") 555*800a58d9SAndroid Build Coastguard Worker expected_cmd = ( 556*800a58d9SAndroid Build Coastguard Worker "HOME=$HOME/dir dir/bin/launch_cvd -daemon " 557*800a58d9SAndroid Build Coastguard Worker "-x_res=1080 -y_res=1920 -dpi=240 " 558*800a58d9SAndroid Build Coastguard Worker "-undefok=report_anonymous_usage_stats,config " 559*800a58d9SAndroid Build Coastguard Worker "-report_anonymous_usage_stats=y") 560*800a58d9SAndroid Build Coastguard Worker cmd = cvd_utils.GetRemoteLaunchCvdCmd("dir", mock_avd_spec, 561*800a58d9SAndroid Build Coastguard Worker config=None, extra_args=()) 562*800a58d9SAndroid Build Coastguard Worker self.assertEqual(cmd, expected_cmd) 563*800a58d9SAndroid Build Coastguard Worker 564*800a58d9SAndroid Build Coastguard Worker # All arguments. 565*800a58d9SAndroid Build Coastguard Worker mock_cfg = mock.Mock(extra_data_disk_size_gb=20) 566*800a58d9SAndroid Build Coastguard Worker hw_property = { 567*800a58d9SAndroid Build Coastguard Worker constants.HW_X_RES: "1080", 568*800a58d9SAndroid Build Coastguard Worker constants.HW_Y_RES: "1920", 569*800a58d9SAndroid Build Coastguard Worker constants.HW_ALIAS_DPI: "240", 570*800a58d9SAndroid Build Coastguard Worker constants.HW_ALIAS_DISK: "10240", 571*800a58d9SAndroid Build Coastguard Worker constants.HW_ALIAS_CPUS: "2", 572*800a58d9SAndroid Build Coastguard Worker constants.HW_ALIAS_MEMORY: "4096"} 573*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock( 574*800a58d9SAndroid Build Coastguard Worker spec=[], 575*800a58d9SAndroid Build Coastguard Worker cfg=mock_cfg, 576*800a58d9SAndroid Build Coastguard Worker hw_customize=True, 577*800a58d9SAndroid Build Coastguard Worker hw_property=hw_property, 578*800a58d9SAndroid Build Coastguard Worker connect_webrtc=True, 579*800a58d9SAndroid Build Coastguard Worker webrtc_device_id="pet-name", 580*800a58d9SAndroid Build Coastguard Worker connect_vnc=True, 581*800a58d9SAndroid Build Coastguard Worker openwrt=True, 582*800a58d9SAndroid Build Coastguard Worker num_avds_per_instance=2, 583*800a58d9SAndroid Build Coastguard Worker base_instance_num=3, 584*800a58d9SAndroid Build Coastguard Worker launch_args="--setupwizard_mode=REQUIRED") 585*800a58d9SAndroid Build Coastguard Worker expected_cmd = ( 586*800a58d9SAndroid Build Coastguard Worker "HOME=$HOME/dir dir/bin/launch_cvd -daemon --extra args " 587*800a58d9SAndroid Build Coastguard Worker "-data_policy=create_if_missing -blank_data_image_mb=20480 " 588*800a58d9SAndroid Build Coastguard Worker "-config=phone -x_res=1080 -y_res=1920 -dpi=240 " 589*800a58d9SAndroid Build Coastguard Worker "-data_policy=always_create -blank_data_image_mb=10240 " 590*800a58d9SAndroid Build Coastguard Worker "-cpus=2 -memory_mb=4096 " 591*800a58d9SAndroid Build Coastguard Worker "--start_webrtc --vm_manager=crosvm " 592*800a58d9SAndroid Build Coastguard Worker "--webrtc_device_id=pet-name " 593*800a58d9SAndroid Build Coastguard Worker "--start_vnc_server=true " 594*800a58d9SAndroid Build Coastguard Worker "-console=true " 595*800a58d9SAndroid Build Coastguard Worker "-num_instances=2 --base_instance_num=3 " 596*800a58d9SAndroid Build Coastguard Worker "--setupwizard_mode=REQUIRED " 597*800a58d9SAndroid Build Coastguard Worker "-undefok=report_anonymous_usage_stats,config " 598*800a58d9SAndroid Build Coastguard Worker "-report_anonymous_usage_stats=y") 599*800a58d9SAndroid Build Coastguard Worker cmd = cvd_utils.GetRemoteLaunchCvdCmd( 600*800a58d9SAndroid Build Coastguard Worker "dir", mock_avd_spec, "phone", ("--extra", "args")) 601*800a58d9SAndroid Build Coastguard Worker self.assertEqual(cmd, expected_cmd) 602*800a58d9SAndroid Build Coastguard Worker 603*800a58d9SAndroid Build Coastguard Worker def testExecuteRemoteLaunchCvd(self): 604*800a58d9SAndroid Build Coastguard Worker """Test ExecuteRemoteLaunchCvd.""" 605*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 606*800a58d9SAndroid Build Coastguard Worker error_msg = cvd_utils.ExecuteRemoteLaunchCvd(mock_ssh, "launch_cvd", 1) 607*800a58d9SAndroid Build Coastguard Worker self.assertFalse(error_msg) 608*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called() 609*800a58d9SAndroid Build Coastguard Worker 610*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = errors.LaunchCVDFail( 611*800a58d9SAndroid Build Coastguard Worker "Test unknown command line flag 'start_vnc_server'.") 612*800a58d9SAndroid Build Coastguard Worker error_msg = cvd_utils.ExecuteRemoteLaunchCvd(mock_ssh, "launch_cvd", 1) 613*800a58d9SAndroid Build Coastguard Worker self.assertIn("VNC is not supported in the current build.", error_msg) 614*800a58d9SAndroid Build Coastguard Worker 615*800a58d9SAndroid Build Coastguard Worker def testGetRemoteFetcherConfigJson(self): 616*800a58d9SAndroid Build Coastguard Worker """Test GetRemoteFetcherConfigJson.""" 617*800a58d9SAndroid Build Coastguard Worker expected_log = {"path": "dir/fetcher_config.json", 618*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_CUTTLEFISH_LOG} 619*800a58d9SAndroid Build Coastguard Worker self.assertEqual(expected_log, 620*800a58d9SAndroid Build Coastguard Worker cvd_utils.GetRemoteFetcherConfigJson("dir")) 621*800a58d9SAndroid Build Coastguard Worker 622*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.utils") 623*800a58d9SAndroid Build Coastguard Worker def testFindRemoteLogs(self, mock_utils): 624*800a58d9SAndroid Build Coastguard Worker """Test FindRemoteLogs with the runtime directories in Android 13.""" 625*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 626*800a58d9SAndroid Build Coastguard Worker mock_utils.FindRemoteFiles.return_value = [ 627*800a58d9SAndroid Build Coastguard Worker "/kernel.log", "/logcat", "/launcher.log", "/access-kregistry", 628*800a58d9SAndroid Build Coastguard Worker "/cuttlefish_config.json"] 629*800a58d9SAndroid Build Coastguard Worker 630*800a58d9SAndroid Build Coastguard Worker logs = cvd_utils.FindRemoteLogs(mock_ssh, "dir", None, None) 631*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with( 632*800a58d9SAndroid Build Coastguard Worker "test -d dir/cuttlefish/instances/cvd-1", retry=0) 633*800a58d9SAndroid Build Coastguard Worker mock_utils.FindRemoteFiles.assert_called_with( 634*800a58d9SAndroid Build Coastguard Worker mock_ssh, ["dir/cuttlefish/instances/cvd-1"]) 635*800a58d9SAndroid Build Coastguard Worker expected_logs = [ 636*800a58d9SAndroid Build Coastguard Worker { 637*800a58d9SAndroid Build Coastguard Worker "path": "/kernel.log", 638*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_KERNEL_LOG, 639*800a58d9SAndroid Build Coastguard Worker "name": "kernel.log" 640*800a58d9SAndroid Build Coastguard Worker }, 641*800a58d9SAndroid Build Coastguard Worker { 642*800a58d9SAndroid Build Coastguard Worker "path": "/logcat", 643*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_LOGCAT, 644*800a58d9SAndroid Build Coastguard Worker "name": "full_gce_logcat" 645*800a58d9SAndroid Build Coastguard Worker }, 646*800a58d9SAndroid Build Coastguard Worker { 647*800a58d9SAndroid Build Coastguard Worker "path": "/launcher.log", 648*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_CUTTLEFISH_LOG, 649*800a58d9SAndroid Build Coastguard Worker "name": "launcher.log" 650*800a58d9SAndroid Build Coastguard Worker }, 651*800a58d9SAndroid Build Coastguard Worker { 652*800a58d9SAndroid Build Coastguard Worker "path": "/cuttlefish_config.json", 653*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_CUTTLEFISH_LOG, 654*800a58d9SAndroid Build Coastguard Worker "name": "cuttlefish_config.json" 655*800a58d9SAndroid Build Coastguard Worker }, 656*800a58d9SAndroid Build Coastguard Worker { 657*800a58d9SAndroid Build Coastguard Worker "path": "dir/cuttlefish/instances/cvd-1/tombstones", 658*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_DIR, 659*800a58d9SAndroid Build Coastguard Worker "name": "tombstones-zip" 660*800a58d9SAndroid Build Coastguard Worker }, 661*800a58d9SAndroid Build Coastguard Worker ] 662*800a58d9SAndroid Build Coastguard Worker self.assertEqual(expected_logs, logs) 663*800a58d9SAndroid Build Coastguard Worker 664*800a58d9SAndroid Build Coastguard Worker @mock.patch("acloud.internal.lib.cvd_utils.utils") 665*800a58d9SAndroid Build Coastguard Worker def testFindRemoteLogsWithLegacyDirs(self, mock_utils): 666*800a58d9SAndroid Build Coastguard Worker """Test FindRemoteLogs with the runtime directories in Android 11.""" 667*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 668*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.side_effect = subprocess.CalledProcessError( 669*800a58d9SAndroid Build Coastguard Worker cmd="test", returncode=1) 670*800a58d9SAndroid Build Coastguard Worker mock_utils.FindRemoteFiles.return_value = [ 671*800a58d9SAndroid Build Coastguard Worker "dir/cuttlefish_runtime/kernel.log", 672*800a58d9SAndroid Build Coastguard Worker "dir/cuttlefish_runtime.4/kernel.log", 673*800a58d9SAndroid Build Coastguard Worker ] 674*800a58d9SAndroid Build Coastguard Worker 675*800a58d9SAndroid Build Coastguard Worker logs = cvd_utils.FindRemoteLogs(mock_ssh, "dir", 3, 2) 676*800a58d9SAndroid Build Coastguard Worker mock_ssh.Run.assert_called_with( 677*800a58d9SAndroid Build Coastguard Worker "test -d dir/cuttlefish/instances/cvd-3", retry=0) 678*800a58d9SAndroid Build Coastguard Worker mock_utils.FindRemoteFiles.assert_called_with( 679*800a58d9SAndroid Build Coastguard Worker mock_ssh, ["dir/cuttlefish_runtime", "dir/cuttlefish_runtime.4"]) 680*800a58d9SAndroid Build Coastguard Worker expected_logs = [ 681*800a58d9SAndroid Build Coastguard Worker { 682*800a58d9SAndroid Build Coastguard Worker "path": "dir/cuttlefish_runtime/kernel.log", 683*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_KERNEL_LOG, 684*800a58d9SAndroid Build Coastguard Worker "name": "kernel.log" 685*800a58d9SAndroid Build Coastguard Worker }, 686*800a58d9SAndroid Build Coastguard Worker { 687*800a58d9SAndroid Build Coastguard Worker "path": "dir/cuttlefish_runtime.4/kernel.log", 688*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_KERNEL_LOG, 689*800a58d9SAndroid Build Coastguard Worker "name": "kernel.1.log" 690*800a58d9SAndroid Build Coastguard Worker }, 691*800a58d9SAndroid Build Coastguard Worker { 692*800a58d9SAndroid Build Coastguard Worker "path": "dir/cuttlefish_runtime/tombstones", 693*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_DIR, 694*800a58d9SAndroid Build Coastguard Worker "name": "tombstones-zip" 695*800a58d9SAndroid Build Coastguard Worker }, 696*800a58d9SAndroid Build Coastguard Worker { 697*800a58d9SAndroid Build Coastguard Worker "path": "dir/cuttlefish_runtime.4/tombstones", 698*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_DIR, 699*800a58d9SAndroid Build Coastguard Worker "name": "tombstones-zip.1" 700*800a58d9SAndroid Build Coastguard Worker }, 701*800a58d9SAndroid Build Coastguard Worker ] 702*800a58d9SAndroid Build Coastguard Worker self.assertEqual(expected_logs, logs) 703*800a58d9SAndroid Build Coastguard Worker 704*800a58d9SAndroid Build Coastguard Worker def testFindLocalLogs(self): 705*800a58d9SAndroid Build Coastguard Worker """Test FindLocalLogs with the runtime directory in Android 13.""" 706*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory() as temp_dir: 707*800a58d9SAndroid Build Coastguard Worker log_dir = os.path.join(temp_dir, "instances", "cvd-2", "logs") 708*800a58d9SAndroid Build Coastguard Worker kernel_log = os.path.join(os.path.join(log_dir, "kernel.log")) 709*800a58d9SAndroid Build Coastguard Worker launcher_log = os.path.join(os.path.join(log_dir, "launcher.log")) 710*800a58d9SAndroid Build Coastguard Worker logcat = os.path.join(os.path.join(log_dir, "logcat")) 711*800a58d9SAndroid Build Coastguard Worker self.CreateFile(kernel_log) 712*800a58d9SAndroid Build Coastguard Worker self.CreateFile(launcher_log) 713*800a58d9SAndroid Build Coastguard Worker self.CreateFile(logcat) 714*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(temp_dir, "legacy.log")) 715*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(log_dir, "log.txt")) 716*800a58d9SAndroid Build Coastguard Worker os.symlink(os.path.join(log_dir, "launcher.log"), 717*800a58d9SAndroid Build Coastguard Worker os.path.join(log_dir, "link.log")) 718*800a58d9SAndroid Build Coastguard Worker 719*800a58d9SAndroid Build Coastguard Worker logs = cvd_utils.FindLocalLogs(temp_dir, 2) 720*800a58d9SAndroid Build Coastguard Worker expected_logs = [ 721*800a58d9SAndroid Build Coastguard Worker { 722*800a58d9SAndroid Build Coastguard Worker "path": kernel_log, 723*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_KERNEL_LOG, 724*800a58d9SAndroid Build Coastguard Worker }, 725*800a58d9SAndroid Build Coastguard Worker { 726*800a58d9SAndroid Build Coastguard Worker "path": launcher_log, 727*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_CUTTLEFISH_LOG, 728*800a58d9SAndroid Build Coastguard Worker }, 729*800a58d9SAndroid Build Coastguard Worker { 730*800a58d9SAndroid Build Coastguard Worker "path": logcat, 731*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_LOGCAT, 732*800a58d9SAndroid Build Coastguard Worker }, 733*800a58d9SAndroid Build Coastguard Worker ] 734*800a58d9SAndroid Build Coastguard Worker self.assertEqual(expected_logs, 735*800a58d9SAndroid Build Coastguard Worker sorted(logs, key=lambda log: log["path"])) 736*800a58d9SAndroid Build Coastguard Worker 737*800a58d9SAndroid Build Coastguard Worker def testFindLocalLogsWithLegacyDir(self): 738*800a58d9SAndroid Build Coastguard Worker """Test FindLocalLogs with the runtime directory in Android 11.""" 739*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory() as temp_dir: 740*800a58d9SAndroid Build Coastguard Worker log_dir = os.path.join(temp_dir, "cuttlefish_runtime.2") 741*800a58d9SAndroid Build Coastguard Worker log_dir_link = os.path.join(temp_dir, "cuttlefish_runtime") 742*800a58d9SAndroid Build Coastguard Worker os.mkdir(log_dir) 743*800a58d9SAndroid Build Coastguard Worker os.symlink(log_dir, log_dir_link, target_is_directory=True) 744*800a58d9SAndroid Build Coastguard Worker launcher_log = os.path.join(log_dir_link, "launcher.log") 745*800a58d9SAndroid Build Coastguard Worker self.CreateFile(launcher_log) 746*800a58d9SAndroid Build Coastguard Worker 747*800a58d9SAndroid Build Coastguard Worker logs = cvd_utils.FindLocalLogs(log_dir_link, 2) 748*800a58d9SAndroid Build Coastguard Worker expected_logs = [ 749*800a58d9SAndroid Build Coastguard Worker { 750*800a58d9SAndroid Build Coastguard Worker "path": launcher_log, 751*800a58d9SAndroid Build Coastguard Worker "type": constants.LOG_TYPE_CUTTLEFISH_LOG, 752*800a58d9SAndroid Build Coastguard Worker }, 753*800a58d9SAndroid Build Coastguard Worker ] 754*800a58d9SAndroid Build Coastguard Worker self.assertEqual(expected_logs, logs) 755*800a58d9SAndroid Build Coastguard Worker 756*800a58d9SAndroid Build Coastguard Worker def testGetOpenWrtInfoDict(self): 757*800a58d9SAndroid Build Coastguard Worker """Test GetOpenWrtInfoDict.""" 758*800a58d9SAndroid Build Coastguard Worker mock_ssh = mock.Mock() 759*800a58d9SAndroid Build Coastguard Worker mock_ssh.GetBaseCmd.return_value = "/mock/ssh" 760*800a58d9SAndroid Build Coastguard Worker openwrt_info = { 761*800a58d9SAndroid Build Coastguard Worker "ssh_command": "/mock/ssh", 762*800a58d9SAndroid Build Coastguard Worker "screen_command": "screen ./cuttlefish_runtime/console"} 763*800a58d9SAndroid Build Coastguard Worker self.assertDictEqual(openwrt_info, 764*800a58d9SAndroid Build Coastguard Worker cvd_utils.GetOpenWrtInfoDict(mock_ssh, ".")) 765*800a58d9SAndroid Build Coastguard Worker mock_ssh.GetBaseCmd.assert_called_with("ssh") 766*800a58d9SAndroid Build Coastguard Worker 767*800a58d9SAndroid Build Coastguard Worker def testGetRemoteBuildInfoDict(self): 768*800a58d9SAndroid Build Coastguard Worker """Test GetRemoteBuildInfoDict.""" 769*800a58d9SAndroid Build Coastguard Worker remote_image = { 770*800a58d9SAndroid Build Coastguard Worker "branch": "aosp-android-12-gsi", 771*800a58d9SAndroid Build Coastguard Worker "build_id": "100000", 772*800a58d9SAndroid Build Coastguard Worker "build_target": "aosp_cf_x86_64_phone-userdebug"} 773*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock( 774*800a58d9SAndroid Build Coastguard Worker spec=[], 775*800a58d9SAndroid Build Coastguard Worker remote_image=remote_image, 776*800a58d9SAndroid Build Coastguard Worker kernel_build_info={"build_target": "kernel"}, 777*800a58d9SAndroid Build Coastguard Worker system_build_info={}, 778*800a58d9SAndroid Build Coastguard Worker bootloader_build_info={}, 779*800a58d9SAndroid Build Coastguard Worker android_efi_loader_build_info = {}) 780*800a58d9SAndroid Build Coastguard Worker self.assertEqual(remote_image, 781*800a58d9SAndroid Build Coastguard Worker cvd_utils.GetRemoteBuildInfoDict(mock_avd_spec)) 782*800a58d9SAndroid Build Coastguard Worker 783*800a58d9SAndroid Build Coastguard Worker kernel_build_info = { 784*800a58d9SAndroid Build Coastguard Worker "branch": "aosp_kernel-common-android12-5.10", 785*800a58d9SAndroid Build Coastguard Worker "build_id": "200000", 786*800a58d9SAndroid Build Coastguard Worker "build_target": "kernel_virt_x86_64"} 787*800a58d9SAndroid Build Coastguard Worker system_build_info = { 788*800a58d9SAndroid Build Coastguard Worker "branch": "aosp-android-12-gsi", 789*800a58d9SAndroid Build Coastguard Worker "build_id": "300000", 790*800a58d9SAndroid Build Coastguard Worker "build_target": "aosp_x86_64-userdebug"} 791*800a58d9SAndroid Build Coastguard Worker bootloader_build_info = { 792*800a58d9SAndroid Build Coastguard Worker "branch": "aosp_u-boot-mainline", 793*800a58d9SAndroid Build Coastguard Worker "build_id": "400000", 794*800a58d9SAndroid Build Coastguard Worker "build_target": "u-boot_crosvm_x86_64"} 795*800a58d9SAndroid Build Coastguard Worker android_efi_loader_build_info = { 796*800a58d9SAndroid Build Coastguard Worker "build_id": "500000", 797*800a58d9SAndroid Build Coastguard Worker "artifact": "gbl_aarch64.efi" 798*800a58d9SAndroid Build Coastguard Worker } 799*800a58d9SAndroid Build Coastguard Worker all_build_info = { 800*800a58d9SAndroid Build Coastguard Worker "kernel_branch": "aosp_kernel-common-android12-5.10", 801*800a58d9SAndroid Build Coastguard Worker "kernel_build_id": "200000", 802*800a58d9SAndroid Build Coastguard Worker "kernel_build_target": "kernel_virt_x86_64", 803*800a58d9SAndroid Build Coastguard Worker "system_branch": "aosp-android-12-gsi", 804*800a58d9SAndroid Build Coastguard Worker "system_build_id": "300000", 805*800a58d9SAndroid Build Coastguard Worker "system_build_target": "aosp_x86_64-userdebug", 806*800a58d9SAndroid Build Coastguard Worker "bootloader_branch": "aosp_u-boot-mainline", 807*800a58d9SAndroid Build Coastguard Worker "bootloader_build_id": "400000", 808*800a58d9SAndroid Build Coastguard Worker "bootloader_build_target": "u-boot_crosvm_x86_64", 809*800a58d9SAndroid Build Coastguard Worker "android_efi_loader_build_id": "500000", 810*800a58d9SAndroid Build Coastguard Worker "android_efi_loader_artifact": "gbl_aarch64.efi" 811*800a58d9SAndroid Build Coastguard Worker } 812*800a58d9SAndroid Build Coastguard Worker all_build_info.update(remote_image) 813*800a58d9SAndroid Build Coastguard Worker mock_avd_spec = mock.Mock( 814*800a58d9SAndroid Build Coastguard Worker spec=[], 815*800a58d9SAndroid Build Coastguard Worker remote_image=remote_image, 816*800a58d9SAndroid Build Coastguard Worker kernel_build_info=kernel_build_info, 817*800a58d9SAndroid Build Coastguard Worker system_build_info=system_build_info, 818*800a58d9SAndroid Build Coastguard Worker bootloader_build_info=bootloader_build_info, 819*800a58d9SAndroid Build Coastguard Worker android_efi_loader_build_info=android_efi_loader_build_info) 820*800a58d9SAndroid Build Coastguard Worker self.assertEqual(all_build_info, 821*800a58d9SAndroid Build Coastguard Worker cvd_utils.GetRemoteBuildInfoDict(mock_avd_spec)) 822*800a58d9SAndroid Build Coastguard Worker 823*800a58d9SAndroid Build Coastguard Worker def testFindMiscInfo(self): 824*800a58d9SAndroid Build Coastguard Worker """Test FindMiscInfo.""" 825*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory() as temp_dir: 826*800a58d9SAndroid Build Coastguard Worker with self.assertRaises(errors.CheckPathError): 827*800a58d9SAndroid Build Coastguard Worker cvd_utils.FindMiscInfo(temp_dir) 828*800a58d9SAndroid Build Coastguard Worker misc_info_path = os.path.join(temp_dir, "META", "misc_info.txt") 829*800a58d9SAndroid Build Coastguard Worker self.CreateFile(misc_info_path, b"key=value") 830*800a58d9SAndroid Build Coastguard Worker self.assertEqual(misc_info_path, cvd_utils.FindMiscInfo(temp_dir)) 831*800a58d9SAndroid Build Coastguard Worker 832*800a58d9SAndroid Build Coastguard Worker def testFindImageDir(self): 833*800a58d9SAndroid Build Coastguard Worker """Test FindImageDir.""" 834*800a58d9SAndroid Build Coastguard Worker with tempfile.TemporaryDirectory() as temp_dir: 835*800a58d9SAndroid Build Coastguard Worker with self.assertRaises(errors.GetLocalImageError): 836*800a58d9SAndroid Build Coastguard Worker cvd_utils.FindImageDir(temp_dir) 837*800a58d9SAndroid Build Coastguard Worker image_dir = os.path.join(temp_dir, "IMAGES") 838*800a58d9SAndroid Build Coastguard Worker self.CreateFile(os.path.join(image_dir, "super.img")) 839*800a58d9SAndroid Build Coastguard Worker self.assertEqual(image_dir, cvd_utils.FindImageDir(temp_dir)) 840*800a58d9SAndroid Build Coastguard Worker 841*800a58d9SAndroid Build Coastguard Worker 842*800a58d9SAndroid Build Coastguard Workerif __name__ == "__main__": 843*800a58d9SAndroid Build Coastguard Worker unittest.main() 844