Rewrite integration test suite in Python
[tinc] / test / integration / variables.py
1 #!/usr/bin/env python3
2
3 """Test tinc and tincd configuration variables."""
4
5 import typing as T
6 from pathlib import Path
7
8 from testlib import check, cmd
9 from testlib.log import log
10 from testlib.proc import Tinc
11 from testlib.test import Test
12
13 bad_subnets = (
14     "1.1.1",
15     "1:2:3:4:5:",
16     "1:2:3:4:5:::6",
17     "1:2:3:4:5:6:7:8:9",
18     "256.256.256.256",
19     "1:2:3:4:5:6:7:8.123",
20     "1:2:3:4:5:6:7:1.2.3.4",
21     "a:b:c:d:e:f:g:h",
22     "1.1.1.1/0",
23     "1.1.1.1/-1",
24     "1.1.1.1/33",
25     "1::/0",
26     "1::/-1",
27     "1::/129",
28     ":" * 1024,
29 )
30
31
32 def init(ctx: Test) -> T.Tuple[Tinc, Tinc]:
33     """Initialize new test nodes."""
34     node0, node1 = ctx.node(), ctx.node()
35
36     log.info("initialize node %s", node0)
37     stdin = f"""
38         init {node0}
39         set Port 0
40         set Address localhost
41         get Name
42     """
43     out, _ = node0.cmd(stdin=stdin)
44     check.equals(node0.name, out.strip())
45
46     return node0, node1
47
48
49 with Test("test case sensitivity") as context:
50     foo, bar = init(context)
51
52     foo.cmd("set", "Mode", "switch")
53     check.equals("switch", cmd.get(foo, "Mode"))
54     check.equals("switch", cmd.get(foo, "mOdE"))
55
56     foo.cmd("set", "Mode", "router")
57     check.equals("router", cmd.get(foo, "MoDE"))
58     check.equals("router", cmd.get(foo, "mode"))
59
60     foo.cmd("set", "Mode", "Switch")
61     check.equals("Switch", cmd.get(foo, "mode"))
62
63     foo.cmd("del", "Mode", "hub", code=1)
64     foo.cmd("del", "Mode", "switch")
65     mode, _ = foo.cmd("get", "Mode", code=1)
66     check.false(mode)
67
68 with Test("single Mode variable is permitted") as context:
69     foo, bar = init(context)
70     foo.cmd("add", "Mode", "switch")
71     foo.cmd("add", "Mode", "hub")
72     check.equals("hub", cmd.get(foo, "Mode"))
73
74 with Test("test addition/deletion of multivalued variables") as context:
75     foo, bar = init(context)
76     for i in range(1, 4):
77         sub = f"{i}.{i}.{i}.{i}"
78         foo.cmd("add", "Subnet", sub)
79         foo.cmd("add", "Subnet", sub)
80     check.equals(["1.1.1.1", "2.2.2.2", "3.3.3.3"], cmd.get(foo, "Subnet").splitlines())
81
82     log.info("delete one subnet")
83     foo.cmd("del", "Subnet", "2.2.2.2")
84     check.equals(["1.1.1.1", "3.3.3.3"], cmd.get(foo, "Subnet").splitlines())
85
86     log.info("delete all subnets")
87     foo.cmd("del", "Subnet")
88     subnet, _ = foo.cmd("get", "Subnet", code=1)
89     check.false(subnet)
90
91 with Test("cannot get/set server variables using node.variable syntax") as context:
92     foo, bar = init(context)
93     name, _ = foo.cmd("get", f"{foo.name}.Name", code=1)
94     check.false(name)
95     foo.cmd("set", f"{foo.name}.Name", "fake", code=1)
96
97 with Test("get/set host variables for other nodes") as context:
98     foo, bar = init(context)
99     foo_bar = foo.sub("hosts", bar.name)
100     Path(foo_bar).touch(0o644, exist_ok=True)
101
102     bar_pmtu = f"{bar.name}.PMTU"
103     foo.cmd("add", bar_pmtu, "1")
104     foo.cmd("add", bar_pmtu, "2")
105     check.equals("2", cmd.get(foo, bar_pmtu))
106
107     bar_subnet = f"{bar.name}.Subnet"
108     for i in range(1, 4):
109         sub = f"{i}.{i}.{i}.{i}"
110         foo.cmd("add", bar_subnet, sub)
111         foo.cmd("add", bar_subnet, sub)
112
113     check.equals(
114         ["1.1.1.1", "2.2.2.2", "3.3.3.3"], cmd.get(foo, bar_subnet).splitlines()
115     )
116
117     foo.cmd("del", bar_subnet, "2.2.2.2")
118     check.equals(["1.1.1.1", "3.3.3.3"], cmd.get(foo, bar_subnet).splitlines())
119
120     foo.cmd("del", bar_subnet)
121     subnet, _ = foo.cmd("get", bar_subnet, code=1)
122     check.false(subnet)
123
124 with Test("cannot get/set variables for nodes with invalid names") as context:
125     foo, bar = init(context)
126     Path(foo.sub("hosts", "fake-node")).touch(0o644, exist_ok=True)
127     foo.cmd("set", "fake-node.Subnet", "1.1.1.1", code=1)
128
129     log.info("cannot set obsolete variables unless forced")
130     foo.cmd("set", "PrivateKey", "12345", code=1)
131     foo.cmd("--force", "set", "PrivateKey", "67890")
132     check.equals("67890", cmd.get(foo, "PrivateKey"))
133
134     foo.cmd("del", "PrivateKey")
135     key, _ = foo.cmd("get", "PrivateKey", code=1)
136     check.false(key)
137
138     log.info("cannot set/add malformed Subnets")
139     for subnet in bad_subnets:
140         log.info("testing subnet %s", subnet)
141         foo.cmd("add", "Subnet", subnet, code=1)
142
143     subnet, _ = foo.cmd("get", "Subnet", code=1)
144     check.false(subnet)