3 """Test supported and unsupported compression levels."""
8 import multiprocessing.connection as mpc
9 import subprocess as subp
13 from testlib import external as ext, cmd, path, check, util
14 from testlib.log import log
15 from testlib.proc import Script, Tinc, Feature
16 from testlib.test import Test
17 from testlib.template import make_netns_config
19 IP_FOO = "192.168.1.1"
20 IP_BAR = "192.168.1.2"
23 CONTENT = "zHgfHEzRsKPU41rWoTzmcxxxUGvjfOtTZ0ZT2S1GezL7QbAcMGiLa8i6JOgn59Dq5BtlfbZj"
26 def run_receiver() -> None:
27 """Run server that receives data it prints it to stdout."""
28 with mpc.Listener((IP_FOO, 0), family="AF_INET") as listener:
29 port = listener.address[1]
30 sys.stdout.write(f"{port}\n")
33 with listener.accept() as conn:
35 print(data, sep="", flush=True)
38 def run_sender() -> None:
39 """Start client that reads data from stdin and sends it to server."""
40 port = int(os.environ["PORT"])
44 with mpc.Client((IP_FOO, port)) as client:
48 log.warning("could not connect to receiver", exc_info=ex)
51 log.error("failed to send data, terminating")
52 os.kill(0, signal.SIGTERM)
55 def get_levels(features: T.Container[Feature]) -> T.Tuple[T.List[int], T.List[int]]:
56 """Get supported compression levels."""
57 log.info("getting supported compression levels")
59 levels: T.List[int] = []
60 bogus: T.List[int] = []
62 for comp, lvl_min, lvl_max in (
63 (Feature.COMP_ZLIB, 1, 9),
64 (Feature.COMP_LZO, 10, 11),
65 (Feature.COMP_LZ4, 12, 12),
67 lvls = range(lvl_min, lvl_max + 1)
73 log.info("supported compression levels: %s", levels)
74 log.info("unsupported compression levels: %s", bogus)
79 def init(ctx: Test) -> T.Tuple[Tinc, Tinc]:
80 """Initialize new test nodes."""
81 foo, bar = ctx.node(addr=IP_FOO), ctx.node(addr=IP_BAR)
86 set Address {foo.address}
87 set Subnet {foo.address}
92 assert ext.netns_add(foo.name)
93 foo.add_script(Script.TINC_UP, make_netns_config(foo.name, foo.address, MASK))
98 set Address {bar.address}
99 set Subnet {bar.address}
104 assert ext.netns_add(bar.name)
105 bar.add_script(Script.TINC_UP, make_netns_config(bar.name, bar.address, MASK))
106 foo.add_script(Script.SUBNET_UP)
108 log.info("start %s and exchange configuration", foo)
110 cmd.exchange(foo, bar)
115 def test_valid_level(foo: Tinc, bar: Tinc) -> None:
116 """Test that supported compression level works correctly."""
118 env = foo[Script.SUBNET_UP].wait().env
119 if env.get("SUBNET") == bar.address:
122 log.info("start receiver in netns")
124 ["ip", "netns", "exec", foo.name, path.PYTHON_PATH, __file__, "--recv"],
128 assert receiver.stdout
129 port = receiver.stdout.readline().strip()
131 log.info("start sender in netns")
133 ["ip", "netns", "exec", bar.name, path.PYTHON_PATH, __file__, "--send"],
134 env={**dict(os.environ), "PORT": port},
136 recv = receiver.stdout.read()
137 log.info('received %d bytes: "%s"', len(recv), recv)
139 check.equals(0, receiver.wait())
140 check.equals(CONTENT, recv.rstrip())
143 def test_bogus_level(node: Tinc) -> None:
144 """Test that unsupported compression level fails to start."""
146 _, stderr = tincd.communicate()
147 check.equals(1, tincd.returncode)
148 check.is_in("Bogus compression level", stderr)
151 def run_tests() -> None:
153 with Test("get supported levels") as ctx:
155 levels, bogus = get_levels(node.features)
157 with Test("valid levels") as ctx:
160 for node in foo, bar:
161 node.cmd("set", "Compression", str(level))
163 test_valid_level(foo, bar)
166 with Test("test bogus levels") as ctx:
169 node.cmd("set", "Compression", str(level))
170 test_bogus_level(node)
177 elif last == "--send":
181 util.require_command("ip", "netns", "list")
182 util.require_path("/dev/net/tun")