1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
|
from io import StringIO
from textwrap import dedent
import pytest
import yaml
from sshoot.config import yaml_dump
from sshoot.profile import Profile
class TestYamlDump:
def test_dump_to_string(self):
"""The method returns YAML data as a string by default."""
data = {"foo": "bar", "baz": [1, 2]}
result = yaml_dump(data)
assert yaml.safe_load(stream=StringIO(result)) == data
def test_dump_to_file(self):
"""The method dumps YAML data to the specified file."""
data = {"foo": "bar", "baz": [1, 2]}
fh = StringIO()
result = yaml_dump(data, fh=fh)
fh.seek(0)
assert result is None
assert yaml.safe_load(stream=fh) == data
class TestConfig:
def test_add_profile(self, config):
"""Profiles can be added to the config."""
profiles = {
"profile1": Profile(["10.0.0.0/24"]),
"profile2": Profile(["192.168.0.0/16"]),
}
for name, profile in profiles.items():
config.add_profile(name, profile)
assert config.profiles == profiles
def test_add_profile_name_present(self, config):
"""An exception is raised if the profile name is already used."""
config.add_profile("profile", Profile(["10.0.0.0/24"]))
with pytest.raises(KeyError):
config.add_profile("profile", Profile(["192.168.0.0/16"]))
def test_remove_profile(self, config):
"""Profiles can be removed to the config."""
profiles = {
"profile1": Profile(["10.0.0.0/24"]),
"profile2": Profile(["192.168.0.0/16"]),
}
for name, profile in profiles.items():
config.add_profile(name, profile)
config.remove_profile("profile1")
assert list(config.profiles), ["profile2"]
def test_remove_profile_not_present(self, config):
"""An exception is raised if the profile name is not known."""
with pytest.raises(KeyError):
config.remove_profile("profile")
def test_load_from_file(self, config, profiles_file):
"""The config is loaded from file."""
profiles = {"profile": {"subnets": ["10.0.0.0/24"], "auto-nets": True}}
profiles_file.write_text(yaml.dump(profiles))
config.load()
profile = config.profiles["profile"]
assert profile.subnets == ["10.0.0.0/24"]
assert profile.auto_nets
def test_load_missing_file(self, config):
"""If no config files are found, config is empty."""
config.load()
assert config.profiles == {}
assert config.config == {}
def test_load_config_options(self, config, config_file):
"""Only known config options are loaded from config file."""
config_data = {
"executable": "/usr/bin/shuttle",
"other-conf": "no",
"extra-options": ["--no-latency-control", "--disable-ipv6"],
}
config_file.write_text(yaml.dump(config_data))
config.load()
assert config.config == {
"executable": "/usr/bin/shuttle",
"extra-options": ["--no-latency-control", "--disable-ipv6"],
}
def test_load_profiles(self, config, profiles_file):
"""The 'profiles' config field is loaded from the config file."""
profiles = {
"profile1": {"subnets": ["10.0.0.0/24"]},
"profile2": {"subnets": ["192.168.0.0/16"]},
}
profiles_file.write_text(yaml.dump(profiles))
config.load()
expected = {
name: Profile(**config) for name, config in profiles.items()
}
assert config.profiles == expected
def test_save_profiles(self, config, profiles_file):
"""Profiles are saved to file."""
profiles = {
"profile1": {"subnets": ["10.0.0.0/24"], "remote": "hostname1"},
"profile2": {"subnets": ["192.168.0.0/16"], "remote": "hostname2"},
}
config.load()
for name, conf in profiles.items():
config.add_profile(name, Profile(**conf))
config.save()
config = yaml.safe_load(profiles_file.read_text())
assert config == profiles
def test_save_from_file(self, config, profiles_file):
"""The config is saved to file."""
config.add_profile("profile", Profile(["10.0.0.0/24"], auto_nets=True))
config.save()
config = dedent(
"""\
profile:
auto-nets: true
subnets:
- 10.0.0.0/24
"""
)
content = profiles_file.read_text()
assert content == config
|