1 | """ |
---|
2 | Ported to Python 3. |
---|
3 | """ |
---|
4 | from __future__ import annotations |
---|
5 | |
---|
6 | import os |
---|
7 | |
---|
8 | from typing import Any |
---|
9 | |
---|
10 | from twisted.trial import unittest |
---|
11 | from twisted.internet import defer, reactor |
---|
12 | from twisted.python import usage |
---|
13 | from allmydata.util import configutil |
---|
14 | from allmydata.util import tor_provider, i2p_provider |
---|
15 | from ..common_util import run_cli, parse_cli |
---|
16 | from ..common import ( |
---|
17 | disable_modules, |
---|
18 | ) |
---|
19 | from ...scripts import create_node |
---|
20 | from ...listeners import ListenerConfig, StaticProvider |
---|
21 | from ... import client |
---|
22 | |
---|
23 | def read_config(basedir): |
---|
24 | tahoe_cfg = os.path.join(basedir, "tahoe.cfg") |
---|
25 | config = configutil.get_config(tahoe_cfg) |
---|
26 | return config |
---|
27 | |
---|
28 | class MergeConfigTests(unittest.TestCase): |
---|
29 | """ |
---|
30 | Tests for ``create_node.merge_config``. |
---|
31 | """ |
---|
32 | def test_disable_left(self) -> None: |
---|
33 | """ |
---|
34 | If the left argument to ``create_node.merge_config`` is ``None`` |
---|
35 | then the return value is ``None``. |
---|
36 | """ |
---|
37 | conf = ListenerConfig([], [], {}) |
---|
38 | self.assertEqual(None, create_node.merge_config(None, conf)) |
---|
39 | |
---|
40 | def test_disable_right(self) -> None: |
---|
41 | """ |
---|
42 | If the right argument to ``create_node.merge_config`` is ``None`` |
---|
43 | then the return value is ``None``. |
---|
44 | """ |
---|
45 | conf = ListenerConfig([], [], {}) |
---|
46 | self.assertEqual(None, create_node.merge_config(conf, None)) |
---|
47 | |
---|
48 | def test_disable_both(self) -> None: |
---|
49 | """ |
---|
50 | If both arguments to ``create_node.merge_config`` are ``None`` |
---|
51 | then the return value is ``None``. |
---|
52 | """ |
---|
53 | self.assertEqual(None, create_node.merge_config(None, None)) |
---|
54 | |
---|
55 | def test_overlapping_keys(self) -> None: |
---|
56 | """ |
---|
57 | If there are any keys in the ``node_config`` of the left and right |
---|
58 | parameters that are shared then ``ValueError`` is raised. |
---|
59 | """ |
---|
60 | left = ListenerConfig([], [], {"foo": [("b", "ar")]}) |
---|
61 | right = ListenerConfig([], [], {"foo": [("ba", "z")]}) |
---|
62 | self.assertRaises(ValueError, lambda: create_node.merge_config(left, right)) |
---|
63 | |
---|
64 | def test_merge(self) -> None: |
---|
65 | """ |
---|
66 | ``create_node.merge_config`` returns a ``ListenerConfig`` that has |
---|
67 | all of the ports, locations, and node config from each of the two |
---|
68 | ``ListenerConfig`` values given. |
---|
69 | """ |
---|
70 | left = ListenerConfig( |
---|
71 | ["left-port"], |
---|
72 | ["left-location"], |
---|
73 | {"left": [("f", "oo")]}, |
---|
74 | ) |
---|
75 | right = ListenerConfig( |
---|
76 | ["right-port"], |
---|
77 | ["right-location"], |
---|
78 | {"right": [("ba", "r")]}, |
---|
79 | ) |
---|
80 | result = create_node.merge_config(left, right) |
---|
81 | self.assertEqual( |
---|
82 | ListenerConfig( |
---|
83 | ["left-port", "right-port"], |
---|
84 | ["left-location", "right-location"], |
---|
85 | {"left": [("f", "oo")], "right": [("ba", "r")]}, |
---|
86 | ), |
---|
87 | result, |
---|
88 | ) |
---|
89 | |
---|
90 | class Config(unittest.TestCase): |
---|
91 | def test_client_unrecognized_options(self): |
---|
92 | tests = [ |
---|
93 | ("--listen", "create-client", "--listen=tcp"), |
---|
94 | ("--hostname", "create-client", "--hostname=computer"), |
---|
95 | ("--port", |
---|
96 | "create-client", "--port=unix:/var/tahoe/socket", |
---|
97 | "--location=tor:myservice.onion:12345"), |
---|
98 | ("--port", "create-client", "--port=unix:/var/tahoe/socket"), |
---|
99 | ("--location", |
---|
100 | "create-client", "--location=tor:myservice.onion:12345"), |
---|
101 | ("--listen", "create-client", "--listen=tor"), |
---|
102 | ("--listen", "create-client", "--listen=i2p"), |
---|
103 | ] |
---|
104 | for test in tests: |
---|
105 | option = test[0] |
---|
106 | verb = test[1] |
---|
107 | args = test[2:] |
---|
108 | e = self.assertRaises(usage.UsageError, parse_cli, verb, *args) |
---|
109 | self.assertIn("option %s not recognized" % (option,), str(e)) |
---|
110 | |
---|
111 | async def test_create_client_config(self): |
---|
112 | """ |
---|
113 | ``create_node.write_client_config`` writes a configuration file |
---|
114 | that can be parsed. |
---|
115 | |
---|
116 | TODO Maybe we should test that we can recover the given configuration |
---|
117 | from the parse, too. |
---|
118 | """ |
---|
119 | d = self.mktemp() |
---|
120 | os.mkdir(d) |
---|
121 | fname = os.path.join(d, 'tahoe.cfg') |
---|
122 | |
---|
123 | with open(fname, 'w') as f: |
---|
124 | opts = {"nickname": "nick", |
---|
125 | "webport": "tcp:3456", |
---|
126 | "hide-ip": False, |
---|
127 | "listen": "none", |
---|
128 | "shares-needed": "1", |
---|
129 | "shares-happy": "1", |
---|
130 | "shares-total": "1", |
---|
131 | } |
---|
132 | await create_node.write_node_config(f, opts) |
---|
133 | create_node.write_client_config(f, opts) |
---|
134 | |
---|
135 | # should succeed, no exceptions |
---|
136 | client.read_config(d, "") |
---|
137 | |
---|
138 | @defer.inlineCallbacks |
---|
139 | def test_client(self): |
---|
140 | basedir = self.mktemp() |
---|
141 | rc, out, err = yield run_cli("create-client", basedir) |
---|
142 | cfg = read_config(basedir) |
---|
143 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True) |
---|
144 | self.assertEqual(cfg.get("node", "tub.port"), "disabled") |
---|
145 | self.assertEqual(cfg.get("node", "tub.location"), "disabled") |
---|
146 | self.assertFalse(cfg.has_section("connections")) |
---|
147 | |
---|
148 | @defer.inlineCallbacks |
---|
149 | def test_non_default_storage_args(self): |
---|
150 | basedir = self.mktemp() |
---|
151 | rc, out, err = yield run_cli( |
---|
152 | "create-client", |
---|
153 | '--shares-total', '19', |
---|
154 | '--shares-needed', '2', |
---|
155 | '--shares-happy', '11', |
---|
156 | basedir, |
---|
157 | ) |
---|
158 | cfg = read_config(basedir) |
---|
159 | self.assertEqual(2, cfg.getint("client", "shares.needed")) |
---|
160 | self.assertEqual(11, cfg.getint("client", "shares.happy")) |
---|
161 | self.assertEqual(19, cfg.getint("client", "shares.total")) |
---|
162 | |
---|
163 | @defer.inlineCallbacks |
---|
164 | def test_illegal_shares_total(self): |
---|
165 | basedir = self.mktemp() |
---|
166 | rc, out, err = yield run_cli( |
---|
167 | "create-client", |
---|
168 | '--shares-total', 'funballs', |
---|
169 | basedir, |
---|
170 | ) |
---|
171 | self.assertNotEqual(0, rc) |
---|
172 | self.assertTrue('--shares-total must be an integer' in err + out) |
---|
173 | |
---|
174 | @defer.inlineCallbacks |
---|
175 | def test_client_hide_ip_no_i2p_txtorcon(self): |
---|
176 | """ |
---|
177 | The ``create-client`` sub-command tells the user to install the necessary |
---|
178 | dependencies if they have neither tor nor i2p support installed and |
---|
179 | they request network location privacy with the ``--hide-ip`` flag. |
---|
180 | """ |
---|
181 | with disable_modules("txi2p", "txtorcon"): |
---|
182 | basedir = self.mktemp() |
---|
183 | rc, out, err = yield run_cli("create-client", "--hide-ip", basedir) |
---|
184 | self.assertTrue(rc != 0, out) |
---|
185 | self.assertTrue('pip install tahoe-lafs[i2p]' in out) |
---|
186 | self.assertTrue('pip install tahoe-lafs[tor]' in out) |
---|
187 | |
---|
188 | @defer.inlineCallbacks |
---|
189 | def test_client_i2p_option_no_txi2p(self): |
---|
190 | with disable_modules("txi2p"): |
---|
191 | basedir = self.mktemp() |
---|
192 | rc, out, err = yield run_cli("create-node", "--listen=i2p", "--i2p-launch", basedir) |
---|
193 | self.assertTrue(rc != 0) |
---|
194 | self.assertTrue("Specifying any I2P options requires the 'txi2p' module" in out) |
---|
195 | |
---|
196 | @defer.inlineCallbacks |
---|
197 | def test_client_tor_option_no_txtorcon(self): |
---|
198 | with disable_modules("txtorcon"): |
---|
199 | basedir = self.mktemp() |
---|
200 | rc, out, err = yield run_cli("create-node", "--listen=tor", "--tor-launch", basedir) |
---|
201 | self.assertTrue(rc != 0) |
---|
202 | self.assertTrue("Specifying any Tor options requires the 'txtorcon' module" in out) |
---|
203 | |
---|
204 | @defer.inlineCallbacks |
---|
205 | def test_client_hide_ip(self): |
---|
206 | basedir = self.mktemp() |
---|
207 | rc, out, err = yield run_cli("create-client", "--hide-ip", basedir) |
---|
208 | self.assertEqual(0, rc) |
---|
209 | cfg = read_config(basedir) |
---|
210 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False) |
---|
211 | self.assertEqual(cfg.get("connections", "tcp"), "tor") |
---|
212 | |
---|
213 | @defer.inlineCallbacks |
---|
214 | def test_client_hide_ip_no_txtorcon(self): |
---|
215 | with disable_modules("txtorcon"): |
---|
216 | basedir = self.mktemp() |
---|
217 | rc, out, err = yield run_cli("create-client", "--hide-ip", basedir) |
---|
218 | self.assertEqual(0, rc) |
---|
219 | cfg = read_config(basedir) |
---|
220 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False) |
---|
221 | self.assertEqual(cfg.get("connections", "tcp"), "disabled") |
---|
222 | |
---|
223 | @defer.inlineCallbacks |
---|
224 | def test_client_basedir_exists(self): |
---|
225 | basedir = self.mktemp() |
---|
226 | os.mkdir(basedir) |
---|
227 | with open(os.path.join(basedir, "foo"), "w") as f: |
---|
228 | f.write("blocker") |
---|
229 | rc, out, err = yield run_cli("create-client", basedir) |
---|
230 | self.assertEqual(rc, -1) |
---|
231 | self.assertIn(basedir, err) |
---|
232 | self.assertIn("is not empty", err) |
---|
233 | self.assertIn("To avoid clobbering anything, I am going to quit now", err) |
---|
234 | |
---|
235 | @defer.inlineCallbacks |
---|
236 | def test_node(self): |
---|
237 | basedir = self.mktemp() |
---|
238 | rc, out, err = yield run_cli("create-node", "--hostname=foo", basedir) |
---|
239 | cfg = read_config(basedir) |
---|
240 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True) |
---|
241 | self.assertFalse(cfg.has_section("connections")) |
---|
242 | |
---|
243 | @defer.inlineCallbacks |
---|
244 | def test_storage_dir(self): |
---|
245 | basedir = self.mktemp() |
---|
246 | rc, out, err = yield run_cli("create-node", "--storage-dir", "/tmp/storage", "--hostname=foo", basedir) |
---|
247 | cfg = read_config(basedir) |
---|
248 | self.assertEqual(cfg.get("storage", "storage_dir"), "/tmp/storage") |
---|
249 | |
---|
250 | @defer.inlineCallbacks |
---|
251 | def test_node_hide_ip(self): |
---|
252 | basedir = self.mktemp() |
---|
253 | rc, out, err = yield run_cli("create-node", "--hide-ip", |
---|
254 | "--hostname=foo", basedir) |
---|
255 | cfg = read_config(basedir) |
---|
256 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False) |
---|
257 | self.assertEqual(cfg.get("connections", "tcp"), "tor") |
---|
258 | |
---|
259 | @defer.inlineCallbacks |
---|
260 | def test_node_hostname(self): |
---|
261 | basedir = self.mktemp() |
---|
262 | rc, out, err = yield run_cli("create-node", "--hostname=computer", basedir) |
---|
263 | cfg = read_config(basedir) |
---|
264 | port = cfg.get("node", "tub.port") |
---|
265 | location = cfg.get("node", "tub.location") |
---|
266 | self.assertRegex(port, r'^tcp:\d+$') |
---|
267 | self.assertRegex(location, r'^tcp:computer:\d+$') |
---|
268 | |
---|
269 | @defer.inlineCallbacks |
---|
270 | def test_node_port_location(self): |
---|
271 | basedir = self.mktemp() |
---|
272 | rc, out, err = yield run_cli("create-node", |
---|
273 | "--port=unix:/var/tahoe/socket", |
---|
274 | "--location=tor:myservice.onion:12345", |
---|
275 | basedir) |
---|
276 | cfg = read_config(basedir) |
---|
277 | self.assertEqual(cfg.get("node", "tub.location"), "tor:myservice.onion:12345") |
---|
278 | self.assertEqual(cfg.get("node", "tub.port"), "unix:/var/tahoe/socket") |
---|
279 | |
---|
280 | def test_node_hostname_port_location(self): |
---|
281 | basedir = self.mktemp() |
---|
282 | e = self.assertRaises(usage.UsageError, |
---|
283 | parse_cli, |
---|
284 | "create-node", "--listen=tcp", |
---|
285 | "--hostname=foo", "--port=bar", "--location=baz", |
---|
286 | basedir) |
---|
287 | self.assertEqual(str(e), |
---|
288 | "--hostname cannot be used with --location/--port") |
---|
289 | |
---|
290 | def test_node_listen_tcp_no_hostname(self): |
---|
291 | basedir = self.mktemp() |
---|
292 | e = self.assertRaises(usage.UsageError, |
---|
293 | parse_cli, |
---|
294 | "create-node", "--listen=tcp", basedir) |
---|
295 | self.assertIn("--listen=tcp requires --hostname=", str(e)) |
---|
296 | |
---|
297 | @defer.inlineCallbacks |
---|
298 | def test_node_listen_none(self): |
---|
299 | basedir = self.mktemp() |
---|
300 | rc, out, err = yield run_cli("create-node", "--listen=none", basedir) |
---|
301 | cfg = read_config(basedir) |
---|
302 | self.assertEqual(cfg.get("node", "tub.port"), "disabled") |
---|
303 | self.assertEqual(cfg.get("node", "tub.location"), "disabled") |
---|
304 | |
---|
305 | def test_node_listen_none_errors(self): |
---|
306 | basedir = self.mktemp() |
---|
307 | e = self.assertRaises(usage.UsageError, |
---|
308 | parse_cli, |
---|
309 | "create-node", "--listen=none", |
---|
310 | "--hostname=foo", |
---|
311 | basedir) |
---|
312 | self.assertEqual(str(e), "--hostname cannot be used when --listen=none") |
---|
313 | |
---|
314 | e = self.assertRaises(usage.UsageError, |
---|
315 | parse_cli, |
---|
316 | "create-node", "--listen=none", |
---|
317 | "--port=foo", "--location=foo", |
---|
318 | basedir) |
---|
319 | self.assertEqual(str(e), "--port/--location cannot be used when --listen=none") |
---|
320 | |
---|
321 | e = self.assertRaises(usage.UsageError, |
---|
322 | parse_cli, |
---|
323 | "create-node", "--listen=tcp,none", |
---|
324 | basedir) |
---|
325 | self.assertEqual(str(e), "--listen=tcp requires --hostname=") |
---|
326 | |
---|
327 | def test_node_listen_bad(self): |
---|
328 | basedir = self.mktemp() |
---|
329 | e = self.assertRaises(usage.UsageError, |
---|
330 | parse_cli, |
---|
331 | "create-node", "--listen=XYZZY,tcp", |
---|
332 | basedir) |
---|
333 | self.assertEqual(str(e), "--listen= must be one/some of: i2p, none, tcp, tor") |
---|
334 | |
---|
335 | def test_node_listen_tor_hostname(self): |
---|
336 | e = self.assertRaises(usage.UsageError, |
---|
337 | parse_cli, |
---|
338 | "create-node", "--listen=tor", |
---|
339 | "--hostname=foo") |
---|
340 | self.assertEqual(str(e), "--listen= must be tcp to use --hostname") |
---|
341 | |
---|
342 | def test_node_port_only(self): |
---|
343 | e = self.assertRaises(usage.UsageError, |
---|
344 | parse_cli, |
---|
345 | "create-node", "--port=unix:/var/tahoe/socket") |
---|
346 | self.assertEqual(str(e), "--port must be used with --location") |
---|
347 | |
---|
348 | def test_node_location_only(self): |
---|
349 | e = self.assertRaises(usage.UsageError, |
---|
350 | parse_cli, |
---|
351 | "create-node", "--location=tor:myservice.onion:12345") |
---|
352 | self.assertEqual(str(e), "--location must be used with --port") |
---|
353 | |
---|
354 | @defer.inlineCallbacks |
---|
355 | def test_node_basedir_exists(self): |
---|
356 | basedir = self.mktemp() |
---|
357 | os.mkdir(basedir) |
---|
358 | with open(os.path.join(basedir, "foo"), "w") as f: |
---|
359 | f.write("blocker") |
---|
360 | rc, out, err = yield run_cli("create-node", "--hostname=foo", basedir) |
---|
361 | self.assertEqual(rc, -1) |
---|
362 | self.assertIn(basedir, err) |
---|
363 | self.assertIn("is not empty", err) |
---|
364 | self.assertIn("To avoid clobbering anything, I am going to quit now", err) |
---|
365 | |
---|
366 | @defer.inlineCallbacks |
---|
367 | def test_node_slow(self): |
---|
368 | """ |
---|
369 | A node can be created using a listener type that returns an |
---|
370 | unfired Deferred from its ``create_config`` method. |
---|
371 | """ |
---|
372 | d = defer.Deferred() |
---|
373 | slow = StaticProvider(True, False, d, None) |
---|
374 | create_node._LISTENERS["xxyzy"] = slow |
---|
375 | self.addCleanup(lambda: create_node._LISTENERS.pop("xxyzy")) |
---|
376 | |
---|
377 | basedir = self.mktemp() |
---|
378 | d2 = run_cli("create-node", "--listen=xxyzy", basedir) |
---|
379 | d.callback(None) |
---|
380 | rc, out, err = yield d2 |
---|
381 | self.assertEqual(rc, 0) |
---|
382 | self.assertIn("Node created", out) |
---|
383 | self.assertEqual(err, "") |
---|
384 | |
---|
385 | def test_introducer_no_hostname(self): |
---|
386 | basedir = self.mktemp() |
---|
387 | e = self.assertRaises(usage.UsageError, parse_cli, |
---|
388 | "create-introducer", basedir) |
---|
389 | self.assertEqual(str(e), "--listen=tcp requires --hostname=") |
---|
390 | |
---|
391 | @defer.inlineCallbacks |
---|
392 | def test_introducer_hide_ip(self): |
---|
393 | basedir = self.mktemp() |
---|
394 | rc, out, err = yield run_cli("create-introducer", "--hide-ip", |
---|
395 | "--hostname=foo", basedir) |
---|
396 | cfg = read_config(basedir) |
---|
397 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), False) |
---|
398 | |
---|
399 | @defer.inlineCallbacks |
---|
400 | def test_introducer_hostname(self): |
---|
401 | basedir = self.mktemp() |
---|
402 | rc, out, err = yield run_cli("create-introducer", |
---|
403 | "--hostname=foo", basedir) |
---|
404 | cfg = read_config(basedir) |
---|
405 | self.assertTrue("foo" in cfg.get("node", "tub.location")) |
---|
406 | self.assertEqual(cfg.getboolean("node", "reveal-IP-address"), True) |
---|
407 | |
---|
408 | @defer.inlineCallbacks |
---|
409 | def test_introducer_basedir_exists(self): |
---|
410 | basedir = self.mktemp() |
---|
411 | os.mkdir(basedir) |
---|
412 | with open(os.path.join(basedir, "foo"), "w") as f: |
---|
413 | f.write("blocker") |
---|
414 | rc, out, err = yield run_cli("create-introducer", "--hostname=foo", |
---|
415 | basedir) |
---|
416 | self.assertEqual(rc, -1) |
---|
417 | self.assertIn(basedir, err) |
---|
418 | self.assertIn("is not empty", err) |
---|
419 | self.assertIn("To avoid clobbering anything, I am going to quit now", err) |
---|
420 | |
---|
421 | def fake_config(testcase: unittest.TestCase, module: Any, result: Any) -> list[tuple]: |
---|
422 | """ |
---|
423 | Monkey-patch a fake configuration function into the given module. |
---|
424 | |
---|
425 | :param testcase: The test case to use to do the monkey-patching. |
---|
426 | |
---|
427 | :param module: The module into which to patch the fake function. |
---|
428 | |
---|
429 | :param result: The return value for the fake function. |
---|
430 | |
---|
431 | :return: A list of tuples of the arguments the fake function was called |
---|
432 | with. |
---|
433 | """ |
---|
434 | calls = [] |
---|
435 | def fake_config(reactor, cli_config): |
---|
436 | calls.append((reactor, cli_config)) |
---|
437 | return result |
---|
438 | testcase.patch(module, "create_config", fake_config) |
---|
439 | return calls |
---|
440 | |
---|
441 | class Tor(unittest.TestCase): |
---|
442 | def test_default(self): |
---|
443 | basedir = self.mktemp() |
---|
444 | tor_config = {"tor": [("abc", "def")]} |
---|
445 | tor_port = "ghi" |
---|
446 | tor_location = "jkl" |
---|
447 | config_d = defer.succeed( |
---|
448 | ListenerConfig([tor_port], [tor_location], tor_config) |
---|
449 | ) |
---|
450 | |
---|
451 | calls = fake_config(self, tor_provider, config_d) |
---|
452 | rc, out, err = self.successResultOf( |
---|
453 | run_cli("create-node", "--listen=tor", basedir), |
---|
454 | ) |
---|
455 | |
---|
456 | self.assertEqual(len(calls), 1) |
---|
457 | args = calls[0] |
---|
458 | self.assertIdentical(args[0], reactor) |
---|
459 | self.assertIsInstance(args[1], create_node.CreateNodeOptions) |
---|
460 | self.assertEqual(args[1]["listen"], "tor") |
---|
461 | cfg = read_config(basedir) |
---|
462 | self.assertEqual(cfg.get("tor", "abc"), "def") |
---|
463 | self.assertEqual(cfg.get("node", "tub.port"), "ghi") |
---|
464 | self.assertEqual(cfg.get("node", "tub.location"), "jkl") |
---|
465 | |
---|
466 | def test_launch(self): |
---|
467 | """ |
---|
468 | The ``--tor-launch`` command line option sets ``tor-launch`` to |
---|
469 | ``True``. |
---|
470 | """ |
---|
471 | basedir = self.mktemp() |
---|
472 | config_d = defer.succeed(None) |
---|
473 | |
---|
474 | calls = fake_config(self, tor_provider, config_d) |
---|
475 | rc, out, err = self.successResultOf( |
---|
476 | run_cli( |
---|
477 | "create-node", "--listen=tor", "--tor-launch", |
---|
478 | basedir, |
---|
479 | ), |
---|
480 | ) |
---|
481 | args = calls[0] |
---|
482 | self.assertEqual(args[1]["listen"], "tor") |
---|
483 | self.assertEqual(args[1]["tor-launch"], True) |
---|
484 | self.assertEqual(args[1]["tor-control-port"], None) |
---|
485 | |
---|
486 | def test_control_port(self): |
---|
487 | """ |
---|
488 | The ``--tor-control-port`` command line parameter's value is |
---|
489 | passed along as the ``tor-control-port`` value. |
---|
490 | """ |
---|
491 | basedir = self.mktemp() |
---|
492 | config_d = defer.succeed(None) |
---|
493 | |
---|
494 | calls = fake_config(self, tor_provider, config_d) |
---|
495 | rc, out, err = self.successResultOf( |
---|
496 | run_cli( |
---|
497 | "create-node", "--listen=tor", "--tor-control-port=mno", |
---|
498 | basedir, |
---|
499 | ), |
---|
500 | ) |
---|
501 | args = calls[0] |
---|
502 | self.assertEqual(args[1]["listen"], "tor") |
---|
503 | self.assertEqual(args[1]["tor-launch"], False) |
---|
504 | self.assertEqual(args[1]["tor-control-port"], "mno") |
---|
505 | |
---|
506 | def test_not_both(self): |
---|
507 | e = self.assertRaises(usage.UsageError, |
---|
508 | parse_cli, |
---|
509 | "create-node", "--listen=tor", |
---|
510 | "--tor-launch", "--tor-control-port=foo") |
---|
511 | self.assertEqual(str(e), "use either --tor-launch or" |
---|
512 | " --tor-control-port=, not both") |
---|
513 | |
---|
514 | def test_launch_without_listen(self): |
---|
515 | e = self.assertRaises(usage.UsageError, |
---|
516 | parse_cli, |
---|
517 | "create-node", "--listen=none", "--tor-launch") |
---|
518 | self.assertEqual(str(e), "--tor-launch requires --listen=tor") |
---|
519 | |
---|
520 | def test_control_port_without_listen(self): |
---|
521 | e = self.assertRaises(usage.UsageError, |
---|
522 | parse_cli, |
---|
523 | "create-node", "--listen=none", |
---|
524 | "--tor-control-port=foo") |
---|
525 | self.assertEqual(str(e), "--tor-control-port= requires --listen=tor") |
---|
526 | |
---|
527 | class I2P(unittest.TestCase): |
---|
528 | def test_default(self): |
---|
529 | basedir = self.mktemp() |
---|
530 | i2p_config = {"i2p": [("abc", "def")]} |
---|
531 | i2p_port = "ghi" |
---|
532 | i2p_location = "jkl" |
---|
533 | dest_d = defer.succeed(ListenerConfig([i2p_port], [i2p_location], i2p_config)) |
---|
534 | |
---|
535 | calls = fake_config(self, i2p_provider, dest_d) |
---|
536 | rc, out, err = self.successResultOf( |
---|
537 | run_cli("create-node", "--listen=i2p", basedir), |
---|
538 | ) |
---|
539 | self.assertEqual(len(calls), 1) |
---|
540 | args = calls[0] |
---|
541 | self.assertIdentical(args[0], reactor) |
---|
542 | self.assertIsInstance(args[1], create_node.CreateNodeOptions) |
---|
543 | self.assertEqual(args[1]["listen"], "i2p") |
---|
544 | cfg = read_config(basedir) |
---|
545 | self.assertEqual(cfg.get("i2p", "abc"), "def") |
---|
546 | self.assertEqual(cfg.get("node", "tub.port"), "ghi") |
---|
547 | self.assertEqual(cfg.get("node", "tub.location"), "jkl") |
---|
548 | |
---|
549 | def test_launch(self): |
---|
550 | e = self.assertRaises(usage.UsageError, |
---|
551 | parse_cli, |
---|
552 | "create-node", "--listen=i2p", "--i2p-launch") |
---|
553 | self.assertEqual(str(e), "--i2p-launch is under development") |
---|
554 | |
---|
555 | |
---|
556 | def test_sam_port(self): |
---|
557 | basedir = self.mktemp() |
---|
558 | dest_d = defer.succeed(None) |
---|
559 | |
---|
560 | calls = fake_config(self, i2p_provider, dest_d) |
---|
561 | rc, out, err = self.successResultOf( |
---|
562 | run_cli( |
---|
563 | "create-node", "--listen=i2p", "--i2p-sam-port=mno", |
---|
564 | basedir, |
---|
565 | ), |
---|
566 | ) |
---|
567 | args = calls[0] |
---|
568 | self.assertEqual(args[1]["listen"], "i2p") |
---|
569 | self.assertEqual(args[1]["i2p-launch"], False) |
---|
570 | self.assertEqual(args[1]["i2p-sam-port"], "mno") |
---|
571 | |
---|
572 | def test_not_both(self): |
---|
573 | e = self.assertRaises(usage.UsageError, |
---|
574 | parse_cli, |
---|
575 | "create-node", "--listen=i2p", |
---|
576 | "--i2p-launch", "--i2p-sam-port=foo") |
---|
577 | self.assertEqual(str(e), "use either --i2p-launch or" |
---|
578 | " --i2p-sam-port=, not both") |
---|
579 | |
---|
580 | def test_launch_without_listen(self): |
---|
581 | e = self.assertRaises(usage.UsageError, |
---|
582 | parse_cli, |
---|
583 | "create-node", "--listen=none", "--i2p-launch") |
---|
584 | self.assertEqual(str(e), "--i2p-launch requires --listen=i2p") |
---|
585 | |
---|
586 | def test_sam_port_without_listen(self): |
---|
587 | e = self.assertRaises(usage.UsageError, |
---|
588 | parse_cli, |
---|
589 | "create-node", "--listen=none", |
---|
590 | "--i2p-sam-port=foo") |
---|
591 | self.assertEqual(str(e), "--i2p-sam-port= requires --listen=i2p") |
---|