diff options
author | Sam Chiu <samchiu@google.com> | 2020-02-15 13:15:55 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2020-02-15 13:15:55 +0000 |
commit | 1771e3a12d2dab5f2ca95fdf8c77ea760adf82a7 (patch) | |
tree | 42817259b16d2a564487581d77c8aa007166d4eb | |
parent | 9a4962774d60c7711b779e7c81828f146e449066 (diff) | |
parent | dd6ce36d016311c52fef33d6ca4051edc63e8756 (diff) | |
download | acloud-1771e3a12d2dab5f2ca95fdf8c77ea760adf82a7.tar.gz |
Merge "Query cf local instance according to the result of cvd_status"
-rw-r--r-- | create/local_image_local_instance.py | 103 | ||||
-rw-r--r-- | create/local_image_local_instance_test.py | 38 | ||||
-rw-r--r-- | delete/delete.py | 72 | ||||
-rw-r--r-- | delete/delete_test.py | 31 | ||||
-rwxr-xr-x | internal/constants.py | 2 | ||||
-rw-r--r-- | internal/lib/cvd_runtime_config.py | 13 | ||||
-rwxr-xr-x | internal/lib/utils.py | 11 | ||||
-rw-r--r-- | internal/lib/utils_test.py | 16 | ||||
-rw-r--r-- | list/instance.py | 235 | ||||
-rw-r--r-- | list/instance_test.py | 18 | ||||
-rw-r--r-- | list/list.py | 65 | ||||
-rw-r--r-- | list/list_test.py | 38 | ||||
-rwxr-xr-x | public/report.py | 12 | ||||
-rw-r--r-- | public/report_test.py | 5 | ||||
-rw-r--r-- | reconnect/reconnect.py | 9 | ||||
-rw-r--r-- | reconnect/reconnect_test.py | 12 |
16 files changed, 352 insertions, 328 deletions
diff --git a/create/local_image_local_instance.py b/create/local_image_local_instance.py index d40dd5e7..43bb1684 100644 --- a/create/local_image_local_instance.py +++ b/create/local_image_local_instance.py @@ -34,7 +34,6 @@ To delete the local instance, we will call stop_cvd with the environment variabl [CUTTLEFISH_CONFIG_FILE] which is pointing to the runtime cuttlefish json. """ -import json import logging import os import shutil @@ -44,7 +43,6 @@ import sys from acloud import errors from acloud.create import base_avd_create -from acloud.delete import delete from acloud.internal import constants from acloud.internal.lib import utils from acloud.internal.lib.adb_tools import AdbTools @@ -63,8 +61,6 @@ _CMD_LAUNCH_CVD_DISK_ARGS = (" -blank_data_image_mb %s " _CONFIRM_RELAUNCH = ("\nCuttlefish AVD[id:%d] is already running. \n" "Enter 'y' to terminate current instance and launch a new " "instance, enter anything else to exit out[y/N]: ") -_ENV_CVD_HOME = "HOME" -_ENV_CUTTLEFISH_INSTANCE = "CUTTLEFISH_INSTANCE" _LAUNCH_CVD_TIMEOUT_SECS = 120 # default timeout as 120 seconds _LAUNCH_CVD_TIMEOUT_ERROR = ("Cuttlefish AVD launch timeout, did not complete " "within %d secs.") @@ -108,7 +104,6 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): result_report = report.Report(command="create") instance_name = instance.GetLocalInstanceName( avd_spec.local_instance_id) - local_ports = instance.GetLocalPortsbyInsId(avd_spec.local_instance_id) try: self.CheckLaunchCVD( cmd, host_bins_path, avd_spec.local_instance_id, local_image_path, @@ -116,18 +111,27 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): except errors.LaunchCVDFail as launch_error: result_report.SetStatus(report.Status.BOOT_FAIL) result_report.AddDeviceBootFailure( - instance_name, constants.LOCALHOST, local_ports.adb_port, - local_ports.vnc_port, str(launch_error)) + instance_name, constants.LOCALHOST, None, None, + error=str(launch_error)) return result_report - result_report.SetStatus(report.Status.SUCCESS) - result_report.AddDevice(instance_name, constants.LOCALHOST, - local_ports.adb_port, local_ports.vnc_port) - # Launch vnc client if we're auto-connecting. - if avd_spec.connect_vnc: - utils.LaunchVNCFromReport(result_report, avd_spec, no_prompts) - if avd_spec.unlock_screen: - AdbTools(local_ports.adb_port).AutoUnlockScreen() + active_ins = list_instance.GetActiveCVD(avd_spec.local_instance_id) + if active_ins: + result_report.SetStatus(report.Status.SUCCESS) + result_report.AddDevice(instance_name, constants.LOCALHOST, + active_ins.adb_port, active_ins.vnc_port) + # Launch vnc client if we're auto-connecting. + if avd_spec.connect_vnc: + utils.LaunchVNCFromReport(result_report, avd_spec, no_prompts) + if avd_spec.unlock_screen: + AdbTools(active_ins.adb_port).AutoUnlockScreen() + else: + err_msg = "cvd_status return non-zero after launch_cvd" + logger.error(err_msg) + result_report.SetStatus(report.Status.BOOT_FAIL) + result_report.AddDeviceBootFailure( + instance_name, constants.LOCALHOST, None, None, error=err_msg) + return result_report @staticmethod @@ -218,10 +222,11 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): # different dir (e.g. downloaded image). os.environ[constants.ENV_ANDROID_HOST_OUT] = host_bins_path # Check if the instance with same id is running. - if self.IsLocalCVDRunning(local_instance_id): + existing_ins = list_instance.GetActiveCVD(local_instance_id) + if existing_ins: if no_prompts or utils.GetUserAnswerYes(_CONFIRM_RELAUNCH % local_instance_id): - self._StopCvd(host_bins_path, local_instance_id) + existing_ins.Delete() else: sys.exit(constants.EXIT_BY_USER) else: @@ -239,36 +244,6 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): self._LaunchCvd(cmd, local_instance_id, timeout=timeout_secs) @staticmethod - def _StopCvd(host_bins_path, local_instance_id): - """Execute stop_cvd to stop cuttlefish instance. - - Args: - host_bins_path: String of host package directory. - local_instance_id: Integer of instance id. - """ - stop_cvd_cmd = os.path.join(host_bins_path, - "bin", - constants.CMD_STOP_CVD) - with open(os.devnull, "w") as dev_null: - cvd_env = os.environ.copy() - cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE] = os.path.join( - instance.GetLocalInstanceRuntimeDir(local_instance_id), - constants.CUTTLEFISH_CONFIG_FILE) - subprocess.check_call( - utils.AddUserGroupsToCmd( - stop_cvd_cmd, constants.LIST_CF_USER_GROUPS), - stderr=dev_null, stdout=dev_null, shell=True, env=cvd_env) - - # Delete ssvnc viewer - local_ports = instance.GetLocalPortsbyInsId(local_instance_id) - delete.CleanupSSVncviewer(local_ports.vnc_port) - # Disconnect adb device - adb_cmd = AdbTools(local_ports.adb_port) - # When relaunch a local instance, we need to pass in retry=True to make - # sure adb device is completely gone since it will use the same adb port - adb_cmd.DisconnectAdb(retry=True) - - @staticmethod @utils.TimeExecute(function_description="Waiting for AVD(s) to boot up") def _LaunchCvd(cmd, local_instance_id, timeout=None): """Execute Launch CVD. @@ -291,8 +266,8 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): os.makedirs(cvd_runtime_dir) cvd_env = os.environ.copy() - cvd_env[_ENV_CVD_HOME] = cvd_home_dir - cvd_env[_ENV_CUTTLEFISH_INSTANCE] = str(local_instance_id) + cvd_env[constants.ENV_CVD_HOME] = cvd_home_dir + cvd_env[constants.ENV_CUTTLEFISH_INSTANCE] = str(local_instance_id) # Check the result of launch_cvd command. # An exit code of 0 is equivalent to VIRTUAL_DEVICE_BOOT_COMPLETED process = subprocess.Popen(cmd, shell=True, stderr=subprocess.STDOUT, @@ -318,19 +293,6 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): utils.TextColors.WARNING) @staticmethod - def IsLocalCVDRunning(local_instance_id): - """Check if the AVD with specific instance id is running - - Args: - local_instance_id: Integer of instance id. - - Return: - Boolean, True if AVD is running. - """ - local_ports = instance.GetLocalPortsbyInsId(local_instance_id) - return AdbTools(local_ports.adb_port).IsAdbConnected() - - @staticmethod def IsLocalImageOccupied(local_image_dir): """Check if the given image path is being used by a running CVD process. @@ -340,15 +302,12 @@ class LocalImageLocalInstance(base_avd_create.BaseAVDCreate): Return: Integer of instance id which using the same image path. """ - local_cvd_ids = list_instance.GetActiveCVDIds() - for cvd_id in local_cvd_ids: - cvd_config_path = os.path.join(instance.GetLocalInstanceRuntimeDir( - cvd_id), constants.CUTTLEFISH_CONFIG_FILE) - if not os.path.isfile(cvd_config_path): - continue - with open(cvd_config_path, "r") as config_file: - json_array = json.load(config_file) - for disk_path in json_array[_VIRTUAL_DISK_PATHS]: + # TODO(149602560): Remove occupied image checking after after cf disk + # overlay is stable + for cf_runtime_config_path in instance.GetAllLocalInstanceConfigs(): + ins = instance.LocalInstance(cf_runtime_config_path) + if ins.CvdStatus(): + for disk_path in ins.virtual_disk_paths: if local_image_dir in disk_path: - return cvd_id + return ins.instance_id return None diff --git a/create/local_image_local_instance_test.py b/create/local_image_local_instance_test.py index eaa43a5f..e5204709 100644 --- a/create/local_image_local_instance_test.py +++ b/create/local_image_local_instance_test.py @@ -24,6 +24,7 @@ import mock from acloud import errors from acloud.create import local_image_local_instance from acloud.list import instance +from acloud.list import list as list_instance from acloud.internal import constants from acloud.internal.lib import driver_test_lib from acloud.internal.lib import utils @@ -51,6 +52,13 @@ EOF""" } ] + _EXPECTED_DEVICES_IN_FAILED_REPORT = [ + { + "instance_name": "local-instance-1", + "ip": "127.0.0.1" + } + ] + def setUp(self): """Initialize new LocalImageLocalInstance.""" super(LocalImageLocalInstanceTest, self).setUp() @@ -58,7 +66,6 @@ EOF""" # pylint: disable=protected-access @mock.patch("acloud.create.local_image_local_instance.utils") - @mock.patch("acloud.create.local_image_local_instance.instance") @mock.patch.object(local_image_local_instance.LocalImageLocalInstance, "PrepareLaunchCVDCmd") @mock.patch.object(local_image_local_instance.LocalImageLocalInstance, @@ -66,17 +73,23 @@ EOF""" @mock.patch.object(local_image_local_instance.LocalImageLocalInstance, "CheckLaunchCVD") def testCreateAVD(self, mock_check_launch_cvd, mock_get_image, - _mock_prepare, mock_instance, mock_utils): + _mock_prepare, mock_utils): """Test the report returned by _CreateAVD.""" mock_utils.IsSupportedPlatform.return_value = True - - mock_instance.GetLocalInstanceName.return_value = "local-instance-1" - mock_instance.GetLocalPortsbyInsId.return_value = mock.Mock( - adb_port=6520, vnc_port=6444) - mock_get_image.return_value = ("/image/path", "/host/bin/path") - mock_avd_spec = mock.Mock(autoconnect=False, unlock_screen=False) + self.Patch(instance, "GetLocalInstanceName", + return_value="local-instance-1") + local_ins = mock.MagicMock( + adb_port=6520, + vnc_port=6444 + ) + local_ins.CvdStatus.return_value = True + self.Patch(instance, "LocalInstance", + return_value=local_ins) + self.Patch(list_instance, "GetActiveCVD", + return_value=local_ins) + # Success report = self.local_image_local_instance._CreateAVD( mock_avd_spec, no_prompts=True) @@ -90,7 +103,7 @@ EOF""" mock_avd_spec, no_prompts=True) self.assertEqual(report.data.get("devices_failing_boot"), - self._EXPECTED_DEVICES_IN_REPORT) + self._EXPECTED_DEVICES_IN_FAILED_REPORT) self.assertEqual(report.errors, ["timeout"]) # pylint: disable=protected-access @@ -147,8 +160,7 @@ EOF""" @mock.patch.object(local_image_local_instance.LocalImageLocalInstance, "_LaunchCvd") @mock.patch.object(utils, "GetUserAnswerYes") - @mock.patch.object(local_image_local_instance.LocalImageLocalInstance, - "IsLocalCVDRunning") + @mock.patch.object(list_instance, "GetActiveCVD") @mock.patch.object(local_image_local_instance.LocalImageLocalInstance, "IsLocalImageOccupied") def testCheckLaunchCVD(self, mock_image_occupied, mock_cvd_running, @@ -195,8 +207,8 @@ EOF""" local_instance_id = 3 launch_cvd_cmd = "launch_cvd" cvd_env = {} - cvd_env[local_image_local_instance._ENV_CVD_HOME] = "fake_home" - cvd_env[local_image_local_instance._ENV_CUTTLEFISH_INSTANCE] = str( + cvd_env[constants.ENV_CVD_HOME] = "fake_home" + cvd_env[constants.ENV_CUTTLEFISH_INSTANCE] = str( local_instance_id) process = mock.MagicMock() process.wait.return_value = True diff --git a/delete/delete.py b/delete/delete.py index 86b0a422..02ee4841 100644 --- a/delete/delete.py +++ b/delete/delete.py @@ -20,7 +20,6 @@ of an Android Virtual Device. from __future__ import print_function import logging -import os import re import subprocess @@ -42,53 +41,9 @@ logger = logging.getLogger(__name__) _COMMAND_GET_PROCESS_ID = ["pgrep", "run_cvd"] _COMMAND_GET_PROCESS_COMMAND = ["ps", "-o", "command", "-p"] _RE_RUN_CVD = re.compile(r"^(?P<run_cvd>.+run_cvd)") -_SSVNC_VIEWER_PATTERN = "vnc://127.0.0.1:%(vnc_port)d" _LOCAL_INSTANCE_PREFIX = "local-" -def _GetStopCvd(): - """Get stop_cvd path. - - "stop_cvd" and "run_cvd" are in the same folder(host package folder). - Try to get directory of "run_cvd" by "ps -o command -p <pid>." command. - For example: "/tmp/bin/run_cvd" - - Returns: - String of stop_cvd file path. - - Raises: - errors.NoExecuteCmd: Can't find stop_cvd. - """ - process_id = subprocess.check_output(_COMMAND_GET_PROCESS_ID) - process_info = subprocess.check_output( - _COMMAND_GET_PROCESS_COMMAND + process_id.splitlines()) - for process in process_info.splitlines(): - match = _RE_RUN_CVD.match(process) - if match: - run_cvd_path = match.group("run_cvd") - stop_cvd_cmd = os.path.join(os.path.dirname(run_cvd_path), - constants.CMD_STOP_CVD) - if os.path.exists(stop_cvd_cmd): - logger.debug("stop_cvd command: %s", stop_cvd_cmd) - return stop_cvd_cmd - - default_stop_cvd = utils.FindExecutable(constants.CMD_STOP_CVD) - if default_stop_cvd: - return default_stop_cvd - - raise errors.NoExecuteCmd("Cannot find stop_cvd binary.") - - -def CleanupSSVncviewer(vnc_port): - """Cleanup the old disconnected ssvnc viewer. - - Args: - vnc_port: Integer, port number of vnc. - """ - ssvnc_viewer_pattern = _SSVNC_VIEWER_PATTERN % {"vnc_port":vnc_port} - utils.CleanupProcess(ssvnc_viewer_pattern) - - def DeleteInstances(cfg, instances_to_delete): """Delete instances according to instances_to_delete. @@ -118,8 +73,8 @@ def DeleteInstances(cfg, instances_to_delete): else: remote_instance_list.append(instance.name) # Delete ssvnc viewer - if instance.forwarding_vnc_port: - CleanupSSVncviewer(instance.forwarding_vnc_port) + if instance.vnc_port: + utils.CleanupSSVncviewer(instance.vnc_port) if remote_instance_list: # TODO(119283708): We should move DeleteAndroidVirtualDevices into @@ -171,7 +126,7 @@ def DeleteRemoteInstances(cfg, instances_to_delete, delete_report=None): def DeleteLocalCuttlefishInstance(instance, delete_report): """Delete a local cuttlefish instance. - Delete local instance with stop_cvd command and write delete instance + Delete local instance and write delete instance information to report. Args: @@ -182,21 +137,12 @@ def DeleteLocalCuttlefishInstance(instance, delete_report): delete_report. """ try: - with open(os.devnull, "w") as dev_null: - cvd_env = os.environ.copy() - if instance.instance_dir: - cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE] = os.path.join( - instance.instance_dir, constants.CUTTLEFISH_CONFIG_FILE) - subprocess.check_call( - utils.AddUserGroupsToCmd(_GetStopCvd(), - constants.LIST_CF_USER_GROUPS), - stderr=dev_null, stdout=dev_null, shell=True, env=cvd_env) - delete_report.SetStatus(report.Status.SUCCESS) - device_driver.AddDeletionResultToReport( - delete_report, [instance.name], failed=[], - error_msgs=[], - resource_name="instance") - CleanupSSVncviewer(instance.vnc_port) + instance.Delete() + delete_report.SetStatus(report.Status.SUCCESS) + device_driver.AddDeletionResultToReport( + delete_report, [instance.name], failed=[], + error_msgs=[], + resource_name="instance") except subprocess.CalledProcessError as e: delete_report.AddError(str(e)) delete_report.SetStatus(report.Status.FAIL) diff --git a/delete/delete_test.py b/delete/delete_test.py index 49cef1cb..829ab7b6 100644 --- a/delete/delete_test.py +++ b/delete/delete_test.py @@ -14,12 +14,10 @@ """Tests for delete.""" import unittest -import subprocess import mock from acloud.delete import delete from acloud.internal.lib import driver_test_lib -from acloud.internal.lib import utils from acloud.list import list as list_instances from acloud.public import report @@ -28,20 +26,8 @@ from acloud.public import report class DeleteTest(driver_test_lib.BaseDriverTest): """Test delete functions.""" - # pylint: disable=protected-access - @mock.patch("os.path.exists", return_value=True) - @mock.patch("subprocess.check_output") - def testGetStopcvd(self, mock_subprocess, mock_path_exist): - """Test _GetStopCvd.""" - mock_subprocess.side_effect = ["fake_id", - "/tmp/bin/run_cvd"] - expected_value = "/tmp/bin/stop_cvd" - self.assertEqual(expected_value, delete._GetStopCvd()) - - @mock.patch.object(delete, "_GetStopCvd", return_value="") @mock.patch("subprocess.check_call") - def testDeleteLocalCuttlefishInstance(self, mock_subprocess, - mock_get_stopcvd): + def testDeleteLocalCuttlefishInstance(self, mock_subprocess): """Test DeleteLocalCuttlefishInstance.""" mock_subprocess.return_value = True instance_object = mock.MagicMock() @@ -108,21 +94,6 @@ class DeleteTest(driver_test_lib.BaseDriverTest): self.assertTrue(len(delete_report.errors) > 0) self.assertEqual(delete_report.status, "FAIL") - # pylint: disable=protected-access, no-member - def testCleanupSSVncviwer(self): - """test cleanup ssvnc viewer.""" - fake_vnc_port = 9999 - fake_ss_vncviewer_pattern = delete._SSVNC_VIEWER_PATTERN % { - "vnc_port": fake_vnc_port} - self.Patch(utils, "IsCommandRunning", return_value=True) - self.Patch(subprocess, "check_call", return_value=True) - delete.CleanupSSVncviewer(fake_vnc_port) - subprocess.check_call.assert_called_with(["pkill", "-9", "-f", fake_ss_vncviewer_pattern]) - - subprocess.check_call.call_count = 0 - self.Patch(utils, "IsCommandRunning", return_value=False) - subprocess.check_call.assert_not_called() - @mock.patch.object(delete, "DeleteInstances", return_value="") @mock.patch.object(delete, "DeleteRemoteInstances", return_value="") def testDeleteInstanceByNames(self, mock_delete_remote_ins, diff --git a/internal/constants.py b/internal/constants.py index fb95d44b..c5302444 100755 --- a/internal/constants.py +++ b/internal/constants.py @@ -150,6 +150,8 @@ INS_KEY_ZONE = "zone" INS_STATUS_RUNNING = "RUNNING" LOCAL_INS_NAME = "local-instance" ENV_CUTTLEFISH_CONFIG_FILE = "CUTTLEFISH_CONFIG_FILE" +ENV_CUTTLEFISH_INSTANCE = "CUTTLEFISH_INSTANCE" +ENV_CVD_HOME = "HOME" CUTTLEFISH_CONFIG_FILE = "cuttlefish_config.json" TEMP_ARTIFACTS_FOLDER = "acloud_image_artifacts" diff --git a/internal/lib/cvd_runtime_config.py b/internal/lib/cvd_runtime_config.py index f15af2ee..fd5bba68 100644 --- a/internal/lib/cvd_runtime_config.py +++ b/internal/lib/cvd_runtime_config.py @@ -75,16 +75,16 @@ class CvdRuntimeConfig(object): "memory_mb" : 4096, "cpus" : 2, "dpi" : 320, - "virtual_disk_paths" : - [ - "/path-to-image" - ], "instances" : { "1" : { "adb_ip_and_port" : "127.0.0.1:6520", "instance_dir" : "/path-to-instance-dir", + "virtual_disk_paths" : + [ + "/path-to-image" + ], } } } @@ -101,8 +101,6 @@ class CvdRuntimeConfig(object): adb_connector = self._config_dict.get(_CFG_KEY_ADB_CONNECTOR_BINARY) self._cvd_tools_path = (os.path.dirname(adb_connector) if adb_connector else None) - self._virtual_disk_paths = self._config_dict.get( - _CFG_KEY_VIRTUAL_DISK_PATHS) # Below properties will be collected inside of instance id node if there # are more than one instance. @@ -110,6 +108,8 @@ class CvdRuntimeConfig(object): self._vnc_port = self._config_dict.get(_CFG_KEY_VNC_PORT) self._adb_port = self._config_dict.get(_CFG_KEY_ADB_PORT) self._adb_ip_port = self._config_dict.get(_CFG_KEY_ADB_IP_PORT) + self._virtual_disk_paths = self._config_dict.get( + _CFG_KEY_VIRTUAL_DISK_PATHS) if not self._instance_dir: ins_cfg = self._config_dict.get(_CFG_KEY_INSTANCES) ins_dict = ins_cfg.get(self._instance_id) @@ -121,6 +121,7 @@ class CvdRuntimeConfig(object): self._vnc_port = ins_dict.get(_CFG_KEY_VNC_PORT) self._adb_port = ins_dict.get(_CFG_KEY_ADB_PORT) self._adb_ip_port = ins_dict.get(_CFG_KEY_ADB_IP_PORT) + self._virtual_disk_paths = ins_dict.get(_CFG_KEY_VIRTUAL_DISK_PATHS) @staticmethod def _GetCuttlefishRuntimeConfig(runtime_cf_config_path): diff --git a/internal/lib/utils.py b/internal/lib/utils.py index e6790d33..f248f544 100755 --- a/internal/lib/utils.py +++ b/internal/lib/utils.py @@ -100,6 +100,7 @@ _EvaluatedResult = collections.namedtuple("EvaluatedResult", # dict of supported system and their distributions. _SUPPORTED_SYSTEMS_AND_DISTS = {"Linux": ["Ubuntu", "Debian"]} _DEFAULT_TIMEOUT_ERR = "Function did not complete within %d secs." +_SSVNC_VIEWER_PATTERN = "vnc://127.0.0.1:%(vnc_port)d" class TempDir(object): @@ -1251,3 +1252,13 @@ def GetDictItems(namedtuple_object): """ return (namedtuple_object.__dict__.items() if six.PY2 else namedtuple_object._asdict().items()) + + +def CleanupSSVncviewer(vnc_port): + """Cleanup the old disconnected ssvnc viewer. + + Args: + vnc_port: Integer, port number of vnc. + """ + ssvnc_viewer_pattern = _SSVNC_VIEWER_PATTERN % {"vnc_port":vnc_port} + CleanupProcess(ssvnc_viewer_pattern) diff --git a/internal/lib/utils_test.py b/internal/lib/utils_test.py index 480b4d2d..169a36d7 100644 --- a/internal/lib/utils_test.py +++ b/internal/lib/utils_test.py @@ -411,6 +411,22 @@ class UtilsTest(driver_test_lib.BaseDriverTest): first_call_args = utils._ExecuteCommand.call_args_list[0][0] self.assertEqual(first_call_args[1], args_list) + # pylint: disable=protected-access, no-member + def testCleanupSSVncviwer(self): + """test cleanup ssvnc viewer.""" + fake_vnc_port = 9999 + fake_ss_vncviewer_pattern = utils._SSVNC_VIEWER_PATTERN % { + "vnc_port": fake_vnc_port} + self.Patch(utils, "IsCommandRunning", return_value=True) + self.Patch(subprocess, "check_call", return_value=True) + utils.CleanupSSVncviewer(fake_vnc_port) + subprocess.check_call.assert_called_with(["pkill", "-9", "-f", fake_ss_vncviewer_pattern]) + + subprocess.check_call.call_count = 0 + self.Patch(utils, "IsCommandRunning", return_value=False) + utils.CleanupSSVncviewer(fake_vnc_port) + subprocess.check_call.assert_not_called() + if __name__ == "__main__": unittest.main() diff --git a/list/instance.py b/list/instance.py index 8f912452..8e4d69a1 100644 --- a/list/instance.py +++ b/list/instance.py @@ -48,6 +48,7 @@ logger = logging.getLogger(__name__) _ACLOUD_CVD_TEMP = os.path.join(tempfile.gettempdir(), "acloud_cvd_temp") _CVD_RUNTIME_FOLDER_NAME = "cuttlefish_runtime" +_CVD_STATUS_BIN = "cvd_status" _MSG_UNABLE_TO_CALCULATE = "Unable to calculate" _RE_GROUP_ADB = "local_adb_port" _RE_GROUP_VNC = "local_vnc_port" @@ -63,10 +64,21 @@ _RE_ZONE = re.compile(r".+/zones/(?P<zone>.+)$") _LOCAL_ZONE = "local" _FULL_NAME_STRING = ("device serial: %(device_serial)s (%(instance_name)s) " "elapsed time: %(elapsed_time)s") +_INDENT = " " * 3 LocalPorts = collections.namedtuple("LocalPorts", [constants.VNC_PORT, constants.ADB_PORT]) +def GetDefaultCuttlefishConfig(): + """Get the path of default cuttlefish instance config. + + Return: + String, path of cf runtime config. + """ + return os.path.join(os.path.expanduser("~"), _CVD_RUNTIME_FOLDER_NAME, + constants.CUTTLEFISH_CONFIG_FILE) + + def GetLocalInstanceName(local_instance_id): """Get local cuttlefish instance name by instance id. @@ -79,58 +91,70 @@ def GetLocalInstanceName(local_instance_id): return "%s-%d" % (constants.LOCAL_INS_NAME, local_instance_id) -def GetLocalInstanceHomeDir(local_instance_id): - """Get local instance home dir accroding to instance id. +def GetLocalInstanceConfig(local_instance_id): + """Get the path of instance config. Args: local_instance_id: Integer of instance id. Return: - String, path of instance home dir. + String, path of cf runtime config. """ - return os.path.join(_ACLOUD_CVD_TEMP, - GetLocalInstanceName(local_instance_id)) + cfg_path = os.path.join(GetLocalInstanceRuntimeDir(local_instance_id), + constants.CUTTLEFISH_CONFIG_FILE) + if os.path.isfile(cfg_path): + return cfg_path + return None -def GetLocalInstanceRuntimeDir(local_instance_id): - """Get instance runtime dir - - Args: - local_instance_id: Integer of instance id. +def GetAllLocalInstanceConfigs(): + """Get the list of instance config. Return: - String, path of instance runtime dir. + List of instance config path. """ - return os.path.join(GetLocalInstanceHomeDir(local_instance_id), - _CVD_RUNTIME_FOLDER_NAME) + cfg_list = [] + # Check if any instance config is under home folder. + cfg_path = GetDefaultCuttlefishConfig() + if os.path.isfile(cfg_path): + cfg_list.append(cfg_path) + + # Check if any instance config is under acloud cvd temp folder. + if os.path.exists(_ACLOUD_CVD_TEMP): + for ins_name in os.listdir(_ACLOUD_CVD_TEMP): + cfg_path = os.path.join(_ACLOUD_CVD_TEMP, + ins_name, + _CVD_RUNTIME_FOLDER_NAME, + constants.CUTTLEFISH_CONFIG_FILE) + if os.path.isfile(cfg_path): + cfg_list.append(cfg_path) + return cfg_list -def GetCuttlefishRuntimeConfig(local_instance_id): - """Get and parse cuttlefish_config.json. +def GetLocalInstanceHomeDir(local_instance_id): + """Get local instance home dir according to instance id. Args: local_instance_id: Integer of instance id. - Returns: - A CvdRuntimeConfig instance. + Return: + String, path of instance home dir. """ - runtime_cf_config_path = os.path.join(GetLocalInstanceRuntimeDir( - local_instance_id), constants.CUTTLEFISH_CONFIG_FILE) - return cvd_runtime_config.CvdRuntimeConfig(runtime_cf_config_path) + return os.path.join(_ACLOUD_CVD_TEMP, + GetLocalInstanceName(local_instance_id)) -def GetLocalPortsbyInsId(local_instance_id): - """Get vnc and adb port by local instance id. +def GetLocalInstanceRuntimeDir(local_instance_id): + """Get instance runtime dir Args: - local_instance_id: local_instance_id: Integer of instance id. + local_instance_id: Integer of instance id. - Returns: - NamedTuple of (vnc_port, adb_port) used by local instance, both are - integers. + Return: + String, path of instance runtime dir. """ - return LocalPorts(vnc_port=constants.CF_VNC_PORT + local_instance_id - 1, - adb_port=constants.CF_ADB_PORT + local_instance_id - 1) + return os.path.join(GetLocalInstanceHomeDir(local_instance_id), + _CVD_RUNTIME_FOLDER_NAME) def _GetCurrentLocalTime(): @@ -193,31 +217,30 @@ class Instance(object): def Summary(self): """Let's make it easy to see what this class is holding.""" - indent = " " * 3 representation = [] representation.append(" name: %s" % self._name) - representation.append("%s IP: %s" % (indent, self._ip)) - representation.append("%s create time: %s" % (indent, self._createtime)) - representation.append("%s elapse time: %s" % (indent, self._elapsed_time)) - representation.append("%s status: %s" % (indent, self._status)) - representation.append("%s avd type: %s" % (indent, self._avd_type)) - representation.append("%s display: %s" % (indent, self._display)) - representation.append("%s vnc: 127.0.0.1:%s" % (indent, self._vnc_port)) - representation.append("%s zone: %s" % (indent, self._zone)) - - if self._adb_port: + representation.append("%s IP: %s" % (_INDENT, self._ip)) + representation.append("%s create time: %s" % (_INDENT, self._createtime)) + representation.append("%s elapse time: %s" % (_INDENT, self._elapsed_time)) + representation.append("%s status: %s" % (_INDENT, self._status)) + representation.append("%s avd type: %s" % (_INDENT, self._avd_type)) + representation.append("%s display: %s" % (_INDENT, self._display)) + representation.append("%s vnc: 127.0.0.1:%s" % (_INDENT, self._vnc_port)) + representation.append("%s zone: %s" % (_INDENT, self._zone)) + + if self._adb_port and self._device_information: representation.append("%s adb serial: 127.0.0.1:%s" % - (indent, self._adb_port)) + (_INDENT, self._adb_port)) representation.append("%s product: %s" % ( - indent, self._device_information["product"])) + _INDENT, self._device_information["product"])) representation.append("%s model: %s" % ( - indent, self._device_information["model"])) + _INDENT, self._device_information["model"])) representation.append("%s device: %s" % ( - indent, self._device_information["device"])) + _INDENT, self._device_information["device"])) representation.append("%s transport_id: %s" % ( - indent, self._device_information["transport_id"])) + _INDENT, self._device_information["transport_id"])) else: - representation.append("%s adb serial: disconnected" % indent) + representation.append("%s adb serial: disconnected" % _INDENT) return "\n".join(representation) @@ -247,16 +270,6 @@ class Instance(object): return self._display @property - def forwarding_adb_port(self): - """Return the adb port.""" - return self._adb_port - - @property - def forwarding_vnc_port(self): - """Return the vnc port.""" - return self._vnc_port - - @property def ssh_tunnel_is_connected(self): """Return the connect status.""" return self._ssh_tunnel_is_connected @@ -299,25 +312,28 @@ class Instance(object): class LocalInstance(Instance): """Class to store data of local cuttlefish instance.""" - - def __init__(self, local_instance_id, cf_runtime_cfg): + def __init__(self, cf_config_path): """Initialize a localInstance object. Args: - local_instance_id: Integer of instance id. - cf_runtime_cfg: A CvdRuntimeConfig instance. + cf_config_path: String, path to the cf runtime config. """ - display = _DISPLAY_STRING % {"x_res": cf_runtime_cfg.x_res, - "y_res": cf_runtime_cfg.y_res, - "dpi": cf_runtime_cfg.dpi} + self._cf_runtime_cfg = cvd_runtime_config.CvdRuntimeConfig(cf_config_path) + self._instance_dir = self._cf_runtime_cfg.instance_dir + self._virtual_disk_paths = self._cf_runtime_cfg.virtual_disk_paths + self._local_instance_id = int(self._cf_runtime_cfg.instance_id) + + display = _DISPLAY_STRING % {"x_res": self._cf_runtime_cfg.x_res, + "y_res": self._cf_runtime_cfg.y_res, + "dpi": self._cf_runtime_cfg.dpi} # TODO(143063678), there's no createtime info in # cuttlefish_config.json so far. - name = GetLocalInstanceName(local_instance_id) + name = GetLocalInstanceName(self._local_instance_id) fullname = (_FULL_NAME_STRING % - {"device_serial": "127.0.0.1:%d" % cf_runtime_cfg.adb_port, + {"device_serial": "127.0.0.1:%d" % self._cf_runtime_cfg.adb_port, "instance_name": name, "elapsed_time": None}) - adb_device = AdbTools(cf_runtime_cfg.adb_port) + adb_device = AdbTools(self._cf_runtime_cfg.adb_port) device_information = None if adb_device.IsAdbConnected(): device_information = adb_device.device_information @@ -325,19 +341,102 @@ class LocalInstance(Instance): super(LocalInstance, self).__init__( name=name, fullname=fullname, display=display, ip="127.0.0.1", status=constants.INS_STATUS_RUNNING, - adb_port=cf_runtime_cfg.adb_port, vnc_port=cf_runtime_cfg.vnc_port, + adb_port=self._cf_runtime_cfg.adb_port, + vnc_port=self._cf_runtime_cfg.vnc_port, createtime=None, elapsed_time=None, avd_type=constants.TYPE_CF, is_local=True, device_information=device_information, zone=_LOCAL_ZONE) - # LocalInstance class properties - self._instance_dir = cf_runtime_cfg.instance_dir + def Summary(self): + """Return the string that this class is holding.""" + instance_home = "%s instance home: %s" % (_INDENT, self._instance_dir) + return "%s\n%s" % (super(LocalInstance, self).Summary(), instance_home) + + def CvdStatus(self): + """check if local instance is active. + + Execute cvd_status cmd to check if it exit without error. + + Returns + True if instance is active. + """ + cvd_env = os.environ.copy() + cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE] = self._cf_runtime_cfg.config_path + cvd_env[constants.ENV_CVD_HOME] = GetLocalInstanceHomeDir(self._local_instance_id) + cvd_env[constants.ENV_CUTTLEFISH_INSTANCE] = str(self._local_instance_id) + try: + cvd_status_cmd = os.path.join(self._cf_runtime_cfg.cvd_tools_path, + _CVD_STATUS_BIN) + logger.debug("Running cmd[%s] to check cvd status.", cvd_status_cmd) + process = subprocess.Popen(cvd_status_cmd, + stdin=None, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + env=cvd_env) + stdout, _ = process.communicate() + if process.returncode != 0: + if stdout: + logger.debug("Local instance[%s] is not active: %s", + self.name, stdout.strip()) + return False + return True + except subprocess.CalledProcessError as cpe: + logger.error("Failed to run cvd_status: %s", cpe.output) + return False + + def Delete(self): + """Execute stop_cvd to stop local cuttlefish instance. + + - We should get the same host tool used to launch cvd to delete instance + , So get stop_cvd bin from the cvd runtime config. + - Add CUTTLEFISH_CONFIG_FILE env variable to tell stop_cvd which cvd + need to be deleted. + - Stop adb since local instance use the fixed adb port and could be + reused again soon. + """ + stop_cvd_cmd = os.path.join(self.cf_runtime_cfg.cvd_tools_path, + constants.CMD_STOP_CVD) + logger.debug("Running cmd[%s] to delete local cvd", stop_cvd_cmd) + with open(os.devnull, "w") as dev_null: + cvd_env = os.environ.copy() + if self.instance_dir: + cvd_env[constants.ENV_CUTTLEFISH_CONFIG_FILE] = self._cf_runtime_cfg.config_path + cvd_env[constants.ENV_CVD_HOME] = GetLocalInstanceHomeDir( + self._local_instance_id) + cvd_env[constants.ENV_CUTTLEFISH_INSTANCE] = str(self._local_instance_id) + else: + logger.error("instance_dir is null!! instance[%d] might not be" + " deleted", self._local_instance_id) + subprocess.check_call( + utils.AddUserGroupsToCmd(stop_cvd_cmd, + constants.LIST_CF_USER_GROUPS), + stderr=dev_null, stdout=dev_null, shell=True, env=cvd_env) + + adb_cmd = AdbTools(self.adb_port) + # When relaunch a local instance, we need to pass in retry=True to make + # sure adb device is completely gone since it will use the same adb port + adb_cmd.DisconnectAdb(retry=True) @property def instance_dir(self): """Return _instance_dir.""" return self._instance_dir + @property + def instance_id(self): + """Return _local_instance_id.""" + return self._local_instance_id + + @property + def virtual_disk_paths(self): + """Return virtual_disk_paths""" + return self._virtual_disk_paths + + @property + def cf_runtime_cfg(self): + """Return _cf_runtime_cfg""" + return self._cf_runtime_cfg + class LocalGoldfishInstance(Instance): """Class to store data of local goldfish instance.""" diff --git a/list/instance_test.py b/list/instance_test.py index 9832c808..a2c79224 100644 --- a/list/instance_test.py +++ b/list/instance_test.py @@ -27,6 +27,7 @@ import dateutil.parser import dateutil.tz from acloud.internal import constants +from acloud.internal.lib import cvd_runtime_config from acloud.internal.lib import driver_test_lib from acloud.internal.lib.adb_tools import AdbTools from acloud.list import instance @@ -62,15 +63,18 @@ class InstanceTest(driver_test_lib.BaseDriverTest): """"Test get local instance info from launch_cvd process.""" self.Patch(subprocess, "check_output", return_value=self.PS_LAUNCH_CVD) cf_config = mock.MagicMock( + instance_id=2, x_res=1080, y_res=1920, dpi=480, instance_dir="fake_instance_dir", adb_port=6521, - vnc_port=6445 + vnc_port=6445, + adb_ip_port="127.0.0.1:6521", ) - - local_instance = instance.LocalInstance(2, cf_config) + self.Patch(cvd_runtime_config, "CvdRuntimeConfig", + return_value=cf_config) + local_instance = instance.LocalInstance(cf_config) self.assertEqual(constants.LOCAL_INS_NAME + "-2", local_instance.name) self.assertEqual(True, local_instance.islocal) @@ -80,8 +84,8 @@ class InstanceTest(driver_test_lib.BaseDriverTest): constants.LOCAL_INS_NAME + "-2", "None")) self.assertEqual(expected_full_name, local_instance.fullname) - self.assertEqual(6521, local_instance.forwarding_adb_port) - self.assertEqual(6445, local_instance.forwarding_vnc_port) + self.assertEqual(6521, local_instance.adb_port) + self.assertEqual(6445, local_instance.vnc_port) @mock.patch("acloud.list.instance.tempfile") @mock.patch("acloud.list.instance.AdbTools") @@ -214,8 +218,8 @@ class InstanceTest(driver_test_lib.BaseDriverTest): # test ssh_tunnel_is_connected will be true if ssh tunnel connection is found instance_info = instance.RemoteInstance(self.GCE_INSTANCE) self.assertTrue(instance_info.ssh_tunnel_is_connected) - self.assertEqual(instance_info.forwarding_adb_port, fake_adb) - self.assertEqual(instance_info.forwarding_vnc_port, fake_vnc) + self.assertEqual(instance_info.adb_port, fake_adb) + self.assertEqual(instance_info.vnc_port, fake_vnc) self.assertEqual("1.1.1.1", instance_info.ip) self.assertEqual("fake_status", instance_info.status) self.assertEqual("fake_type", instance_info.avd_type) diff --git a/list/list.py b/list/list.py index 6afaf0af..febd6f39 100644 --- a/list/list.py +++ b/list/list.py @@ -20,8 +20,7 @@ of an Android Virtual Device. from __future__ import print_function import getpass import logging -import re -import subprocess +import os from acloud import errors from acloud.internal import constants @@ -35,28 +34,6 @@ from acloud.public import config logger = logging.getLogger(__name__) _COMMAND_PS_LAUNCH_CVD = ["ps", "-wweo", "lstart,cmd"] -_RE_LOCAL_CVD_PORT = re.compile(r"^127\.0\.0\.1:65(?P<cvd_port_suffix>\d{2})\s+") - - -def GetActiveCVDIds(): - """Get active local cvd ids from adb devices. - - The adb port of local instance will be decided according to instance id. - The rule of adb port will be '6520 + [instance id] - 1'. So we grep last - two digits of port and calculate the instance id. - - Return: - List of cvd id. - """ - local_cvd_ids = [] - adb_cmd = [constants.ADB_BIN, "devices"] - device_info = subprocess.check_output(adb_cmd) - for device in device_info.splitlines(): - match = _RE_LOCAL_CVD_PORT.match(device) - if match: - cvd_serial = match.group("cvd_port_suffix") - local_cvd_ids.append(int(cvd_serial) - 19) - return local_cvd_ids def _ProcessInstances(instance_list): @@ -144,19 +121,39 @@ def _GetLocalCuttlefishInstances(): Returns: instance_list: List of local instances. """ - local_cvd_ids = GetActiveCVDIds() local_instance_list = [] - for cvd_id in local_cvd_ids: - try: - cf_runtime_cfg = instance.GetCuttlefishRuntimeConfig(cvd_id) - local_instance_list.append( - instance.LocalInstance(cvd_id, cf_runtime_cfg)) - except errors.ConfigError: - logger.error("Instance[id:%d] dir not found!", cvd_id) - + for cf_runtime_config_path in instance.GetAllLocalInstanceConfigs(): + ins = instance.LocalInstance(cf_runtime_config_path) + if ins.CvdStatus(): + local_instance_list.append(ins) + else: + logger.info("cvd runtime config found but instance is not active:%s" + , cf_runtime_config_path) return local_instance_list +def GetActiveCVD(local_instance_id): + """Check if the local AVD with specific instance id is running + + Args: + local_instance_id: Integer of instance id. + + Return: + LocalInstance object. + """ + cfg_path = instance.GetLocalInstanceConfig(local_instance_id) + if cfg_path: + ins = instance.LocalInstance(cfg_path) + if ins.CvdStatus(): + return ins + cfg_path = instance.GetDefaultCuttlefishConfig() + if local_instance_id == 1 and os.path.isfile(cfg_path): + ins = instance.LocalInstance(cfg_path) + if ins.CvdStatus(): + return ins + return None + + def GetLocalInstances(): """Look for local cuttleifsh and goldfish instances. @@ -308,7 +305,7 @@ def FilterInstancesByAdbPort(instances, adb_port): """ all_instance_info = [] for instance_object in instances: - if instance_object.forwarding_adb_port == adb_port: + if instance_object.adb_port == adb_port: return [instance_object] all_instance_info.append(instance_object.fullname) diff --git a/list/list_test.py b/list/list_test.py index 12f7ce45..a4b466c0 100644 --- a/list/list_test.py +++ b/list/list_test.py @@ -12,12 +12,13 @@ # See the License for the specific language governing permissions and # limitations under the License. """Tests for list.""" -import subprocess + import unittest import mock from acloud import errors +from acloud.internal.lib import cvd_runtime_config from acloud.internal.lib import driver_test_lib from acloud.internal.lib import utils from acloud.list import list as list_instance @@ -91,7 +92,7 @@ class ListTest(driver_test_lib.BaseDriverTest): def testFilterInstancesByAdbPort(self): """test FilterInstancesByAdbPort.""" alive_instance1 = InstanceObject("alive_instance1") - alive_instance1.forwarding_adb_port = 1111 + alive_instance1.adb_port = 1111 alive_instance1.fullname = "device serial: 127.0.0.1:1111 alive_instance1" expected_instance = [alive_instance1] # Test to find instance by adb port number. @@ -105,17 +106,24 @@ class ListTest(driver_test_lib.BaseDriverTest): # pylint: disable=protected-access def testGetLocalCuttlefishInstances(self): """test _GetLocalCuttlefishInstances.""" - cf_config = mock.MagicMock() - # Test getting two instance case - self.Patch(list_instance, "GetActiveCVDIds", return_value=[1, 2]) - self.Patch(instance, "GetCuttlefishRuntimeConfig", return_value=cf_config) + self.Patch(instance, "GetAllLocalInstanceConfigs", + return_value=["fake_path1", "fake_path2"]) self.Patch(instance, "GetLocalInstanceRuntimeDir") - self.Patch(instance, "LocalInstance") + + local_ins = mock.MagicMock() + local_ins.CvdStatus.return_value = True + self.Patch(instance, "LocalInstance", return_value=local_ins) ins_list = list_instance._GetLocalCuttlefishInstances() self.assertEqual(2, len(ins_list)) + local_ins = mock.MagicMock() + local_ins.CvdStatus.return_value = False + self.Patch(instance, "LocalInstance", return_value=local_ins) + ins_list = list_instance._GetLocalCuttlefishInstances() + self.assertEqual(0, len(ins_list)) + # pylint: disable=no-member def testPrintInstancesDetails(self): """test PrintInstancesDetails.""" @@ -125,10 +133,13 @@ class ListTest(driver_test_lib.BaseDriverTest): x_res=728, y_res=728, dpi=240, - instance_dir="fake_dir" + instance_dir="fake_dir", + adb_ip_port="127.0.0.1:6520" ) + self.Patch(cvd_runtime_config, "CvdRuntimeConfig", + return_value=cf_config) - ins = instance.LocalInstance(1, cf_config) + ins = instance.LocalInstance("fake_cf_path") list_instance.PrintInstancesDetails([ins], verbose=True) instance.Instance.Summary.assert_called_once() @@ -141,15 +152,6 @@ class ListTest(driver_test_lib.BaseDriverTest): list_instance.PrintInstancesDetails([], verbose=True) instance.Instance.Summary.assert_not_called() - # pylint: disable=no-member - def testGetActiveCVDIds(self): - """test GetActiveCVDIds.""" - # Test getting two local devices - adb_output = "127.0.0.1:6520 device\n127.0.0.1:6521 device" - expected_result = [1, 2] - self.Patch(subprocess, "check_output", return_value=adb_output) - self.assertEqual(list_instance.GetActiveCVDIds(), expected_result) - if __name__ == "__main__": unittest.main() diff --git a/public/report.py b/public/report.py index 5f5a07a4..dd95c4e4 100755 --- a/public/report.py +++ b/public/report.py @@ -150,7 +150,7 @@ class Report(object): "requested to update to a status with lower severity %s, ignored.", self.status, status) - def AddDevice(self, instance_name, ip_address, adb_port, vnc_port=None, + def AddDevice(self, instance_name, ip_address, adb_port, vnc_port, key="devices"): """Add a record of a device. @@ -161,9 +161,13 @@ class Report(object): vnc_port: An integer. key: A string, the data entry where the record is added. """ - device = {constants.INSTANCE_NAME: instance_name, - constants.IP: "%s:%d" % (ip_address, adb_port), - constants.ADB_PORT: adb_port} + device = {constants.INSTANCE_NAME: instance_name} + if adb_port: + device[constants.ADB_PORT] = adb_port + device[constants.IP] = "%s:%d" % (ip_address, adb_port) + else: + device[constants.IP] = ip_address + if vnc_port: device[constants.VNC_PORT] = vnc_port self.AddData(key=key, value=device) diff --git a/public/report_test.py b/public/report_test.py index 772c9875..d3987c80 100644 --- a/public/report_test.py +++ b/public/report_test.py @@ -63,12 +63,13 @@ class ReportTest(unittest.TestCase): def testAddDevice(self): """test AddDevice.""" test_report = report.Report("create") - test_report.AddDevice("instance_1", "127.0.0.1", 6520) + test_report.AddDevice("instance_1", "127.0.0.1", 6520, 6444) expected = { "devices": [{ "instance_name": "instance_1", "ip": "127.0.0.1:6520", - "adb_port": 6520 + "adb_port": 6520, + "vnc_port": 6444 }] } self.assertEqual(test_report.data, expected) diff --git a/reconnect/reconnect.py b/reconnect/reconnect.py index 1be95676..d354b4e2 100644 --- a/reconnect/reconnect.py +++ b/reconnect/reconnect.py @@ -22,7 +22,6 @@ Reconnect will: import re from acloud import errors -from acloud.delete import delete from acloud.internal import constants from acloud.internal.lib import auth from acloud.internal.lib import android_compute_client @@ -51,7 +50,7 @@ def StartVnc(vnc_port, display): vnc_started_pattern = _VNC_STARTED_PATTERN % {"vnc_port": vnc_port} if not utils.IsCommandRunning(vnc_started_pattern): #clean old disconnect ssvnc viewer. - delete.CleanupSSVncviewer(vnc_port) + utils.CleanupSSVncviewer(vnc_port) match = _RE_DISPLAY.match(display) if match: @@ -110,9 +109,9 @@ def ReconnectInstance(ssh_private_key_path, "unknown avd type: %s" % (instance.name, instance.avd_type)) - adb_cmd = AdbTools(instance.forwarding_adb_port) - vnc_port = instance.forwarding_vnc_port - adb_port = instance.forwarding_adb_port + adb_cmd = AdbTools(instance.adb_port) + vnc_port = instance.vnc_port + adb_port = instance.adb_port # ssh tunnel is up but device is disconnected on adb if instance.ssh_tunnel_is_connected and not adb_cmd.IsAdbConnectionAlive(): adb_cmd.DisconnectAdb() diff --git a/reconnect/reconnect_test.py b/reconnect/reconnect_test.py index 493067b5..70ea801b 100644 --- a/reconnect/reconnect_test.py +++ b/reconnect/reconnect_test.py @@ -42,7 +42,7 @@ class ReconnectTest(driver_test_lib.BaseDriverTest): instance_object = mock.MagicMock() instance_object.ip = "1.1.1.1" instance_object.islocal = False - instance_object.forwarding_adb_port = "8686" + instance_object.adb_port = "8686" instance_object.avd_type = "cuttlefish" self.Patch(subprocess, "check_call", return_value=True) self.Patch(utils, "LaunchVncClient") @@ -52,7 +52,7 @@ class ReconnectTest(driver_test_lib.BaseDriverTest): self.Patch(utils, "IsCommandRunning", return_value=False) #test ssh tunnel not connected, remote instance. - instance_object.forwarding_vnc_port = 6666 + instance_object.vnc_port = 6666 instance_object.display = "" utils.AutoConnect.call_count = 0 reconnect.ReconnectInstance(ssh_private_key_path, instance_object, fake_report) @@ -69,7 +69,7 @@ class ReconnectTest(driver_test_lib.BaseDriverTest): instance_object.ssh_tunnel_is_connected = False instance_object.display = "" utils.AutoConnect.call_count = 0 - instance_object.forwarding_vnc_port = 5555 + instance_object.vnc_port = 5555 extra_args_ssh_tunnel = None self.Patch(utils, "AutoConnect", return_value=ForwardedPorts(vnc_port=11111, adb_port=22222)) @@ -100,7 +100,7 @@ class ReconnectTest(driver_test_lib.BaseDriverTest): #test reconnect local instance. instance_object.islocal = True instance_object.display = "" - instance_object.forwarding_vnc_port = 5555 + instance_object.vnc_port = 5555 instance_object.ssh_tunnel_is_connected = False utils.AutoConnect.call_count = 0 reconnect.ReconnectInstance(ssh_private_key_path, @@ -115,8 +115,8 @@ class ReconnectTest(driver_test_lib.BaseDriverTest): fake_report = mock.MagicMock() instance_object = mock.MagicMock() instance_object.ip = "1.1.1.1" - instance_object.forwarding_vnc_port = 9999 - instance_object.forwarding_adb_port = "9999" + instance_object.vnc_port = 9999 + instance_object.adb_port = "9999" instance_object.islocal = False instance_object.ssh_tunnel_is_connected = False self.Patch(utils, "AutoConnect") |