xref: /aosp_15_r20/tools/acloud/list/instance_test.py (revision 800a58d989c669b8eb8a71d8df53b1ba3d411444)
1*800a58d9SAndroid Build Coastguard Worker#!/usr/bin/env python
2*800a58d9SAndroid Build Coastguard Worker#
3*800a58d9SAndroid Build Coastguard Worker# Copyright 2018 - The Android Open Source Project
4*800a58d9SAndroid Build Coastguard Worker#
5*800a58d9SAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*800a58d9SAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*800a58d9SAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*800a58d9SAndroid Build Coastguard Worker#
9*800a58d9SAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*800a58d9SAndroid Build Coastguard Worker#
11*800a58d9SAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*800a58d9SAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*800a58d9SAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*800a58d9SAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*800a58d9SAndroid Build Coastguard Worker# limitations under the License.
16*800a58d9SAndroid Build Coastguard Worker"""Tests for instance class."""
17*800a58d9SAndroid Build Coastguard Worker
18*800a58d9SAndroid Build Coastguard Workerimport collections
19*800a58d9SAndroid Build Coastguard Workerimport datetime
20*800a58d9SAndroid Build Coastguard Workerimport os
21*800a58d9SAndroid Build Coastguard Workerimport subprocess
22*800a58d9SAndroid Build Coastguard Workerimport unittest
23*800a58d9SAndroid Build Coastguard Worker
24*800a58d9SAndroid Build Coastguard Workerfrom unittest import mock
25*800a58d9SAndroid Build Coastguard Worker
26*800a58d9SAndroid Build Coastguard Worker# pylint: disable=import-error
27*800a58d9SAndroid Build Coastguard Workerimport dateutil.parser
28*800a58d9SAndroid Build Coastguard Workerimport dateutil.tz
29*800a58d9SAndroid Build Coastguard Worker
30*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal import constants
31*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import cvd_runtime_config
32*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import driver_test_lib
33*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import gcompute_client
34*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib import utils
35*800a58d9SAndroid Build Coastguard Workerfrom acloud.internal.lib.adb_tools import AdbTools
36*800a58d9SAndroid Build Coastguard Workerfrom acloud.list import instance
37*800a58d9SAndroid Build Coastguard Worker
38*800a58d9SAndroid Build Coastguard Worker
39*800a58d9SAndroid Build Coastguard Workerclass InstanceTest(driver_test_lib.BaseDriverTest):
40*800a58d9SAndroid Build Coastguard Worker    """Test instance."""
41*800a58d9SAndroid Build Coastguard Worker    PS_SSH_TUNNEL = ("/fake_ps_1 --fake arg \n"
42*800a58d9SAndroid Build Coastguard Worker                     "/fake_ps_2 --fake arg \n"
43*800a58d9SAndroid Build Coastguard Worker                     "/usr/bin/ssh -i ~/.ssh/acloud_rsa "
44*800a58d9SAndroid Build Coastguard Worker                     "-o UserKnownHostsFile=/dev/null "
45*800a58d9SAndroid Build Coastguard Worker                     "-o StrictHostKeyChecking=no -L 54321:127.0.0.1:6520 "
46*800a58d9SAndroid Build Coastguard Worker                     "-L 12345:127.0.0.1:6444 -N -f -l user 1.1.1.1").encode()
47*800a58d9SAndroid Build Coastguard Worker    GCE_INSTANCE = {
48*800a58d9SAndroid Build Coastguard Worker        constants.INS_KEY_NAME: "fake_ins_name",
49*800a58d9SAndroid Build Coastguard Worker        constants.INS_KEY_CREATETIME: "fake_create_time",
50*800a58d9SAndroid Build Coastguard Worker        constants.INS_KEY_STATUS: "fake_status",
51*800a58d9SAndroid Build Coastguard Worker        constants.INS_KEY_ZONE: "test/zones/fake_zone",
52*800a58d9SAndroid Build Coastguard Worker        "networkInterfaces": [{"accessConfigs": [{"natIP": "1.1.1.1"}]}],
53*800a58d9SAndroid Build Coastguard Worker        "labels": {constants.INS_KEY_AVD_TYPE: "fake_type",
54*800a58d9SAndroid Build Coastguard Worker                   constants.INS_KEY_AVD_FLAVOR: "fake_flavor"},
55*800a58d9SAndroid Build Coastguard Worker        "metadata": {
56*800a58d9SAndroid Build Coastguard Worker            "items":[{"key":constants.INS_KEY_AVD_TYPE,
57*800a58d9SAndroid Build Coastguard Worker                      "value":"fake_type"},
58*800a58d9SAndroid Build Coastguard Worker                     {"key":constants.INS_KEY_AVD_FLAVOR,
59*800a58d9SAndroid Build Coastguard Worker                      "value":"fake_flavor"},
60*800a58d9SAndroid Build Coastguard Worker                     {"key":constants.INS_KEY_WEBRTC_PORT,
61*800a58d9SAndroid Build Coastguard Worker                      "value":"fake_webrtc_port"}]}
62*800a58d9SAndroid Build Coastguard Worker    }
63*800a58d9SAndroid Build Coastguard Worker
64*800a58d9SAndroid Build Coastguard Worker    @staticmethod
65*800a58d9SAndroid Build Coastguard Worker    def _MockCvdRuntimeConfig():
66*800a58d9SAndroid Build Coastguard Worker        """Create a mock CvdRuntimeConfig."""
67*800a58d9SAndroid Build Coastguard Worker        return mock.MagicMock(
68*800a58d9SAndroid Build Coastguard Worker            instance_id=2,
69*800a58d9SAndroid Build Coastguard Worker            display_configs=[{'dpi': 480, 'x_res': 1080, 'y_res': 1920}],
70*800a58d9SAndroid Build Coastguard Worker            instance_dir="fake_instance_dir",
71*800a58d9SAndroid Build Coastguard Worker            adb_port=6521,
72*800a58d9SAndroid Build Coastguard Worker            vnc_port=6445,
73*800a58d9SAndroid Build Coastguard Worker            adb_ip_port="127.0.0.1:6521",
74*800a58d9SAndroid Build Coastguard Worker            cvd_tools_path="fake_cvd_tools_path",
75*800a58d9SAndroid Build Coastguard Worker            config_path="fake_config_path",
76*800a58d9SAndroid Build Coastguard Worker            instances={},
77*800a58d9SAndroid Build Coastguard Worker            root_dir="/tmp/acloud_cvd_temp/local-instance-2/cuttlefish_runtime"
78*800a58d9SAndroid Build Coastguard Worker        )
79*800a58d9SAndroid Build Coastguard Worker
80*800a58d9SAndroid Build Coastguard Worker    @mock.patch("acloud.list.instance.AdbTools")
81*800a58d9SAndroid Build Coastguard Worker    def testCreateLocalInstance(self, mock_adb_tools):
82*800a58d9SAndroid Build Coastguard Worker        """Test getting local instance info from cvd runtime config."""
83*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools_object = mock.Mock(device_information={})
84*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools_object.IsAdbConnected.return_value = True
85*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools.return_value = mock_adb_tools_object
86*800a58d9SAndroid Build Coastguard Worker        self.Patch(cvd_runtime_config, "CvdRuntimeConfig",
87*800a58d9SAndroid Build Coastguard Worker                   return_value=self._MockCvdRuntimeConfig())
88*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance.LocalInstance, "_GetDevidInfoFromCvdStatus",
89*800a58d9SAndroid Build Coastguard Worker                   return_value=None)
90*800a58d9SAndroid Build Coastguard Worker        local_instance = instance.LocalInstance("fake_config_path")
91*800a58d9SAndroid Build Coastguard Worker
92*800a58d9SAndroid Build Coastguard Worker        self.assertEqual("local-instance-2", local_instance.name)
93*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(True, local_instance.islocal)
94*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(["1080x1920 (480)"], local_instance.display)
95*800a58d9SAndroid Build Coastguard Worker        expected_full_name = ("device serial: 0.0.0.0:%s %s (%s) elapsed time: %s"
96*800a58d9SAndroid Build Coastguard Worker                              % ("6521",
97*800a58d9SAndroid Build Coastguard Worker                                 "cvd-2",
98*800a58d9SAndroid Build Coastguard Worker                                 "local-instance-2",
99*800a58d9SAndroid Build Coastguard Worker                                 "None"))
100*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(expected_full_name, local_instance.fullname)
101*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(6521, local_instance.adb_port)
102*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(6445, local_instance.vnc_port)
103*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(8444, local_instance.webrtc_port)
104*800a58d9SAndroid Build Coastguard Worker
105*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=protected-access
106*800a58d9SAndroid Build Coastguard Worker    def testGetCvdEnv(self):
107*800a58d9SAndroid Build Coastguard Worker        """Test GetCvdEnv."""
108*800a58d9SAndroid Build Coastguard Worker        self.Patch(cvd_runtime_config, "CvdRuntimeConfig",
109*800a58d9SAndroid Build Coastguard Worker                   return_value=self._MockCvdRuntimeConfig())
110*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "_IsProcessRunning", return_value=False)
111*800a58d9SAndroid Build Coastguard Worker        local_instance = instance.LocalInstance("fake_config_path")
112*800a58d9SAndroid Build Coastguard Worker        cvd_env = local_instance._GetCvdEnv()
113*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(cvd_env[constants.ENV_CUTTLEFISH_INSTANCE], "2")
114*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE],
115*800a58d9SAndroid Build Coastguard Worker                         "fake_config_path")
116*800a58d9SAndroid Build Coastguard Worker
117*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=protected-access
118*800a58d9SAndroid Build Coastguard Worker    def testParsingCvdFleetOutput(self):
119*800a58d9SAndroid Build Coastguard Worker        """Test ParsingCvdFleetOutput."""
120*800a58d9SAndroid Build Coastguard Worker        cvd_fleet_output = """WARNING: cvd_server client version does not match
121*800a58d9SAndroid Build Coastguard Worker{
122*800a58d9SAndroid Build Coastguard Worker"adb_serial" : "0.0.0.0:6520",
123*800a58d9SAndroid Build Coastguard Worker"instance_name" : "cvd-1",
124*800a58d9SAndroid Build Coastguard Worker}"""
125*800a58d9SAndroid Build Coastguard Worker
126*800a58d9SAndroid Build Coastguard Worker        expected_result = """{
127*800a58d9SAndroid Build Coastguard Worker"adb_serial" : "0.0.0.0:6520",
128*800a58d9SAndroid Build Coastguard Worker"instance_name" : "cvd-1",
129*800a58d9SAndroid Build Coastguard Worker}"""
130*800a58d9SAndroid Build Coastguard Worker
131*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(
132*800a58d9SAndroid Build Coastguard Worker            instance.LocalInstance._ParsingCvdFleetOutput(cvd_fleet_output),
133*800a58d9SAndroid Build Coastguard Worker            expected_result)
134*800a58d9SAndroid Build Coastguard Worker
135*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=protected-access
136*800a58d9SAndroid Build Coastguard Worker    def testIsProcessRunning(self):
137*800a58d9SAndroid Build Coastguard Worker        """Test IsProcessRunning."""
138*800a58d9SAndroid Build Coastguard Worker        process = "cvd_server"
139*800a58d9SAndroid Build Coastguard Worker        self.Patch(utils, "CheckOutput",
140*800a58d9SAndroid Build Coastguard Worker                   return_value="/bin/cvd_server -server_fd=4")
141*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance._IsProcessRunning(process), True)
142*800a58d9SAndroid Build Coastguard Worker
143*800a58d9SAndroid Build Coastguard Worker        self.Patch(utils, "CheckOutput", return_value="/bin/cvd start")
144*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance._IsProcessRunning(process), False)
145*800a58d9SAndroid Build Coastguard Worker
146*800a58d9SAndroid Build Coastguard Worker    @mock.patch("acloud.list.instance.AdbTools")
147*800a58d9SAndroid Build Coastguard Worker    def testDeleteLocalInstance(self, mock_adb_tools):
148*800a58d9SAndroid Build Coastguard Worker        """Test executing 'cvd stop' command."""
149*800a58d9SAndroid Build Coastguard Worker        self.Patch(cvd_runtime_config, "CvdRuntimeConfig",
150*800a58d9SAndroid Build Coastguard Worker                   return_value=self._MockCvdRuntimeConfig())
151*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools_object = mock.Mock(device_information={})
152*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools_object.IsAdbConnected.return_value = True
153*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools.return_value = mock_adb_tools_object
154*800a58d9SAndroid Build Coastguard Worker        self.Patch(utils, "AddUserGroupsToCmd",
155*800a58d9SAndroid Build Coastguard Worker                   side_effect=lambda cmd, groups: cmd)
156*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance.LocalInstance, "_GetDevidInfoFromCvdStatus",
157*800a58d9SAndroid Build Coastguard Worker                   return_value=None)
158*800a58d9SAndroid Build Coastguard Worker        mock_check_call = self.Patch(subprocess, "check_call")
159*800a58d9SAndroid Build Coastguard Worker        mock_check_output = self.Patch(
160*800a58d9SAndroid Build Coastguard Worker            subprocess, "check_output",
161*800a58d9SAndroid Build Coastguard Worker            return_value="cvd_internal_stop E stop cvd failed")
162*800a58d9SAndroid Build Coastguard Worker
163*800a58d9SAndroid Build Coastguard Worker        local_instance = instance.LocalInstance("fake_config_path")
164*800a58d9SAndroid Build Coastguard Worker        with mock.patch.dict("acloud.list.instance.os.environ", clear=True):
165*800a58d9SAndroid Build Coastguard Worker            local_instance.Delete()
166*800a58d9SAndroid Build Coastguard Worker
167*800a58d9SAndroid Build Coastguard Worker        expected_env = {
168*800a58d9SAndroid Build Coastguard Worker            "CUTTLEFISH_INSTANCE": "2",
169*800a58d9SAndroid Build Coastguard Worker            "HOME": "/tmp/acloud_cvd_temp/local-instance-2",
170*800a58d9SAndroid Build Coastguard Worker            "CUTTLEFISH_CONFIG_FILE": "fake_config_path",
171*800a58d9SAndroid Build Coastguard Worker            "ANDROID_HOST_OUT": "",
172*800a58d9SAndroid Build Coastguard Worker            "ANDROID_SOONG_HOST_OUT": "",
173*800a58d9SAndroid Build Coastguard Worker        }
174*800a58d9SAndroid Build Coastguard Worker        mock_check_output.assert_called_with(
175*800a58d9SAndroid Build Coastguard Worker            "/tmp/acloud_cvd_temp/local-instance-2/host_bins/bin/cvd stop",
176*800a58d9SAndroid Build Coastguard Worker            stderr=subprocess.STDOUT, shell=True, env=expected_env, text=True,
177*800a58d9SAndroid Build Coastguard Worker            timeout=instance._CVD_TIMEOUT)
178*800a58d9SAndroid Build Coastguard Worker        mock_check_call.assert_called_with(
179*800a58d9SAndroid Build Coastguard Worker            "/tmp/acloud_cvd_temp/local-instance-2/host_bins/bin/stop_cvd",
180*800a58d9SAndroid Build Coastguard Worker            stderr=subprocess.STDOUT, shell=True, env=expected_env)
181*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools_object.DisconnectAdb.assert_called()
182*800a58d9SAndroid Build Coastguard Worker
183*800a58d9SAndroid Build Coastguard Worker    @mock.patch("acloud.list.instance.tempfile")
184*800a58d9SAndroid Build Coastguard Worker    @mock.patch("acloud.list.instance.AdbTools")
185*800a58d9SAndroid Build Coastguard Worker    def testCreateLocalGoldfishInstance(self, mock_adb_tools, mock_tempfile):
186*800a58d9SAndroid Build Coastguard Worker        """"Test the attributes of LocalGoldfishInstance."""
187*800a58d9SAndroid Build Coastguard Worker        mock_tempfile.gettempdir.return_value = "/unit/test"
188*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools.return_value = mock.Mock(device_information={})
189*800a58d9SAndroid Build Coastguard Worker
190*800a58d9SAndroid Build Coastguard Worker        inst = instance.LocalGoldfishInstance(1)
191*800a58d9SAndroid Build Coastguard Worker
192*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(inst.name, "local-goldfish-instance-1")
193*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(inst.avd_type, constants.TYPE_GF)
194*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(inst.adb_port, 5555)
195*800a58d9SAndroid Build Coastguard Worker        self.assertTrue(inst.islocal)
196*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(inst.console_port, 5554)
197*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(inst.device_serial, "emulator-5554")
198*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(inst.instance_dir,
199*800a58d9SAndroid Build Coastguard Worker                         "/unit/test/acloud_gf_temp/local-goldfish-instance-1")
200*800a58d9SAndroid Build Coastguard Worker
201*800a58d9SAndroid Build Coastguard Worker    @mock.patch("acloud.list.instance.AdbTools")
202*800a58d9SAndroid Build Coastguard Worker    def testGetLocalGoldfishInstances(self, mock_adb_tools):
203*800a58d9SAndroid Build Coastguard Worker        """Test LocalGoldfishInstance.GetExistingInstances."""
204*800a58d9SAndroid Build Coastguard Worker        mock_adb_tools.GetDeviceSerials.return_value = [
205*800a58d9SAndroid Build Coastguard Worker            "127.0.0.1:6520", "emulator-5554", "ABCD", "emulator-5558"]
206*800a58d9SAndroid Build Coastguard Worker
207*800a58d9SAndroid Build Coastguard Worker        instances = instance.LocalGoldfishInstance.GetExistingInstances()
208*800a58d9SAndroid Build Coastguard Worker
209*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(len(instances), 2)
210*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instances[0].console_port, 5554)
211*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instances[0].name, "local-goldfish-instance-1")
212*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instances[1].console_port, 5558)
213*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instances[1].name, "local-goldfish-instance-3")
214*800a58d9SAndroid Build Coastguard Worker
215*800a58d9SAndroid Build Coastguard Worker    def testGetMaxNumberOfGoldfishInstances(self):
216*800a58d9SAndroid Build Coastguard Worker        """Test LocalGoldfishInstance.GetMaxNumberOfInstances."""
217*800a58d9SAndroid Build Coastguard Worker        mock_environ = {}
218*800a58d9SAndroid Build Coastguard Worker        with mock.patch.dict("acloud.list.instance.os.environ",
219*800a58d9SAndroid Build Coastguard Worker                             mock_environ, clear=True):
220*800a58d9SAndroid Build Coastguard Worker            num = instance.LocalGoldfishInstance.GetMaxNumberOfInstances()
221*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(num, 16)
222*800a58d9SAndroid Build Coastguard Worker
223*800a58d9SAndroid Build Coastguard Worker        mock_environ["ADB_LOCAL_TRANSPORT_MAX_PORT"] = "5565"
224*800a58d9SAndroid Build Coastguard Worker        with mock.patch.dict("acloud.list.instance.os.environ",
225*800a58d9SAndroid Build Coastguard Worker                             mock_environ, clear=True):
226*800a58d9SAndroid Build Coastguard Worker            num = instance.LocalGoldfishInstance.GetMaxNumberOfInstances()
227*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(num, 6)
228*800a58d9SAndroid Build Coastguard Worker
229*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=protected-access
230*800a58d9SAndroid Build Coastguard Worker    def testGetElapsedTime(self):
231*800a58d9SAndroid Build Coastguard Worker        """Test _GetElapsedTime"""
232*800a58d9SAndroid Build Coastguard Worker        # Instance time can't parse
233*800a58d9SAndroid Build Coastguard Worker        start_time = "error time"
234*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance._MSG_UNABLE_TO_CALCULATE,
235*800a58d9SAndroid Build Coastguard Worker                         instance._GetElapsedTime(start_time))
236*800a58d9SAndroid Build Coastguard Worker
237*800a58d9SAndroid Build Coastguard Worker        # Remote instance elapsed time
238*800a58d9SAndroid Build Coastguard Worker        now = "2019-01-14T13:00:00.000-07:00"
239*800a58d9SAndroid Build Coastguard Worker        start_time = "2019-01-14T03:00:00.000-07:00"
240*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "datetime")
241*800a58d9SAndroid Build Coastguard Worker        instance.datetime.datetime.now.return_value = dateutil.parser.parse(now)
242*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(
243*800a58d9SAndroid Build Coastguard Worker            datetime.timedelta(hours=10), instance._GetElapsedTime(start_time))
244*800a58d9SAndroid Build Coastguard Worker
245*800a58d9SAndroid Build Coastguard Worker        # Local instance elapsed time
246*800a58d9SAndroid Build Coastguard Worker        now = "Mon Jan 14 10:10:10 2019"
247*800a58d9SAndroid Build Coastguard Worker        start_time = "Mon Jan 14 08:10:10 2019"
248*800a58d9SAndroid Build Coastguard Worker        instance.datetime.datetime.now.return_value = dateutil.parser.parse(
249*800a58d9SAndroid Build Coastguard Worker            now).replace(tzinfo=dateutil.tz.tzlocal())
250*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(
251*800a58d9SAndroid Build Coastguard Worker            datetime.timedelta(hours=2), instance._GetElapsedTime(start_time))
252*800a58d9SAndroid Build Coastguard Worker
253*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=protected-access
254*800a58d9SAndroid Build Coastguard Worker    def testGetAdbVncPortFromSSHTunnel(self):
255*800a58d9SAndroid Build Coastguard Worker        """"Test Get forwarding adb and vnc port from ssh tunnel."""
256*800a58d9SAndroid Build Coastguard Worker        self.Patch(subprocess, "check_output", return_value=self.PS_SSH_TUNNEL)
257*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "_GetElapsedTime", return_value="fake_time")
258*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance.RemoteInstance, "_GetZoneName", return_value="fake_zone")
259*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance.RemoteInstance,
260*800a58d9SAndroid Build Coastguard Worker                   "_GetProjectName",
261*800a58d9SAndroid Build Coastguard Worker                   return_value="fake_project")
262*800a58d9SAndroid Build Coastguard Worker        self.Patch(gcompute_client, "GetGCEHostName", return_value="fake_hostname")
263*800a58d9SAndroid Build Coastguard Worker        forwarded_ports = instance.RemoteInstance(
264*800a58d9SAndroid Build Coastguard Worker            mock.MagicMock()).GetAdbVncPortFromSSHTunnel(
265*800a58d9SAndroid Build Coastguard Worker                "1.1.1.1", "fake_hostname", constants.TYPE_CF)
266*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(54321, forwarded_ports.adb_port)
267*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(12345, forwarded_ports.vnc_port)
268*800a58d9SAndroid Build Coastguard Worker
269*800a58d9SAndroid Build Coastguard Worker        # If avd_type is undefined in utils.AVD_PORT_DICT.
270*800a58d9SAndroid Build Coastguard Worker        forwarded_ports = instance.RemoteInstance(
271*800a58d9SAndroid Build Coastguard Worker            mock.MagicMock()).GetAdbVncPortFromSSHTunnel(
272*800a58d9SAndroid Build Coastguard Worker                "1.1.1.1", "fake_hostname", "undefined_avd_type")
273*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(None, forwarded_ports.adb_port)
274*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(None, forwarded_ports.vnc_port)
275*800a58d9SAndroid Build Coastguard Worker
276*800a58d9SAndroid Build Coastguard Worker    # pylint: disable=protected-access
277*800a58d9SAndroid Build Coastguard Worker    def testProcessGceInstance(self):
278*800a58d9SAndroid Build Coastguard Worker        """"Test process instance detail."""
279*800a58d9SAndroid Build Coastguard Worker        fake_adb = 123456
280*800a58d9SAndroid Build Coastguard Worker        fake_vnc = 654321
281*800a58d9SAndroid Build Coastguard Worker        forwarded_ports = collections.namedtuple("ForwardedPorts",
282*800a58d9SAndroid Build Coastguard Worker                                                 [constants.VNC_PORT,
283*800a58d9SAndroid Build Coastguard Worker                                                  constants.ADB_PORT])
284*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance.RemoteInstance,
285*800a58d9SAndroid Build Coastguard Worker                   "_GetProjectName",
286*800a58d9SAndroid Build Coastguard Worker                   return_value="fake_project")
287*800a58d9SAndroid Build Coastguard Worker        self.Patch(
288*800a58d9SAndroid Build Coastguard Worker            instance.RemoteInstance,
289*800a58d9SAndroid Build Coastguard Worker            "GetAdbVncPortFromSSHTunnel",
290*800a58d9SAndroid Build Coastguard Worker            return_value=forwarded_ports(vnc_port=fake_vnc, adb_port=fake_adb))
291*800a58d9SAndroid Build Coastguard Worker        self.Patch(utils, "GetWebrtcPortFromSSHTunnel",
292*800a58d9SAndroid Build Coastguard Worker                   return_value="fake_webrtc_port")
293*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "_GetElapsedTime", return_value="fake_time")
294*800a58d9SAndroid Build Coastguard Worker        self.Patch(AdbTools, "IsAdbConnected", return_value=True)
295*800a58d9SAndroid Build Coastguard Worker
296*800a58d9SAndroid Build Coastguard Worker        # test ssh_tunnel_is_connected will be true if ssh tunnel connection is found
297*800a58d9SAndroid Build Coastguard Worker        instance_info = instance.RemoteInstance(self.GCE_INSTANCE)
298*800a58d9SAndroid Build Coastguard Worker        self.assertTrue(instance_info.ssh_tunnel_is_connected)
299*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance_info.adb_port, fake_adb)
300*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance_info.vnc_port, fake_vnc)
301*800a58d9SAndroid Build Coastguard Worker        self.assertEqual("1.1.1.1", instance_info.ip)
302*800a58d9SAndroid Build Coastguard Worker        self.assertEqual("fake_status", instance_info.status)
303*800a58d9SAndroid Build Coastguard Worker        self.assertEqual("fake_type", instance_info.avd_type)
304*800a58d9SAndroid Build Coastguard Worker        self.assertEqual("fake_flavor", instance_info.avd_flavor)
305*800a58d9SAndroid Build Coastguard Worker        expected_full_name = "device serial: 127.0.0.1:%s (%s) elapsed time: %s" % (
306*800a58d9SAndroid Build Coastguard Worker            fake_adb, self.GCE_INSTANCE[constants.INS_KEY_NAME], "fake_time")
307*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(expected_full_name, instance_info.fullname)
308*800a58d9SAndroid Build Coastguard Worker
309*800a58d9SAndroid Build Coastguard Worker        # test ssh tunnel is connected but adb is disconnected
310*800a58d9SAndroid Build Coastguard Worker        self.Patch(AdbTools, "IsAdbConnected", return_value=False)
311*800a58d9SAndroid Build Coastguard Worker        instance_info = instance.RemoteInstance(self.GCE_INSTANCE)
312*800a58d9SAndroid Build Coastguard Worker        self.assertTrue(instance_info.ssh_tunnel_is_connected)
313*800a58d9SAndroid Build Coastguard Worker        expected_full_name = "device serial: not connected (%s) elapsed time: %s" % (
314*800a58d9SAndroid Build Coastguard Worker            instance_info.name, "fake_time")
315*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(expected_full_name, instance_info.fullname)
316*800a58d9SAndroid Build Coastguard Worker
317*800a58d9SAndroid Build Coastguard Worker        # test ssh_tunnel_is_connected will be false if ssh tunnel connection is not found
318*800a58d9SAndroid Build Coastguard Worker        self.Patch(
319*800a58d9SAndroid Build Coastguard Worker            instance.RemoteInstance,
320*800a58d9SAndroid Build Coastguard Worker            "GetAdbVncPortFromSSHTunnel",
321*800a58d9SAndroid Build Coastguard Worker            return_value=forwarded_ports(vnc_port=None, adb_port=None))
322*800a58d9SAndroid Build Coastguard Worker        instance_info = instance.RemoteInstance(self.GCE_INSTANCE)
323*800a58d9SAndroid Build Coastguard Worker        self.assertFalse(instance_info.ssh_tunnel_is_connected)
324*800a58d9SAndroid Build Coastguard Worker        expected_full_name = "device serial: not connected (%s) elapsed time: %s" % (
325*800a58d9SAndroid Build Coastguard Worker            self.GCE_INSTANCE[constants.INS_KEY_NAME], "fake_time")
326*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(expected_full_name, instance_info.fullname)
327*800a58d9SAndroid Build Coastguard Worker
328*800a58d9SAndroid Build Coastguard Worker    def testInstanceSummary(self):
329*800a58d9SAndroid Build Coastguard Worker        """Test instance summary."""
330*800a58d9SAndroid Build Coastguard Worker        fake_adb = 123456
331*800a58d9SAndroid Build Coastguard Worker        fake_vnc = 654321
332*800a58d9SAndroid Build Coastguard Worker        forwarded_ports = collections.namedtuple("ForwardedPorts",
333*800a58d9SAndroid Build Coastguard Worker                                                 [constants.VNC_PORT,
334*800a58d9SAndroid Build Coastguard Worker                                                  constants.ADB_PORT])
335*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance.RemoteInstance,
336*800a58d9SAndroid Build Coastguard Worker                   "_GetProjectName",
337*800a58d9SAndroid Build Coastguard Worker                   return_value="fake_project")
338*800a58d9SAndroid Build Coastguard Worker        self.Patch(
339*800a58d9SAndroid Build Coastguard Worker            instance.RemoteInstance,
340*800a58d9SAndroid Build Coastguard Worker            "GetAdbVncPortFromSSHTunnel",
341*800a58d9SAndroid Build Coastguard Worker            return_value=forwarded_ports(vnc_port=fake_vnc, adb_port=fake_adb))
342*800a58d9SAndroid Build Coastguard Worker        self.Patch(utils, "GetWebrtcPortFromSSHTunnel", return_value=8443)
343*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "_GetElapsedTime", return_value="fake_time")
344*800a58d9SAndroid Build Coastguard Worker        self.Patch(AdbTools, "IsAdbConnected", return_value=True)
345*800a58d9SAndroid Build Coastguard Worker        remote_instance = instance.RemoteInstance(self.GCE_INSTANCE)
346*800a58d9SAndroid Build Coastguard Worker        result_summary = (" name: fake_ins_name\n "
347*800a58d9SAndroid Build Coastguard Worker                          "   IP: 1.1.1.1\n "
348*800a58d9SAndroid Build Coastguard Worker                          "   create time: fake_create_time\n "
349*800a58d9SAndroid Build Coastguard Worker                          "   elapse time: fake_time\n "
350*800a58d9SAndroid Build Coastguard Worker                          "   status: fake_status\n "
351*800a58d9SAndroid Build Coastguard Worker                          "   avd type: fake_type\n "
352*800a58d9SAndroid Build Coastguard Worker                          "   display: None\n "
353*800a58d9SAndroid Build Coastguard Worker                          "   vnc: 127.0.0.1:654321\n "
354*800a58d9SAndroid Build Coastguard Worker                          "   zone: fake_zone\n "
355*800a58d9SAndroid Build Coastguard Worker                          "   autoconnect: webrtc\n "
356*800a58d9SAndroid Build Coastguard Worker                          "   webrtc port: fake_webrtc_port\n "
357*800a58d9SAndroid Build Coastguard Worker                          "   webrtc forward port: 8443\n "
358*800a58d9SAndroid Build Coastguard Worker                          "   adb serial: 127.0.0.1:123456\n "
359*800a58d9SAndroid Build Coastguard Worker                          "   product: None\n "
360*800a58d9SAndroid Build Coastguard Worker                          "   model: None\n "
361*800a58d9SAndroid Build Coastguard Worker                          "   device: None\n "
362*800a58d9SAndroid Build Coastguard Worker                          "   transport_id: None")
363*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(remote_instance.Summary(), result_summary)
364*800a58d9SAndroid Build Coastguard Worker
365*800a58d9SAndroid Build Coastguard Worker        self.Patch(
366*800a58d9SAndroid Build Coastguard Worker            instance.RemoteInstance,
367*800a58d9SAndroid Build Coastguard Worker            "GetAdbVncPortFromSSHTunnel",
368*800a58d9SAndroid Build Coastguard Worker            return_value=forwarded_ports(vnc_port=None, adb_port=None))
369*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "_GetElapsedTime", return_value="fake_time")
370*800a58d9SAndroid Build Coastguard Worker        self.Patch(AdbTools, "IsAdbConnected", return_value=False)
371*800a58d9SAndroid Build Coastguard Worker        remote_instance = instance.RemoteInstance(self.GCE_INSTANCE)
372*800a58d9SAndroid Build Coastguard Worker        result_summary = (" name: fake_ins_name\n "
373*800a58d9SAndroid Build Coastguard Worker                          "   IP: 1.1.1.1\n "
374*800a58d9SAndroid Build Coastguard Worker                          "   create time: fake_create_time\n "
375*800a58d9SAndroid Build Coastguard Worker                          "   elapse time: fake_time\n "
376*800a58d9SAndroid Build Coastguard Worker                          "   status: fake_status\n "
377*800a58d9SAndroid Build Coastguard Worker                          "   avd type: fake_type\n "
378*800a58d9SAndroid Build Coastguard Worker                          "   display: None\n "
379*800a58d9SAndroid Build Coastguard Worker                          "   vnc: 127.0.0.1:None\n "
380*800a58d9SAndroid Build Coastguard Worker                          "   zone: fake_zone\n "
381*800a58d9SAndroid Build Coastguard Worker                          "   autoconnect: webrtc\n "
382*800a58d9SAndroid Build Coastguard Worker                          "   webrtc port: fake_webrtc_port\n "
383*800a58d9SAndroid Build Coastguard Worker                          "   webrtc forward port: 8443\n "
384*800a58d9SAndroid Build Coastguard Worker                          "   adb serial: disconnected")
385*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(remote_instance.Summary(), result_summary)
386*800a58d9SAndroid Build Coastguard Worker
387*800a58d9SAndroid Build Coastguard Worker    def testGetZoneName(self):
388*800a58d9SAndroid Build Coastguard Worker        """Test GetZoneName."""
389*800a58d9SAndroid Build Coastguard Worker        zone_info = "v1/projects/project/zones/us-central1-c"
390*800a58d9SAndroid Build Coastguard Worker        expected_result = "us-central1-c"
391*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance.RemoteInstance._GetZoneName(zone_info),
392*800a58d9SAndroid Build Coastguard Worker                         expected_result)
393*800a58d9SAndroid Build Coastguard Worker        # Test can't get zone name from zone info.
394*800a58d9SAndroid Build Coastguard Worker        zone_info = "v1/projects/project/us-central1-c"
395*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance.RemoteInstance._GetZoneName(zone_info), None)
396*800a58d9SAndroid Build Coastguard Worker
397*800a58d9SAndroid Build Coastguard Worker    def testGetProjectName(self):
398*800a58d9SAndroid Build Coastguard Worker        """Test GetProjectName."""
399*800a58d9SAndroid Build Coastguard Worker        zone_info = "v1/projects/fake_project/zones/us-central1-c"
400*800a58d9SAndroid Build Coastguard Worker        expected_result = "fake_project"
401*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance.RemoteInstance._GetProjectName(zone_info),
402*800a58d9SAndroid Build Coastguard Worker                         expected_result)
403*800a58d9SAndroid Build Coastguard Worker
404*800a58d9SAndroid Build Coastguard Worker    def testGetLocalInstanceConfig(self):
405*800a58d9SAndroid Build Coastguard Worker        """Test GetLocalInstanceConfig."""
406*800a58d9SAndroid Build Coastguard Worker        self.Patch(instance, "GetLocalInstanceHomeDir",
407*800a58d9SAndroid Build Coastguard Worker                  return_value="ins_home")
408*800a58d9SAndroid Build Coastguard Worker        self.Patch(os.path, "isfile", return_value=False)
409*800a58d9SAndroid Build Coastguard Worker        instance_id = 1
410*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(instance.GetLocalInstanceConfig(instance_id), None)
411*800a58d9SAndroid Build Coastguard Worker
412*800a58d9SAndroid Build Coastguard Worker        # Test config in new folder path.
413*800a58d9SAndroid Build Coastguard Worker        self.Patch(os.path, "isfile", return_value=True)
414*800a58d9SAndroid Build Coastguard Worker        expected_result = "ins_home/cuttlefish_assembly/cuttlefish_config.json"
415*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(
416*800a58d9SAndroid Build Coastguard Worker            instance.GetLocalInstanceConfig(instance_id), expected_result)
417*800a58d9SAndroid Build Coastguard Worker
418*800a58d9SAndroid Build Coastguard Worker    def testGetAutoConnect(self):
419*800a58d9SAndroid Build Coastguard Worker        """Test GetAutoConnect."""
420*800a58d9SAndroid Build Coastguard Worker        name = "ins_name"
421*800a58d9SAndroid Build Coastguard Worker        fullname = "fake_fullname"
422*800a58d9SAndroid Build Coastguard Worker        display = "1080x1920 (480)"
423*800a58d9SAndroid Build Coastguard Worker        ip = "fake_ip"
424*800a58d9SAndroid Build Coastguard Worker        ins_webrtc = instance.Instance(
425*800a58d9SAndroid Build Coastguard Worker            name, fullname, display, ip, webrtc_port=8443)
426*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(ins_webrtc._GetAutoConnect(), constants.INS_KEY_WEBRTC)
427*800a58d9SAndroid Build Coastguard Worker
428*800a58d9SAndroid Build Coastguard Worker        ins_webrtc = instance.Instance(
429*800a58d9SAndroid Build Coastguard Worker            name, fullname, display, ip, vnc_port=6520)
430*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(ins_webrtc._GetAutoConnect(), constants.INS_KEY_VNC)
431*800a58d9SAndroid Build Coastguard Worker
432*800a58d9SAndroid Build Coastguard Worker        ins_webrtc = instance.Instance(
433*800a58d9SAndroid Build Coastguard Worker            name, fullname, display, ip, adb_port=6666)
434*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(ins_webrtc._GetAutoConnect(), constants.INS_KEY_ADB)
435*800a58d9SAndroid Build Coastguard Worker
436*800a58d9SAndroid Build Coastguard Worker        ins_webrtc = instance.Instance(name, fullname, display, ip)
437*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(ins_webrtc._GetAutoConnect(), None)
438*800a58d9SAndroid Build Coastguard Worker
439*800a58d9SAndroid Build Coastguard Worker    @mock.patch("acloud.list.instance.LocalInstance")
440*800a58d9SAndroid Build Coastguard Worker    def testGetCuttleFishLocalInstances(self, mock_local_instance):
441*800a58d9SAndroid Build Coastguard Worker        """Test GetCuttleFishLocalInstances."""
442*800a58d9SAndroid Build Coastguard Worker        self.Patch(cvd_runtime_config, "CvdRuntimeConfig",
443*800a58d9SAndroid Build Coastguard Worker                   return_value=mock.MagicMock(instance_ids=["2", "3"]))
444*800a58d9SAndroid Build Coastguard Worker        instance.GetCuttleFishLocalInstances("fake_config_path")
445*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(mock_local_instance.call_count, 2)
446*800a58d9SAndroid Build Coastguard Worker
447*800a58d9SAndroid Build Coastguard Worker    def testGetDeviceFullName(self):
448*800a58d9SAndroid Build Coastguard Worker        """Test GetDeviceFullName."""
449*800a58d9SAndroid Build Coastguard Worker        device_serial = "0.0.0.0:6520"
450*800a58d9SAndroid Build Coastguard Worker        webrtc_device_id = "codelab"
451*800a58d9SAndroid Build Coastguard Worker        instance_name = "local-instance-1"
452*800a58d9SAndroid Build Coastguard Worker        elapsed_time = "10:10:24"
453*800a58d9SAndroid Build Coastguard Worker
454*800a58d9SAndroid Build Coastguard Worker        expected_result = ("device serial: 0.0.0.0:6520 codelab "
455*800a58d9SAndroid Build Coastguard Worker                           "(local-instance-1) elapsed time: 10:10:24")
456*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(expected_result, instance._GetDeviceFullName(
457*800a58d9SAndroid Build Coastguard Worker            device_serial, instance_name, elapsed_time, webrtc_device_id))
458*800a58d9SAndroid Build Coastguard Worker
459*800a58d9SAndroid Build Coastguard Worker        # Test with no webrtc_device_id
460*800a58d9SAndroid Build Coastguard Worker        webrtc_device_id = None
461*800a58d9SAndroid Build Coastguard Worker        expected_result = ("device serial: 0.0.0.0:6520 (local-instance-1) "
462*800a58d9SAndroid Build Coastguard Worker                           "elapsed time: 10:10:24")
463*800a58d9SAndroid Build Coastguard Worker        self.assertEqual(expected_result, instance._GetDeviceFullName(
464*800a58d9SAndroid Build Coastguard Worker            device_serial, instance_name, elapsed_time, webrtc_device_id))
465*800a58d9SAndroid Build Coastguard Worker
466*800a58d9SAndroid Build Coastguard Worker
467*800a58d9SAndroid Build Coastguard Workerif __name__ == "__main__":
468*800a58d9SAndroid Build Coastguard Worker    unittest.main()
469