]> git.ipfire.org Git - thirdparty/systemd.git/blame - test/test-network/systemd-networkd-tests.py
test-network: fix typo in class name
[thirdparty/systemd.git] / test / test-network / systemd-networkd-tests.py
CommitLineData
1f0e3109
SS
1#!/usr/bin/env python3
2# SPDX-License-Identifier: LGPL-2.1+
3# systemd-networkd tests
4
5import os
6import sys
7import unittest
8import subprocess
9import time
201bf07f 10import re
1f0e3109
SS
11import shutil
12import signal
13import socket
14import threading
15from shutil import copytree
16
d486a2d0 17network_unit_file_path='/run/systemd/network'
bad4969b 18networkd_runtime_directory='/run/systemd/netif'
d486a2d0 19networkd_ci_path='/run/networkd-ci'
1f0e3109
SS
20network_sysctl_ipv6_path='/proc/sys/net/ipv6/conf'
21network_sysctl_ipv4_path='/proc/sys/net/ipv4/conf'
22
d486a2d0
YW
23dnsmasq_config_file='/run/networkd-ci/test-dnsmasq.conf'
24dnsmasq_pid_file='/run/networkd-ci/test-test-dnsmasq.pid'
25dnsmasq_log_file='/run/networkd-ci/test-dnsmasq-log-file'
1f0e3109 26
7a0a37b2 27def is_module_available(module_name):
201bf07f
EV
28 lsmod_output = subprocess.check_output('lsmod', universal_newlines=True)
29 module_re = re.compile(r'^{0}\b'.format(re.escape(module_name)), re.MULTILINE)
30 return module_re.search(lsmod_output) or not subprocess.call(["modprobe", module_name])
7a0a37b2
EV
31
32def expectedFailureIfModuleIsNotAvailable(module_name):
33 def f(func):
34 if not is_module_available(module_name):
35 return unittest.expectedFailure(func)
36 return func
37
38 return f
39
1f0e3109
SS
40def setUpModule():
41
42 os.makedirs(network_unit_file_path, exist_ok=True)
43 os.makedirs(networkd_ci_path, exist_ok=True)
44
45 shutil.rmtree(networkd_ci_path)
6aea9276 46 copytree(os.path.join(os.path.dirname(os.path.abspath(__file__)), 'conf'), networkd_ci_path)
1f0e3109 47
c0bf6733
YW
48 subprocess.check_call('systemctl stop systemd-networkd.socket', shell=True)
49
1f0e3109
SS
50def tearDownModule():
51 shutil.rmtree(networkd_ci_path)
52
c0bf6733
YW
53 subprocess.check_call('systemctl stop systemd-networkd.service', shell=True)
54 subprocess.check_call('systemctl start systemd-networkd.socket', shell=True)
55 subprocess.check_call('systemctl start systemd-networkd.service', shell=True)
56
1f0e3109
SS
57class Utilities():
58 dhcp_server_data = []
59
60 def read_link_attr(self, link, dev, attribute):
61 with open(os.path.join(os.path.join(os.path.join('/sys/class/net/', link), dev), attribute)) as f:
62 return f.readline().strip()
63
4d7ed14f
SS
64 def read_bridge_port_attr(self, bridge, link, attribute):
65
66 path_bridge = os.path.join('/sys/devices/virtual/net', bridge)
67 path_port = 'lower_' + link + '/brport'
68 path = os.path.join(path_bridge, path_port)
69
70 with open(os.path.join(path, attribute)) as f:
71 return f.readline().strip()
72
1f0e3109
SS
73 def link_exits(self, link):
74 return os.path.exists(os.path.join('/sys/class/net', link))
75
76 def link_remove(self, links):
77 for link in links:
78 if os.path.exists(os.path.join('/sys/class/net', link)):
79 subprocess.call(['ip', 'link', 'del', 'dev', link])
9a4720a9 80 time.sleep(1)
1f0e3109
SS
81
82 def read_ipv6_sysctl_attr(self, link, attribute):
83 with open(os.path.join(os.path.join(network_sysctl_ipv6_path, link), attribute)) as f:
84 return f.readline().strip()
85
86 def read_ipv4_sysctl_attr(self, link, attribute):
87 with open(os.path.join(os.path.join(network_sysctl_ipv4_path, link), attribute)) as f:
88 return f.readline().strip()
89
90 def copy_unit_to_networkd_unit_path(self, *units):
91 for unit in units:
92 shutil.copy(os.path.join(networkd_ci_path, unit), network_unit_file_path)
013c8dc9
YW
93 if (os.path.exists(os.path.join(networkd_ci_path, unit + '.d'))):
94 copytree(os.path.join(networkd_ci_path, unit + '.d'), os.path.join(network_unit_file_path, unit + '.d'))
1f0e3109
SS
95
96 def remove_unit_from_networkd_path(self, units):
97 for unit in units:
98 if (os.path.exists(os.path.join(network_unit_file_path, unit))):
99 os.remove(os.path.join(network_unit_file_path, unit))
013c8dc9
YW
100 if (os.path.exists(os.path.join(network_unit_file_path, unit + '.d'))):
101 shutil.rmtree(os.path.join(network_unit_file_path, unit + '.d'))
1f0e3109
SS
102
103 def start_dnsmasq(self):
104 subprocess.check_call('dnsmasq -8 /var/run/networkd-ci/test-dnsmasq-log-file --log-queries=extra --log-dhcp --pid-file=/var/run/networkd-ci/test-test-dnsmasq.pid --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range=2600::10,2600::20 --dhcp-range=192.168.5.10,192.168.5.200 -R --dhcp-leasefile=/var/run/networkd-ci/lease --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --dhcp-option=33,192.168.5.4,192.168.5.5', shell=True)
105
106 time.sleep(10)
107
108 def stop_dnsmasq(self, pid_file):
109 if os.path.exists(pid_file):
110 with open(pid_file, 'r') as f:
111 pid = f.read().rstrip(' \t\r\n\0')
112 os.kill(int(pid), signal.SIGTERM)
113
114 os.remove(pid_file)
115
116 def search_words_in_file(self, word):
117 if os.path.exists(dnsmasq_log_file):
118 with open (dnsmasq_log_file) as in_file:
119 contents = in_file.read()
120 print(contents)
121 for part in contents.split():
122 if word in part:
123 in_file.close()
124 print("%s, %s" % (word, part))
125 return True
126 return False
127
128 def remove_lease_file(self):
129 if os.path.exists(os.path.join(networkd_ci_path, 'lease')):
130 os.remove(os.path.join(networkd_ci_path, 'lease'))
131
132 def remove_log_file(self):
133 if os.path.exists(dnsmasq_log_file):
134 os.remove(dnsmasq_log_file)
135
136 def start_networkd(self):
bad4969b
YW
137 if (os.path.exists(os.path.join(networkd_runtime_directory, 'state'))):
138 subprocess.check_call('systemctl stop systemd-networkd', shell=True)
139 os.remove(os.path.join(networkd_runtime_directory, 'state'))
140 subprocess.check_call('systemctl start systemd-networkd', shell=True)
141 else:
142 subprocess.check_call('systemctl restart systemd-networkd', shell=True)
1f0e3109
SS
143 time.sleep(5)
144
145global ip
146global port
147
148class DHCPServer(threading.Thread):
149 def __init__(self, name):
150 threading.Thread.__init__(self)
151 self.name = name
152
153 def run(self):
154 self.start_dhcp_server()
155
156 def start_dhcp_server(self):
157 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
158
159 server_address = ('0.0.0.0', 67)
160 sock.bind(server_address)
161
162 print('Starting DHCP Server ...\n')
163 data, addr = sock.recvfrom(1024) # buffer size is 1024 bytes
164
165 global ip
166 ip = addr[0]
167
168 global port
169 port = addr[1]
170 sock.close()
171
172class NetworkdNetDevTests(unittest.TestCase, Utilities):
173
174 links =['bridge99', 'bond99', 'bond99', 'vlan99', 'test1', 'macvtap99',
175 'macvlan99', 'ipvlan99', 'vxlan99', 'veth99', 'vrf99', 'tun99',
d29dc4f1 176 'tap99', 'vcan99', 'geneve99', 'dummy98', 'ipiptun99', 'sittun99', '6rdtun99',
2266864b 177 'gretap99', 'vtitun99', 'vti6tun99','ip6tnl99', 'gretun99', 'ip6gretap99',
d0e728b6 178 'wg99', 'dropin-test', 'erspan-test', 'isataptun99']
1f0e3109
SS
179
180 units = ['25-bridge.netdev', '25-bond.netdev', '21-vlan.netdev', '11-dummy.netdev', '21-vlan.network',
181 '21-macvtap.netdev', 'macvtap.network', '21-macvlan.netdev', 'macvlan.network', 'vxlan.network',
182 '25-vxlan.netdev', '25-ipvlan.netdev', 'ipvlan.network', '25-veth.netdev', '25-vrf.netdev',
183 '25-tun.netdev', '25-tun.netdev', '25-vcan.netdev', '25-geneve.netdev', '25-ipip-tunnel.netdev',
2266864b
SS
184 '25-ip6tnl-tunnel.netdev', '25-ip6gre-tunnel.netdev', '25-sit-tunnel.netdev', '25-6rd-tunnel.netdev',
185 '25-erspan-tunnel.netdev', '25-gre-tunnel.netdev', '25-gretap-tunnel.netdev', '25-vti-tunnel.netdev',
186 '25-vti6-tunnel.netdev', '12-dummy.netdev', 'gre.network', 'ipip.network', 'ip6gretap.network',
187 'gretun.network', 'ip6tnl.network', '25-tap.netdev', 'vti6.network', 'vti.network', 'gretap.network',
d0e728b6
SS
188 'sit.network', '25-ipip-tunnel-independent.netdev', '25-wireguard.netdev', '6rd.network', '10-dropin-test.netdev',
189 '25-isatap-tunnel.netdev', 'isatap.network']
1f0e3109
SS
190
191 def setUp(self):
192 self.link_remove(self.links)
193
194 def tearDown(self):
195 self.link_remove(self.links)
196 self.remove_unit_from_networkd_path(self.units)
197
d80734f7
YW
198 def test_dropin(self):
199 self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev')
200
201 self.start_networkd()
202
203 self.assertTrue(self.link_exits('dropin-test'))
204
205 output = subprocess.check_output(['ip', 'link', 'show', 'dropin-test']).rstrip().decode('utf-8')
206 print(output)
207 self.assertRegex(output, '00:50:56:c0:00:28')
208
1f0e3109
SS
209 def test_bridge(self):
210 self.copy_unit_to_networkd_unit_path('25-bridge.netdev')
211 self.start_networkd()
212
213 self.assertTrue(self.link_exits('bridge99'))
214
215 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'hello_time'))
216 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge', 'max_age'))
217 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','forward_delay'))
218 self.assertEqual('900', self.read_link_attr('bridge99', 'bridge','ageing_time'))
219 self.assertEqual('9', self.read_link_attr('bridge99', 'bridge','priority'))
220 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_querier'))
221 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','multicast_snooping'))
222 self.assertEqual('1', self.read_link_attr('bridge99', 'bridge','stp_state'))
223
224 def test_bond(self):
225 self.copy_unit_to_networkd_unit_path('25-bond.netdev')
226 self.start_networkd()
227
228 self.assertTrue(self.link_exits('bond99'))
229
99f68ef0
TJ
230 self.assertEqual('802.3ad 4', self.read_link_attr('bond99', 'bonding', 'mode'))
231 self.assertEqual('layer3+4 1', self.read_link_attr('bond99', 'bonding', 'xmit_hash_policy'))
232 self.assertEqual('1000', self.read_link_attr('bond99', 'bonding', 'miimon'))
233 self.assertEqual('fast 1', self.read_link_attr('bond99', 'bonding', 'lacp_rate'))
234 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'updelay'))
235 self.assertEqual('2000', self.read_link_attr('bond99', 'bonding', 'downdelay'))
236 self.assertEqual('4', self.read_link_attr('bond99', 'bonding', 'resend_igmp'))
237 self.assertEqual('1', self.read_link_attr('bond99', 'bonding', 'min_links'))
238 self.assertEqual('1218', self.read_link_attr('bond99', 'bonding', 'ad_actor_sys_prio'))
239 self.assertEqual('811', self.read_link_attr('bond99', 'bonding', 'ad_user_port_key'))
240 self.assertEqual('00:11:22:33:44:55', self.read_link_attr('bond99', 'bonding', 'ad_actor_system'))
1f0e3109
SS
241
242 def test_vlan(self):
243 self.copy_unit_to_networkd_unit_path('21-vlan.netdev', '11-dummy.netdev', '21-vlan.network')
244
245 self.start_networkd()
246
247 self.assertTrue(self.link_exits('vlan99'))
248
249 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vlan99']).rstrip().decode('utf-8')
250 self.assertTrue(output, 'REORDER_HDR')
251 self.assertTrue(output, 'LOOSE_BINDING')
252 self.assertTrue(output, 'GVRP')
253 self.assertTrue(output, 'MVRP')
254 self.assertTrue(output, '99')
255
256 def test_macvtap(self):
257 self.copy_unit_to_networkd_unit_path('21-macvtap.netdev', '11-dummy.netdev', 'macvtap.network')
258
259 self.start_networkd()
260
261 self.assertTrue(self.link_exits('macvtap99'))
262
263 def test_macvlan(self):
264 self.copy_unit_to_networkd_unit_path('21-macvlan.netdev', '11-dummy.netdev', 'macvlan.network')
265
266 self.start_networkd()
267
268 self.assertTrue(self.link_exits('macvlan99'))
269
7a0a37b2 270 @expectedFailureIfModuleIsNotAvailable('ipvlan')
1f0e3109
SS
271 def test_ipvlan(self):
272 self.copy_unit_to_networkd_unit_path('25-ipvlan.netdev', '11-dummy.netdev', 'ipvlan.network')
273
274 self.start_networkd()
275
276 self.assertTrue(self.link_exits('ipvlan99'))
277
278 def test_veth(self):
279 self.copy_unit_to_networkd_unit_path('25-veth.netdev')
280
281 self.start_networkd()
282
283 self.assertTrue(self.link_exits('veth99'))
284
285 def test_dummy(self):
286 self.copy_unit_to_networkd_unit_path('11-dummy.netdev')
287
288 self.start_networkd()
289
290 self.assertTrue(self.link_exits('test1'))
291
292 def test_tun(self):
293 self.copy_unit_to_networkd_unit_path('25-tun.netdev')
294
295 self.start_networkd()
296
297 self.assertTrue(self.link_exits('tun99'))
298
299 def test_tap(self):
300 self.copy_unit_to_networkd_unit_path('25-tap.netdev')
301
302 self.start_networkd()
303
304 self.assertTrue(self.link_exits('tap99'))
305
7a0a37b2 306 @expectedFailureIfModuleIsNotAvailable('vrf')
1f0e3109
SS
307 def test_vrf(self):
308 self.copy_unit_to_networkd_unit_path('25-vrf.netdev')
309
310 self.start_networkd()
311
312 self.assertTrue(self.link_exits('vrf99'))
313
7a0a37b2 314 @expectedFailureIfModuleIsNotAvailable('vcan')
1f0e3109
SS
315 def test_vcan(self):
316 self.copy_unit_to_networkd_unit_path('25-vcan.netdev')
317
318 self.start_networkd()
319
320 self.assertTrue(self.link_exits('vcan99'))
321
7a3bc5a8
EV
322 @expectedFailureIfModuleIsNotAvailable('wireguard')
323 def test_wireguard(self):
324 self.copy_unit_to_networkd_unit_path('25-wireguard.netdev')
325
326 self.start_networkd()
327
328 if shutil.which('wg'):
329 subprocess.call('wg')
330
331 self.assertTrue(self.link_exits('wg99'))
332
1f0e3109
SS
333 def test_geneve(self):
334 self.copy_unit_to_networkd_unit_path('25-geneve.netdev')
335
336 self.start_networkd()
337
338 self.assertTrue(self.link_exits('geneve99'))
339
340 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'geneve99']).rstrip().decode('utf-8')
341 self.assertTrue(output, '192.168.22.1')
342 self.assertTrue(output, '6082')
343 self.assertTrue(output, 'udpcsum')
344 self.assertTrue(output, 'udp6zerocsumrx')
345
346 def test_ipip_tunnel(self):
347 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ipip-tunnel.netdev', 'ipip.network')
348 self.start_networkd()
349
350 self.assertTrue(self.link_exits('dummy98'))
351 self.assertTrue(self.link_exits('ipiptun99'))
352
353 def test_gre_tunnel(self):
354 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gre-tunnel.netdev', 'gretun.network')
355 self.start_networkd()
356
357 self.assertTrue(self.link_exits('dummy98'))
358 self.assertTrue(self.link_exits('gretun99'))
359
360 def test_gretap_tunnel(self):
361 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-gretap-tunnel.netdev', 'gretap.network')
362 self.start_networkd()
363
364 self.assertTrue(self.link_exits('dummy98'))
365 self.assertTrue(self.link_exits('gretap99'))
366
367 def test_ip6gretap_tunnel(self):
368 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6gre-tunnel.netdev', 'ip6gretap.network')
369 self.start_networkd()
370
371 self.assertTrue(self.link_exits('dummy98'))
372 self.assertTrue(self.link_exits('ip6gretap99'))
373
374 def test_vti_tunnel(self):
375 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti-tunnel.netdev', 'vti.network')
376 self.start_networkd()
377
378 self.assertTrue(self.link_exits('dummy98'))
379 self.assertTrue(self.link_exits('vtitun99'))
380
381 def test_vti6_tunnel(self):
382 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-vti6-tunnel.netdev', 'vti6.network')
383 self.start_networkd()
384
385 self.assertTrue(self.link_exits('dummy98'))
386 self.assertTrue(self.link_exits('vti6tun99'))
387
388 def test_ip6tnl_tunnel(self):
389 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-ip6tnl-tunnel.netdev', 'ip6tnl.network')
390 self.start_networkd()
391
392 self.assertTrue(self.link_exits('dummy98'))
393 self.assertTrue(self.link_exits('ip6tnl99'))
394
395 def test_sit_tunnel(self):
396 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-sit-tunnel.netdev', 'sit.network')
397 self.start_networkd()
398
399 self.assertTrue(self.link_exits('dummy98'))
400 self.assertTrue(self.link_exits('sittun99'))
401
d0e728b6
SS
402 def test_isatap_tunnel(self):
403 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-isatap-tunnel.netdev', 'isatap.network')
404 self.start_networkd()
405
406 self.assertTrue(self.link_exits('dummy98'))
407 self.assertTrue(self.link_exits('isataptun99'))
408 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'isataptun99']).rstrip().decode('utf-8')
409 self.assertRegex(output, "isatap ")
410
d29dc4f1
DA
411 def test_6rd_tunnel(self):
412 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', '25-6rd-tunnel.netdev', '6rd.network')
413 self.start_networkd()
414
415 self.assertTrue(self.link_exits('dummy98'))
416 self.assertTrue(self.link_exits('sittun99'))
417
2266864b
SS
418 def test_erspan_tunnel(self):
419 self.copy_unit_to_networkd_unit_path('25-erspan-tunnel.netdev')
420 self.start_networkd()
421
422 self.assertTrue(self.link_exits('erspan-test'))
423
424 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'erspan-test']).rstrip().decode('utf-8')
425 print(output)
426 self.assertTrue(output, '172.16.1.200')
427 self.assertTrue(output, '172.16.1.100')
428 self.assertTrue(output, '101')
429
1f0e3109
SS
430 def test_tunnel_independent(self):
431 self.copy_unit_to_networkd_unit_path('25-ipip-tunnel-independent.netdev')
432
433 self.start_networkd()
434 self.assertTrue(self.link_exits('ipiptun99'))
435
436 def test_vxlan(self):
437 self.copy_unit_to_networkd_unit_path('25-vxlan.netdev', 'vxlan.network','11-dummy.netdev')
438
439 self.start_networkd()
440
441 self.assertTrue(self.link_exits('vxlan99'))
442
443 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'vxlan99']).rstrip().decode('utf-8')
444 self.assertRegex(output, "999")
445 self.assertRegex(output, '5555')
446 self.assertRegex(output, 'l2miss')
447 self.assertRegex(output, 'l3miss')
448 self.assertRegex(output, 'udpcsum')
449 self.assertRegex(output, 'udp6zerocsumtx')
450 self.assertRegex(output, 'udp6zerocsumrx')
451 self.assertRegex(output, 'remcsumtx')
452 self.assertRegex(output, 'remcsumrx')
453 self.assertRegex(output, 'gbp')
454
455class NetworkdNetWorkTests(unittest.TestCase, Utilities):
456 links = ['dummy98', 'test1', 'bond199']
457
458 units = ['12-dummy.netdev', 'test-static.network', 'configure-without-carrier.network', '11-dummy.netdev',
459 '23-primary-slave.network', '23-test1-bond199.network', '11-dummy.netdev', '23-bond199.network',
460 '25-bond-active-backup-slave.netdev', '12-dummy.netdev', '23-active-slave.network',
efecf9cd 461 'routing-policy-rule.network', '25-fibrule-port-range.network', '25-fibrule-invert.network', '25-address-section.network',
926062f0
SS
462 '25-address-section-miscellaneous.network', '25-route-section.network', '25-route-type.network',
463 '25-route-tcp-window-settings.network', '25-route-gateway.network', '25-route-gateway-on-link.network',
1f0e3109 464 '25-address-link-section.network', '25-ipv6-address-label-section.network', '25-link-section-unmanaged.network',
0d34228f 465 '25-sysctl.network', '25-route-reverse-order.network']
1f0e3109
SS
466
467 def setUp(self):
468 self.link_remove(self.links)
469
470 def tearDown(self):
471 self.link_remove(self.links)
472 self.remove_unit_from_networkd_path(self.units)
473
474 def test_static_address(self):
475 self.copy_unit_to_networkd_unit_path('12-dummy.netdev', 'test-static.network')
476 self.start_networkd()
477
478 self.assertTrue(self.link_exits('dummy98'))
479 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
480 print(output)
481 self.assertRegex(output, '192.168.0.15')
482 self.assertRegex(output, '192.168.0.1')
483 self.assertRegex(output, 'routable')
484
485 def test_configure_without_carrier(self):
486 self.copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
487 self.start_networkd()
488
489 self.assertTrue(self.link_exits('test1'))
490 output = subprocess.check_output(['networkctl', 'status', 'test1']).rstrip().decode('utf-8')
491 print(output)
492 self.assertRegex(output, '192.168.0.15')
493 self.assertRegex(output, '192.168.0.1')
494 self.assertRegex(output, 'routable')
495
496 def test_bond_active_slave(self):
497 self.copy_unit_to_networkd_unit_path('23-active-slave.network', '23-bond199.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
498 self.start_networkd()
499
500 self.assertTrue(self.link_exits('dummy98'))
501 self.assertTrue(self.link_exits('bond199'))
502 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
503 print(output)
504 self.assertRegex(output, 'active_slave dummy98')
505
506 def test_bond_primary_slave(self):
507 self.copy_unit_to_networkd_unit_path('23-primary-slave.network', '23-test1-bond199.network', '25-bond-active-backup-slave.netdev', '11-dummy.netdev')
508 self.start_networkd()
509
510 self.assertTrue(self.link_exits('test1'))
511 self.assertTrue(self.link_exits('bond199'))
512 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'bond199']).rstrip().decode('utf-8')
513 print(output)
514 self.assertRegex(output, 'primary test1')
515
516 def test_routing_policy_rule(self):
517 self.copy_unit_to_networkd_unit_path('routing-policy-rule.network', '11-dummy.netdev')
518 self.start_networkd()
519
520 self.assertTrue(self.link_exits('test1'))
521 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
522 print(output)
523 self.assertRegex(output, '111')
524 self.assertRegex(output, 'from 192.168.100.18')
f7bdd562 525 self.assertRegex(output, r'tos (?:0x08|throughput)\s')
1f0e3109
SS
526 self.assertRegex(output, 'iif test1')
527 self.assertRegex(output, 'oif test1')
528 self.assertRegex(output, 'lookup 7')
529
926062f0
SS
530 def test_routing_policy_rule_port_range(self):
531 self.copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
532 self.start_networkd()
533
534 self.assertTrue(self.link_exits('test1'))
535 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
536 print(output)
537 self.assertRegex(output, '111')
538 self.assertRegex(output, 'from 192.168.100.18')
539 self.assertRegex(output, '1123-1150')
540 self.assertRegex(output, '3224-3290')
541 self.assertRegex(output, 'tcp')
542 self.assertRegex(output, 'lookup 7')
1f0e3109 543
efecf9cd
SS
544 def test_routing_policy_rule_invert(self):
545 self.copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
546 self.start_networkd()
547
548 self.assertTrue(self.link_exits('test1'))
549 output = subprocess.check_output(['ip', 'rule']).rstrip().decode('utf-8')
550 print(output)
551
552 self.assertRegex(output, '111')
553 self.assertRegex(output, 'not.*?from.*?192.168.100.18')
554 self.assertRegex(output, 'tcp')
555 self.assertRegex(output, 'lookup 7')
556
1f0e3109
SS
557 def test_address_preferred_lifetime_zero_ipv6(self):
558 self.copy_unit_to_networkd_unit_path('25-address-section-miscellaneous.network', '12-dummy.netdev')
559 self.start_networkd()
560
561 self.assertTrue(self.link_exits('dummy98'))
562
563 output = subprocess.check_output(['ip', 'address', 'show', 'dummy98']).rstrip().decode('utf-8')
564 print(output)
565 self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope link deprecated dummy98')
566 self.assertRegex(output, 'inet6 2001:db8:0:f101::1/64 scope global')
567
568 def test_ip_route(self):
569 self.copy_unit_to_networkd_unit_path('25-route-section.network', '12-dummy.netdev')
570 self.start_networkd()
571
572 self.assertTrue(self.link_exits('dummy98'))
573
574 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98']).rstrip().decode('utf-8')
575 print(output)
576 self.assertRegex(output, '192.168.0.1')
577 self.assertRegex(output, 'static')
578 self.assertRegex(output, '192.168.0.0/24')
579
0d34228f
SS
580 def test_ip_route_reverse(self):
581 self.copy_unit_to_networkd_unit_path('25-route-reverse-order.network', '12-dummy.netdev')
582 self.start_networkd()
583
584 self.assertTrue(self.link_exits('dummy98'))
585
586 output = subprocess.check_output(['ip', '-6', 'route', 'show', 'dev', 'dummy98']).rstrip().decode('utf-8')
587 print(output)
588 self.assertRegex(output, '2001:1234:5:8fff:ff:ff:ff:ff')
589 self.assertRegex(output, '2001:1234:5:8f63::1')
590
1f0e3109
SS
591 def test_ip_route_blackhole_unreachable_prohibit(self):
592 self.copy_unit_to_networkd_unit_path('25-route-type.network', '12-dummy.netdev')
593 self.start_networkd()
594
595 self.assertTrue(self.link_exits('dummy98'))
596
597 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
598 print(output)
599 self.assertRegex(output, 'blackhole')
600 self.assertRegex(output, 'unreachable')
601 self.assertRegex(output, 'prohibit')
602
603 subprocess.call(['ip', 'route', 'del', 'blackhole', '202.54.1.2'])
604 subprocess.call(['ip', 'route', 'del', 'unreachable', '202.54.1.3'])
605 subprocess.call(['ip', 'route', 'del', 'prohibit', '202.54.1.4'])
606
607 def test_ip_route_tcp_window(self):
608 self.copy_unit_to_networkd_unit_path('25-route-tcp-window-settings.network', '11-dummy.netdev')
609 self.start_networkd()
610
611 self.assertTrue(self.link_exits('test1'))
612
613 output = subprocess.check_output(['ip', 'route', 'list']).rstrip().decode('utf-8')
614 print(output)
615 self.assertRegex(output, 'initcwnd 20')
616 self.assertRegex(output, 'initrwnd 30')
617
f5050e48
YW
618 def test_ip_route_gateway(self):
619 self.copy_unit_to_networkd_unit_path('25-route-gateway.network', '12-dummy.netdev')
620 self.start_networkd()
621
622 self.assertTrue(self.link_exits('dummy98'))
623
624 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
625 print(output)
626 self.assertRegex(output, 'default')
627 self.assertRegex(output, 'via')
628 self.assertRegex(output, '149.10.124.64')
629 self.assertRegex(output, 'proto')
630 self.assertRegex(output, 'static')
631
632 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
633 print(output)
634 self.assertRegex(output, '149.10.124.48/28')
635 self.assertRegex(output, 'proto')
636 self.assertRegex(output, 'kernel')
637 self.assertRegex(output, 'scope')
638 self.assertRegex(output, 'link')
639
640 def test_ip_route_gateway_on_link(self):
641 self.copy_unit_to_networkd_unit_path('25-route-gateway-on-link.network', '12-dummy.netdev')
642 self.start_networkd()
643
644 self.assertTrue(self.link_exits('dummy98'))
645
646 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'default']).rstrip().decode('utf-8')
647 print(output)
648 self.assertRegex(output, 'default')
649 self.assertRegex(output, 'via')
650 self.assertRegex(output, '149.10.125.65')
651 self.assertRegex(output, 'proto')
652 self.assertRegex(output, 'static')
653 self.assertRegex(output, 'onlink')
654
655 output = subprocess.check_output(['ip', 'route', 'list', 'dev', 'dummy98', 'src', '149.10.124.58']).rstrip().decode('utf-8')
656 print(output)
657 self.assertRegex(output, '149.10.124.48/28')
658 self.assertRegex(output, 'proto')
659 self.assertRegex(output, 'kernel')
660 self.assertRegex(output, 'scope')
661 self.assertRegex(output, 'link')
662
1f0e3109
SS
663 def test_ip_link_mac_address(self):
664 self.copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
665 self.start_networkd()
666
667 self.assertTrue(self.link_exits('dummy98'))
668
669 output = subprocess.check_output(['ip', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
670 print(output)
671 self.assertRegex(output, '00:01:02:aa:bb:cc')
672
673 def test_ip_link_unmanaged(self):
674 self.copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
675 self.start_networkd()
676
677 self.assertTrue(self.link_exits('dummy98'))
678
679 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
680 print(output)
681 self.assertRegex(output, 'unmanaged')
682
683 def test_ipv6_address_label(self):
684 self.copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
685 self.start_networkd()
686
687 self.assertTrue(self.link_exits('dummy98'))
688
689 output = subprocess.check_output(['ip', 'addrlabel', 'list']).rstrip().decode('utf-8')
690 print(output)
691 self.assertRegex(output, '2004:da8:1::/64')
692
693 def test_sysctl(self):
694 self.copy_unit_to_networkd_unit_path('25-sysctl.network', '12-dummy.netdev')
695 self.start_networkd()
696
697 self.assertTrue(self.link_exits('dummy98'))
698
699 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'forwarding'), '1')
700 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'use_tempaddr'), '2')
701 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'dad_transmits'), '3')
702 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'hop_limit'), '5')
703 self.assertEqual(self.read_ipv6_sysctl_attr('dummy98', 'proxy_ndp'), '1')
704 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'forwarding'),'1')
705 self.assertEqual(self.read_ipv4_sysctl_attr('dummy98', 'proxy_arp'), '1')
706
14dc0335 707class NetworkdNetWorkBridgeTests(unittest.TestCase, Utilities):
1f0e3109
SS
708 links = ['dummy98', 'test1', 'bridge99']
709
710 units = ['11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev', '26-bridge-slave-interface-1.network',
711 '26-bridge-slave-interface-2.network', 'bridge99.network']
712
713 def setUp(self):
714 self.link_remove(self.links)
715
716 def tearDown(self):
717 self.link_remove(self.links)
718 self.remove_unit_from_networkd_path(self.units)
719
720 def test_bridge_property(self):
721 self.copy_unit_to_networkd_unit_path('11-dummy.netdev', '12-dummy.netdev', '26-bridge.netdev',
722 '26-bridge-slave-interface-1.network', '26-bridge-slave-interface-2.network',
723 'bridge99.network')
724 self.start_networkd()
725
726 self.assertTrue(self.link_exits('dummy98'))
727 self.assertTrue(self.link_exits('test1'))
728 self.assertTrue(self.link_exits('bridge99'))
729
730 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'test1']).rstrip().decode('utf-8')
731 print(output)
732 self.assertRegex(output, 'master')
733 self.assertRegex(output, 'bridge')
734
735 output = subprocess.check_output(['ip', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
736 print(output)
737 self.assertRegex(output, 'master')
738 self.assertRegex(output, 'bridge')
739
740 output = subprocess.check_output(['ip', 'addr', 'show', 'bridge99']).rstrip().decode('utf-8')
741 print(output)
742 self.assertRegex(output, '192.168.0.15')
743 self.assertRegex(output, '192.168.0.1')
744
745 output = subprocess.check_output(['bridge', '-d', 'link', 'show', 'dummy98']).rstrip().decode('utf-8')
746 print(output)
4d7ed14f
SS
747
748 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'hairpin_mode'), '1')
749 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'path_cost'), '400')
750 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'unicast_flood'), '1')
751 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_fast_leave'), '1')
752
753 # CONFIG_BRIDGE_IGMP_SNOOPING=y
754 if (os.path.exists('/sys/devices/virtual/net/bridge00/lower_dummy98/brport/multicast_to_unicast')):
755 self.assertEqual(self.read_bridge_port_attr('bridge99', 'dummy98', 'multicast_to_unicast'), '1')
1f0e3109
SS
756
757class NetworkdNetWorkLLDPTests(unittest.TestCase, Utilities):
758 links = ['veth99']
759
760 units = ['23-emit-lldp.network', '24-lldp.network', '25-veth.netdev']
761
762 def setUp(self):
763 self.link_remove(self.links)
764
765 def tearDown(self):
766 self.link_remove(self.links)
767 self.remove_unit_from_networkd_path(self.units)
768
769 def test_lldp(self):
770 self.copy_unit_to_networkd_unit_path('23-emit-lldp.network', '24-lldp.network', '25-veth.netdev')
771 self.start_networkd()
772
773 self.assertTrue(self.link_exits('veth99'))
774
775 output = subprocess.check_output(['networkctl', 'lldp']).rstrip().decode('utf-8')
776 print(output)
777 self.assertRegex(output, 'veth-peer')
778 self.assertRegex(output, 'veth99')
779
780class NetworkdNetworkRATests(unittest.TestCase, Utilities):
781 links = ['veth99']
782
783 units = ['25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network']
784
785 def setUp(self):
786 self.link_remove(self.links)
787
788 def tearDown(self):
789 self.link_remove(self.links)
790 self.remove_unit_from_networkd_path(self.units)
791
792 def test_ipv6_prefix_delegation(self):
793 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'ipv6-prefix.network', 'ipv6-prefix-veth.network')
794 self.start_networkd()
795
796 self.assertTrue(self.link_exits('veth99'))
797
798 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
799 print(output)
800 self.assertRegex(output, '2002:da8:1:0')
801
802class NetworkdNetworkDHCPServerTests(unittest.TestCase, Utilities):
803 links = ['veth99', 'dummy98']
804
805 units = ['25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network', '12-dummy.netdev', '24-search-domain.network',
806 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network']
807
808 def setUp(self):
809 self.link_remove(self.links)
810
811 def tearDown(self):
812 self.link_remove(self.links)
813 self.remove_unit_from_networkd_path(self.units)
814
815 def test_dhcp_server(self):
816 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client.network', 'dhcp-server.network')
817 self.start_networkd()
818
819 self.assertTrue(self.link_exits('veth99'))
820
821 time.sleep(5)
822
823 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
824 print(output)
825 self.assertRegex(output, '192.168.5.*')
826 self.assertRegex(output, 'Gateway: 192.168.5.1')
827 self.assertRegex(output, 'DNS: 192.168.5.1')
828 self.assertRegex(output, 'NTP: 192.168.5.1')
829
830 def test_domain(self):
831 self.copy_unit_to_networkd_unit_path( '12-dummy.netdev', '24-search-domain.network')
832 self.start_networkd()
833
834 self.assertTrue(self.link_exits('dummy98'))
835
836 output = subprocess.check_output(['networkctl', 'status', 'dummy98']).rstrip().decode('utf-8')
837 print(output)
838 self.assertRegex(output, 'Address: 192.168.42.100')
839 self.assertRegex(output, 'DNS: 192.168.42.1')
840 self.assertRegex(output, 'Search Domains: one')
841
842 def test_emit_router_timezone(self):
843 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-client-timezone-router.network', 'dhcp-server-timezone-router.network')
844 self.start_networkd()
845
846 self.assertTrue(self.link_exits('veth99'))
847
848 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
849 print(output)
850 self.assertRegex(output, 'Gateway: 192.168.5.*')
851 self.assertRegex(output, '192.168.5.*')
852 self.assertRegex(output, 'Europe/Berlin')
853
854class NetworkdNetworkDHCPClientTests(unittest.TestCase, Utilities):
855 links = ['veth99', 'dummy98']
856
857 units = ['25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network',
858 'dhcp-client-ipv4-only-ipv6-disabled.network', 'dhcp-client-ipv4-only.network',
859 'dhcp-client-ipv4-dhcp-settings.network', 'dhcp-client-anonymize.network',
860 'dhcp-client-ipv6-rapid-commit.network', 'dhcp-client-route-table.network',
861 'dhcp-v4-server-veth-peer.network', 'dhcp-client-listen-port.network',
862 'dhcp-client-route-metric.network', 'dhcp-client-critical-connection.network']
863
864 def setUp(self):
865 self.link_remove(self.links)
866 self.stop_dnsmasq(dnsmasq_pid_file)
867
868 def tearDown(self):
869 self.link_remove(self.links)
870 self.remove_unit_from_networkd_path(self.units)
871 self.stop_dnsmasq(dnsmasq_pid_file)
872 self.remove_lease_file()
873 self.remove_log_file()
874
875 def test_dhcp_client_ipv6_only(self):
876 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv6-only.network')
877 self.start_networkd()
878
879 self.assertTrue(self.link_exits('veth99'))
880
881 self.start_dnsmasq()
882
883 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
884 print(output)
885 self.assertRegex(output, '2600::')
886 self.assertNotRegex(output, '192.168.5')
887
888 def test_dhcp_client_ipv4_only(self):
889 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network','dhcp-client-ipv4-only-ipv6-disabled.network')
890 self.start_networkd()
891
892 self.assertTrue(self.link_exits('veth99'))
893
894 self.start_dnsmasq()
895
896 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
897 print(output)
898 self.assertNotRegex(output, '2600::')
899 self.assertRegex(output, '192.168.5')
900
901 def test_dhcp_client_ipv4_ipv6(self):
902 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network',
903 'dhcp-client-ipv4-only.network')
904 self.start_networkd()
905
906 self.assertTrue(self.link_exits('veth99'))
907
908 self.start_dnsmasq()
909
910 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
911 print(output)
912 self.assertRegex(output, '2600::')
913 self.assertRegex(output, '192.168.5')
914
915 def test_dhcp_client_settings(self):
916 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv4-dhcp-settings.network')
917 self.start_networkd()
918
919 self.assertTrue(self.link_exits('veth99'))
920
921 self.start_dnsmasq()
922
923 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
924 print(output)
925 self.assertRegex(output, '12:34:56:78:9a:bc')
926 self.assertRegex(output, '192.168.5')
927 self.assertRegex(output, '1492')
928
929 output = subprocess.check_output(['ip', 'route']).rstrip().decode('utf-8')
930 print(output)
931 self.assertRegex(output, 'default.*dev veth99 proto dhcp')
932
933 self.search_words_in_file('vendor class: SusantVendorTest')
934 self.search_words_in_file('client MAC address: 12:34:56:78:9a:bc')
935 self.search_words_in_file('client provides name: test-hostname')
936 self.search_words_in_file('26:mtu')
937
938 def test_dhcp6_client_settings_rapidcommit_true(self):
939 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-only.network')
940 self.start_networkd()
941
942 self.assertTrue(self.link_exits('veth99'))
943
944 self.start_dnsmasq()
945
946 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
947 print(output)
948 self.assertRegex(output, '12:34:56:78:9a:bc')
949
950 self.assertTrue(self.search_words_in_file('14:rapid-commit'))
951
952 def test_dhcp6_client_settings_rapidcommit_false(self):
953 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-ipv6-rapid-commit.network')
954 self.start_networkd()
955
956 self.assertTrue(self.link_exits('veth99'))
957
958 self.start_dnsmasq()
959
960 output = subprocess.check_output(['ip', 'address', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
961 print(output)
962 self.assertRegex(output, '12:34:56:78:9a:bc')
963
964 self.assertFalse(self.search_words_in_file('14:rapid-commit'))
965
966 def test_dhcp_client_settings_anonymize(self):
967 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-anonymize.network')
968 self.start_networkd()
969
970 self.assertTrue(self.link_exits('veth99'))
971
972 self.start_dnsmasq()
973 self.assertFalse(self.search_words_in_file('VendorClassIdentifier=SusantVendorTest'))
974 self.assertFalse(self.search_words_in_file('test-hostname'))
975 self.assertFalse(self.search_words_in_file('26:mtu'))
976
977 def test_dhcp_client_listen_port(self):
978 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client-listen-port.network')
979 dh_server = DHCPServer("dhcp_server")
980 dh_server.start()
981
982 self.start_networkd()
983
984 self.assertTrue(self.link_exits('veth99'))
985
986 global port
987 global ip
988
989 self.assertRegex(str(port), '5555')
990 self.assertRegex(str(ip), '0.0.0.0')
991
992 dh_server.join()
993
994 def test_dhcp_route_table_id(self):
995 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-table.network')
996 self.start_networkd()
997 self.start_dnsmasq()
998
999 self.assertTrue(self.link_exits('veth99'))
1000
1001 output = subprocess.check_output(['ip', 'route', 'show', 'table', '12']).rstrip().decode('utf-8')
1002 print(output)
1003
1004 self.assertRegex(output, 'veth99 proto dhcp')
1005 self.assertRegex(output, '192.168.5.1')
1006
1007 def test_dhcp_route_metric(self):
1008 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-route-metric.network')
1009 self.start_networkd()
1010 self.start_dnsmasq()
1011
1012 self.assertTrue(self.link_exits('veth99'))
1013
1014 output = subprocess.check_output(['ip', 'route', 'show', 'dev', 'veth99']).rstrip().decode('utf-8')
1015 print(output)
1016
1017 self.assertRegex(output, 'metric 24')
1018
1019 def test_dhcp_route_criticalconnection_true(self):
1020 self.copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
1021 self.start_networkd()
1022 self.start_dnsmasq()
1023
1024 self.assertTrue(self.link_exits('veth99'))
1025
1026 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1027 print(output)
1028
1029 self.assertRegex(output, '192.168.5.*')
1030 # Stoping dnsmasq as networkd won't be allowed to renew the DHCP lease.
1031 self.stop_dnsmasq(dnsmasq_pid_file)
1032
1033 # Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
1034 time.sleep(125)
1035
1036 output = subprocess.check_output(['networkctl', 'status', 'veth99']).rstrip().decode('utf-8')
1037 print(output)
1038 self.assertRegex(output, '192.168.5.*')
1039
1040if __name__ == '__main__':
1041 unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
1042 verbosity=3))