def test_simple_override_hostname(no_system_ssh_config, no_user_ssh_config):
    paramiko_config = paramiko.SSHConfig()
    paramiko_config.parse(io.StringIO(SSH_CONFIG_OVERRIDE_HOSTNAME))

    config = ssh_helpers.parse_ssh_config(paramiko_config, PROXY_JUMP_1)
    assert PROXY_JUMP_1 in config
    assert config[PROXY_JUMP_1].hostname == PROXY_JUMP_2
    assert PROXY_JUMP_2 in config
    assert config[PROXY_JUMP_1] == config[PROXY_JUMP_2]
def test_simple_override_chain_proxy_jump(system_ssh_config, user_ssh_config):
    mock.mock_open(system_ssh_config, SSH_CONFIG_ALL_NO_PROXY)
    mock.mock_open(user_ssh_config, SSH_CONFIG_MULTI_PROXY_JUMP)

    config = ssh_helpers.parse_ssh_config(None, HOST)

    host_config = config[HOST]

    assert host_config.hostname == HOST
    assert host_config.proxycommand is None
    assert host_config.proxyjump == PROXY_JUMP_1

    assert PROXY_JUMP_1 in config
    assert config[PROXY_JUMP_1].hostname == PROXY_JUMP_1
    assert config[PROXY_JUMP_1].proxyjump == PROXY_JUMP_2

    assert PROXY_JUMP_2 in config
    assert config[PROXY_JUMP_2].hostname == PROXY_JUMP_2
    assert config[PROXY_JUMP_2].proxyjump is None

    # Rebuild possibility even with chains
    config_as_dict = {host: conf.as_dict for host, conf in config.items()}
    assert ssh_helpers.parse_ssh_config(config_as_dict, HOST) == config
def test_simple_override_proxy_command(system_ssh_config, user_ssh_config):
    mock.mock_open(system_ssh_config, SSH_CONFIG_ALL_NO_PROXY)
    mock.mock_open(user_ssh_config, SSH_CONFIG_PROXY_COMMAND)

    config = ssh_helpers.parse_ssh_config(None, HOST)

    host_config = config[HOST]

    assert host_config.hostname == HOST
    assert host_config.proxycommand == f"ssh -q -A {PROXY_JUMP_1} nc {HOST} {PORT}"

    assert host_config.as_dict == host_config
    assert ssh_helpers.SSHConfig.from_ssh_config(
        host_config.as_dict) == host_config
def test_simple_config(system_ssh_config, user_ssh_config):
    mock.mock_open(system_ssh_config, read_data=SYSTEM_REAL_SSH_CONFIG)
    mock.mock_open(user_ssh_config, SSH_CONFIG_ALL_NO_PROXY)

    config = ssh_helpers.parse_ssh_config(None, HOST)

    host_config = config[HOST]

    assert host_config.hostname == HOST
    assert host_config.port == PORT

    assert host_config.user == USER
    assert host_config.identityfile == tuple(IDENTIFY_FILES)

    assert host_config.controlpath == f"~/.ssh/.control-{USER}@{HOST}:{PORT}"
    assert not host_config.controlmaster  # auto => False
def test_no_configs(no_system_ssh_config, no_user_ssh_config):
    config = ssh_helpers.parse_ssh_config(None, HOST)
    assert config == {HOST: {"hostname": HOST}}

    host_config = config[HOST]
    assert host_config == ssh_helpers.SSHConfig(hostname=HOST)
    assert host_config != object()

    assert host_config.port is None

    assert host_config.user is None
    assert host_config.identityfile == ()

    assert host_config.proxycommand is None
    assert host_config.proxyjump is None

    assert host_config.controlpath is None
    assert host_config.controlmaster is None
def test_simple_override_single_proxy_jump(system_ssh_config, user_ssh_config):
    mock.mock_open(system_ssh_config, SSH_CONFIG_ALL_NO_PROXY)
    mock.mock_open(user_ssh_config, SSH_CONFIG_PROXY_JUMP)

    config = ssh_helpers.parse_ssh_config(None, HOST)

    host_config = config[HOST]

    assert host_config.hostname == HOST
    assert host_config.proxycommand is None
    assert host_config.proxyjump == PROXY_JUMP_1

    assert PROXY_JUMP_1 in config
    assert config[PROXY_JUMP_1].hostname == PROXY_JUMP_1

    assert host_config.as_dict == host_config
    assert ssh_helpers.SSHConfig.from_ssh_config(
        host_config.as_dict) == host_config
def test_negative_read(system_ssh_config, no_user_ssh_config):
    system_ssh_config.side_effect = RuntimeError()
    config = ssh_helpers.parse_ssh_config(None, HOST)
    assert config == {HOST: {"hostname": HOST}}