1#!/usr/bin/env python
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.public.actions.create_goldfish_actions."""
17import uuid
18import unittest
19
20from unittest import mock
21
22from acloud.internal import constants
23from acloud.internal.lib import android_build_client
24from acloud.internal.lib import android_compute_client
25from acloud.internal.lib import auth
26from acloud.internal.lib import driver_test_lib
27from acloud.internal.lib import goldfish_compute_client
28from acloud.internal.lib import ssh
29from acloud.public.actions import create_goldfish_action
30
31
32class CreateGoldfishActionTest(driver_test_lib.BaseDriverTest):
33    """Tests create_goldfish_action."""
34
35    IP = ssh.IP(external="127.0.0.1", internal="10.0.0.1")
36    INSTANCE = "fake-instance"
37    IMAGE = "fake-image"
38    BUILD_TARGET = "fake-build-target"
39    EMULATOR_BUILD_TARGET = "emu-fake-target"
40    BUILD_ID = "12345"
41    EMULATOR_BUILD_ID = "1234567"
42    GPU = "nvidia-tesla-k80"
43    BRANCH = "fake-branch"
44    EMULATOR_BRANCH = "emu-fake-branch"
45    KERNEL_BRANCH = "fake-kernel-branch"
46    KERNEL_BUILD_ID = "54321"
47    KERNEL_BUILD_TARGET = "kernel"
48    GOLDFISH_HOST_IMAGE_NAME = "fake-stable-host-image-name"
49    GOLDFISH_HOST_IMAGE_PROJECT = "fake-stable-host-image-project"
50    EXTRA_DATA_DISK_GB = 4
51    EXTRA_SCOPES = None
52    LAUNCH_ARGS = "fake-args"
53    DEFAULT_ADB_PORT = 5555
54
55    def setUp(self):
56        """Sets up the test."""
57        super().setUp()
58        self.build_client = mock.MagicMock()
59        self.Patch(
60            android_build_client,
61            "AndroidBuildClient",
62            return_value=self.build_client)
63        self.compute_client = mock.MagicMock()
64        self.compute_client.openwrt = False
65        self.compute_client.gce_hostname = None
66        self.Patch(
67            goldfish_compute_client,
68            "GoldfishComputeClient",
69            return_value=self.compute_client)
70        self.Patch(
71            android_compute_client,
72            "AndroidComputeClient",
73            return_value=self.compute_client)
74        self.Patch(auth, "CreateCredentials", return_value=mock.MagicMock())
75        #Initialize new avd_spec
76        self.avd_spec = mock.MagicMock()
77        self.avd_spec.cfg = self._CreateCfg()
78        self.avd_spec.remote_image = {constants.BUILD_ID: self.BUILD_ID,
79                                      constants.BUILD_BRANCH: self.BRANCH,
80                                      constants.BUILD_TARGET: self.BUILD_TARGET}
81        self.avd_spec.emulator_build_id = self.EMULATOR_BUILD_ID
82        self.avd_spec.gpu = self.GPU
83        self.avd_spec.serial_log_file = None
84        self.avd_spec.autoconnect = False
85
86    def _CreateCfg(self):
87        """A helper method that creates a mock configuration object."""
88        cfg = mock.MagicMock()
89        cfg.service_account_name = "fake@service.com"
90        cfg.service_account_private_key_path = "/fake/path/to/key"
91        cfg.zone = "fake_zone"
92        cfg.ssh_private_key_path = ""
93        cfg.ssh_public_key_path = ""
94        cfg.stable_goldfish_host_image_name = self.GOLDFISH_HOST_IMAGE_NAME
95        cfg.stable_goldfish_host_image_project = self.GOLDFISH_HOST_IMAGE_PROJECT
96        cfg.emulator_build_target = self.EMULATOR_BUILD_TARGET
97        cfg.extra_data_disk_size_gb = self.EXTRA_DATA_DISK_GB
98        cfg.extra_scopes = self.EXTRA_SCOPES
99        cfg.launch_args = self.LAUNCH_ARGS
100        return cfg
101
102    def testCreateDevices(self):
103        """Tests CreateDevices."""
104        cfg = self._CreateCfg()
105
106        # Mock uuid
107        fake_uuid = mock.MagicMock(hex="1234")
108        self.Patch(uuid, "uuid4", return_value=fake_uuid)
109
110        # Mock compute client methods
111        self.compute_client.GetInstanceIP.return_value = self.IP
112        self.compute_client.GenerateImageName.return_value = self.IMAGE
113        self.compute_client.GenerateInstanceName.return_value = self.INSTANCE
114
115        # Mock build client method
116        self.build_client.GetBuildInfo.side_effect = [
117            android_build_client.BuildInfo(
118                self.BRANCH, self.BUILD_ID, self.BUILD_TARGET, None),
119            android_build_client.BuildInfo(
120                self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID,
121                self.EMULATOR_BUILD_TARGET, None),
122            android_build_client.BuildInfo(
123                self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
124                self.KERNEL_BUILD_TARGET, None)]
125
126        none_avd_spec = None
127
128        # Call CreateDevices with avd_spec is None
129        report = create_goldfish_action.CreateDevices(
130            none_avd_spec, cfg, build_target=self.BUILD_TARGET,
131            build_id=self.BUILD_ID, emulator_build_id=self.EMULATOR_BUILD_ID,
132            gpu=self.GPU,
133            kernel_branch=self.KERNEL_BRANCH,
134            kernel_build_id=self.KERNEL_BUILD_ID,
135            kernel_build_target=self.KERNEL_BUILD_TARGET)
136
137        # Verify
138        self.compute_client.CreateInstance.assert_called_with(
139            instance=self.INSTANCE,
140            blank_data_disk_size_gb=self.EXTRA_DATA_DISK_GB,
141            image_name=self.GOLDFISH_HOST_IMAGE_NAME,
142            image_project=self.GOLDFISH_HOST_IMAGE_PROJECT,
143            build_target=self.BUILD_TARGET,
144            branch=self.BRANCH,
145            build_id=self.BUILD_ID,
146            emulator_branch=self.EMULATOR_BRANCH,
147            emulator_build_id=self.EMULATOR_BUILD_ID,
148            emulator_build_target=self.EMULATOR_BUILD_TARGET,
149            kernel_branch=self.KERNEL_BRANCH,
150            kernel_build_id=self.KERNEL_BUILD_ID,
151            kernel_build_target=self.KERNEL_BUILD_TARGET,
152            gpu=self.GPU,
153            avd_spec=none_avd_spec,
154            extra_scopes=self.EXTRA_SCOPES,
155            tags=None,
156            launch_args=self.LAUNCH_ARGS)
157
158        self.assertEqual(report.data, {
159            "devices": [
160                {
161                    "instance_name": self.INSTANCE,
162                    "ip": self.IP.external + ":" + str(self.DEFAULT_ADB_PORT),
163                    "branch": self.BRANCH,
164                    "build_id": self.BUILD_ID,
165                    "build_target": self.BUILD_TARGET,
166                    "emulator_branch": self.EMULATOR_BRANCH,
167                    "emulator_build_id": self.EMULATOR_BUILD_ID,
168                    "emulator_build_target": self.EMULATOR_BUILD_TARGET,
169                    "kernel_branch": self.KERNEL_BRANCH,
170                    "kernel_build_id": self.KERNEL_BUILD_ID,
171                    "kernel_build_target": self.KERNEL_BUILD_TARGET,
172                },
173            ],
174        })
175        self.assertEqual(report.command, "create_gf")
176        self.assertEqual(report.status, "SUCCESS")
177
178        # Call CreateDevices with avd_spec
179        self.build_client.GetBranch.side_effect = [
180            self.BRANCH, self.EMULATOR_BRANCH
181        ]
182        # TODO: Break out avd spec testing into its own testcase.
183        # Mock build client method
184        self.build_client.GetBuildInfo.side_effect = [
185            android_build_client.BuildInfo(
186                self.BRANCH, self.BUILD_ID, self.BUILD_TARGET, None),
187            android_build_client.BuildInfo(
188                self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID,
189                self.EMULATOR_BUILD_TARGET, None),
190            android_build_client.BuildInfo(
191                self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
192                self.KERNEL_BUILD_TARGET, None)]
193
194        report = create_goldfish_action.CreateDevices(avd_spec=self.avd_spec)
195        # Verify
196        self.compute_client.CreateInstance.assert_called_with(
197            instance=self.INSTANCE,
198            blank_data_disk_size_gb=self.EXTRA_DATA_DISK_GB,
199            image_name=self.GOLDFISH_HOST_IMAGE_NAME,
200            image_project=self.GOLDFISH_HOST_IMAGE_PROJECT,
201            build_target=self.BUILD_TARGET,
202            branch=self.BRANCH,
203            build_id=self.BUILD_ID,
204            emulator_branch=self.EMULATOR_BRANCH,
205            emulator_build_id=self.EMULATOR_BUILD_ID,
206            emulator_build_target=self.EMULATOR_BUILD_TARGET,
207            kernel_branch=self.KERNEL_BRANCH,
208            kernel_build_id=self.KERNEL_BUILD_ID,
209            kernel_build_target=self.KERNEL_BUILD_TARGET,
210            gpu=self.GPU,
211            avd_spec=self.avd_spec,
212            extra_scopes=self.EXTRA_SCOPES,
213            tags=None,
214            launch_args=self.LAUNCH_ARGS)
215
216    def testCreateDevicesWithoutBuildId(self):
217        """Test CreateDevices when emulator sysimage buildid is not provided."""
218        cfg = self._CreateCfg()
219
220        # Mock uuid
221        fake_uuid = mock.MagicMock(hex="1234")
222        self.Patch(uuid, "uuid4", return_value=fake_uuid)
223
224        # Mock compute client methods
225        self.compute_client.GetInstanceIP.return_value = self.IP
226        self.compute_client.GenerateImageName.return_value = self.IMAGE
227        self.compute_client.GenerateInstanceName.return_value = self.INSTANCE
228
229        # Mock build client method
230        self.build_client.GetBuildInfo.side_effect = [
231            android_build_client.BuildInfo(
232                self.BRANCH, self.BUILD_ID, self.BUILD_TARGET, None),
233            android_build_client.BuildInfo(
234                self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID,
235                self.EMULATOR_BUILD_TARGET, None),
236            android_build_client.BuildInfo(
237                self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
238                self.KERNEL_BUILD_TARGET, None)]
239
240        # Mock _FetchBuildIdFromFile method
241        self.Patch(
242            create_goldfish_action,
243            "_FetchBuildIdFromFile",
244            return_value=self.BUILD_ID)
245
246        none_avd_spec = None
247        # Call CreateDevices with no avd_spec
248        report = create_goldfish_action.CreateDevices(
249            none_avd_spec,
250            cfg,
251            build_target=self.BUILD_TARGET,
252            build_id=None,
253            emulator_build_id=self.EMULATOR_BUILD_ID,
254            emulator_branch=None,
255            gpu=self.GPU,
256            branch=None,
257            kernel_branch=self.KERNEL_BRANCH,
258            kernel_build_id=self.KERNEL_BUILD_ID,
259            kernel_build_target=self.KERNEL_BUILD_TARGET)
260
261        # Verify
262        self.compute_client.CreateInstance.assert_called_with(
263            instance=self.INSTANCE,
264            blank_data_disk_size_gb=self.EXTRA_DATA_DISK_GB,
265            image_name=self.GOLDFISH_HOST_IMAGE_NAME,
266            image_project=self.GOLDFISH_HOST_IMAGE_PROJECT,
267            build_target=self.BUILD_TARGET,
268            branch=self.BRANCH,
269            build_id=self.BUILD_ID,
270            emulator_branch=self.EMULATOR_BRANCH,
271            emulator_build_id=self.EMULATOR_BUILD_ID,
272            emulator_build_target=self.EMULATOR_BUILD_TARGET,
273            kernel_branch=self.KERNEL_BRANCH,
274            kernel_build_id=self.KERNEL_BUILD_ID,
275            kernel_build_target=self.KERNEL_BUILD_TARGET,
276            gpu=self.GPU,
277            avd_spec=none_avd_spec,
278            extra_scopes=self.EXTRA_SCOPES,
279            tags=None,
280            launch_args=self.LAUNCH_ARGS)
281
282        self.assertEqual(report.data, {
283            "devices": [{
284                "instance_name": self.INSTANCE,
285                "ip": self.IP.external + ":" + str(self.DEFAULT_ADB_PORT),
286                "branch": self.BRANCH,
287                "build_id": self.BUILD_ID,
288                "build_target": self.BUILD_TARGET,
289                "emulator_branch": self.EMULATOR_BRANCH,
290                "emulator_build_id": self.EMULATOR_BUILD_ID,
291                "emulator_build_target": self.EMULATOR_BUILD_TARGET,
292                "kernel_branch": self.KERNEL_BRANCH,
293                "kernel_build_id": self.KERNEL_BUILD_ID,
294                "kernel_build_target": self.KERNEL_BUILD_TARGET,
295            },],
296        })
297        self.assertEqual(report.command, "create_gf")
298        self.assertEqual(report.status, "SUCCESS")
299
300        # Call CreateDevices with avd_spec
301        self.build_client.GetBranch.side_effect = [
302            self.BRANCH, self.EMULATOR_BRANCH
303        ]
304        # TODO: Break out avd spec testing into its own testcase.
305        # Mock build client method
306        self.build_client.GetBuildInfo.side_effect = [
307            android_build_client.BuildInfo(
308                self.BRANCH, self.BUILD_ID, self.BUILD_TARGET, None),
309            android_build_client.BuildInfo(
310                self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID,
311                self.EMULATOR_BUILD_TARGET, None),
312            android_build_client.BuildInfo(
313                self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
314                self.KERNEL_BUILD_TARGET, None)]
315
316        report = create_goldfish_action.CreateDevices(avd_spec=self.avd_spec)
317        # Verify
318        self.compute_client.CreateInstance.assert_called_with(
319            instance=self.INSTANCE,
320            blank_data_disk_size_gb=self.EXTRA_DATA_DISK_GB,
321            image_name=self.GOLDFISH_HOST_IMAGE_NAME,
322            image_project=self.GOLDFISH_HOST_IMAGE_PROJECT,
323            build_target=self.BUILD_TARGET,
324            branch=self.BRANCH,
325            build_id=self.BUILD_ID,
326            emulator_branch=self.EMULATOR_BRANCH,
327            emulator_build_id=self.EMULATOR_BUILD_ID,
328            emulator_build_target=self.EMULATOR_BUILD_TARGET,
329            kernel_branch=self.KERNEL_BRANCH,
330            kernel_build_id=self.KERNEL_BUILD_ID,
331            kernel_build_target=self.KERNEL_BUILD_TARGET,
332            gpu=self.GPU,
333            avd_spec=self.avd_spec,
334            extra_scopes=self.EXTRA_SCOPES,
335            tags=None,
336            launch_args=self.LAUNCH_ARGS)
337
338    #pylint: disable=invalid-name
339    def testCreateDevicesWithoutEmulatorBuildId(self):
340        """Test CreateDevices when emulator build id is not provided."""
341        cfg = self._CreateCfg()
342
343        # Mock uuid
344        fake_uuid = mock.MagicMock(hex="1234")
345        self.Patch(uuid, "uuid4", return_value=fake_uuid)
346
347        # Mock compute client methods
348        self.compute_client.GetInstanceIP.return_value = self.IP
349        self.compute_client.GenerateImageName.return_value = self.IMAGE
350        self.compute_client.GenerateInstanceName.return_value = self.INSTANCE
351
352        # Mock build client method
353        self.build_client.GetBuildInfo.side_effect = [
354            android_build_client.BuildInfo(
355                self.BRANCH, self.BUILD_ID, self.BUILD_TARGET, None),
356            android_build_client.BuildInfo(
357                self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID,
358                self.EMULATOR_BUILD_TARGET, None),
359            android_build_client.BuildInfo(
360                self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
361                self.KERNEL_BUILD_TARGET, None)]
362
363        # Mock _FetchBuildIdFromFile method
364        self.Patch(
365            create_goldfish_action,
366            "_FetchBuildIdFromFile",
367            return_value=self.EMULATOR_BUILD_ID)
368
369        none_avd_spec = None
370        # Call CreateDevices
371        report = create_goldfish_action.CreateDevices(
372            none_avd_spec, cfg, build_target=self.BUILD_TARGET,
373            build_id=self.BUILD_ID, emulator_build_id=None,
374            gpu=self.GPU)
375
376        # Verify
377        self.compute_client.CreateInstance.assert_called_with(
378            instance=self.INSTANCE,
379            blank_data_disk_size_gb=self.EXTRA_DATA_DISK_GB,
380            image_name=self.GOLDFISH_HOST_IMAGE_NAME,
381            image_project=self.GOLDFISH_HOST_IMAGE_PROJECT,
382            build_target=self.BUILD_TARGET,
383            branch=self.BRANCH,
384            build_id=self.BUILD_ID,
385            emulator_branch=self.EMULATOR_BRANCH,
386            emulator_build_id=self.EMULATOR_BUILD_ID,
387            emulator_build_target=self.EMULATOR_BUILD_TARGET,
388            kernel_branch=self.KERNEL_BRANCH,
389            kernel_build_id=self.KERNEL_BUILD_ID,
390            kernel_build_target=self.KERNEL_BUILD_TARGET,
391            gpu=self.GPU,
392            avd_spec=none_avd_spec,
393            extra_scopes=self.EXTRA_SCOPES,
394            tags=None,
395            launch_args=self.LAUNCH_ARGS)
396
397        self.assertEqual(report.data, {
398            "devices": [{
399                "instance_name": self.INSTANCE,
400                "ip": self.IP.external + ":" + str(self.DEFAULT_ADB_PORT),
401                "branch": self.BRANCH,
402                "build_id": self.BUILD_ID,
403                "build_target": self.BUILD_TARGET,
404                "emulator_branch": self.EMULATOR_BRANCH,
405                "emulator_build_id": self.EMULATOR_BUILD_ID,
406                "emulator_build_target": self.EMULATOR_BUILD_TARGET,
407                "kernel_branch": self.KERNEL_BRANCH,
408                "kernel_build_id": self.KERNEL_BUILD_ID,
409                "kernel_build_target": self.KERNEL_BUILD_TARGET,
410            },],
411        })
412        self.assertEqual(report.command, "create_gf")
413        self.assertEqual(report.status, "SUCCESS")
414
415        # Call CreateDevices with avd_spec
416        self.build_client.GetBranch.side_effect = [
417            self.BRANCH, self.EMULATOR_BRANCH
418        ]
419        # TODO: Break out avd spec testing into its own testcase.
420        # Mock build client method
421        self.build_client.GetBuildInfo.side_effect = [
422            android_build_client.BuildInfo(
423                self.BRANCH, self.BUILD_ID, self.BUILD_TARGET, None),
424            android_build_client.BuildInfo(
425                self.EMULATOR_BRANCH, self.EMULATOR_BUILD_ID,
426                self.EMULATOR_BUILD_TARGET, None),
427            android_build_client.BuildInfo(
428                self.KERNEL_BRANCH, self.KERNEL_BUILD_ID,
429                self.KERNEL_BUILD_TARGET, None)]
430
431        report = create_goldfish_action.CreateDevices(avd_spec=self.avd_spec)
432        # Verify
433        self.compute_client.CreateInstance.assert_called_with(
434            instance=self.INSTANCE,
435            blank_data_disk_size_gb=self.EXTRA_DATA_DISK_GB,
436            image_name=self.GOLDFISH_HOST_IMAGE_NAME,
437            image_project=self.GOLDFISH_HOST_IMAGE_PROJECT,
438            build_target=self.BUILD_TARGET,
439            branch=self.BRANCH,
440            build_id=self.BUILD_ID,
441            emulator_branch=self.EMULATOR_BRANCH,
442            emulator_build_id=self.EMULATOR_BUILD_ID,
443            emulator_build_target=self.EMULATOR_BUILD_TARGET,
444            kernel_branch=self.KERNEL_BRANCH,
445            kernel_build_id=self.KERNEL_BUILD_ID,
446            kernel_build_target=self.KERNEL_BUILD_TARGET,
447            gpu=self.GPU,
448            avd_spec=self.avd_spec,
449            extra_scopes=self.EXTRA_SCOPES,
450            tags=None,
451            launch_args=self.LAUNCH_ARGS)
452
453
454if __name__ == "__main__":
455    unittest.main()
456