Add tests for some device & address variables
[tinc] / test / integration / invite_tinc_up.py
1 #!/usr/bin/env python3
2
3 """Test inviting tinc nodes through tinc-up script."""
4
5 import os
6 import typing as T
7
8 from testlib import check, util
9 from testlib.log import log
10 from testlib.proc import Tinc, Script
11 from testlib.test import Test
12
13 IFCONFIG = "93.184.216.34/24"
14 ROUTES_IPV6 = ("2606:2800:220:1::/64", "2606:2800:220:1:248:1893:25c8:1946")
15 BAD_IPV4 = "1234::"
16 ED_PUBKEY = "Ed25519PublicKey"
17
18
19 def make_inv_created(export_output: str) -> str:
20     """Generate script for invitation-created script."""
21     return f'''
22     node, invite = os.environ['NODE'], os.environ['INVITATION_FILE']
23     log.info('writing to invitation file %s, node %s', invite, node)
24
25     script = f"""
26 Name = {{node}}
27 Ifconfig = {IFCONFIG}
28 Route = {' '.join(ROUTES_IPV6)}
29 Route = 1.2.3.4 {BAD_IPV4}
30
31 {export_output}
32 """.strip()
33
34     with open(invite, 'w', encoding='utf-8') as f:
35         f.write(script)
36     '''
37
38
39 def init(ctx: Test) -> T.Tuple[Tinc, Tinc]:
40     """Initialize new test nodes."""
41     foo, bar = ctx.node(init=True), ctx.node()
42     foo.start()
43     return foo, bar
44
45
46 def run_tests(ctx: Test) -> None:
47     """Run all tests."""
48     foo, bar = init(ctx)
49
50     log.info("run export")
51     export, _ = foo.cmd("export")
52     assert export
53
54     log.info("adding invitation-created script")
55     code = make_inv_created(export)
56     foo.add_script(Script.INVITATION_CREATED, code)
57
58     log.info("inviting %s", bar)
59     url, _ = foo.cmd("invite", bar.name)
60     url = url.strip()
61     assert url
62
63     log.info('joining %s to %s with "%s"', bar, foo, url)
64     bar.cmd("--batch", "join", url)
65     bar.cmd("set", "Port", "0")
66
67     log.info("comparing host configs")
68     check.files_eq(foo.sub("hosts", foo.name), bar.sub("hosts", foo.name))
69
70     log.info("comparing public keys")
71     foo_key = util.find_line(foo.sub("hosts", bar.name), ED_PUBKEY)
72     bar_key = util.find_line(bar.sub("hosts", bar.name), ED_PUBKEY)
73     check.equals(foo_key, bar_key)
74
75     log.info("bar.tinc-up must not exist")
76     assert not os.path.exists(bar.sub("tinc-up"))
77
78     inv = bar.sub("tinc-up.invitation")
79     log.info("testing %s", inv)
80
81     content = util.read_text(inv)
82     check.is_in(IFCONFIG, content)
83     check.not_in(BAD_IPV4, content)
84
85     for route in ROUTES_IPV6:
86         check.is_in(route, content)
87
88     if os.name != "nt":
89         assert not os.access(inv, os.X_OK)
90
91
92 with Test("invite-tinc-up") as context:
93     run_tests(context)