• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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