commandline.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. #!/usr/bin/env python3
  2. """Test supported and unsupported commandline flags."""
  3. import os
  4. import signal
  5. import subprocess as subp
  6. import time
  7. from testlib import check, util, path
  8. from testlib.log import log
  9. from testlib.proc import Tinc, Script
  10. from testlib.test import Test
  11. from testlib.feature import SANDBOX_LEVEL
  12. tinc_flags = (
  13. (0, ("get", "name")),
  14. (0, ("-n", "foo", "get", "name")),
  15. (0, ("-nfoo", "get", "name")),
  16. (0, ("--net=foo", "get", "name")),
  17. (0, ("--net", "foo", "get", "name")),
  18. (0, ("-c", "conf", "-c", "conf")),
  19. (0, ("-n", "net", "-n", "net")),
  20. (0, ("--pidfile=pid", "--pidfile=pid")),
  21. (1, ("-n", "foo", "get", "somethingreallyunknown")),
  22. (1, ("--net",)),
  23. (1, ("--net", "get", "name")),
  24. (1, ("foo",)),
  25. (1, ("-c", "conf", "-n", "n/e\\t")),
  26. )
  27. tincd_flags = (
  28. (0, ("-D",)),
  29. (0, ("--no-detach",)),
  30. (0, ("-D", "-d")),
  31. (0, ("-D", "-d2")),
  32. (0, ("-D", "-d", "2")),
  33. (0, ("-D", "-n", "foo")),
  34. (0, ("-D", "-nfoo")),
  35. (0, ("-D", "--net=foo")),
  36. (0, ("-D", "--net", "foo")),
  37. (0, ("-D", "-c", ".", "-c", ".")),
  38. (0, ("-D", "-n", "net", "-n", "net")),
  39. (0, ("-D", "-n", "net", "-o", "FakeOpt=42")),
  40. (0, ("-D", "--logfile=log", "--logfile=log")),
  41. (0, ("-D", "--pidfile=pid", "--pidfile=pid")),
  42. (1, ("foo",)),
  43. (1, ("--pidfile",)),
  44. (1, ("--foo",)),
  45. (1, ("-n", "net", "-o", "Compression=")),
  46. (1, ("-c", "fakedir", "-n", "n/e\\t")),
  47. )
  48. def init(ctx: Test) -> Tinc:
  49. """Initialize new test nodes."""
  50. tinc = ctx.node()
  51. stdin = f"""
  52. init {tinc}
  53. set Port 0
  54. set Address localhost
  55. set DeviceType dummy
  56. set Sandbox {SANDBOX_LEVEL}
  57. """
  58. tinc.cmd(stdin=stdin)
  59. tinc.add_script(Script.TINC_UP)
  60. return tinc
  61. with Test("commandline flags") as context:
  62. node = init(context)
  63. for code, flags in tincd_flags:
  64. COOKIE = util.random_string(10)
  65. server = node.tincd(*flags, env={"COOKIE": COOKIE})
  66. if not code:
  67. log.info("waiting for tincd to come up")
  68. env = node[Script.TINC_UP].wait().env
  69. check.equals(COOKIE, env["COOKIE"])
  70. log.info("stopping tinc")
  71. node.cmd("stop", code=code)
  72. log.info("reading tincd output")
  73. stdout, stderr = server.communicate()
  74. log.debug('got code %d, ("%s", "%s")', server.returncode, stdout, stderr)
  75. check.equals(code, server.returncode)
  76. for code, flags in tinc_flags:
  77. node.cmd(*flags, code=code)
  78. def test_relative_path(ctx: Test, chroot: bool) -> None:
  79. """Test tincd with relative paths."""
  80. foo = init(ctx)
  81. conf_dir = os.path.realpath(foo.sub("."))
  82. dirname = os.path.dirname(conf_dir)
  83. basename = os.path.basename(conf_dir)
  84. log.info("using confdir %s, dirname %s, basename %s", conf_dir, dirname, basename)
  85. args = [
  86. path.TINCD_PATH,
  87. "-D",
  88. "-c",
  89. basename,
  90. "--pidfile",
  91. "pid",
  92. "--logfile",
  93. ".//./log",
  94. ]
  95. if chroot:
  96. args.append("-R")
  97. pidfile = os.path.join(dirname, "pid")
  98. util.remove_file(pidfile)
  99. logfile = os.path.join(dirname, "log")
  100. util.remove_file(logfile)
  101. with subp.Popen(args, stderr=subp.STDOUT, cwd=dirname) as tincd:
  102. foo[Script.TINC_UP].wait(10)
  103. log.info("pidfile and logfile must exist at expected paths")
  104. check.file_exists(pidfile)
  105. check.file_exists(logfile)
  106. # chrooted tincd won't be able to reopen its log since in this
  107. # test we put the log outside tinc's configuration directory.
  108. if os.name != "nt" and not chroot:
  109. log.info("test log file rotation")
  110. time.sleep(1)
  111. util.remove_file(logfile)
  112. os.kill(tincd.pid, signal.SIGHUP)
  113. time.sleep(1)
  114. log.info("pidfile and logfile must still exist")
  115. check.file_exists(pidfile)
  116. check.file_exists(logfile)
  117. log.info("stopping tinc through '%s'", pidfile)
  118. foo.cmd("--pidfile", pidfile, "stop")
  119. check.equals(0, tincd.wait())
  120. with Test("relative path to tincd dir") as context:
  121. test_relative_path(context, chroot=False)
  122. if os.name != "nt" and not os.getuid():
  123. with Test("relative path to tincd dir (chroot)") as context:
  124. test_relative_path(context, chroot=True)