1#!/usr/bin/env python3 2# 3# Copyright 2018 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16"""Tests for acloud.internal.lib.goldfish_compute_client.""" 17import unittest 18 19from unittest import mock 20 21from acloud import errors 22from acloud.internal.lib import driver_test_lib 23from acloud.internal.lib import gcompute_client 24from acloud.internal.lib import goldfish_compute_client 25 26 27class GoldfishComputeClientTest(driver_test_lib.BaseDriverTest): 28 """Test GoldfishComputeClient.""" 29 30 EMULATOR_FETCH_FAILED_LOG = """ 31Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: ERROR: EMULATOR_FETCH_FAILED 32Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: VIRTUAL_DEVICE_FAILED 33Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: VIRTUAL_DEVICE_BOOT_FAILED 34""" 35 ANDROID_FETCH_FAILED_LOG = """ 36Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: ERROR: ANDROID_FETCH_FAILED 37Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: VIRTUAL_DEVICE_FAILED 38Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: VIRTUAL_DEVICE_BOOT_FAILED 39""" 40 BOOT_TIMEOUT_LOG = """ 41Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: VIRTUAL_DEVICE_FAILED 42Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk fetch_cvd[123]: VIRTUAL_DEVICE_BOOT_FAILED 43""" 44 SUCCESS_LOG = """ 45Jan 12 12:00:00 ins-abcdefgh-5000000-sdk-x86-64-sdk launch_emulator[123]: VIRTUAL_DEVICE_BOOT_COMPLETED 46""" 47 SSH_PUBLIC_KEY_PATH = "" 48 INSTANCE = "fake-instance" 49 IMAGE = "fake-image" 50 IMAGE_PROJECT = "fake-iamge-project" 51 MACHINE_TYPE = "fake-machine-type" 52 NETWORK = "fake-network" 53 ZONE = "fake-zone" 54 BRANCH = "fake-branch" 55 TARGET = "sdk_phone_x86_64-sdk" 56 BUILD_ID = "2263051" 57 KERNEL_BRANCH = "kernel-p-dev-android-goldfish-4.14-x86-64" 58 KERNEL_BUILD_ID = "112233" 59 KERNEL_BUILD_TARGET = "kernel_x86_64" 60 KERNEL_BUILD_ARTIFACT = "bzImage" 61 EMULATOR_BRANCH = "aosp-emu-master-dev" 62 EMULATOR_BUILD_ID = "1234567" 63 EMULATOR_BUILD_TARGET = "emulator-linux_x64_nolocationui" 64 DPI = 160 65 X_RES = 720 66 Y_RES = 1280 67 AVD_SPEC_FLAVOR = "sdk_phone_x86_64" 68 AVD_SPEC_DPI = 320 69 AVD_SPEC_X_RES = 2560 70 AVD_SPEC_Y_RES = 1800 71 METADATA = {"metadata_key": "metadata_value"} 72 EXTRA_DATA_DISK_SIZE_GB = 4 73 BOOT_DISK_SIZE_GB = 10 74 GPU = "nvidia-tesla-k80" 75 EXTRA_SCOPES = "scope1" 76 TAGS = ['http-server'] 77 LAUNCH_ARGS = "fake-args" 78 79 def _GetFakeConfig(self): 80 """Create a fake configuration object. 81 82 Returns: 83 A fake configuration mock object. 84 """ 85 fake_cfg = mock.MagicMock() 86 fake_cfg.ssh_public_key_path = self.SSH_PUBLIC_KEY_PATH 87 fake_cfg.machine_type = self.MACHINE_TYPE 88 fake_cfg.network = self.NETWORK 89 fake_cfg.zone = self.ZONE 90 fake_cfg.resolution = "{x}x{y}x32x{dpi}".format( 91 x=self.X_RES, y=self.Y_RES, dpi=self.DPI) 92 fake_cfg.metadata_variable = self.METADATA 93 fake_cfg.extra_data_disk_size_gb = self.EXTRA_DATA_DISK_SIZE_GB 94 fake_cfg.extra_scopes = self.EXTRA_SCOPES 95 fake_cfg.launch_args = self.LAUNCH_ARGS 96 return fake_cfg 97 98 def setUp(self): 99 """Set up the test.""" 100 super().setUp() 101 self.Patch(goldfish_compute_client.GoldfishComputeClient, 102 "InitResourceHandle") 103 self.goldfish_compute_client = ( 104 goldfish_compute_client.GoldfishComputeClient( 105 self._GetFakeConfig(), mock.MagicMock())) 106 self.Patch( 107 gcompute_client.ComputeClient, 108 "CompareMachineSize", 109 return_value=1) 110 self.Patch( 111 gcompute_client.ComputeClient, 112 "GetImage", 113 return_value={"diskSizeGb": 10}) 114 self._mock_create_instance = self.Patch( 115 gcompute_client.ComputeClient, "CreateInstance") 116 self.Patch( 117 goldfish_compute_client.GoldfishComputeClient, 118 "_GetDiskArgs", 119 return_value=[{ 120 "fake_arg": "fake_value" 121 }]) 122 self.Patch(goldfish_compute_client.GoldfishComputeClient, 123 "_VerifyZoneByQuota", 124 return_value=True) 125 126 def testCheckBootFailure(self): 127 """Test CheckBootFailure.""" 128 with self.assertRaisesRegex(errors.DownloadArtifactError, 129 "Failed to download emulator build"): 130 self.goldfish_compute_client.CheckBootFailure( 131 self.EMULATOR_FETCH_FAILED_LOG, None) 132 133 with self.assertRaisesRegex(errors.DownloadArtifactError, 134 "Failed to download system image build"): 135 self.goldfish_compute_client.CheckBootFailure( 136 self.ANDROID_FETCH_FAILED_LOG, None) 137 138 with self.assertRaisesRegex(errors.DeviceBootError, 139 "Emulator timed out while booting"): 140 self.goldfish_compute_client.CheckBootFailure( 141 self.BOOT_TIMEOUT_LOG, None) 142 143 self.goldfish_compute_client.CheckBootFailure(self.SUCCESS_LOG, None) 144 145 @mock.patch("getpass.getuser", return_value="fake_user") 146 def testCreateInstance(self, _mock_user): 147 """Test CreateInstance.""" 148 149 expected_metadata = { 150 "user": "fake_user", 151 "avd_type": "goldfish", 152 "cvd_01_fetch_android_build_target": self.TARGET, 153 "cvd_01_fetch_android_bid": 154 "{branch}/{build_id}".format( 155 branch=self.BRANCH, build_id=self.BUILD_ID), 156 "cvd_01_fetch_kernel_bid": 157 "{branch}/{build_id}".format( 158 branch=self.KERNEL_BRANCH, build_id=self.KERNEL_BUILD_ID), 159 "cvd_01_fetch_kernel_build_target": self.KERNEL_BUILD_TARGET, 160 "cvd_01_fetch_kernel_build_artifact": self.KERNEL_BUILD_ARTIFACT, 161 "cvd_01_use_custom_kernel": "true", 162 "cvd_01_fetch_emulator_bid": 163 "{branch}/{build_id}".format( 164 branch=self.EMULATOR_BRANCH, 165 build_id=self.EMULATOR_BUILD_ID), 166 "cvd_01_fetch_emulator_build_target": self.EMULATOR_BUILD_TARGET, 167 "cvd_01_launch": "1", 168 "cvd_01_dpi": str(self.DPI), 169 "cvd_01_x_res": str(self.X_RES), 170 "cvd_01_y_res": str(self.Y_RES), 171 "launch_args": self.LAUNCH_ARGS, 172 } 173 expected_metadata.update(self.METADATA) 174 expected_disk_args = [{"fake_arg": "fake_value"}] 175 176 self.goldfish_compute_client.CreateInstance( 177 self.INSTANCE, self.IMAGE, self.IMAGE_PROJECT, self.TARGET, 178 self.BRANCH, self.BUILD_ID, 179 self.KERNEL_BRANCH, 180 self.KERNEL_BUILD_ID, 181 self.KERNEL_BUILD_TARGET, 182 self.EMULATOR_BRANCH, 183 self.EMULATOR_BUILD_ID, 184 self.EMULATOR_BUILD_TARGET, 185 self.EXTRA_DATA_DISK_SIZE_GB, self.GPU, 186 extra_scopes=self.EXTRA_SCOPES, 187 tags=self.TAGS, 188 launch_args=self.LAUNCH_ARGS) 189 190 self._mock_create_instance.assert_called_with( 191 self.goldfish_compute_client, 192 instance=self.INSTANCE, 193 image_name=self.IMAGE, 194 image_project=self.IMAGE_PROJECT, 195 disk_args=expected_disk_args, 196 metadata=expected_metadata, 197 machine_type=self.MACHINE_TYPE, 198 network=self.NETWORK, 199 zone=self.ZONE, 200 gpu=self.GPU, 201 tags=self.TAGS, 202 extra_scopes=self.EXTRA_SCOPES) 203 204 @mock.patch("getpass.getuser", return_value="fake_user") 205 def testCreateInstanceWithAvdSpec(self, _mock_user): 206 """Test CreateInstance with AVD spec overriding metadata.""" 207 208 expected_metadata = { 209 "user": "fake_user", 210 "avd_type": "goldfish", 211 "cvd_01_fetch_android_build_target": self.TARGET, 212 "cvd_01_fetch_android_bid": 213 "{branch}/{build_id}".format( 214 branch=self.BRANCH, build_id=self.BUILD_ID), 215 "cvd_01_fetch_kernel_bid": 216 "{branch}/{build_id}".format( 217 branch=self.KERNEL_BRANCH, build_id=self.KERNEL_BUILD_ID), 218 "cvd_01_fetch_kernel_build_target": self.KERNEL_BUILD_TARGET, 219 "cvd_01_fetch_kernel_build_artifact": self.KERNEL_BUILD_ARTIFACT, 220 "cvd_01_use_custom_kernel": "true", 221 "cvd_01_fetch_emulator_bid": 222 "{branch}/{build_id}".format( 223 branch=self.EMULATOR_BRANCH, 224 build_id=self.EMULATOR_BUILD_ID), 225 "cvd_01_fetch_emulator_build_target": self.EMULATOR_BUILD_TARGET, 226 "cvd_01_launch": "1", 227 "display": 228 "{x}x{y} ({dpi})".format( 229 x=self.AVD_SPEC_X_RES, 230 y=self.AVD_SPEC_Y_RES, 231 dpi=self.AVD_SPEC_DPI), 232 "flavor": self.AVD_SPEC_FLAVOR, 233 "cvd_01_dpi": str(self.AVD_SPEC_DPI), 234 "cvd_01_x_res": str(self.AVD_SPEC_X_RES), 235 "cvd_01_y_res": str(self.AVD_SPEC_Y_RES), 236 "launch_args": self.LAUNCH_ARGS, 237 } 238 expected_metadata.update(self.METADATA) 239 expected_disk_args = [{"fake_arg": "fake_value"}] 240 241 avd_spec_attrs = { 242 "flavor": self.AVD_SPEC_FLAVOR, 243 "hw_property": { 244 "x_res": str(self.AVD_SPEC_X_RES), 245 "y_res": str(self.AVD_SPEC_Y_RES), 246 "dpi": str(self.AVD_SPEC_DPI), 247 }, 248 } 249 mock_avd_spec = mock.Mock(spec=[avd_spec_attrs.keys()], 250 **avd_spec_attrs) 251 252 self.goldfish_compute_client.CreateInstance( 253 self.INSTANCE, self.IMAGE, self.IMAGE_PROJECT, self.TARGET, 254 self.BRANCH, self.BUILD_ID, self.KERNEL_BRANCH, 255 self.KERNEL_BUILD_ID, self.KERNEL_BUILD_TARGET, 256 self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID, 257 self.EMULATOR_BUILD_TARGET, self.EXTRA_DATA_DISK_SIZE_GB, self.GPU, 258 avd_spec=mock_avd_spec, extra_scopes=self.EXTRA_SCOPES, 259 tags=self.TAGS, launch_args=self.LAUNCH_ARGS) 260 261 self._mock_create_instance.assert_called_with( 262 self.goldfish_compute_client, 263 instance=self.INSTANCE, 264 image_name=self.IMAGE, 265 image_project=self.IMAGE_PROJECT, 266 disk_args=expected_disk_args, 267 metadata=expected_metadata, 268 machine_type=self.MACHINE_TYPE, 269 network=self.NETWORK, 270 zone=self.ZONE, 271 gpu=self.GPU, 272 tags=self.TAGS, 273 extra_scopes=self.EXTRA_SCOPES) 274 275 276if __name__ == "__main__": 277 unittest.main() 278