3 """Test supported and unsupported commandline flags."""
8 import subprocess as subp
12 from testlib import check, util, path
13 from testlib.log import log
14 from testlib.proc import Tinc, Script
15 from testlib.test import Test
16 from testlib.feature import SANDBOX_LEVEL
19 def init(ctx: Test) -> Tinc:
20 """Initialize new test nodes."""
21 tinc = ctx.node(init=f"set Sandbox {SANDBOX_LEVEL}")
22 tinc.add_script(Script.TINC_UP)
26 with Test("commandline flags") as context:
32 (0, ("--no-detach",)),
35 (0, ("-D", "-d", "2")),
36 (0, ("-D", "-n", "foo")),
38 (0, ("-D", "--net=foo")),
39 (0, ("-D", "--net", "foo")),
40 (0, ("-D", "-c", ".", "-c", ".")),
41 (0, ("-D", "-n", "net", "-n", "net")),
42 (0, ("-D", "-n", "net", "-o", "FakeOpt=42")),
43 (0, ("-D", "--logfile=log", "--logfile=log")),
44 (0, ("-D", f"--pidfile={pf}", f"--pidfile={pf}")),
48 (1, ("-n", "net", "-o", "Compression=")),
49 (1, ("-c", "fakedir", "-n", "n/e\\t")),
52 for code, flags in tincd_flags:
53 COOKIE = util.random_string(10)
54 server = node.tincd(*flags, env={"COOKIE": COOKIE})
57 log.info("waiting for tincd to come up")
58 env = node[Script.TINC_UP].wait().env
59 check.equals(COOKIE, env["COOKIE"])
61 log.info("stopping tinc")
62 node.cmd("stop", code=code)
64 log.info("reading tincd output")
65 stdout, stderr = server.communicate()
67 log.debug('got code %d, ("%s", "%s")', server.returncode, stdout, stderr)
68 check.equals(code, server.returncode)
72 (0, ("-n", "foo", "get", "name")),
73 (0, ("-nfoo", "get", "name")),
74 (0, ("--net=foo", "get", "name")),
75 (0, ("--net", "foo", "get", "name")),
76 (0, ("-c", "conf", "-c", "conf")),
77 (0, ("-n", "net", "-n", "net")),
78 (0, (f"--pidfile={pf}", f"--pidfile={pf}")),
79 (1, ("-n", "foo", "get", "somethingreallyunknown")),
81 (1, ("--net", "get", "name")),
83 (1, ("-c", "conf", "-n", "n/e\\t")),
86 for code, flags in tinc_flags:
87 node.cmd(*flags, code=code)
90 def test_relative_path(ctx: Test, chroot: bool) -> None:
91 """Test tincd with relative paths."""
94 confdir = os.path.realpath(foo.sub("."))
96 # Workaround for the 108-char limit on UNIX socket path length.
97 shortcut = tempfile.mkdtemp()
98 os.symlink(confdir, os.path.join(shortcut, "conf"))
100 log.info("using paths: confdir '%s', shortcut '%s'", confdir, shortcut)
116 pidfile = os.path.join(shortcut, "pid")
117 logfile = os.path.join(confdir, "log")
119 with subp.Popen(args, stderr=subp.STDOUT, cwd=shortcut) as tincd:
120 foo[Script.TINC_UP].wait(10)
122 log.info("pidfile and logfile must exist at expected paths")
123 check.file_exists(pidfile)
124 check.file_exists(logfile)
126 # chrooted tincd won't be able to reopen its log since in this
127 # test we put the log outside tinc's configuration directory.
128 if os.name != "nt" and not chroot:
129 log.info("test log file rotation")
131 util.remove_file(logfile)
132 os.kill(tincd.pid, signal.SIGHUP)
135 log.info("pidfile and logfile must still exist")
136 check.file_exists(pidfile)
137 check.file_exists(logfile)
139 log.info("stopping tinc through '%s'", pidfile)
140 foo.cmd("--pidfile", pidfile, "stop")
141 check.success(tincd.wait())
143 # Leave behind as debugging aid if there's an exception
144 shutil.rmtree(shortcut)
147 with Test("relative path to tincd dir") as context:
148 test_relative_path(context, chroot=False)
150 if os.name != "nt" and not os.getuid():
151 with Test("relative path to tincd dir (chroot)") as context:
152 test_relative_path(context, chroot=True)