Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 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. |
cylan | 4569dca | 2018-11-02 12:12:53 +0800 | [diff] [blame] | 16 | """Tests for instance class.""" |
Sam Chiu | 943b64d | 2019-02-13 22:16:39 +0800 | [diff] [blame] | 17 | |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 18 | import collections |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 19 | import datetime |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 20 | import subprocess |
| 21 | |
| 22 | import unittest |
chojoyce | 7a36173 | 2018-11-26 16:26:13 +0800 | [diff] [blame] | 23 | import mock |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 24 | |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 25 | # pylint: disable=import-error |
| 26 | import dateutil.parser |
| 27 | import dateutil.tz |
| 28 | |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 29 | from acloud.internal import constants |
| 30 | from acloud.internal.lib import driver_test_lib |
Sam Chiu | 943b64d | 2019-02-13 22:16:39 +0800 | [diff] [blame] | 31 | from acloud.internal.lib.adb_tools import AdbTools |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 32 | from acloud.list import instance |
| 33 | |
| 34 | |
| 35 | class InstanceTest(driver_test_lib.BaseDriverTest): |
| 36 | """Test instance.""" |
| 37 | PS_SSH_TUNNEL = ("/fake_ps_1 --fake arg \n" |
| 38 | "/fake_ps_2 --fake arg \n" |
| 39 | "/usr/bin/ssh -i ~/.ssh/acloud_rsa " |
| 40 | "-o UserKnownHostsFile=/dev/null " |
| 41 | "-o StrictHostKeyChecking=no -L 12345:127.0.0.1:6444 " |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 42 | "-L 54321:127.0.0.1:6520 -N -f -l user 1.1.1.1") |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 43 | PS_LAUNCH_CVD = ("Sat Nov 10 21:55:10 2018 /fake_path/bin/launch_cvd " |
| 44 | "--daemon --cpus 2 --x_res 1080 --y_res 1920 --dpi 480" |
| 45 | " --memory_mb 4096 --blank_data_image_mb 4096 --data_policy" |
| 46 | " always_create --system_image_dir /fake " |
| 47 | "--vnc_server_port 6444") |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 48 | GCE_INSTANCE = { |
| 49 | constants.INS_KEY_NAME: "fake_ins_name", |
| 50 | constants.INS_KEY_CREATETIME: "fake_create_time", |
| 51 | constants.INS_KEY_STATUS: "fake_status", |
| 52 | "networkInterfaces": [{"accessConfigs": [{"natIP": "1.1.1.1"}]}], |
| 53 | "labels": {constants.INS_KEY_AVD_TYPE: "fake_type", |
| 54 | constants.INS_KEY_AVD_FLAVOR: "fake_flavor"}, |
| 55 | "metadata": { |
| 56 | "items":[{"key":constants.INS_KEY_AVD_TYPE, |
| 57 | "value":"fake_type"}, |
| 58 | {"key":constants.INS_KEY_AVD_FLAVOR, |
| 59 | "value":"fake_flavor"}]} |
| 60 | } |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 61 | |
| 62 | # pylint: disable=protected-access |
| 63 | def testCreateLocalInstance(self): |
| 64 | """"Test get local instance info from launch_cvd process.""" |
| 65 | self.Patch(subprocess, "check_output", return_value=self.PS_LAUNCH_CVD) |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 66 | self.Patch(instance, "_GetElapsedTime", return_value="fake_time") |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 67 | local_instance = instance.LocalInstance() |
| 68 | self.assertEqual(constants.LOCAL_INS_NAME, local_instance.name) |
| 69 | self.assertEqual(True, local_instance.islocal) |
| 70 | self.assertEqual("1080x1920 (480)", local_instance.display) |
| 71 | self.assertEqual("Sat Nov 10 21:55:10 2018", local_instance.createtime) |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 72 | expected_full_name = "device serial: 127.0.0.1:%s (%s) elapsed time: %s" % ( |
herbertxue | 543457e | 2019-03-18 18:13:34 +0800 | [diff] [blame] | 73 | constants.CF_ADB_PORT, constants.LOCAL_INS_NAME, "fake_time") |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 74 | self.assertEqual(expected_full_name, local_instance.fullname) |
| 75 | |
| 76 | # test return None if no launch_cvd process found |
| 77 | self.Patch(subprocess, "check_output", return_value="no launch_cvd " |
| 78 | "found") |
| 79 | self.assertEqual(None, instance.LocalInstance()) |
| 80 | |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 81 | def testGetElapsedTime(self): |
| 82 | """Test _GetElapsedTime""" |
| 83 | # Instance time can't parse |
| 84 | start_time = "error time" |
| 85 | self.assertEqual(instance._MSG_UNABLE_TO_CALCULATE, |
| 86 | instance._GetElapsedTime(start_time)) |
| 87 | |
| 88 | # Remote instance elapsed time |
| 89 | now = "2019-01-14T13:00:00.000-07:00" |
| 90 | start_time = "2019-01-14T03:00:00.000-07:00" |
| 91 | self.Patch(instance, "datetime") |
| 92 | instance.datetime.datetime.now.return_value = dateutil.parser.parse(now) |
| 93 | self.assertEqual( |
| 94 | datetime.timedelta(hours=10), instance._GetElapsedTime(start_time)) |
| 95 | |
| 96 | # Local instance elapsed time |
| 97 | now = "Mon Jan 14 10:10:10 2019" |
| 98 | start_time = "Mon Jan 14 08:10:10 2019" |
| 99 | instance.datetime.datetime.now.return_value = dateutil.parser.parse( |
| 100 | now).replace(tzinfo=dateutil.tz.tzlocal()) |
| 101 | self.assertEqual( |
| 102 | datetime.timedelta(hours=2), instance._GetElapsedTime(start_time)) |
| 103 | |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 104 | # pylint: disable=protected-access |
| 105 | def testGetAdbVncPortFromSSHTunnel(self): |
| 106 | """"Test Get forwarding adb and vnc port from ssh tunnel.""" |
| 107 | self.Patch(subprocess, "check_output", return_value=self.PS_SSH_TUNNEL) |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 108 | self.Patch(instance, "_GetElapsedTime", return_value="fake_time") |
chojoyce | 7a36173 | 2018-11-26 16:26:13 +0800 | [diff] [blame] | 109 | forwarded_ports = instance.RemoteInstance( |
| 110 | mock.MagicMock()).GetAdbVncPortFromSSHTunnel( |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 111 | "1.1.1.1", constants.TYPE_CF) |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 112 | self.assertEqual(54321, forwarded_ports.adb_port) |
| 113 | self.assertEqual(12345, forwarded_ports.vnc_port) |
| 114 | |
| 115 | # pylint: disable=protected-access |
| 116 | def testProcessGceInstance(self): |
| 117 | """"Test process instance detail.""" |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 118 | fake_adb = 123456 |
| 119 | fake_vnc = 654321 |
| 120 | forwarded_ports = collections.namedtuple("ForwardedPorts", |
| 121 | [constants.VNC_PORT, |
| 122 | constants.ADB_PORT]) |
| 123 | self.Patch( |
| 124 | instance.RemoteInstance, |
Sam Chiu | 56c5889 | 2018-10-25 09:53:19 +0800 | [diff] [blame] | 125 | "GetAdbVncPortFromSSHTunnel", |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 126 | return_value=forwarded_ports(vnc_port=fake_vnc, adb_port=fake_adb)) |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 127 | self.Patch(instance, "_GetElapsedTime", return_value="fake_time") |
Sam Chiu | 943b64d | 2019-02-13 22:16:39 +0800 | [diff] [blame] | 128 | self.Patch(AdbTools, "IsAdbConnected", return_value=True) |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 129 | |
cylan | 4569dca | 2018-11-02 12:12:53 +0800 | [diff] [blame] | 130 | # test ssh_tunnel_is_connected will be true if ssh tunnel connection is found |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 131 | instance_info = instance.RemoteInstance(self.GCE_INSTANCE) |
cylan | 4569dca | 2018-11-02 12:12:53 +0800 | [diff] [blame] | 132 | self.assertTrue(instance_info.ssh_tunnel_is_connected) |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 133 | self.assertEqual(instance_info.forwarding_adb_port, fake_adb) |
| 134 | self.assertEqual(instance_info.forwarding_vnc_port, fake_vnc) |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 135 | self.assertEqual("1.1.1.1", instance_info.ip) |
| 136 | self.assertEqual("fake_status", instance_info.status) |
| 137 | self.assertEqual("fake_type", instance_info.avd_type) |
| 138 | self.assertEqual("fake_flavor", instance_info.avd_flavor) |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 139 | expected_full_name = "device serial: 127.0.0.1:%s (%s) elapsed time: %s" % ( |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 140 | fake_adb, self.GCE_INSTANCE[constants.INS_KEY_NAME], "fake_time") |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 141 | self.assertEqual(expected_full_name, instance_info.fullname) |
| 142 | |
Sam Chiu | 943b64d | 2019-02-13 22:16:39 +0800 | [diff] [blame] | 143 | # test ssh tunnel is connected but adb is disconnected |
| 144 | self.Patch(AdbTools, "IsAdbConnected", return_value=False) |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 145 | instance_info = instance.RemoteInstance(self.GCE_INSTANCE) |
Sam Chiu | 943b64d | 2019-02-13 22:16:39 +0800 | [diff] [blame] | 146 | self.assertTrue(instance_info.ssh_tunnel_is_connected) |
| 147 | expected_full_name = "device serial: not connected (%s) elapsed time: %s" % ( |
| 148 | instance_info.name, "fake_time") |
| 149 | self.assertEqual(expected_full_name, instance_info.fullname) |
| 150 | |
cylan | 4569dca | 2018-11-02 12:12:53 +0800 | [diff] [blame] | 151 | # test ssh_tunnel_is_connected will be false if ssh tunnel connection is not found |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 152 | self.Patch( |
| 153 | instance.RemoteInstance, |
Sam Chiu | 56c5889 | 2018-10-25 09:53:19 +0800 | [diff] [blame] | 154 | "GetAdbVncPortFromSSHTunnel", |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 155 | return_value=forwarded_ports(vnc_port=None, adb_port=None)) |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 156 | instance_info = instance.RemoteInstance(self.GCE_INSTANCE) |
cylan | 4569dca | 2018-11-02 12:12:53 +0800 | [diff] [blame] | 157 | self.assertFalse(instance_info.ssh_tunnel_is_connected) |
herbertxue | 6705f5b | 2018-12-25 14:47:53 +0800 | [diff] [blame] | 158 | expected_full_name = "device serial: not connected (%s) elapsed time: %s" % ( |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 159 | self.GCE_INSTANCE[constants.INS_KEY_NAME], "fake_time") |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 160 | self.assertEqual(expected_full_name, instance_info.fullname) |
| 161 | |
cylan | 1b00321 | 2019-06-13 16:00:47 +0800 | [diff] [blame^] | 162 | def testInstanceSummary(self): |
| 163 | """Test instance summary.""" |
| 164 | fake_adb = 123456 |
| 165 | fake_vnc = 654321 |
| 166 | forwarded_ports = collections.namedtuple("ForwardedPorts", |
| 167 | [constants.VNC_PORT, |
| 168 | constants.ADB_PORT]) |
| 169 | self.Patch( |
| 170 | instance.RemoteInstance, |
| 171 | "GetAdbVncPortFromSSHTunnel", |
| 172 | return_value=forwarded_ports(vnc_port=fake_vnc, adb_port=fake_adb)) |
| 173 | self.Patch(instance, "_GetElapsedTime", return_value="fake_time") |
| 174 | self.Patch(AdbTools, "IsAdbConnected", return_value=True) |
| 175 | remote_instance = instance.RemoteInstance(self.GCE_INSTANCE) |
| 176 | result_summary = (" name: fake_ins_name\n " |
| 177 | " IP: 1.1.1.1\n " |
| 178 | " create time: fake_create_time\n " |
| 179 | " elapse time: fake_time\n " |
| 180 | " status: fake_status\n " |
| 181 | " avd type: fake_type\n " |
| 182 | " display: None\n " |
| 183 | " vnc: 127.0.0.1:654321\n " |
| 184 | " adb serial: 127.0.0.1:123456\n " |
| 185 | " product: None\n " |
| 186 | " model: None\n " |
| 187 | " device: None\n " |
| 188 | " transport_id: None") |
| 189 | self.assertEqual(remote_instance.Summary(), result_summary) |
| 190 | |
| 191 | self.Patch( |
| 192 | instance.RemoteInstance, |
| 193 | "GetAdbVncPortFromSSHTunnel", |
| 194 | return_value=forwarded_ports(vnc_port=None, adb_port=None)) |
| 195 | self.Patch(instance, "_GetElapsedTime", return_value="fake_time") |
| 196 | self.Patch(AdbTools, "IsAdbConnected", return_value=False) |
| 197 | remote_instance = instance.RemoteInstance(self.GCE_INSTANCE) |
| 198 | result_summary = (" name: fake_ins_name\n " |
| 199 | " IP: 1.1.1.1\n " |
| 200 | " create time: fake_create_time\n " |
| 201 | " elapse time: fake_time\n " |
| 202 | " status: fake_status\n " |
| 203 | " avd type: fake_type\n " |
| 204 | " display: None\n " |
| 205 | " vnc: 127.0.0.1:None\n " |
| 206 | " adb serial: disconnected") |
| 207 | self.assertEqual(remote_instance.Summary(), result_summary) |
| 208 | |
Sam Chiu | 5029a25 | 2018-11-06 20:54:13 +0800 | [diff] [blame] | 209 | |
| 210 | if __name__ == "__main__": |
| 211 | unittest.main() |