xref: /aosp_15_r20/tools/acloud/create/avd_spec_test.py (revision 800a58d989c669b8eb8a71d8df53b1ba3d411444)
1# Copyright 2018 - The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Tests for avd_spec."""
15
16import glob
17import os
18import subprocess
19import unittest
20
21from unittest import mock
22
23from acloud import errors
24from acloud.create import avd_spec
25from acloud.internal import constants
26from acloud.internal.lib import android_build_client
27from acloud.internal.lib import auth
28from acloud.internal.lib import driver_test_lib
29from acloud.internal.lib import utils
30from acloud.list import list as list_instances
31from acloud.public import config
32
33
34# pylint: disable=invalid-name,protected-access
35class AvdSpecTest(driver_test_lib.BaseDriverTest):
36    """Test avd_spec methods."""
37
38    def setUp(self):
39        """Initialize new avd_spec.AVDSpec."""
40        super().setUp()
41        self.args = mock.MagicMock()
42        self.args.flavor = ""
43        self.args.local_image = None
44        self.args.local_kernel_image = None
45        self.args.local_system_image = None
46        self.args.local_vendor_boot_image = None
47        self.args.config_file = ""
48        self.args.build_target = "fake_build_target"
49        self.args.adb_port = None
50        self.args.launch_args = None
51        self.Patch(list_instances, "ChooseOneRemoteInstance", return_value=mock.MagicMock())
52        self.Patch(list_instances, "GetInstancesFromInstanceNames", return_value=mock.MagicMock())
53
54        # Setup mock Acloud config for usage in tests.
55        self.mock_config = mock.MagicMock()
56        self.mock_config.launch_args = None
57        self.Patch(config, 'GetAcloudConfig', return_value=self.mock_config)
58
59        self.AvdSpec = avd_spec.AVDSpec(self.args)
60
61    # pylint: disable=protected-access
62    def testProcessLocalImageArgs(self):
63        """Test process args.local_image."""
64        self.Patch(glob, "glob", return_value=["fake.img"])
65        expected_image_artifact = "/path/cf_x86_phone-img-eng.user.zip"
66        expected_image_dir = "/path-to-image-dir"
67        self.Patch(os.path, "exists",
68                   side_effect=lambda path: path in (expected_image_artifact,
69                                                     expected_image_dir))
70        self.Patch(os.path, "isdir",
71                   side_effect=lambda path: path == expected_image_dir)
72        self.Patch(os.path, "isfile",
73                   side_effect=lambda path: path == expected_image_artifact)
74
75        # Specified --local-image to a local zipped image file
76        self.args.local_image = "/path/cf_x86_phone-img-eng.user.zip"
77        self.AvdSpec._avd_type = constants.TYPE_CF
78        self.AvdSpec._instance_type = constants.INSTANCE_TYPE_REMOTE
79        self.AvdSpec._ProcessLocalImageArgs(self.args)
80        self.assertEqual(self.AvdSpec._local_image_artifact,
81                         expected_image_artifact)
82
83        # Specified --local-image to a dir contains images
84        self.Patch(utils, "GetBuildEnvironmentVariable",
85                   return_value="test_cf_x86")
86        self.args.local_image = "/path-to-image-dir"
87        self.AvdSpec._avd_type = constants.TYPE_CF
88        self.AvdSpec._instance_type = constants.INSTANCE_TYPE_REMOTE
89        self.AvdSpec._ProcessLocalImageArgs(self.args)
90        self.assertEqual(self.AvdSpec._local_image_dir, expected_image_dir)
91
92        # Specified local_image without arg
93        self.args.local_image = constants.FIND_IN_BUILD_ENV
94        self.Patch(utils, "GetBuildEnvironmentVariable",
95                   side_effect=["cf_x86_auto", "test_environ", "test_environ"])
96        self.AvdSpec._ProcessLocalImageArgs(self.args)
97        self.assertEqual(self.AvdSpec._local_image_dir, "test_environ")
98        self.assertEqual(self.AvdSpec.local_image_artifact, expected_image_artifact)
99
100        # Specified --avd-type=goldfish --local-image with a dir
101        self.Patch(utils, "GetBuildEnvironmentVariable",
102                   return_value="test_environ")
103        self.args.local_image = "/path-to-image-dir"
104        self.AvdSpec._avd_type = constants.TYPE_GF
105        self.AvdSpec._instance_type = constants.INSTANCE_TYPE_LOCAL
106        self.AvdSpec._ProcessLocalImageArgs(self.args)
107        self.assertEqual(self.AvdSpec._local_image_dir, expected_image_dir)
108
109    def testProcessLocalMixedImageArgs(self):
110        """Test process args.local_kernel_image and args.local_system_image."""
111        expected_image_dir = "/path-to-image-dir"
112        expected_image_file = "/path-to-image-file"
113        self.Patch(os.path, "exists",
114                   side_effect=lambda path: path in (expected_image_file,
115                                                     expected_image_dir))
116        self.Patch(os.path, "isdir",
117                   side_effect=lambda path: path == expected_image_dir)
118        self.Patch(os.path, "isfile",
119                   side_effect=lambda path: path == expected_image_file)
120
121        # Specified --local-*-image with dirs.
122        self.args.local_kernel_image = expected_image_dir
123        self.args.local_system_image = expected_image_dir
124        self.args.local_system_dlkm_image = expected_image_dir
125        self.args.local_vendor_image = expected_image_dir
126        self.AvdSpec._ProcessImageArgs(self.args)
127        self.assertEqual(self.AvdSpec.local_kernel_image, expected_image_dir)
128        self.assertEqual(self.AvdSpec.local_system_image, expected_image_dir)
129        self.assertEqual(self.AvdSpec.local_system_dlkm_image, expected_image_dir)
130        self.assertEqual(self.AvdSpec.local_vendor_image, expected_image_dir)
131
132        # Specified --local-*-image with files.
133        self.args.local_kernel_image = expected_image_file
134        self.args.local_system_image = expected_image_file
135        self.args.local_system_dlkm_image = expected_image_file
136        self.args.local_vendor_boot_image = expected_image_file
137        self.AvdSpec._ProcessImageArgs(self.args)
138        self.assertEqual(self.AvdSpec.local_kernel_image, expected_image_file)
139        self.assertEqual(self.AvdSpec.local_system_image, expected_image_file)
140        self.assertEqual(self.AvdSpec.local_system_dlkm_image, expected_image_file)
141        self.assertEqual(self.AvdSpec.local_vendor_boot_image, expected_image_file)
142
143        # Specified --local-*-image without args.
144        self.args.local_kernel_image = constants.FIND_IN_BUILD_ENV
145        self.args.local_system_image = constants.FIND_IN_BUILD_ENV
146        self.args.local_system_dlkm_image = constants.FIND_IN_BUILD_ENV
147        self.args.local_vendor_image = constants.FIND_IN_BUILD_ENV
148        with mock.patch("acloud.create.avd_spec.utils."
149                        "GetBuildEnvironmentVariable",
150                        return_value=expected_image_dir):
151            self.AvdSpec._ProcessImageArgs(self.args)
152        self.assertEqual(self.AvdSpec.local_kernel_image, expected_image_dir)
153        self.assertEqual(self.AvdSpec.local_system_image, expected_image_dir)
154        self.assertEqual(self.AvdSpec.local_system_dlkm_image, expected_image_dir)
155        self.assertEqual(self.AvdSpec.local_vendor_image, expected_image_dir)
156
157    def testProcessAutoconnect(self):
158        """Test process autoconnect."""
159        self.AvdSpec._autoconnect = False
160        self.AvdSpec._ProcessAutoconnect()
161        self.assertEqual(self.AvdSpec._autoconnect, False)
162
163        self.AvdSpec._avd_type = constants.TYPE_CF
164        self.AvdSpec._autoconnect = "webrtc"
165        self.AvdSpec._ProcessAutoconnect()
166        self.assertEqual(self.AvdSpec._autoconnect, "webrtc")
167
168        self.AvdSpec._autoconnect = "vnc"
169        self.AvdSpec._ProcessAutoconnect()
170        self.assertEqual(self.AvdSpec._autoconnect, "vnc")
171
172        self.AvdSpec._avd_type = constants.TYPE_GF
173        self.AvdSpec._autoconnect = "webrtc"
174        self.AvdSpec._ProcessAutoconnect()
175        self.assertEqual(self.AvdSpec._autoconnect, "vnc")
176
177    def testProcessImageArgs(self):
178        """Test process image source."""
179        self.Patch(glob, "glob", return_value=["fake.img"])
180        # No specified local_image, image source is from remote
181        self.AvdSpec._ProcessImageArgs(self.args)
182        self.assertEqual(self.AvdSpec._image_source, constants.IMAGE_SRC_REMOTE)
183        self.assertEqual(self.AvdSpec._local_image_dir, None)
184        self.assertEqual(self.AvdSpec.local_kernel_image, None)
185        self.assertEqual(self.AvdSpec.local_system_image, None)
186
187        # Specified local_image with an arg for cf type
188        self.Patch(os.path, "isfile", return_value=True)
189        self.args.local_image = "/test_path/cf_x86_phone-img-eng.user.zip"
190        self.AvdSpec._avd_type = constants.TYPE_CF
191        self.AvdSpec._instance_type = constants.INSTANCE_TYPE_REMOTE
192        self.AvdSpec._ProcessImageArgs(self.args)
193        self.assertEqual(self.AvdSpec._image_source, constants.IMAGE_SRC_LOCAL)
194        self.assertEqual(self.AvdSpec._local_image_artifact,
195                         "/test_path/cf_x86_phone-img-eng.user.zip")
196
197        # Specified local_image with an arg for gce type
198        self.Patch(os.path, "isfile", return_value=False)
199        self.Patch(os.path, "exists", return_value=True)
200        self.args.local_image = "/test_path_to_dir/"
201        self.AvdSpec._avd_type = constants.TYPE_GCE
202        self.AvdSpec._ProcessImageArgs(self.args)
203        self.assertEqual(self.AvdSpec._image_source, constants.IMAGE_SRC_LOCAL)
204        self.assertEqual(self.AvdSpec._local_image_artifact,
205                         "/test_path_to_dir/avd-system.tar.gz")
206
207    @mock.patch.object(avd_spec.AVDSpec, "_GetGitRemote")
208    def testGetBranchFromRepo(self, mock_gitremote):
209        """Test get branch name from repo info."""
210        # Check aosp repo gets proper branch prefix.
211        fake_subprocess = mock.MagicMock()
212        fake_subprocess.stdout = mock.MagicMock()
213        fake_subprocess.stdout.readline = mock.MagicMock(return_value='')
214        fake_subprocess.poll = mock.MagicMock(return_value=0)
215        fake_subprocess.returncode = 0
216        return_value = "Manifest branch: fake_branch"
217        fake_subprocess.communicate = mock.MagicMock(return_value=(return_value, ''))
218        self.Patch(subprocess, "Popen", return_value=fake_subprocess)
219
220        mock_gitremote.return_value = "aosp"
221        self.assertEqual(self.AvdSpec._GetBranchFromRepo(), "aosp-fake_branch")
222
223        # Check default repo gets default branch prefix.
224        mock_gitremote.return_value = ""
225        return_value = "Manifest branch: fake_branch"
226        fake_subprocess.communicate = mock.MagicMock(return_value=(return_value, ''))
227        self.Patch(subprocess, "Popen", return_value=fake_subprocess)
228        self.assertEqual(self.AvdSpec._GetBranchFromRepo(), "git_fake_branch")
229
230        # Can't get branch from repo info, set it as default branch.
231        return_value = "Manifest branch:"
232        fake_subprocess.communicate = mock.MagicMock(return_value=(return_value, ''))
233        self.Patch(subprocess, "Popen", return_value=fake_subprocess)
234        self.assertEqual(self.AvdSpec._GetBranchFromRepo(), "aosp-main")
235
236    def testGetBuildBranch(self):
237        """Test GetBuildBranch function"""
238        # Test infer branch from build_id and build_target.
239        build_client = mock.MagicMock()
240        build_id = "fake_build_id"
241        build_target = "fake_build_target"
242        expected_branch = "fake_build_branch"
243        self.Patch(android_build_client, "AndroidBuildClient",
244                   return_value=build_client)
245        self.Patch(auth, "CreateCredentials", return_value=mock.MagicMock())
246        self.Patch(build_client, "GetBranch", return_value=expected_branch)
247        self.assertEqual(self.AvdSpec._GetBuildBranch(build_id, build_target),
248                         expected_branch)
249        # Infer branch from "repo info" when build_id and build_target is None.
250        self.Patch(self.AvdSpec, "_GetBranchFromRepo", return_value="repo_branch")
251        build_id = None
252        build_target = None
253        expected_branch = "repo_branch"
254        self.assertEqual(self.AvdSpec._GetBuildBranch(build_id, build_target),
255                         expected_branch)
256
257    # pylint: disable=protected-access
258    def testGetBuildTarget(self):
259        """Test get build target name."""
260        branch = "git_branch"
261        self.AvdSpec._flavor = constants.FLAVOR_IOT
262        self.args.avd_type = constants.TYPE_GCE
263        self.assertEqual(
264            self.AvdSpec._GetBuildTarget(self.args, branch),
265            "gce_x86_64_iot-userdebug")
266
267        branch = "aosp-master"
268        self.AvdSpec._flavor = constants.FLAVOR_PHONE
269        self.args.avd_type = constants.TYPE_CF
270        self.assertEqual(
271            self.AvdSpec._GetBuildTarget(self.args, branch),
272            "aosp_cf_x86_64_phone-userdebug")
273
274        branch = "aosp-main"
275        self.AvdSpec._flavor = constants.FLAVOR_PHONE
276        self.args.avd_type = constants.TYPE_CF
277        self.assertEqual(
278            self.AvdSpec._GetBuildTarget(self.args, branch),
279            "aosp_cf_x86_64_phone-trunk_staging-userdebug")
280
281        branch = "git_branch"
282        self.AvdSpec._flavor = constants.FLAVOR_PHONE
283        self.args.avd_type = constants.TYPE_CF
284        self.assertEqual(
285            self.AvdSpec._GetBuildTarget(self.args, branch),
286            "cf_x86_64_phone-userdebug")
287
288    # pylint: disable=protected-access
289    def testProcessHWPropertyWithInvalidArgs(self):
290        """Test _ProcessHWPropertyArgs with invalid args."""
291        # Checking wrong resolution.
292        args = mock.MagicMock()
293        args.hw_property = "cpu:3,resolution:1280"
294        args.reuse_instance_name = None
295        with self.assertRaises(errors.InvalidHWPropertyError):
296            self.AvdSpec._ProcessHWPropertyArgs(args)
297
298        # Checking property should be int.
299        args = mock.MagicMock()
300        args.hw_property = "cpu:3,dpi:fake"
301        with self.assertRaises(errors.InvalidHWPropertyError):
302            self.AvdSpec._ProcessHWPropertyArgs(args)
303
304        # Checking disk property should be with 'g' suffix.
305        args = mock.MagicMock()
306        args.hw_property = "cpu:3,disk:2"
307        with self.assertRaises(errors.InvalidHWPropertyError):
308            self.AvdSpec._ProcessHWPropertyArgs(args)
309
310        # Checking memory property should be with 'g' suffix.
311        args = mock.MagicMock()
312        args.hw_property = "cpu:3,memory:2"
313        with self.assertRaises(errors.InvalidHWPropertyError):
314            self.AvdSpec._ProcessHWPropertyArgs(args)
315
316    # pylint: disable=protected-access
317    @mock.patch.object(utils, "PrintColorString")
318    def testCheckCFBuildTarget(self, print_warning):
319        """Test _CheckCFBuildTarget."""
320        # patch correct env variable.
321        self.Patch(utils, "GetBuildEnvironmentVariable",
322                   return_value="cf_x86_phone-userdebug")
323        self.AvdSpec._CheckCFBuildTarget(constants.INSTANCE_TYPE_REMOTE)
324        self.AvdSpec._CheckCFBuildTarget(constants.INSTANCE_TYPE_LOCAL)
325
326        self.Patch(utils, "GetBuildEnvironmentVariable",
327                   return_value="aosp_cf_arm64_auto-userdebug")
328        self.AvdSpec._CheckCFBuildTarget(constants.INSTANCE_TYPE_HOST)
329        # patch wrong env variable.
330        self.Patch(utils, "GetBuildEnvironmentVariable",
331                   return_value="test_environ")
332        self.AvdSpec._CheckCFBuildTarget(constants.INSTANCE_TYPE_REMOTE)
333
334        print_warning.assert_called_once()
335
336    # pylint: disable=protected-access
337    def testParseHWPropertyStr(self):
338        """Test _ParseHWPropertyStr."""
339        expected_dict = {"cpu": "2", "x_res": "1080", "y_res": "1920",
340                         "dpi": "240", "memory": "4096", "disk": "4096"}
341        args_str = "cpu:2,resolution:1080x1920,dpi:240,memory:4g,disk:4g"
342        result_dict = self.AvdSpec._ParseHWPropertyStr(args_str)
343        self.assertTrue(expected_dict == result_dict)
344
345        expected_dict = {"cpu": "2", "x_res": "1080", "y_res": "1920",
346                         "dpi": "240", "memory": "512", "disk": "4096"}
347        args_str = "cpu:2,resolution:1080x1920,dpi:240,memory:512m,disk:4g"
348        result_dict = self.AvdSpec._ParseHWPropertyStr(args_str)
349        self.assertTrue(expected_dict == result_dict)
350
351    def testGetFlavorFromBuildTargetString(self):
352        """Test _GetFlavorFromLocalImage."""
353        img_path = "/fack_path/cf_x86_tv-img-eng.user.zip"
354        self.assertEqual(self.AvdSpec._GetFlavorFromString(img_path),
355                         "tv")
356
357        build_target_str = "aosp_cf_x86_auto"
358        self.assertEqual(self.AvdSpec._GetFlavorFromString(
359            build_target_str), "auto")
360
361        # Flavor is not supported.
362        img_path = "/fack_path/cf_x86_error-img-eng.user.zip"
363        self.assertEqual(self.AvdSpec._GetFlavorFromString(img_path),
364                         None)
365
366    # pylint: disable=protected-access,too-many-statements
367    def testProcessRemoteBuildArgs(self):
368        """Test _ProcessRemoteBuildArgs."""
369        self.args.branch = "git_master"
370        self.args.build_id = "1234"
371        self.args.launch_args = None
372
373        # Verify auto-assigned avd_type if build_targe contains "_gce_".
374        self.args.build_target = "aosp_gce_x86_phone-userdebug"
375        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
376        self.assertTrue(self.AvdSpec.avd_type == "gce")
377
378        # Verify auto-assigned avd_type if build_targe contains "gce_".
379        self.args.build_target = "gce_x86_phone-userdebug"
380        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
381        self.assertTrue(self.AvdSpec.avd_type == "gce")
382
383        # Verify auto-assigned avd_type if build_targe contains "_cf_".
384        self.args.build_target = "aosp_cf_x86_64_phone-userdebug"
385        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
386        self.assertTrue(self.AvdSpec.avd_type == "cuttlefish")
387
388        # Verify auto-assigned avd_type if build_targe contains "cf_".
389        self.args.build_target = "cf_x86_phone-userdebug"
390        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
391        self.assertTrue(self.AvdSpec.avd_type == "cuttlefish")
392
393        # Verify auto-assigned avd_type if build_targe contains "sdk_".
394        self.args.build_target = "sdk_phone_armv7-sdk"
395        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
396        self.assertTrue(self.AvdSpec.avd_type == "goldfish")
397
398        # Verify auto-assigned avd_type if build_targe contains "_sdk_".
399        self.args.build_target = "aosp_sdk_phone_armv7-sdk"
400        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
401        self.assertTrue(self.AvdSpec.avd_type == "goldfish")
402
403        # Verify auto-assigned avd_type if build_target contains "_trusty_".
404        self.args.build_target = "qemu_trusty_arm64-trunk_staging-userdebug"
405        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
406        self.assertTrue(self.AvdSpec.avd_type == "trusty")
407
408        # Verify extra build info.
409        self.args.system_branch = "system_branch"
410        self.args.system_build_target = "system_build_target"
411        self.args.system_build_id = "system_build_id"
412        self.args.ota_branch = "ota_branch"
413        self.args.ota_build_target = "ota_build_target"
414        self.args.ota_build_id = "ota_build_id"
415        self.args.kernel_branch = "kernel_branch"
416        self.args.kernel_build_target = "kernel_build_target"
417        self.args.kernel_build_id = "kernel_build_id"
418        self.args.boot_branch = "boot_branch"
419        self.args.boot_build_target = "boot_build_target"
420        self.args.boot_build_id = "boot_build_id"
421        self.args.boot_artifact = "boot_artifact"
422        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
423        self.assertEqual(
424            {constants.BUILD_BRANCH: "system_branch",
425             constants.BUILD_TARGET: "system_build_target",
426             constants.BUILD_ID: "system_build_id"},
427            self.AvdSpec.system_build_info)
428        self.assertEqual(
429            {constants.BUILD_BRANCH: "kernel_branch",
430             constants.BUILD_TARGET: "kernel_build_target",
431             constants.BUILD_ID: "kernel_build_id"},
432            self.AvdSpec.kernel_build_info)
433        self.assertEqual(
434            {constants.BUILD_BRANCH: "boot_branch",
435             constants.BUILD_TARGET: "boot_build_target",
436             constants.BUILD_ID: "boot_build_id",
437             constants.BUILD_ARTIFACT: "boot_artifact"},
438            self.AvdSpec.boot_build_info)
439        self.assertEqual(
440            {constants.BUILD_BRANCH: "ota_branch",
441             constants.BUILD_TARGET: "ota_build_target",
442             constants.BUILD_ID: "ota_build_id"},
443            self.AvdSpec.ota_build_info)
444
445        # Verify auto-assigned avd_type if no match, default as cuttlefish.
446        self.args.build_target = "mini_emulator_arm64-userdebug"
447        self.args.avd_type = "cuttlefish"
448        # reset args.avd_type default value as cuttlefish.
449        self.AvdSpec = avd_spec.AVDSpec(self.args)
450        self.AvdSpec._ProcessRemoteBuildArgs(self.args)
451        self.assertTrue(self.AvdSpec.avd_type == "cuttlefish")
452
453    def testEscapeAnsi(self):
454        """Test EscapeAnsi."""
455        test_string = "\033[1;32;40m Manifest branch:"
456        expected_result = " Manifest branch:"
457        self.assertEqual(avd_spec.EscapeAnsi(test_string), expected_result)
458
459    def testGetGceLocalImagePath(self):
460        """Test get gce local image path."""
461        self.Patch(os.path, "isfile", return_value=True)
462        # Verify when specify --local-image ~/XXX.tar.gz.
463        fake_image_path = "~/gce_local_image_dir/gce_image.tar.gz"
464        self.Patch(os.path, "exists", return_value=True)
465        self.assertEqual(self.AvdSpec._GetGceLocalImagePath(fake_image_path),
466                         "~/gce_local_image_dir/gce_image.tar.gz")
467
468        # Verify when specify --local-image ~/XXX.img.
469        fake_image_path = "~/gce_local_image_dir/gce_image.img"
470        self.assertEqual(self.AvdSpec._GetGceLocalImagePath(fake_image_path),
471                         "~/gce_local_image_dir/gce_image.img")
472
473        # Verify if exist argument --local-image as a directory.
474        self.Patch(os.path, "isfile", return_value=False)
475        self.Patch(os.path, "exists", return_value=True)
476        fake_image_path = "~/gce_local_image_dir/"
477        # Default to find */avd-system.tar.gz if exist then return the path.
478        self.assertEqual(self.AvdSpec._GetGceLocalImagePath(fake_image_path),
479                         "~/gce_local_image_dir/avd-system.tar.gz")
480
481        # Otherwise choose raw file */android_system_disk_syslinux.img if
482        # exist then return the path.
483        self.Patch(os.path, "exists", side_effect=[False, True])
484        self.assertEqual(self.AvdSpec._GetGceLocalImagePath(fake_image_path),
485                         "~/gce_local_image_dir/android_system_disk_syslinux.img")
486
487        # Both _GCE_LOCAL_IMAGE_CANDIDATE could not be found then raise error.
488        self.Patch(os.path, "exists", side_effect=[False, False])
489        self.assertRaises(errors.ImgDoesNotExist,
490                          self.AvdSpec._GetGceLocalImagePath, fake_image_path)
491
492    def testProcessMiscArgs(self):
493        """Test process misc args."""
494        self.args.remote_host = None
495        self.args.local_instance = None
496        self.AvdSpec._ProcessMiscArgs(self.args)
497        self.assertEqual(self.AvdSpec._instance_type, constants.INSTANCE_TYPE_REMOTE)
498
499        self.args.remote_host = None
500        self.args.local_instance = 0
501        self.AvdSpec._ProcessMiscArgs(self.args)
502        self.assertEqual(self.AvdSpec._instance_type, constants.INSTANCE_TYPE_LOCAL)
503
504        self.args.remote_host = "1.1.1.1"
505        self.args.local_instance = None
506        self.AvdSpec._ProcessMiscArgs(self.args)
507        self.assertEqual(self.AvdSpec._instance_type, constants.INSTANCE_TYPE_HOST)
508
509        self.args.remote_host = "1.1.1.1"
510        self.args.local_instance = 1
511        self.AvdSpec._ProcessMiscArgs(self.args)
512        self.assertEqual(self.AvdSpec._instance_type, constants.INSTANCE_TYPE_HOST)
513
514        self.args.oxygen = True
515        self.AvdSpec._ProcessMiscArgs(self.args)
516        self.assertTrue(self.AvdSpec._oxygen)
517
518        # Test avd_spec.autoconnect
519        self.args.autoconnect = False
520        self.AvdSpec._ProcessMiscArgs(self.args)
521        self.assertEqual(self.AvdSpec.autoconnect, False)
522        self.assertEqual(self.AvdSpec.connect_adb, False)
523        self.assertEqual(self.AvdSpec.connect_vnc, False)
524        self.assertEqual(self.AvdSpec.connect_webrtc, False)
525
526        self.args.autoconnect = constants.INS_KEY_VNC
527        self.AvdSpec._ProcessMiscArgs(self.args)
528        self.assertEqual(self.AvdSpec.autoconnect, True)
529        self.assertEqual(self.AvdSpec.connect_adb, True)
530        self.assertEqual(self.AvdSpec.connect_vnc, True)
531        self.assertEqual(self.AvdSpec.connect_webrtc, False)
532
533        self.args.autoconnect = constants.INS_KEY_ADB
534        self.AvdSpec._ProcessMiscArgs(self.args)
535        self.assertEqual(self.AvdSpec.autoconnect, True)
536        self.assertEqual(self.AvdSpec.connect_adb, True)
537        self.assertEqual(self.AvdSpec.connect_vnc, False)
538        self.assertEqual(self.AvdSpec.connect_webrtc, False)
539
540        self.args.autoconnect = constants.INS_KEY_WEBRTC
541        self.AvdSpec._ProcessMiscArgs(self.args)
542        self.assertEqual(self.AvdSpec.autoconnect, True)
543        self.assertEqual(self.AvdSpec.connect_adb, True)
544        self.assertEqual(self.AvdSpec.connect_vnc, False)
545        self.assertEqual(self.AvdSpec.connect_webrtc, True)
546
547        # Test stable host image name.
548        self.args.stable_host_image_name = "fake_host_image"
549        self.AvdSpec._ProcessMiscArgs(self.args)
550        self.assertEqual(self.AvdSpec.stable_host_image_name, "fake_host_image")
551
552        # Setup acloud config with betty_image spec
553        self.mock_config.betty_image = 'from-config'
554        # --betty-image from cmdline should override config
555        self.args.cheeps_betty_image = 'from-cmdline'
556        self.AvdSpec._ProcessMiscArgs(self.args)
557        self.assertEqual(self.AvdSpec.cheeps_betty_image, 'from-cmdline')
558        # acloud config value is used otherwise
559        self.args.cheeps_betty_image = None
560        self.AvdSpec._ProcessMiscArgs(self.args)
561        self.assertEqual(self.AvdSpec.cheeps_betty_image, 'from-config')
562
563        # Verify cheeps_features is assigned from args.
564        self.args.cheeps_features = ['a', 'b', 'c']
565        self.AvdSpec._ProcessMiscArgs(self.args)
566        self.assertEqual(self.args.cheeps_features, ['a', 'b', 'c'])
567
568        # Verify connect_hostname
569        self.mock_config.connect_hostname = True
570        self.AvdSpec._ProcessMiscArgs(self.args)
571        self.assertTrue(self.AvdSpec.connect_hostname)
572        self.args.connect_hostname = True
573        self.mock_config.connect_hostname = False
574        self.assertTrue(self.AvdSpec.connect_hostname)
575
576        # Verify fetch_cvd_version
577        self.args.fetch_cvd_build_id = None
578        self.AvdSpec._ProcessMiscArgs(self.args)
579        self.assertEqual(self.AvdSpec.fetch_cvd_version, "LKGB")
580
581        self.args.fetch_cvd_build_id = "23456"
582        self.AvdSpec._ProcessMiscArgs(self.args)
583        self.assertEqual(self.AvdSpec.fetch_cvd_version, "23456")
584
585        self.args.trusty_branch = "trusty_branch"
586        self.args.trusty_build_id = "trusty_build_id"
587        self.args.trusty_build_target = "trusty_build_target"
588        self.AvdSpec._ProcessMiscArgs(self.args)
589        self.assertEqual(
590            {constants.BUILD_BRANCH: "trusty_branch",
591             constants.BUILD_TARGET: "trusty_build_target",
592             constants.BUILD_ID: "trusty_build_id"},
593            self.AvdSpec.trusty_build_info)
594
595
596if __name__ == "__main__":
597    unittest.main()
598