File: config_test.py

package info (click to toggle)
python-sshoot 1.6.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 344 kB
  • sloc: python: 1,579; makefile: 23; sh: 1
file content (130 lines) | stat: -rw-r--r-- 4,649 bytes parent folder | download
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