def test_unix_remote_with_sshshell_cant_use_unix_local_states( loaded_unix_remote_config): with pytest.raises(ValueError) as err: DeviceFactory.get_device(name="UX_REMOTE", initial_state="UNIX_LOCAL") assert "has no UNIX_LOCAL/UNIX_LOCAL_ROOT states" in str(err.value) assert "since it uses following io: ThreadedSshShell" in str(err.value) assert 'You need io of type "terminal" to have unix-local states' in str( err.value)
def load_device_from_config(config, add_only=False): create_at_startup = False topology = None cloned_devices = dict() cloned_id = 'CLONED_FROM' from moler.device.device import DeviceFactory if 'DEVICES' in config: if 'DEFAULT_CONNECTION' in config['DEVICES']: default_conn = config['DEVICES'].pop('DEFAULT_CONNECTION') if add_only is False: conn_desc = default_conn['CONNECTION_DESC'] dev_cfg.set_default_connection(**conn_desc) if 'CREATE_AT_STARTUP' in config['DEVICES']: create_at_startup = config['DEVICES'].pop('CREATE_AT_STARTUP') topology = config['DEVICES'].pop('LOGICAL_TOPOLOGY', None) for device_name in config['DEVICES']: device_def = config['DEVICES'][device_name] # check if device name is already used if not _is_device_creation_needed(device_name, device_def): continue if cloned_id in device_def: cloned_devices[device_name] = dict() cloned_devices[device_name]['source'] = device_def[cloned_id] cloned_devices[device_name]['state'] = device_def.get( 'INITIAL_STATE', None) cloned_devices[device_name][ 'lazy_cmds_events'] = device_def.get( 'LAZY_CMDS_EVENTS', False) else: # create all devices defined directly dev_cfg.define_device( name=device_name, device_class=device_def['DEVICE_CLASS'], connection_desc=device_def.get('CONNECTION_DESC', dev_cfg.default_connection), connection_hops={ 'CONNECTION_HOPS': device_def.get('CONNECTION_HOPS', {}) }, initial_state=device_def.get('INITIAL_STATE', None), lazy_cmds_events=device_def.get('LAZY_CMDS_EVENTS', False)) for device_name, device_desc in cloned_devices.items(): cloned_from = device_desc['source'] initial_state = device_desc['state'] lazy_cmds_events = device_desc['lazy_cmds_events'] DeviceFactory.get_cloned_device(source_device=cloned_from, new_name=device_name, initial_state=initial_state, establish_connection=False, lazy_cmds_events=lazy_cmds_events) if create_at_startup is True: DeviceFactory.create_all_devices() _load_topology(topology=topology)
def test_create_device_without_hops(): connection_desc = {"io_type": "terminal", "variant": "threaded"} dev = DeviceFactory.get_device( connection_desc=connection_desc, device_class='moler.device.unixlocal.UnixLocal', connection_hops=dict()) assert dev is not None
def test_adb_remote_with_terminal_can_use_unix_local_states( loaded_adb_device_config, uxlocal2adbshell_connection_hops): # check backward compatibility dev = DeviceFactory.get_device( name="ADB_LHOST", initial_state="UNIX_LOCAL", connection_hops=uxlocal2adbshell_connection_hops, connection_desc={"io_type": "terminal"}) assert dev.current_state == "UNIX_LOCAL" dev.goto_state("PROXY_PC") assert dev.current_state == "PROXY_PC" dev.goto_state("UNIX_REMOTE") assert dev.current_state == "UNIX_REMOTE" dev.goto_state("ADB_SHELL") assert dev.current_state == "ADB_SHELL" # dev.goto_state("ADB_SHELL_ROOT") # can't test; need to know root password on CI machine # assert dev.current_state == "ADB_SHELL_ROOT" dev.goto_state("UNIX_REMOTE") assert dev.current_state == "UNIX_REMOTE" dev.goto_state("PROXY_PC") assert dev.current_state == "PROXY_PC" dev.goto_state("UNIX_LOCAL") assert dev.current_state == "UNIX_LOCAL" dev.goto_state("NOT_CONNECTED") assert dev.current_state == "NOT_CONNECTED" dev.remove()
def test_adb_remote_with_sshshell_via_proxy_pc( loaded_adb_device_config, proxypc2adbshell_connection_hops): dev = DeviceFactory.get_device( name="ADB_LHOST", initial_state="PROXY_PC", connection_desc={ 'io_type': 'sshshell', 'host': 'localhost', 'login': '******', 'password': '******' }, connection_hops=proxypc2adbshell_connection_hops) assert dev._use_proxy_pc is True assert dev.current_state == "PROXY_PC" dev.goto_state("UNIX_REMOTE") assert dev.current_state == "UNIX_REMOTE" dev.goto_state("ADB_SHELL") assert dev.current_state == "ADB_SHELL" # dev.goto_state("ADB_SHELL_ROOT") # can't test; need to know root password on CI machine # assert dev.current_state == "ADB_SHELL_ROOT" dev.goto_state("UNIX_REMOTE") assert dev.current_state == "UNIX_REMOTE" dev.goto_state("PROXY_PC") assert dev.current_state == "PROXY_PC" dev.goto_state("NOT_CONNECTED") assert dev.current_state == "NOT_CONNECTED" dev.remove()
def _load_topology(topology): """ Loads topology from passed dict. :param topology: dict where key is devices name and value is list with names of neighbour devices. :return: None """ if topology: from moler.device import DeviceFactory for device_name in topology: device = DeviceFactory.get_device(name=device_name, establish_connection=False) for neighbour_device_name in topology[device_name]: neighbour_device = DeviceFactory.get_device( name=neighbour_device_name, establish_connection=False) device.add_neighbour_device(neighbour_device=neighbour_device, bidirectional=True)
def test_unix_remote_with_sshshell_only(loaded_unix_remote_config): dev = DeviceFactory.get_device(name="UX_REMOTE") assert dev.current_state == "UNIX_REMOTE" # dev.goto_state("UNIX_REMOTE_ROOT") # can't test; need to know root password on CI machine # assert dev.current_state == "UNIX_REMOTE_ROOT" dev.goto_state("NOT_CONNECTED") assert dev.current_state == "NOT_CONNECTED" dev.remove()
def _is_device_creation_needed(name, requested_device_def): """ :param name: Name of device :param requested_device_def: Definition of device requested to create/ :return: True if device doesn't exist. False if device already exists. : """ from moler.device.device import DeviceFactory try: DeviceFactory.get_device(name) msg = DeviceFactory.differences_bewteen_devices_descriptions( name, requested_device_def) if msg: raise WrongUsage(msg) return False # Device exists and have the same construct parameters except KeyError: return True
def get_device(name, connection, device_output, test_file_path): dir_path = os.path.dirname(os.path.realpath(test_file_path)) load_config( os.path.join(dir_path, os.pardir, os.pardir, 'test', 'resources', 'device_config.yml')) device = DeviceFactory.get_device(name, io_connection=connection) _prepare_device(device=device, connection=connection, device_output=device_output) return device
def load_config(config=None, from_env_var=None, *args, **kwargs): """ Load Moler's configuration from config file. Load Moler's configuration from config file. :param config: either dict or config filename directly provided (overwrites 'from_env_var' if both given). :type config: dict or str :param from_env_var: name of environment variable storing config filename (file is in YAML format) :return: None """ global loaded_config add_devices_only = False from moler.device import DeviceFactory if config is not None and isinstance(config, dict): config = copy_dict(config, deep_copy=True) if "NOT_LOADED_YET" in loaded_config: loaded_config = [config] elif not DeviceFactory.was_any_device_deleted() and configs_are_same( config_list=loaded_config, config_to_find=config): return else: # Config was already loaded and now we have to add new devices. add_devices_only = True if not configs_are_same(config_list=loaded_config, config_to_find=config): loaded_config.append(config) wrong_type_config = not isinstance( config, six.string_types) and not isinstance(config, dict) if config is None and from_env_var is None: raise WrongUsage( "Provide either 'config' or 'from_env_var' parameter (none given)." ) elif (not from_env_var and wrong_type_config) or (config and wrong_type_config): raise WrongUsage( "Unsupported config type: '{}'. Allowed are: 'dict' or 'str' holding config filename (file is in YAML format)." .format(type(config))) if not config: if from_env_var not in os.environ: raise KeyError( "Environment variable '{}' is not set".format(from_env_var)) path = os.environ[from_env_var] config = read_yaml_configfile(path) elif isinstance(config, six.string_types): path = config config = read_yaml_configfile(path) # TODO: check schema if add_devices_only is False: load_logger_from_config(config) load_connection_from_config(config) load_device_from_config(config=config, add_only=add_devices_only)
def get_cloned_device(src_device, new_name, new_connection): device_output = src_device.io_connection.data device = DeviceFactory.get_cloned_device(source_device=src_device, new_name=new_name, establish_connection=False, lazy_cmds_events=True, io_connection=new_connection) _prepare_device(device=device, connection=new_connection, device_output=device_output) return device
def get_device(name, connection, device_output, test_file_path): dir_path = os.path.dirname(os.path.realpath(test_file_path)) load_config( os.path.join(dir_path, os.pardir, os.pardir, 'test', 'resources', 'device_config.yml')) device = DeviceFactory.get_device(name) device.io_connection = connection device.io_connection.name = device.name device.io_connection.moler_connection.name = device.name device.io_connection.remote_inject_response(device_output) device.io_connection.set_device(device) return device
def test_proxy_pc_with_terminal_can_use_unix_local_states( loaded_proxy_pc_config, uxlocal2proxypc_connection_hops): # check backward compatibility dev = DeviceFactory.get_device( name="PROXY", initial_state="UNIX_LOCAL", connection_hops=uxlocal2proxypc_connection_hops, connection_desc={"io_type": "terminal"}) assert dev.current_state == "UNIX_LOCAL" dev.goto_state("PROXY_PC") assert dev.current_state == "PROXY_PC" dev.goto_state("UNIX_LOCAL") assert dev.current_state == "UNIX_LOCAL" dev.goto_state("NOT_CONNECTED") assert dev.current_state == "NOT_CONNECTED" dev.remove()
def test_proxy_pc_with_sshshell(loaded_proxy_pc_config): dev = DeviceFactory.get_device(name="PROXY") assert dev.current_state == "PROXY_PC" dev.goto_state("NOT_CONNECTED") assert dev.current_state == "NOT_CONNECTED" dev.remove()