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."""
27 set Sandbox {SANDBOX_LEVEL}
30 tinc.add_script(Script.TINC_UP)
34 with Test("commandline flags") as context:
40 (0, ("--no-detach",)),
43 (0, ("-D", "-d", "2")),
44 (0, ("-D", "-n", "foo")),
46 (0, ("-D", "--net=foo")),
47 (0, ("-D", "--net", "foo")),
48 (0, ("-D", "-c", ".", "-c", ".")),
49 (0, ("-D", "-n", "net", "-n", "net")),
50 (0, ("-D", "-n", "net", "-o", "FakeOpt=42")),
51 (0, ("-D", "--logfile=log", "--logfile=log")),
52 (0, ("-D", f"--pidfile={pf}", f"--pidfile={pf}")),
56 (1, ("-n", "net", "-o", "Compression=")),
57 (1, ("-c", "fakedir", "-n", "n/e\\t")),
60 for code, flags in tincd_flags:
61 COOKIE = util.random_string(10)
62 server = node.tincd(*flags, env={"COOKIE": COOKIE})
65 log.info("waiting for tincd to come up")
66 env = node[Script.TINC_UP].wait().env
67 check.equals(COOKIE, env["COOKIE"])
69 log.info("stopping tinc")
70 node.cmd("stop", code=code)
72 log.info("reading tincd output")
73 stdout, stderr = server.communicate()
75 log.debug('got code %d, ("%s", "%s")', server.returncode, stdout, stderr)
76 check.equals(code, server.returncode)
80 (0, ("-n", "foo", "get", "name")),
81 (0, ("-nfoo", "get", "name")),
82 (0, ("--net=foo", "get", "name")),
83 (0, ("--net", "foo", "get", "name")),
84 (0, ("-c", "conf", "-c", "conf")),
85 (0, ("-n", "net", "-n", "net")),
86 (0, (f"--pidfile={pf}", f"--pidfile={pf}")),
87 (1, ("-n", "foo", "get", "somethingreallyunknown")),
89 (1, ("--net", "get", "name")),
91 (1, ("-c", "conf", "-n", "n/e\\t")),
94 for code, flags in tinc_flags:
95 node.cmd(*flags, code=code)
98 def test_relative_path(ctx: Test, chroot: bool) -> None:
99 """Test tincd with relative paths."""
102 confdir = os.path.realpath(foo.sub("."))
104 # Workaround for the 108-char limit on UNIX socket path length.
105 shortcut = tempfile.mkdtemp()
106 os.symlink(confdir, os.path.join(shortcut, "conf"))
108 log.info("using paths: confdir '%s', shortcut '%s'", confdir, shortcut)
124 pidfile = os.path.join(shortcut, "pid")
125 logfile = os.path.join(confdir, "log")
127 with subp.Popen(args, stderr=subp.STDOUT, cwd=shortcut) as tincd:
128 foo[Script.TINC_UP].wait(10)
130 log.info("pidfile and logfile must exist at expected paths")
131 check.file_exists(pidfile)
132 check.file_exists(logfile)
134 # chrooted tincd won't be able to reopen its log since in this
135 # test we put the log outside tinc's configuration directory.
136 if os.name != "nt" and not chroot:
137 log.info("test log file rotation")
139 util.remove_file(logfile)
140 os.kill(tincd.pid, signal.SIGHUP)
143 log.info("pidfile and logfile must still exist")
144 check.file_exists(pidfile)
145 check.file_exists(logfile)
147 log.info("stopping tinc through '%s'", pidfile)
148 foo.cmd("--pidfile", pidfile, "stop")
149 check.equals(0, tincd.wait())
151 # Leave behind as debugging aid if there's an exception
152 shutil.rmtree(shortcut)
155 with Test("relative path to tincd dir") as context:
156 test_relative_path(context, chroot=False)
158 if os.name != "nt" and not os.getuid():
159 with Test("relative path to tincd dir (chroot)") as context:
160 test_relative_path(context, chroot=True)