Added more tests for user config parsing.
[electrum-nvc.git] / lib / tests / test_simple_config.py
1 import sys
2 import os
3 import unittest
4 import tempfile
5 import shutil
6
7 from StringIO import StringIO
8 from lib.simple_config import (SimpleConfig, read_system_config,
9                                read_user_config)
10
11
12 class Test_SimpleConfig(unittest.TestCase):
13
14     def setUp(self):
15         super(Test_SimpleConfig, self).setUp()
16         # make sure "read_user_config" and "user_dir" return a temporary directory.
17         self.electrum_dir = tempfile.mkdtemp()
18         # Do the same for the user dir to avoid overwriting the real configuration
19         # for development machines with electrum installed :)
20         self.user_dir = tempfile.mkdtemp()
21
22         self.options = {"electrum_path": self.electrum_dir}
23         self._saved_stdout = sys.stdout
24         self._stdout_buffer = StringIO()
25         sys.stdout = self._stdout_buffer
26
27     def tearDown(self):
28         super(Test_SimpleConfig, self).tearDown()
29         # Remove the temporary directory after each test (to make sure we don't
30         # pollute /tmp for nothing.
31         shutil.rmtree(self.electrum_dir)
32         shutil.rmtree(self.user_dir)
33
34         # Restore the "real" stdout
35         sys.stdout = self._saved_stdout
36
37     def test_simple_config_command_line_overrides_everything(self):
38         """Options passed by command line override all other configuration
39         sources"""
40         fake_read_system = lambda : {"electrum_path": "a"}
41         fake_read_user = lambda _: {"electrum_path": "b"}
42         read_user_dir = lambda : self.user_dir
43         config = SimpleConfig(options=self.options,
44                               read_system_config_function=fake_read_system,
45                               read_user_config_function=fake_read_user,
46                               read_user_dir_function=read_user_dir)
47         self.assertEqual(self.options.get("electrum_path"),
48                          config.get("electrum_path"))
49
50     def test_simple_config_system_config_overrides_user_config(self):
51         """Options passed in system config override user config."""
52         fake_read_system = lambda : {"electrum_path": self.electrum_dir}
53         fake_read_user = lambda _: {"electrum_path": "b"}
54         read_user_dir = lambda : self.user_dir
55         config = SimpleConfig(options=None,
56                               read_system_config_function=fake_read_system,
57                               read_user_config_function=fake_read_user,
58                               read_user_dir_function=read_user_dir)
59         self.assertEqual(self.options.get("electrum_path"),
60                          config.get("electrum_path"))
61
62     def test_simple_config_system_config_ignored_if_portable(self):
63         """If electrum is started with the "portable" flag, system
64         configuration is completely ignored."""
65         another_path = tempfile.mkdtemp()
66         fake_read_system = lambda : {"electrum_path": self.electrum_dir}
67         fake_read_user = lambda _: {"electrum_path": another_path}
68         read_user_dir = lambda : self.user_dir
69         config = SimpleConfig(options={"portable": True},
70                               read_system_config_function=fake_read_system,
71                               read_user_config_function=fake_read_user,
72                               read_user_dir_function=read_user_dir)
73         self.assertEqual(another_path, config.get("electrum_path"))
74
75     def test_simple_config_user_config_is_used_if_others_arent_specified(self):
76         """If no system-wide configuration and no command-line options are
77         specified, the user configuration is used instead."""
78         fake_read_system = lambda : {}
79         fake_read_user = lambda _: {"electrum_path": self.electrum_dir}
80         read_user_dir = lambda : self.user_dir
81         config = SimpleConfig(options=None,
82                               read_system_config_function=fake_read_system,
83                               read_user_config_function=fake_read_user,
84                               read_user_dir_function=read_user_dir)
85         self.assertEqual(self.options.get("electrum_path"),
86                          config.get("electrum_path"))
87
88     def test_cannot_set_options_passed_by_command_line(self):
89         fake_read_system = lambda : {}
90         fake_read_user = lambda _: {"electrum_path": "b"}
91         read_user_dir = lambda : self.user_dir
92         config = SimpleConfig(options=self.options,
93                               read_system_config_function=fake_read_system,
94                               read_user_config_function=fake_read_user,
95                               read_user_dir_function=read_user_dir)
96         config.set_key("electrum_path", "c")
97         self.assertEqual(self.options.get("electrum_path"),
98                          config.get("electrum_path"))
99
100     def test_cannot_set_options_from_system_config(self):
101         fake_read_system = lambda : {"electrum_path": self.electrum_dir}
102         fake_read_user = lambda _: {}
103         read_user_dir = lambda : self.user_dir
104         config = SimpleConfig(options={},
105                               read_system_config_function=fake_read_system,
106                               read_user_config_function=fake_read_user,
107                               read_user_dir_function=read_user_dir)
108         config.set_key("electrum_path", "c")
109         self.assertEqual(self.options.get("electrum_path"),
110                          config.get("electrum_path"))
111
112     def test_can_set_options_set_in_user_config(self):
113         another_path = tempfile.mkdtemp()
114         fake_read_system = lambda : {}
115         fake_read_user = lambda _: {"electrum_path": self.electrum_dir}
116         read_user_dir = lambda : self.user_dir
117         config = SimpleConfig(options={},
118                               read_system_config_function=fake_read_system,
119                               read_user_config_function=fake_read_user,
120                               read_user_dir_function=read_user_dir)
121         config.set_key("electrum_path", another_path)
122         self.assertEqual(another_path, config.get("electrum_path"))
123
124     def test_can_set_options_from_system_config_if_portable(self):
125         """If the "portable" flag is set, the user can overwrite system
126         configuration options."""
127         another_path = tempfile.mkdtemp()
128         fake_read_system = lambda : {"electrum_path": self.electrum_dir}
129         fake_read_user = lambda _: {}
130         read_user_dir = lambda : self.user_dir
131         config = SimpleConfig(options={"portable": True},
132                               read_system_config_function=fake_read_system,
133                               read_user_config_function=fake_read_user,
134                               read_user_dir_function=read_user_dir)
135         config.set_key("electrum_path", another_path)
136         self.assertEqual(another_path, config.get("electrum_path"))
137
138
139 class TestSystemConfig(unittest.TestCase):
140
141     sample_conf = """
142 [client]
143 gap_limit = 5
144
145 [something_else]
146 everything = 42
147 """
148
149     def setUp(self):
150         super(TestSystemConfig, self).setUp()
151         self.thefile = tempfile.mkstemp(suffix=".electrum.test.conf")[1]
152
153     def tearDown(self):
154         super(TestSystemConfig, self).tearDown()
155         os.remove(self.thefile)
156
157     def test_read_system_config_file_does_not_exist(self):
158         somefile = "/foo/I/do/not/exist/electrum.conf"
159         result = read_system_config(somefile)
160         self.assertEqual({}, result)
161
162     def test_read_system_config_file_returns_file_options(self):
163         with open(self.thefile, "w") as f:
164             f.write(self.sample_conf)
165
166         result = read_system_config(self.thefile)
167         self.assertEqual({"gap_limit": "5"}, result)
168
169     def test_read_system_config_file_no_sections(self):
170
171         with open(self.thefile, "w") as f:
172             f.write("gap_limit = 5")  # The file has no sections at all
173
174         result = read_system_config(self.thefile)
175         self.assertEqual({}, result)
176
177
178 class TestUserConfig(unittest.TestCase):
179
180     def setUp(self):
181         super(TestUserConfig, self).setUp()
182         self._saved_stdout = sys.stdout
183         self._stdout_buffer = StringIO()
184         sys.stdout = self._stdout_buffer
185
186         self.user_dir = tempfile.mkdtemp()
187
188     def tearDown(self):
189         super(TestUserConfig, self).tearDown()
190         shutil.rmtree(self.user_dir)
191         sys.stdout = self._saved_stdout
192
193     def test_no_path_means_no_result(self):
194        result = read_user_config(None)
195        self.assertEqual({}, result)
196
197     def test_path_with_reprd_dict(self):
198         thefile = os.path.join(self.user_dir, "config")
199         payload = {"gap_limit": 5}
200         with open(thefile, "w") as f:
201             f.write(repr(payload))
202
203         result = read_user_config(self.user_dir)
204         self.assertEqual(payload, result)
205
206     def test_path_without_config_file(self):
207         """We pass a path but if does not contain a "config" file."""
208         result = read_user_config(self.user_dir)
209         self.assertEqual({}, result)
210
211     def test_path_with_reprd_object(self):
212
213         class something(object):
214             pass
215
216         thefile = os.path.join(self.user_dir, "config")
217         payload = something()
218         with open(thefile, "w") as f:
219             f.write(repr(payload))
220
221         result = read_user_config(self.user_dir)
222         self.assertEqual({}, result)