3 """Test miscellaneous commands."""
8 from testlib import check, cmd, util
9 from testlib.log import log
10 from testlib.proc import Tinc, Script
11 from testlib.test import Test
13 SUBNETS_BAR = ("10.20.30.40", "fe80::")
16 def init(ctx: Test) -> Tinc:
17 """Initialize a node."""
30 def configure_nodes(ctx: Test) -> T.Tuple[Tinc, Tinc]:
31 """Create and configure nodes."""
33 log.info("initialize nodes")
34 foo, bar = init(ctx), init(ctx)
36 log.info("configure and start nodes")
37 foo.cmd("add", "Subnet", "1.2.3.4")
38 foo.add_script(Script.TINC_UP)
39 foo.add_script(bar.script_up)
42 for sub in SUBNETS_BAR:
43 bar.cmd("add", "Subnet", sub)
46 log.info("connect nodes")
47 cmd.exchange(foo, bar)
48 foo.cmd("add", "ConnectTo", bar.name)
50 foo[bar.script_up].wait()
55 def test_version(foo: Tinc) -> None:
56 """Test command 'version'."""
58 log.info("test command 'version' with redundant arguments")
59 _, err = foo.cmd("version", "foo", code=1)
60 check.is_in("Too many arguments", err)
62 log.info("test command 'version'")
63 out, _ = foo.cmd("version")
64 check.has_prefix(out, "tinc version ")
67 def test_help(foo: Tinc) -> None:
68 """Test command 'help'."""
70 log.info("test command 'help'")
71 out, _ = foo.cmd("help")
72 check.is_in("Valid options are", out)
74 out, _ = foo.cmd("help", "foobar")
75 check.is_in("Valid options are", out)
78 def test_info(foo: Tinc, bar: Tinc) -> None:
79 """Test command 'info'."""
81 log.info("info invalid arguments")
82 _, err = foo.cmd("info", code=1)
83 check.is_in("Invalid number of arguments", err)
85 log.info("info unknown node")
86 _, err = foo.cmd("info", "foobar", code=1)
87 check.is_in("Unknown node foobar", err)
89 log.info("info own node")
90 out, _ = foo.cmd("info", foo.name)
91 check.is_in("can reach itself", out)
93 log.info("info peer node")
94 out, _ = foo.cmd("info", bar.name)
95 check.is_in(bar.name, out)
96 for sub in SUBNETS_BAR:
99 log.info("info unknown subnet")
100 for sub in "1.1.1.1", "fe82:42::":
101 _, err = foo.cmd("info", sub, code=1)
102 check.is_in("Unknown address", err)
104 log.info("info own valid subnet")
105 out, _ = foo.cmd("info", "1.2.3.4")
106 check.is_in("Subnet: 1.2.3.4", out)
107 check.is_in(f"Owner: {foo}", out)
109 for sub in SUBNETS_BAR:
110 log.info("info peer's valid subnet %s", sub)
111 out, _ = foo.cmd("info", sub)
112 check.is_in(f"Subnet: {sub}", out)
113 check.is_in(f"Owner: {bar}", out)
116 def test_pid(foo: Tinc) -> None:
117 """Test command 'pid'."""
119 log.info("test pid with too many arguments")
120 _, err = foo.cmd("pid", "foo", code=1)
121 check.is_in("Too many arguments", err)
123 log.info("test pid without arguments")
124 pidfile = util.read_text(foo.sub("pid"))
125 pid, _ = pidfile.split(maxsplit=1)
127 out, _ = foo.cmd("pid")
128 check.equals(pid, out.strip())
131 def test_debug(foo: Tinc) -> None:
132 """Test command 'debug'."""
134 for args in ("debug",), ("debug", "1", "2"):
135 _, err = foo.cmd(*args, code=1)
136 check.is_in("Invalid number of arguments", err)
138 _, err = foo.cmd("debug", "5")
139 check.is_in("new level 5", err)
142 def test_log(foo: Tinc) -> None:
143 """Test command 'log'."""
145 log.info("test with too many arguments")
146 _, err = foo.cmd("log", "foo", "bar", code=1)
147 check.is_in("Too many arguments", err)
149 log.info("test correct call")
150 log_client = foo.tinc("log")
155 out, _ = log_client.communicate()
159 def test_restart(foo: Tinc) -> None:
160 """Test command 'restart'."""
162 log.info("restart without arguments")
164 foo[Script.TINC_UP].wait()
166 log.info("restart with an argument")
167 foo.cmd("restart", "-d3")
168 foo[Script.TINC_UP].wait()
170 # Checking the error message is unreliable since
171 # it's provided by getopt() and differs from OS to OS.
172 log.info("restart with invalid options")
173 foo.cmd("restart", "--fake-invalid-option", code=1)
175 log.info("restart with invalid arguments")
176 _, err = foo.cmd("restart", "bad-incorrect-argument", code=1)
177 check.is_in("unrecognized argument", err)
180 def test_shell(foo: Tinc) -> None:
183 log.info("indented comments are not ignored")
184 _, err = foo.cmd(stdin=" # ", code=1)
185 check.is_in("Unknown command", err)
187 log.info("comments are ignored")
188 _, err = foo.cmd(stdin="# this_will_fail unless comments are ignored")
189 assert "this_will_fail" not in err
191 log.info("inline comments are treated as arguments")
192 _, err = foo.cmd(stdin="version # inline comments are not ignored", code=1)
193 check.is_in("Too many arguments", err)
195 log.info("check exit commands")
196 for command in "exit", "quit":
197 out, _ = foo.cmd(stdin=command)
201 def run_tests(ctx: Test) -> None:
204 foo, bar = configure_nodes(ctx)
215 with Test("run tests") as context: