diff --git a/moler/device/adbremote.py b/moler/device/adbremote.py index 7916249f3..fe5b3edb3 100644 --- a/moler/device/adbremote.py +++ b/moler/device/adbremote.py @@ -12,8 +12,6 @@ import logging from moler.device.textualdevice import TextualDevice -# from moler.device.proxy_pc import ProxyPc # TODO: allow jumping towards ADB_REMOTE via proxy-pc -from moler.device.unixlocal import UnixLocal from moler.device.unixremote import UnixRemote from moler.cmd.adb.adb_shell import AdbShell from moler.helpers import call_base_class_method_with_same_name, mark_to_call_base_class_method_with_same_name @@ -86,7 +84,7 @@ def _get_default_sm_configuration_without_proxy_pc(self): """ config = { # TODO: shell we use direct-string names of config dicts? change simplicity vs readability TextualDevice.connection_hops: { - UnixRemote.unix_remote: { # from + AdbRemote.unix_remote: { # from AdbRemote.adb_shell: { # to "execute_command": "adb_shell", "command_params": { # with parameters @@ -99,7 +97,7 @@ def _get_default_sm_configuration_without_proxy_pc(self): }, }, AdbRemote.adb_shell: { # from - UnixRemote.unix_remote: { # to + AdbRemote.unix_remote: { # to "execute_command": "exit", # using command "command_params": { # with parameters "expected_prompt": r'remote_user_prompt', # overwritten in _configure_state_machine() @@ -143,7 +141,7 @@ def _get_default_sm_configuration_with_proxy_pc(self): """ config = { # TODO: shell we use direct-string names of config dicts? change simplicity vs readability TextualDevice.connection_hops: { - UnixRemote.unix_remote: { # from + AdbRemote.unix_remote: { # from AdbRemote.adb_shell: { # to "execute_command": "adb_shell", "command_params": { # with parameters @@ -156,7 +154,7 @@ def _get_default_sm_configuration_with_proxy_pc(self): }, }, AdbRemote.adb_shell: { # from - UnixRemote.unix_remote: { # to + AdbRemote.unix_remote: { # to "execute_command": "exit", # using command "command_params": { # with parameters "expected_prompt": r'remote_user_prompt', # overwritten in _configure_state_machine() @@ -199,7 +197,7 @@ def _prepare_transitions_with_proxy_pc(self): :return: transitions without proxy_pc state. """ transitions = { - UnixRemote.unix_remote: { + AdbRemote.unix_remote: { AdbRemote.adb_shell: { "action": [ "_execute_command_to_change_state" @@ -207,7 +205,7 @@ def _prepare_transitions_with_proxy_pc(self): } }, AdbRemote.adb_shell: { - UnixRemote.unix_remote: { + AdbRemote.unix_remote: { "action": [ "_execute_command_to_change_state" ], @@ -235,7 +233,7 @@ def _prepare_transitions_without_proxy_pc(self): :return: transitions without proxy_pc state. """ transitions = { - UnixRemote.unix_remote: { + AdbRemote.unix_remote: { AdbRemote.adb_shell: { "action": [ "_execute_command_to_change_state" @@ -243,7 +241,7 @@ def _prepare_transitions_without_proxy_pc(self): } }, AdbRemote.adb_shell: { - UnixRemote.unix_remote: { + AdbRemote.unix_remote: { "action": [ "_execute_command_to_change_state" ], @@ -271,7 +269,7 @@ def _prepare_state_prompts_without_proxy_pc(self): :return: textual prompt for each state without proxy_pc state. """ hops_config = self._configurations[TextualDevice.connection_hops] - cfg_ux2adb = hops_config[UnixRemote.unix_remote][AdbRemote.adb_shell] + cfg_ux2adb = hops_config[AdbRemote.unix_remote][AdbRemote.adb_shell] cfg_adb2adbroot = hops_config[AdbRemote.adb_shell][AdbRemote.adb_shell_root] adb_shell_cmd_params = cfg_ux2adb["command_params"] adb_shell_prompt = self._get_adb_shell_prompt(adb_shell_cmd_params) @@ -298,7 +296,7 @@ def _prepare_state_prompts_with_proxy_pc(self): :return: textual prompt for each state without proxy_pc state. """ hops_config = self._configurations[TextualDevice.connection_hops] - cfg_ux2adb = hops_config[UnixRemote.unix_remote][AdbRemote.adb_shell] + cfg_ux2adb = hops_config[AdbRemote.unix_remote][AdbRemote.adb_shell] cfg_adb2adbroot = hops_config[AdbRemote.adb_shell][AdbRemote.adb_shell_root] adb_shell_cmd_params = cfg_ux2adb["command_params"] adb_shell_prompt = self._get_adb_shell_prompt(adb_shell_cmd_params) @@ -326,7 +324,7 @@ def _serial_number(self): :return: serial_number. """ hops_config = self._configurations[TextualDevice.connection_hops] - cfg_ux2adb = hops_config[UnixRemote.unix_remote][AdbRemote.adb_shell] + cfg_ux2adb = hops_config[AdbRemote.unix_remote][AdbRemote.adb_shell] serial_number = cfg_ux2adb["command_params"]["serial_number"] return serial_number @@ -346,7 +344,7 @@ def _prepare_newline_chars_without_proxy_pc(self): :return: newline char for each state without proxy_pc state. """ hops_config = self._configurations[TextualDevice.connection_hops] - cfg_ux2adb = hops_config[UnixRemote.unix_remote][AdbRemote.adb_shell] + cfg_ux2adb = hops_config[AdbRemote.unix_remote][AdbRemote.adb_shell] cfg_adb2adbroot = hops_config[AdbRemote.adb_shell][AdbRemote.adb_shell_root] adb_shell_newline = cfg_ux2adb["command_params"]["target_newline"] adb_shell_root_newline = cfg_adb2adbroot["command_params"]["target_newline"] @@ -366,7 +364,7 @@ def _prepare_newline_chars_with_proxy_pc(self): :return: newline char for each state without proxy_pc state. """ hops_config = self._configurations[TextualDevice.connection_hops] - cfg_ux2adb = hops_config[UnixRemote.unix_remote][AdbRemote.adb_shell] + cfg_ux2adb = hops_config[AdbRemote.unix_remote][AdbRemote.adb_shell] cfg_adb2adbroot = hops_config[AdbRemote.adb_shell][AdbRemote.adb_shell_root] adb_shell_newline = cfg_ux2adb["command_params"]["target_newline"] adb_shell_root_newline = cfg_adb2adbroot["command_params"]["target_newline"] @@ -387,48 +385,48 @@ def _prepare_state_hops_without_proxy_pc(self): """ state_hops = { TextualDevice.not_connected: { - UnixLocal.unix_local_root: UnixLocal.unix_local, - UnixRemote.unix_remote: UnixLocal.unix_local, - UnixRemote.unix_remote_root: UnixLocal.unix_local, - AdbRemote.adb_shell: UnixLocal.unix_local, - AdbRemote.adb_shell_root: UnixLocal.unix_local, + AdbRemote.unix_local_root: AdbRemote.unix_local, + AdbRemote.unix_remote: AdbRemote.unix_local, + AdbRemote.unix_remote_root: AdbRemote.unix_local, + AdbRemote.adb_shell: AdbRemote.unix_local, + AdbRemote.adb_shell_root: AdbRemote.unix_local, }, - UnixLocal.unix_local: { - UnixRemote.unix_remote_root: UnixRemote.unix_remote, - AdbRemote.adb_shell: UnixRemote.unix_remote, - AdbRemote.adb_shell_root: UnixRemote.unix_remote, + AdbRemote.unix_local: { + AdbRemote.unix_remote_root: AdbRemote.unix_remote, + AdbRemote.adb_shell: AdbRemote.unix_remote, + AdbRemote.adb_shell_root: AdbRemote.unix_remote, }, - UnixLocal.unix_local_root: { - TextualDevice.not_connected: UnixLocal.unix_local, - UnixRemote.unix_remote: UnixLocal.unix_local, - UnixRemote.unix_remote_root: UnixLocal.unix_local, - AdbRemote.adb_shell: UnixLocal.unix_local, - AdbRemote.adb_shell_root: UnixLocal.unix_local, + AdbRemote.unix_local_root: { + TextualDevice.not_connected: AdbRemote.unix_local, + AdbRemote.unix_remote: AdbRemote.unix_local, + AdbRemote.unix_remote_root: AdbRemote.unix_local, + AdbRemote.adb_shell: AdbRemote.unix_local, + AdbRemote.adb_shell_root: AdbRemote.unix_local, }, - UnixRemote.unix_remote: { - TextualDevice.not_connected: UnixLocal.unix_local, - UnixLocal.unix_local_root: UnixLocal.unix_local, + AdbRemote.unix_remote: { + TextualDevice.not_connected: AdbRemote.unix_local, + AdbRemote.unix_local_root: AdbRemote.unix_local, AdbRemote.adb_shell_root: AdbRemote.adb_shell, }, - UnixRemote.unix_remote_root: { - TextualDevice.not_connected: UnixRemote.unix_remote, - UnixLocal.unix_local: UnixRemote.unix_remote, - UnixLocal.unix_local_root: UnixRemote.unix_remote, - AdbRemote.adb_shell: UnixRemote.unix_remote, - AdbRemote.adb_shell_root: UnixRemote.unix_remote, + AdbRemote.unix_remote_root: { + TextualDevice.not_connected: AdbRemote.unix_remote, + AdbRemote.unix_local: AdbRemote.unix_remote, + AdbRemote.unix_local_root: AdbRemote.unix_remote, + AdbRemote.adb_shell: AdbRemote.unix_remote, + AdbRemote.adb_shell_root: AdbRemote.unix_remote, }, AdbRemote.adb_shell: { - TextualDevice.not_connected: UnixRemote.unix_remote, - UnixLocal.unix_local: UnixRemote.unix_remote, - UnixLocal.unix_local_root: UnixRemote.unix_remote, - UnixRemote.unix_remote_root: UnixRemote.unix_remote, + TextualDevice.not_connected: AdbRemote.unix_remote, + AdbRemote.unix_local: AdbRemote.unix_remote, + AdbRemote.unix_local_root: AdbRemote.unix_remote, + AdbRemote.unix_remote_root: AdbRemote.unix_remote, }, AdbRemote.adb_shell_root: { TextualDevice.not_connected: AdbRemote.adb_shell, - UnixLocal.unix_local: AdbRemote.adb_shell, - UnixLocal.unix_local_root: AdbRemote.adb_shell, - UnixRemote.unix_remote: AdbRemote.adb_shell, - UnixRemote.unix_remote_root: AdbRemote.adb_shell, + AdbRemote.unix_local: AdbRemote.adb_shell, + AdbRemote.unix_local_root: AdbRemote.adb_shell, + AdbRemote.unix_remote: AdbRemote.adb_shell, + AdbRemote.unix_remote_root: AdbRemote.adb_shell, }, } return state_hops @@ -441,49 +439,62 @@ def _prepare_state_hops_with_proxy_pc(self): """ state_hops = { TextualDevice.not_connected: { - UnixLocal.unix_local_root: UnixLocal.unix_local, - UnixRemote.unix_remote: UnixLocal.unix_local, - UnixRemote.unix_remote_root: UnixLocal.unix_local, - AdbRemote.adb_shell: UnixLocal.unix_local, - AdbRemote.adb_shell_root: UnixLocal.unix_local, + AdbRemote.unix_local_root: AdbRemote.unix_local, + AdbRemote.proxy_pc: AdbRemote.unix_local, + AdbRemote.unix_remote: AdbRemote.unix_local, + AdbRemote.unix_remote_root: AdbRemote.unix_local, + AdbRemote.adb_shell: AdbRemote.unix_local, + AdbRemote.adb_shell_root: AdbRemote.unix_local, }, - UnixLocal.unix_local: { - UnixRemote.unix_remote_root: UnixRemote.unix_remote, - AdbRemote.adb_shell: UnixRemote.unix_remote, - AdbRemote.adb_shell_root: UnixRemote.unix_remote, + AdbRemote.unix_local: { + AdbRemote.unix_remote_root: AdbRemote.proxy_pc, + AdbRemote.adb_shell: AdbRemote.proxy_pc, + AdbRemote.adb_shell_root: AdbRemote.proxy_pc, }, - UnixLocal.unix_local_root: { - TextualDevice.not_connected: UnixLocal.unix_local, - UnixRemote.unix_remote: UnixLocal.unix_local, - UnixRemote.unix_remote_root: UnixLocal.unix_local, - AdbRemote.adb_shell: UnixLocal.unix_local, - AdbRemote.adb_shell_root: UnixLocal.unix_local, + AdbRemote.unix_local_root: { + TextualDevice.not_connected: AdbRemote.unix_local, + AdbRemote.proxy_pc: AdbRemote.unix_local, + AdbRemote.unix_remote: AdbRemote.unix_local, + AdbRemote.unix_remote_root: AdbRemote.unix_local, + AdbRemote.adb_shell: AdbRemote.unix_local, + AdbRemote.adb_shell_root: AdbRemote.unix_local, }, - UnixRemote.unix_remote: { - TextualDevice.not_connected: UnixLocal.unix_local, - UnixLocal.unix_local_root: UnixLocal.unix_local, + AdbRemote.unix_remote: { + AdbRemote.unix_local: AdbRemote.proxy_pc, + TextualDevice.not_connected: AdbRemote.proxy_pc, + AdbRemote.unix_local_root: AdbRemote.proxy_pc, AdbRemote.adb_shell_root: AdbRemote.adb_shell, }, - UnixRemote.unix_remote_root: { - TextualDevice.not_connected: UnixRemote.unix_remote, - UnixLocal.unix_local: UnixRemote.unix_remote, - UnixLocal.unix_local_root: UnixRemote.unix_remote, - AdbRemote.adb_shell: UnixRemote.unix_remote, - AdbRemote.adb_shell_root: UnixRemote.unix_remote, + AdbRemote.unix_remote_root: { + TextualDevice.not_connected: AdbRemote.unix_remote, + AdbRemote.proxy_pc: AdbRemote.unix_remote, + AdbRemote.unix_local: AdbRemote.unix_remote, + AdbRemote.unix_local_root: AdbRemote.unix_remote, + AdbRemote.adb_shell: AdbRemote.unix_remote, + AdbRemote.adb_shell_root: AdbRemote.unix_remote, }, AdbRemote.adb_shell: { - TextualDevice.not_connected: UnixRemote.unix_remote, - UnixLocal.unix_local: UnixRemote.unix_remote, - UnixLocal.unix_local_root: UnixRemote.unix_remote, - UnixRemote.unix_remote_root: UnixRemote.unix_remote, + TextualDevice.not_connected: AdbRemote.unix_remote, + AdbRemote.proxy_pc: AdbRemote.unix_remote, + AdbRemote.unix_local: AdbRemote.unix_remote, + AdbRemote.unix_local_root: AdbRemote.unix_remote, + AdbRemote.unix_remote_root: AdbRemote.unix_remote, }, AdbRemote.adb_shell_root: { TextualDevice.not_connected: AdbRemote.adb_shell, - UnixLocal.unix_local: AdbRemote.adb_shell, - UnixLocal.unix_local_root: AdbRemote.adb_shell, - UnixRemote.unix_remote: AdbRemote.adb_shell, - UnixRemote.unix_remote_root: AdbRemote.adb_shell, + AdbRemote.proxy_pc: AdbRemote.adb_shell, + AdbRemote.unix_local: AdbRemote.adb_shell, + AdbRemote.unix_local_root: AdbRemote.adb_shell, + AdbRemote.unix_remote: AdbRemote.adb_shell, + AdbRemote.unix_remote_root: AdbRemote.adb_shell, }, + AdbRemote.proxy_pc: { + AdbRemote.unix_remote_root: AdbRemote.unix_remote, + AdbRemote.adb_shell: AdbRemote.unix_remote, + AdbRemote.adb_shell_root: AdbRemote.unix_remote, + AdbRemote.not_connected: AdbRemote.unix_remote, + AdbRemote.unix_local_root: AdbRemote.unix_local, + } } return state_hops @@ -498,13 +509,16 @@ def _configure_state_machine(self, sm_params): hops_config = self._configurations[TextualDevice.connection_hops] # copy prompt for ADB_SHELL/exit from UNIX_LOCAL/ssh - cfg_uxloc2ux = hops_config[UnixLocal.unix_local][UnixRemote.unix_remote] - cfg_adb2ux = hops_config[AdbRemote.adb_shell][UnixRemote.unix_remote] + if self._use_proxy_pc: + cfg_uxloc2ux = hops_config[AdbRemote.proxy_pc][AdbRemote.unix_remote] + else: + cfg_uxloc2ux = hops_config[AdbRemote.unix_local][AdbRemote.unix_remote] + cfg_adb2ux = hops_config[AdbRemote.adb_shell][AdbRemote.unix_remote] remote_ux_prompt = cfg_uxloc2ux["command_params"]["expected_prompt"] cfg_adb2ux["command_params"]["expected_prompt"] = remote_ux_prompt # copy prompt for ADB_SHELL_ROOT/exit from UNIX_REMOTE/adb shell - cfg_ux2adb = hops_config[UnixRemote.unix_remote][AdbRemote.adb_shell] + cfg_ux2adb = hops_config[AdbRemote.unix_remote][AdbRemote.adb_shell] cfg_adbroot2adb = hops_config[AdbRemote.adb_shell_root][AdbRemote.adb_shell] adb_shell_prompt = self._get_adb_shell_prompt(cfg_ux2adb["command_params"]) cfg_adbroot2adb["command_params"]["expected_prompt"] = adb_shell_prompt @@ -531,7 +545,7 @@ def _get_packages_for_state(self, state, observer): TextualDevice.events: ['moler.events.shared']} if available: return available[observer] - elif state == UnixRemote.unix_remote: # this is unix extended with adb commands + elif state == AdbRemote.unix_remote: # this is unix extended with adb commands if observer == TextualDevice.cmds: available.append('moler.cmd.adb') diff --git a/moler/device/textualdevice.py b/moler/device/textualdevice.py index 242446132..575456f15 100644 --- a/moler/device/textualdevice.py +++ b/moler/device/textualdevice.py @@ -159,6 +159,7 @@ def _prepare_sm_data(self, sm_params): self._prepare_transitions() self._prepare_state_hops() self._configure_state_machine(sm_params) + self._validate_device_configuration() self._prepare_newline_chars() self._send_transitions_to_sm(self._stored_transitions) @@ -1153,7 +1154,6 @@ def _configure_state_machine(self, sm_params): self._configurations = self._prepare_sm_configuration( default_sm_configurations, sm_params ) - self._validate_device_configuration() self._prepare_state_prompts() def _prepare_sm_configuration(self, default_sm_configurations, sm_params): diff --git a/moler/device/unixremote.py b/moler/device/unixremote.py index f729888d2..fa601f68c 100644 --- a/moler/device/unixremote.py +++ b/moler/device/unixremote.py @@ -435,6 +435,10 @@ def _overwrite_prompts(self): Overwrite prompts for some states to easily configure the SM. """ if self._use_proxy_pc: + self._configurations[UnixRemote.connection_hops][UnixRemote.unix_remote][UnixRemote.proxy_pc][ + "command_params"]["expected_prompt"] = \ + self._configurations[UnixRemote.connection_hops][UnixRemote.unix_local][UnixRemote.proxy_pc][ + "command_params"]["expected_prompt"] self._configurations[UnixRemote.connection_hops][UnixRemote.unix_remote_root][UnixRemote.unix_remote][ "command_params"]["expected_prompt"] = \ self._configurations[UnixRemote.connection_hops][UnixRemote.proxy_pc][UnixRemote.unix_remote][ diff --git a/test/device/test_SM_adb_remote.py b/test/device/test_SM_adb_remote.py index adf7e8250..2dfdde3c3 100644 --- a/test/device/test_SM_adb_remote.py +++ b/test/device/test_SM_adb_remote.py @@ -10,6 +10,7 @@ # adb_remotes = ['ADB_REMOTE', 'ADB_REMOTE3'] adb_remotes = ['ADB_REMOTE'] # TODO: add ADB_REMOTE3 when it will be implemented +adb_remotes_proxy_pc = ['ADB_REMOTE_PROXY_PC'] @pytest.mark.parametrize("device_name", adb_remotes) def test_adb_remote_device(device_name, device_connection, adb_remote_output): @@ -19,6 +20,13 @@ def test_adb_remote_device(device_name, device_connection, adb_remote_output): iterate_over_device_states(device=adb_remote) +@pytest.mark.parametrize("device_name", adb_remotes_proxy_pc) +def test_adb_remote_device_proxy_pc(device_name, device_connection, adb_remote_output_proxy_pc): + adb_remote = get_device(name=device_name, connection=device_connection, device_output=adb_remote_output_proxy_pc, + test_file_path=__file__) + + iterate_over_device_states(device=adb_remote) + # @pytest.mark.parametrize("devices", [adb_remotes]) # def test_unix_sm_identity(devices): # dev0 = DeviceFactory.get_device(name=devices[0]) @@ -62,3 +70,40 @@ def adb_remote_output(): } return output + + +@pytest.fixture +def adb_remote_output_proxy_pc(): + output = { + "UNIX_LOCAL": { + 'TERM=xterm-mono ssh -l proxy_pc_login -o ServerAliveInterval=7 -o ServerAliveCountMax=2 proxy_pc_host': 'proxy_pc#', + 'su': 'local_root_prompt' + }, + "UNIX_LOCAL_ROOT": { + 'exit': 'moler_bash#' + }, + "UNIX_REMOTE": { + 'exit': 'proxy_pc#', + 'su': 'remote_root_prompt', + 'adb -s f57e6b77 shell': 'shell@adbhost:/ $', # adb shell is changing prompt so it triggers following 2 send-responses + '': 'shell@adbhost:/ $', # to allow for self.connection.sendline("") in _send_prompt_set() + 'export PS1="adb_shell@f57e6b77 \\$ "': 'adb_shell@f57e6b77 $' # to allow for self.connection.sendline(self.set_prompt) in _send_prompt_set() + }, + "ADB_SHELL": { + '': 'adb_shell@f57e6b77 $', + 'exit': 'remote#', + 'su': 'adb_shell@f57e6b77 #', + }, + "ADB_SHELL_ROOT": { + 'exit': 'adb_shell@f57e6b77 $', + }, + "UNIX_REMOTE_ROOT": { + 'exit': 'remote#', + }, + "PROXY_PC": { + 'TERM=xterm-mono ssh -l remote_login -o ServerAliveInterval=7 -o ServerAliveCountMax=2 remote_host': 'remote#', + 'exit': 'moler_bash#' + }, + } + + return output diff --git a/test/resources/device_config.yml b/test/resources/device_config.yml index 9df9696d9..97b7bc64b 100644 --- a/test/resources/device_config.yml +++ b/test/resources/device_config.yml @@ -404,6 +404,34 @@ DEVICES: command_params: serial_number: 'f57e6b77' # to create: adb -s f57e6b77 shell + ADB_REMOTE_PROXY_PC: + DEVICE_CLASS: moler.device.adbremote.AdbRemote + INITIAL_STATE: UNIX_LOCAL + CONNECTION_HOPS: + UNIX_LOCAL: + PROXY_PC: + execute_command: ssh + command_params: + expected_prompt: "proxy_pc#" + host: proxy_pc_host + login: proxy_pc_login + password: password + set_timeout: null + PROXY_PC: + UNIX_REMOTE: + execute_command: ssh # default value + command_params: + expected_prompt: 'remote#' + host: remote_host + login: remote_login + password: passwd4remote + set_timeout: null + UNIX_REMOTE: + ADB_SHELL: + execute_command: adb_shell # default value; default command is: adb shell + command_params: + serial_number: 'f57e6b77' # to create: adb -s f57e6b77 shell + # ADB_REMOTE3: # DEVICE_CLASS: moler.device.adbremote3.AdbRemote3 # INITIAL_STATE: UNIX_LOCAL