|
|
|
@@ -38,13 +38,16 @@ which_paths = ':'.join(systemd_lib_paths + os.getenv('PATH', os.defpath).lstrip(
|
|
|
|
|
|
|
|
|
|
networkd_bin = shutil.which('systemd-networkd', path=which_paths)
|
|
|
|
|
resolved_bin = shutil.which('systemd-resolved', path=which_paths)
|
|
|
|
|
timesyncd_bin = shutil.which('systemd-timesyncd', path=which_paths)
|
|
|
|
|
udevd_bin = shutil.which('systemd-udevd', path=which_paths)
|
|
|
|
|
wait_online_bin = shutil.which('systemd-networkd-wait-online', path=which_paths)
|
|
|
|
|
networkctl_bin = shutil.which('networkctl', path=which_paths)
|
|
|
|
|
resolvectl_bin = shutil.which('resolvectl', path=which_paths)
|
|
|
|
|
timedatectl_bin = shutil.which('timedatectl', path=which_paths)
|
|
|
|
|
udevadm_bin = shutil.which('udevadm', path=which_paths)
|
|
|
|
|
|
|
|
|
|
use_valgrind = False
|
|
|
|
|
valgrind_cmd = ''
|
|
|
|
|
enable_debug = True
|
|
|
|
|
env = {}
|
|
|
|
|
wait_online_env = {}
|
|
|
|
@@ -92,24 +95,29 @@ def mkdir_p(path):
|
|
|
|
|
def touch(path):
|
|
|
|
|
pathlib.Path(path).touch()
|
|
|
|
|
|
|
|
|
|
def check_output(*command, text=True, **kwargs):
|
|
|
|
|
def check_output(*command, **kwargs):
|
|
|
|
|
# This checks the result and returns stdout (and stderr) on success.
|
|
|
|
|
command = command[0].split() + list(command[1:])
|
|
|
|
|
return subprocess.run(command, check=True, universal_newlines=text, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs).stdout.rstrip()
|
|
|
|
|
ret = subprocess.run(command, check=False, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kwargs)
|
|
|
|
|
if ret.returncode == 0:
|
|
|
|
|
return ret.stdout.rstrip()
|
|
|
|
|
# When returncode != 0, print stdout and stderr, then trigger CalledProcessError.
|
|
|
|
|
print(ret.stdout)
|
|
|
|
|
ret.check_returncode()
|
|
|
|
|
|
|
|
|
|
def call(*command, text=True, **kwargs):
|
|
|
|
|
def call(*command, **kwargs):
|
|
|
|
|
# This returns returncode. stdout and stderr are merged and shown in console
|
|
|
|
|
command = command[0].split() + list(command[1:])
|
|
|
|
|
return subprocess.run(command, check=False, universal_newlines=text, stderr=subprocess.STDOUT, **kwargs).returncode
|
|
|
|
|
return subprocess.run(command, check=False, universal_newlines=True, stderr=subprocess.STDOUT, **kwargs).returncode
|
|
|
|
|
|
|
|
|
|
def call_quiet(*command, text=True, **kwargs):
|
|
|
|
|
def call_quiet(*command, **kwargs):
|
|
|
|
|
command = command[0].split() + list(command[1:])
|
|
|
|
|
return subprocess.run(command, check=False, universal_newlines=text, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, **kwargs).returncode
|
|
|
|
|
return subprocess.run(command, check=False, universal_newlines=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, **kwargs).returncode
|
|
|
|
|
|
|
|
|
|
def run(*command, text=True, **kwargs):
|
|
|
|
|
def run(*command, **kwargs):
|
|
|
|
|
# This returns CompletedProcess instance.
|
|
|
|
|
command = command[0].split() + list(command[1:])
|
|
|
|
|
return subprocess.run(command, check=False, universal_newlines=text, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
|
|
|
|
|
return subprocess.run(command, check=False, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs)
|
|
|
|
|
|
|
|
|
|
def is_module_available(module_name):
|
|
|
|
|
lsmod_output = check_output('lsmod')
|
|
|
|
@@ -231,53 +239,8 @@ def expectedFailureIfNetdevsimWithSRIOVIsNotAvailable():
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
def expectedFailureIfCAKEIsNotAvailable():
|
|
|
|
|
def f(func):
|
|
|
|
|
call_quiet('ip link add dummy98 type dummy')
|
|
|
|
|
rc = call_quiet('tc qdisc add dev dummy98 parent root cake')
|
|
|
|
|
remove_link('dummy98')
|
|
|
|
|
return func if rc == 0 else unittest.expectedFailure(func)
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
def expectedFailureIfPIEIsNotAvailable():
|
|
|
|
|
def f(func):
|
|
|
|
|
call_quiet('ip link add dummy98 type dummy')
|
|
|
|
|
rc = call_quiet('tc qdisc add dev dummy98 parent root pie')
|
|
|
|
|
remove_link('dummy98')
|
|
|
|
|
return func if rc == 0 else unittest.expectedFailure(func)
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
def expectedFailureIfHHFIsNotAvailable():
|
|
|
|
|
def f(func):
|
|
|
|
|
call_quiet('ip link add dummy98 type dummy')
|
|
|
|
|
rc = call_quiet('tc qdisc add dev dummy98 parent root hhf')
|
|
|
|
|
remove_link('dummy98')
|
|
|
|
|
return func if rc == 0 else unittest.expectedFailure(func)
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
def expectedFailureIfETSIsNotAvailable():
|
|
|
|
|
def f(func):
|
|
|
|
|
call_quiet('ip link add dummy98 type dummy')
|
|
|
|
|
rc = call_quiet('tc qdisc add dev dummy98 parent root ets bands 10')
|
|
|
|
|
remove_link('dummy98')
|
|
|
|
|
return func if rc == 0 else unittest.expectedFailure(func)
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
def expectedFailureIfFQPIEIsNotAvailable():
|
|
|
|
|
def f(func):
|
|
|
|
|
call_quiet('ip link add dummy98 type dummy')
|
|
|
|
|
rc = call_quiet('tc qdisc add dev dummy98 parent root fq_pie')
|
|
|
|
|
remove_link('dummy98')
|
|
|
|
|
return func if rc == 0 else unittest.expectedFailure(func)
|
|
|
|
|
|
|
|
|
|
return f
|
|
|
|
|
|
|
|
|
|
def udev_reload():
|
|
|
|
|
check_output('udevadm control --reload')
|
|
|
|
|
check_output(*udevadm_cmd, 'control', '--reload')
|
|
|
|
|
|
|
|
|
|
def copy_network_unit(*units, copy_dropins=True):
|
|
|
|
|
"""
|
|
|
|
@@ -371,7 +334,7 @@ def clear_udev_rules():
|
|
|
|
|
|
|
|
|
|
def save_active_units():
|
|
|
|
|
for u in ['systemd-networkd.socket', 'systemd-networkd.service',
|
|
|
|
|
'systemd-resolved.service',
|
|
|
|
|
'systemd-resolved.service', 'systemd-timesyncd.service',
|
|
|
|
|
'firewalld.service']:
|
|
|
|
|
if call(f'systemctl is-active --quiet {u}') == 0:
|
|
|
|
|
call(f'systemctl stop {u}')
|
|
|
|
@@ -383,6 +346,46 @@ def restore_active_units():
|
|
|
|
|
for u in active_units:
|
|
|
|
|
call(f'systemctl restart {u}')
|
|
|
|
|
|
|
|
|
|
def create_service_dropin(service, command, reload_command=None, additional_settings=None):
|
|
|
|
|
drop_in = [
|
|
|
|
|
'[Service]',
|
|
|
|
|
'ExecStart=',
|
|
|
|
|
f'ExecStart=!!{valgrind_cmd}{command}',
|
|
|
|
|
]
|
|
|
|
|
if reload_command:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'ExecReload=',
|
|
|
|
|
f'ExecReload={valgrind_cmd}{reload_command}',
|
|
|
|
|
]
|
|
|
|
|
if enable_debug:
|
|
|
|
|
drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
|
|
|
|
|
if asan_options:
|
|
|
|
|
drop_in += [f'Environment=ASAN_OPTIONS="{asan_options}"']
|
|
|
|
|
if lsan_options:
|
|
|
|
|
drop_in += [f'Environment=LSAN_OPTIONS="{lsan_options}"']
|
|
|
|
|
if ubsan_options:
|
|
|
|
|
drop_in += [f'Environment=UBSAN_OPTIONS="{ubsan_options}"']
|
|
|
|
|
if asan_options or lsan_options or ubsan_options:
|
|
|
|
|
drop_in += ['SystemCallFilter=']
|
|
|
|
|
if use_valgrind or asan_options or lsan_options or ubsan_options:
|
|
|
|
|
drop_in += ['MemoryDenyWriteExecute=no']
|
|
|
|
|
if use_valgrind:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'Environment=SYSTEMD_MEMPOOL=0',
|
|
|
|
|
'PrivateTmp=yes',
|
|
|
|
|
]
|
|
|
|
|
if with_coverage:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'ProtectSystem=no',
|
|
|
|
|
'ProtectHome=no',
|
|
|
|
|
]
|
|
|
|
|
if additional_settings:
|
|
|
|
|
drop_in += additional_settings
|
|
|
|
|
|
|
|
|
|
mkdir_p(f'/run/systemd/system/{service}.service.d')
|
|
|
|
|
with open(f'/run/systemd/system/{service}.service.d/00-override.conf', mode='w', encoding='utf-8') as f:
|
|
|
|
|
f.write('\n'.join(drop_in))
|
|
|
|
|
|
|
|
|
|
def link_exists(link):
|
|
|
|
|
return os.path.exists(os.path.join('/sys/class/net', link, 'ifindex'))
|
|
|
|
|
|
|
|
|
@@ -497,14 +500,14 @@ def flush_l2tp_tunnels():
|
|
|
|
|
|
|
|
|
|
def save_timezone():
|
|
|
|
|
global saved_timezone
|
|
|
|
|
r = run('timedatectl show --value --property Timezone')
|
|
|
|
|
r = run(*timedatectl_cmd, 'show', '--value', '--property', 'Timezone', env=env)
|
|
|
|
|
if r.returncode == 0:
|
|
|
|
|
saved_timezone = r.stdout.rstrip()
|
|
|
|
|
print(f'### Saved timezone: {saved_timezone}')
|
|
|
|
|
|
|
|
|
|
def restore_timezone():
|
|
|
|
|
if saved_timezone:
|
|
|
|
|
call(f'timedatectl set-timezone {saved_timezone}')
|
|
|
|
|
call(*timedatectl_cmd, 'set-timezone', f'{saved_timezone}', env=env)
|
|
|
|
|
|
|
|
|
|
def read_link_attr(*args):
|
|
|
|
|
with open(os.path.join('/sys/class/net', *args), encoding='utf-8') as f:
|
|
|
|
@@ -657,82 +660,21 @@ def setUpModule():
|
|
|
|
|
save_routing_policy_rules()
|
|
|
|
|
save_timezone()
|
|
|
|
|
|
|
|
|
|
create_service_dropin('systemd-networkd', networkd_bin,
|
|
|
|
|
f'{networkctl_bin} reload',
|
|
|
|
|
['[Service]', 'Restart=no', '[Unit]', 'StartLimitIntervalSec=0'])
|
|
|
|
|
create_service_dropin('systemd-resolved', resolved_bin)
|
|
|
|
|
create_service_dropin('systemd-timesyncd', timesyncd_bin)
|
|
|
|
|
|
|
|
|
|
# TODO: also run udevd with sanitizers, valgrind, or coverage
|
|
|
|
|
#create_service_dropin('systemd-udevd', udevd_bin,
|
|
|
|
|
# f'{udevadm_bin} control --reload --timeout 0')
|
|
|
|
|
drop_in = [
|
|
|
|
|
'[Unit]',
|
|
|
|
|
'StartLimitIntervalSec=0',
|
|
|
|
|
'[Service]',
|
|
|
|
|
'Restart=no',
|
|
|
|
|
'ExecStart=',
|
|
|
|
|
f'ExecStart=!!{udevd_bin}',
|
|
|
|
|
'ExecReload=',
|
|
|
|
|
]
|
|
|
|
|
if use_valgrind:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'ExecStart=!!valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ' + networkd_bin,
|
|
|
|
|
f'ExecReload=valgrind {networkctl_bin} reload',
|
|
|
|
|
'PrivateTmp=yes'
|
|
|
|
|
]
|
|
|
|
|
else:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'ExecStart=!!' + networkd_bin,
|
|
|
|
|
f'ExecReload={networkctl_bin} reload',
|
|
|
|
|
]
|
|
|
|
|
if enable_debug:
|
|
|
|
|
drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
|
|
|
|
|
if asan_options:
|
|
|
|
|
drop_in += ['Environment=ASAN_OPTIONS="' + asan_options + '"']
|
|
|
|
|
if lsan_options:
|
|
|
|
|
drop_in += ['Environment=LSAN_OPTIONS="' + lsan_options + '"']
|
|
|
|
|
if ubsan_options:
|
|
|
|
|
drop_in += ['Environment=UBSAN_OPTIONS="' + ubsan_options + '"']
|
|
|
|
|
if asan_options or lsan_options or ubsan_options:
|
|
|
|
|
drop_in += ['SystemCallFilter=']
|
|
|
|
|
if use_valgrind or asan_options or lsan_options or ubsan_options:
|
|
|
|
|
drop_in += ['MemoryDenyWriteExecute=no']
|
|
|
|
|
if with_coverage:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'ProtectSystem=no',
|
|
|
|
|
'ProtectHome=no',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
mkdir_p('/run/systemd/system/systemd-networkd.service.d')
|
|
|
|
|
with open('/run/systemd/system/systemd-networkd.service.d/00-override.conf', mode='w', encoding='utf-8') as f:
|
|
|
|
|
f.write('\n'.join(drop_in))
|
|
|
|
|
|
|
|
|
|
drop_in = [
|
|
|
|
|
'[Service]',
|
|
|
|
|
'Restart=no',
|
|
|
|
|
'ExecStart=',
|
|
|
|
|
]
|
|
|
|
|
if use_valgrind:
|
|
|
|
|
drop_in += ['ExecStart=!!valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all ' + resolved_bin]
|
|
|
|
|
else:
|
|
|
|
|
drop_in += ['ExecStart=!!' + resolved_bin]
|
|
|
|
|
if enable_debug:
|
|
|
|
|
drop_in += ['Environment=SYSTEMD_LOG_LEVEL=debug']
|
|
|
|
|
if asan_options:
|
|
|
|
|
drop_in += ['Environment=ASAN_OPTIONS="' + asan_options + '"']
|
|
|
|
|
if lsan_options:
|
|
|
|
|
drop_in += ['Environment=LSAN_OPTIONS="' + lsan_options + '"']
|
|
|
|
|
if ubsan_options:
|
|
|
|
|
drop_in += ['Environment=UBSAN_OPTIONS="' + ubsan_options + '"']
|
|
|
|
|
if asan_options or lsan_options or ubsan_options:
|
|
|
|
|
drop_in += ['SystemCallFilter=']
|
|
|
|
|
if use_valgrind or asan_options or lsan_options or ubsan_options:
|
|
|
|
|
drop_in += ['MemoryDenyWriteExecute=no']
|
|
|
|
|
if with_coverage:
|
|
|
|
|
drop_in += [
|
|
|
|
|
'ProtectSystem=no',
|
|
|
|
|
'ProtectHome=no',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
mkdir_p('/run/systemd/system/systemd-resolved.service.d')
|
|
|
|
|
with open('/run/systemd/system/systemd-resolved.service.d/00-override.conf', mode='w', encoding='utf-8') as f:
|
|
|
|
|
f.write('\n'.join(drop_in))
|
|
|
|
|
|
|
|
|
|
drop_in = [
|
|
|
|
|
'[Service]',
|
|
|
|
|
'ExecStart=',
|
|
|
|
|
'ExecStart=!!' + udevd_bin,
|
|
|
|
|
f'ExecReload={udevadm_bin} control --reload --timeout 0',
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
mkdir_p('/run/systemd/system/systemd-udevd.service.d')
|
|
|
|
@@ -742,8 +684,10 @@ def setUpModule():
|
|
|
|
|
check_output('systemctl daemon-reload')
|
|
|
|
|
print(check_output('systemctl cat systemd-networkd.service'))
|
|
|
|
|
print(check_output('systemctl cat systemd-resolved.service'))
|
|
|
|
|
print(check_output('systemctl cat systemd-timesyncd.service'))
|
|
|
|
|
print(check_output('systemctl cat systemd-udevd.service'))
|
|
|
|
|
check_output('systemctl restart systemd-resolved.service')
|
|
|
|
|
check_output('systemctl restart systemd-timesyncd.service')
|
|
|
|
|
check_output('systemctl restart systemd-udevd.service')
|
|
|
|
|
|
|
|
|
|
def tearDownModule():
|
|
|
|
@@ -756,6 +700,7 @@ def tearDownModule():
|
|
|
|
|
|
|
|
|
|
rm_rf('/run/systemd/system/systemd-networkd.service.d')
|
|
|
|
|
rm_rf('/run/systemd/system/systemd-resolved.service.d')
|
|
|
|
|
rm_rf('/run/systemd/system/systemd-timesyncd.service.d')
|
|
|
|
|
rm_rf('/run/systemd/system/systemd-udevd.service.d')
|
|
|
|
|
check_output('systemctl daemon-reload')
|
|
|
|
|
check_output('systemctl restart systemd-udevd.service')
|
|
|
|
@@ -886,7 +831,7 @@ class Utilities():
|
|
|
|
|
try:
|
|
|
|
|
check_output(*args, env=wait_online_env)
|
|
|
|
|
except subprocess.CalledProcessError as e:
|
|
|
|
|
print(e.stdout) # show logs only on failure
|
|
|
|
|
# show detailed status on failure
|
|
|
|
|
for link in links_with_operstate:
|
|
|
|
|
name = link.split(':')[0]
|
|
|
|
|
if link_exists(name):
|
|
|
|
@@ -1362,24 +1307,18 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities):
|
|
|
|
|
self.assertRegex(output, 'link/ether 12:34:56:78:9a:bf')
|
|
|
|
|
self.assertRegex(output, 'mtu 1800')
|
|
|
|
|
|
|
|
|
|
def test_tun(self):
|
|
|
|
|
copy_network_unit('25-tun.netdev')
|
|
|
|
|
def test_tuntap(self):
|
|
|
|
|
copy_network_unit('25-tun.netdev', '25-tap.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
|
|
|
|
|
self.wait_online(['tun99:off'], setup_state='unmanaged')
|
|
|
|
|
self.wait_online(['testtun99:off', 'testtap99:off'], setup_state='unmanaged')
|
|
|
|
|
|
|
|
|
|
output = check_output('ip -d link show tun99')
|
|
|
|
|
output = check_output('ip -d link show testtun99')
|
|
|
|
|
print(output)
|
|
|
|
|
# Old ip command does not support IFF_ flags
|
|
|
|
|
self.assertRegex(output, 'tun (type tun pi on vnet_hdr on multi_queue|addrgenmode) ')
|
|
|
|
|
|
|
|
|
|
def test_tap(self):
|
|
|
|
|
copy_network_unit('25-tap.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
|
|
|
|
|
self.wait_online(['tap99:off'], setup_state='unmanaged')
|
|
|
|
|
|
|
|
|
|
output = check_output('ip -d link show tap99')
|
|
|
|
|
output = check_output('ip -d link show testtap99')
|
|
|
|
|
print(output)
|
|
|
|
|
# Old ip command does not support IFF_ flags
|
|
|
|
|
self.assertRegex(output, 'tun (type tap pi on vnet_hdr on multi_queue|addrgenmode) ')
|
|
|
|
@@ -3281,109 +3220,15 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertEqual(output, '')
|
|
|
|
|
|
|
|
|
|
def test_qdisc(self):
|
|
|
|
|
copy_network_unit('25-qdisc-clsact-and-htb.network', '12-dummy.netdev',
|
|
|
|
|
'25-qdisc-ingress-netem-compat.network', '11-dummy.netdev')
|
|
|
|
|
check_output('modprobe sch_teql max_equalizers=2')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable', 'test1:routable'])
|
|
|
|
|
class NetworkdTCTests(unittest.TestCase, Utilities):
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev test1')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc netem')
|
|
|
|
|
self.assertRegex(output, 'limit 100 delay 50(.0)?ms 10(.0)?ms loss 20%')
|
|
|
|
|
self.assertRegex(output, 'qdisc ingress')
|
|
|
|
|
def setUp(self):
|
|
|
|
|
setup_common()
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc clsact')
|
|
|
|
|
def tearDown(self):
|
|
|
|
|
tear_down_common()
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc htb 2: root')
|
|
|
|
|
self.assertRegex(output, r'default (0x30|30)')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc netem 30: parent 2:30')
|
|
|
|
|
self.assertRegex(output, 'limit 100 delay 50(.0)?ms 10(.0)?ms loss 20%')
|
|
|
|
|
self.assertRegex(output, 'qdisc fq_codel')
|
|
|
|
|
self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10(.0)?ms ce_threshold 100(.0)?ms interval 200(.0)?ms memory_limit 64Mb ecn')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc teql1 31: parent 2:31')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc fq 32: parent 2:32')
|
|
|
|
|
self.assertRegex(output, 'limit 1000p flow_limit 200p buckets 512 orphan_mask 511')
|
|
|
|
|
self.assertRegex(output, 'quantum 1500')
|
|
|
|
|
self.assertRegex(output, 'initial_quantum 13000')
|
|
|
|
|
self.assertRegex(output, 'maxrate 1Mbit')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc codel 33: parent 2:33')
|
|
|
|
|
self.assertRegex(output, 'limit 2000p target 10(.0)?ms ce_threshold 100(.0)?ms interval 50(.0)?ms ecn')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc fq_codel 34: parent 2:34')
|
|
|
|
|
self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10(.0)?ms ce_threshold 100(.0)?ms interval 200(.0)?ms memory_limit 64Mb ecn')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc tbf 35: parent 2:35')
|
|
|
|
|
self.assertRegex(output, 'rate 1Gbit burst 5000b peakrate 100Gbit minburst 987500b lat 70(.0)?ms')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc sfq 36: parent 2:36')
|
|
|
|
|
self.assertRegex(output, 'perturb 5sec')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc pfifo 37: parent 2:37')
|
|
|
|
|
self.assertRegex(output, 'limit 100000p')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc gred 38: parent 2:38')
|
|
|
|
|
self.assertRegex(output, 'vqs 12 default 10 grio')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc sfb 39: parent 2:39')
|
|
|
|
|
self.assertRegex(output, 'limit 200000')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc bfifo 3a: parent 2:3a')
|
|
|
|
|
self.assertRegex(output, 'limit 1000000')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc pfifo_head_drop 3b: parent 2:3b')
|
|
|
|
|
self.assertRegex(output, 'limit 1023p')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc pfifo_fast 3c: parent 2:3c')
|
|
|
|
|
|
|
|
|
|
output = check_output('tc -d class show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'class htb 2:30 root leaf 30:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:31 root leaf 31:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:32 root leaf 32:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:33 root leaf 33:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:34 root leaf 34:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:35 root leaf 35:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:36 root leaf 36:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:37 root leaf 37:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:38 root leaf 38:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:39 root leaf 39:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:3a root leaf 3a:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:3b root leaf 3b:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:3c root leaf 3c:')
|
|
|
|
|
self.assertRegex(output, 'prio 1 quantum 4000 rate 1Mbit overhead 100 ceil 500Kbit')
|
|
|
|
|
self.assertRegex(output, 'burst 123456')
|
|
|
|
|
self.assertRegex(output, 'cburst 123457')
|
|
|
|
|
|
|
|
|
|
def test_qdisc2(self):
|
|
|
|
|
copy_network_unit('25-qdisc-drr.network', '12-dummy.netdev',
|
|
|
|
|
'25-qdisc-qfq.network', '11-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable', 'test1:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc drr 2: root')
|
|
|
|
|
output = check_output('tc class show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'class drr 2:30 root quantum 2000b')
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev test1')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc qfq 2: root')
|
|
|
|
|
output = check_output('tc class show dev test1')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'class qfq 2:30 root weight 2 maxpkt 16000')
|
|
|
|
|
self.assertRegex(output, 'class qfq 2:31 root weight 10 maxpkt 8000')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfCAKEIsNotAvailable()
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_cake')
|
|
|
|
|
def test_qdisc_cake(self):
|
|
|
|
|
copy_network_unit('25-qdisc-cake.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
@@ -3405,29 +3250,31 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|
|
|
|
self.assertIn('mpu 20', output)
|
|
|
|
|
self.assertIn('fwmark 0xff00', output)
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfPIEIsNotAvailable()
|
|
|
|
|
def test_qdisc_pie(self):
|
|
|
|
|
copy_network_unit('25-qdisc-pie.network', '12-dummy.netdev')
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_codel')
|
|
|
|
|
def test_qdisc_codel(self):
|
|
|
|
|
copy_network_unit('25-qdisc-codel.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc pie 3a: root')
|
|
|
|
|
self.assertRegex(output, 'limit 200000')
|
|
|
|
|
self.assertRegex(output, 'qdisc codel 33: root')
|
|
|
|
|
self.assertRegex(output, 'limit 2000p target 10(.0)?ms ce_threshold 100(.0)?ms interval 50(.0)?ms ecn')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfHHFIsNotAvailable()
|
|
|
|
|
def test_qdisc_hhf(self):
|
|
|
|
|
copy_network_unit('25-qdisc-hhf.network', '12-dummy.netdev')
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_drr')
|
|
|
|
|
def test_qdisc_drr(self):
|
|
|
|
|
copy_network_unit('25-qdisc-drr.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc hhf 3a: root')
|
|
|
|
|
self.assertRegex(output, 'limit 1022p')
|
|
|
|
|
self.assertRegex(output, 'qdisc drr 2: root')
|
|
|
|
|
output = check_output('tc class show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'class drr 2:30 root quantum 2000b')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfETSIsNotAvailable()
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_ets')
|
|
|
|
|
def test_qdisc_ets(self):
|
|
|
|
|
copy_network_unit('25-qdisc-ets.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
@@ -3441,7 +3288,32 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|
|
|
|
self.assertRegex(output, 'quanta 1 2 3 4 5')
|
|
|
|
|
self.assertRegex(output, 'priomap 3 4 5 6 7')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfFQPIEIsNotAvailable()
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_fq')
|
|
|
|
|
def test_qdisc_fq(self):
|
|
|
|
|
copy_network_unit('25-qdisc-fq.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc fq 32: root')
|
|
|
|
|
self.assertRegex(output, 'limit 1000p flow_limit 200p buckets 512 orphan_mask 511')
|
|
|
|
|
self.assertRegex(output, 'quantum 1500')
|
|
|
|
|
self.assertRegex(output, 'initial_quantum 13000')
|
|
|
|
|
self.assertRegex(output, 'maxrate 1Mbit')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_fq_codel')
|
|
|
|
|
def test_qdisc_fq_codel(self):
|
|
|
|
|
copy_network_unit('25-qdisc-fq_codel.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc fq_codel 34: root')
|
|
|
|
|
self.assertRegex(output, 'limit 20480p flows 2048 quantum 1400 target 10(.0)?ms ce_threshold 100(.0)?ms interval 200(.0)?ms memory_limit 64Mb ecn')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_fq_pie')
|
|
|
|
|
def test_qdisc_fq_pie(self):
|
|
|
|
|
copy_network_unit('25-qdisc-fq_pie.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
@@ -3453,6 +3325,172 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
|
|
|
|
self.assertRegex(output, 'qdisc fq_pie 3a: root')
|
|
|
|
|
self.assertRegex(output, 'limit 200000p')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_gred')
|
|
|
|
|
def test_qdisc_gred(self):
|
|
|
|
|
copy_network_unit('25-qdisc-gred.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc gred 38: root')
|
|
|
|
|
self.assertRegex(output, 'vqs 12 default 10 grio')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_hhf')
|
|
|
|
|
def test_qdisc_hhf(self):
|
|
|
|
|
copy_network_unit('25-qdisc-hhf.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc hhf 3a: root')
|
|
|
|
|
self.assertRegex(output, 'limit 1022p')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_htb')
|
|
|
|
|
def test_qdisc_htb_fifo(self):
|
|
|
|
|
copy_network_unit('25-qdisc-htb-fifo.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc htb 2: root')
|
|
|
|
|
self.assertRegex(output, r'default (0x30|30)')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc pfifo 37: parent 2:37')
|
|
|
|
|
self.assertRegex(output, 'limit 100000p')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc bfifo 3a: parent 2:3a')
|
|
|
|
|
self.assertRegex(output, 'limit 1000000')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc pfifo_head_drop 3b: parent 2:3b')
|
|
|
|
|
self.assertRegex(output, 'limit 1023p')
|
|
|
|
|
|
|
|
|
|
self.assertRegex(output, 'qdisc pfifo_fast 3c: parent 2:3c')
|
|
|
|
|
|
|
|
|
|
output = check_output('tc -d class show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'class htb 2:37 root leaf 37:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:3a root leaf 3a:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:3b root leaf 3b:')
|
|
|
|
|
self.assertRegex(output, 'class htb 2:3c root leaf 3c:')
|
|
|
|
|
self.assertRegex(output, 'prio 1 quantum 4000 rate 1Mbit overhead 100 ceil 500Kbit')
|
|
|
|
|
self.assertRegex(output, 'burst 123456')
|
|
|
|
|
self.assertRegex(output, 'cburst 123457')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_ingress')
|
|
|
|
|
def test_qdisc_ingress(self):
|
|
|
|
|
copy_network_unit('25-qdisc-clsact.network', '12-dummy.netdev',
|
|
|
|
|
'25-qdisc-ingress.network', '11-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable', 'test1:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc clsact')
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev test1')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc ingress')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_netem')
|
|
|
|
|
def test_qdisc_netem(self):
|
|
|
|
|
copy_network_unit('25-qdisc-netem.network', '12-dummy.netdev',
|
|
|
|
|
'25-qdisc-netem-compat.network', '11-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable', 'test1:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc netem 30: root')
|
|
|
|
|
self.assertRegex(output, 'limit 100 delay 50(.0)?ms 10(.0)?ms loss 20%')
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev test1')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc netem [0-9a-f]*: root')
|
|
|
|
|
self.assertRegex(output, 'limit 100 delay 50(.0)?ms 10(.0)?ms loss 20%')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_pie')
|
|
|
|
|
def test_qdisc_pie(self):
|
|
|
|
|
copy_network_unit('25-qdisc-pie.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc pie 3a: root')
|
|
|
|
|
self.assertRegex(output, 'limit 200000')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_qfq')
|
|
|
|
|
def test_qdisc_qfq(self):
|
|
|
|
|
copy_network_unit('25-qdisc-qfq.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc qfq 2: root')
|
|
|
|
|
output = check_output('tc class show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'class qfq 2:30 root weight 2 maxpkt 16000')
|
|
|
|
|
self.assertRegex(output, 'class qfq 2:31 root weight 10 maxpkt 8000')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_sfb')
|
|
|
|
|
def test_qdisc_sfb(self):
|
|
|
|
|
copy_network_unit('25-qdisc-sfb.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc sfb 39: root')
|
|
|
|
|
self.assertRegex(output, 'limit 200000')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_sfq')
|
|
|
|
|
def test_qdisc_sfq(self):
|
|
|
|
|
copy_network_unit('25-qdisc-sfq.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc sfq 36: root')
|
|
|
|
|
self.assertRegex(output, 'perturb 5sec')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_tbf')
|
|
|
|
|
def test_qdisc_tbf(self):
|
|
|
|
|
copy_network_unit('25-qdisc-tbf.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc tbf 35: root')
|
|
|
|
|
self.assertRegex(output, 'rate 1Gbit burst 5000b peakrate 100Gbit minburst 987500b lat 70(.0)?ms')
|
|
|
|
|
|
|
|
|
|
@expectedFailureIfModuleIsNotAvailable('sch_teql')
|
|
|
|
|
def test_qdisc_teql(self):
|
|
|
|
|
call_quiet('rmmod sch_teql')
|
|
|
|
|
|
|
|
|
|
copy_network_unit('25-qdisc-teql.network', '12-dummy.netdev')
|
|
|
|
|
start_networkd()
|
|
|
|
|
self.wait_links('dummy98')
|
|
|
|
|
check_output('modprobe sch_teql max_equalizers=2')
|
|
|
|
|
self.wait_online(['dummy98:routable'])
|
|
|
|
|
|
|
|
|
|
output = check_output('tc qdisc show dev dummy98')
|
|
|
|
|
print(output)
|
|
|
|
|
self.assertRegex(output, 'qdisc teql1 31: root')
|
|
|
|
|
|
|
|
|
|
class NetworkWaitOnlineTests(unittest.TestCase, Utilities):
|
|
|
|
|
|
|
|
|
|
def setUp(self):
|
|
|
|
|
setup_common()
|
|
|
|
|
|
|
|
|
|
def tearDown(self):
|
|
|
|
|
tear_down_common()
|
|
|
|
|
|
|
|
|
|
def test_wait_online_ipv4(self):
|
|
|
|
|
copy_network_unit('25-veth.netdev', '25-dhcp-server-with-ipv6-prefix.network', '25-dhcp-client-ipv4-ipv6ra-prefix-client-with-delay.network')
|
|
|
|
|
start_networkd()
|
|
|
|
@@ -3952,7 +3990,7 @@ class NetworkdSRIOVTests(unittest.TestCase, Utilities):
|
|
|
|
|
f.write('[Link]\nSR-IOVVirtualFunctions=4\n')
|
|
|
|
|
|
|
|
|
|
udev_reload()
|
|
|
|
|
call('udevadm trigger --action add --settle /sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
call(*udevadm_cmd, 'trigger', '--action=add', '--settle', '/sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
|
|
|
|
|
output = check_output('ip link show dev eni99np1')
|
|
|
|
|
print(output)
|
|
|
|
@@ -3968,7 +4006,7 @@ class NetworkdSRIOVTests(unittest.TestCase, Utilities):
|
|
|
|
|
f.write('[Link]\nSR-IOVVirtualFunctions=\n')
|
|
|
|
|
|
|
|
|
|
udev_reload()
|
|
|
|
|
call('udevadm trigger --action add --settle /sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
call(*udevadm_cmd, 'trigger', '--action=add', '--settle', '/sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
|
|
|
|
|
output = check_output('ip link show dev eni99np1')
|
|
|
|
|
print(output)
|
|
|
|
@@ -3984,7 +4022,7 @@ class NetworkdSRIOVTests(unittest.TestCase, Utilities):
|
|
|
|
|
f.write('[Link]\nSR-IOVVirtualFunctions=2\n')
|
|
|
|
|
|
|
|
|
|
udev_reload()
|
|
|
|
|
call('udevadm trigger --action add --settle /sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
call(*udevadm_cmd, 'trigger', '--action=add', '--settle', '/sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
|
|
|
|
|
output = check_output('ip link show dev eni99np1')
|
|
|
|
|
print(output)
|
|
|
|
@@ -4000,7 +4038,7 @@ class NetworkdSRIOVTests(unittest.TestCase, Utilities):
|
|
|
|
|
f.write('[Link]\nSR-IOVVirtualFunctions=\n')
|
|
|
|
|
|
|
|
|
|
udev_reload()
|
|
|
|
|
call('udevadm trigger --action add --settle /sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
call(*udevadm_cmd, 'trigger', '--action=add', '--settle', '/sys/devices/netdevsim99/net/eni99np1')
|
|
|
|
|
|
|
|
|
|
output = check_output('ip link show dev eni99np1')
|
|
|
|
|
print(output)
|
|
|
|
@@ -5307,11 +5345,13 @@ if __name__ == '__main__':
|
|
|
|
|
parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
|
|
|
|
|
parser.add_argument('--networkd', help='Path to systemd-networkd', dest='networkd_bin')
|
|
|
|
|
parser.add_argument('--resolved', help='Path to systemd-resolved', dest='resolved_bin')
|
|
|
|
|
parser.add_argument('--timesyncd', help='Path to systemd-timesyncd', dest='timesyncd_bin')
|
|
|
|
|
parser.add_argument('--udevd', help='Path to systemd-udevd', dest='udevd_bin')
|
|
|
|
|
parser.add_argument('--wait-online', help='Path to systemd-networkd-wait-online', dest='wait_online_bin')
|
|
|
|
|
parser.add_argument('--networkctl', help='Path to networkctl', dest='networkctl_bin')
|
|
|
|
|
parser.add_argument('--resolvectl', help='Path to resolvectl', dest='resolvectl_bin')
|
|
|
|
|
parser.add_argument('--timedatectl', help='Path to timedatectl', dest='timedatectl_bin')
|
|
|
|
|
parser.add_argument('--udevadm', help='Path to udevadm', dest='udevadm_bin')
|
|
|
|
|
parser.add_argument('--valgrind', help='Enable valgrind', dest='use_valgrind', type=bool, nargs='?', const=True, default=use_valgrind)
|
|
|
|
|
parser.add_argument('--debug', help='Generate debugging logs', dest='enable_debug', type=bool, nargs='?', const=True, default=enable_debug)
|
|
|
|
|
parser.add_argument('--asan-options', help='ASAN options', dest='asan_options')
|
|
|
|
@@ -5321,20 +5361,25 @@ if __name__ == '__main__':
|
|
|
|
|
ns, unknown_args = parser.parse_known_args(namespace=unittest)
|
|
|
|
|
|
|
|
|
|
if ns.build_dir:
|
|
|
|
|
if ns.networkd_bin or ns.resolved_bin or ns.udevd_bin or ns.wait_online_bin or ns.networkctl_bin or ns.resolvectl_bin or ns.timedatectl_bin:
|
|
|
|
|
print('WARNING: --networkd, --resolved, --wait-online, --networkctl, --resolvectl, or --timedatectl options are ignored when --build-dir is specified.')
|
|
|
|
|
if ns.networkd_bin or ns.resolved_bin or ns.timesyncd_bin or ns.udevd_bin or \
|
|
|
|
|
ns.wait_online_bin or ns.networkctl_bin or ns.resolvectl_bin or ns.timedatectl_bin or ns.udevadm_bin:
|
|
|
|
|
print('WARNING: --networkd, --resolved, --timesyncd, --udevd, --wait-online, --networkctl, --resolvectl, --timedatectl, or --udevadm options are ignored when --build-dir is specified.')
|
|
|
|
|
networkd_bin = os.path.join(ns.build_dir, 'systemd-networkd')
|
|
|
|
|
resolved_bin = os.path.join(ns.build_dir, 'systemd-resolved')
|
|
|
|
|
timesyncd_bin = os.path.join(ns.build_dir, 'systemd-timesyncd')
|
|
|
|
|
udevd_bin = os.path.join(ns.build_dir, 'systemd-udevd')
|
|
|
|
|
wait_online_bin = os.path.join(ns.build_dir, 'systemd-networkd-wait-online')
|
|
|
|
|
networkctl_bin = os.path.join(ns.build_dir, 'networkctl')
|
|
|
|
|
resolvectl_bin = os.path.join(ns.build_dir, 'resolvectl')
|
|
|
|
|
timedatectl_bin = os.path.join(ns.build_dir, 'timedatectl')
|
|
|
|
|
udevadm_bin = os.path.join(ns.build_dir, 'udevadm')
|
|
|
|
|
else:
|
|
|
|
|
if ns.networkd_bin:
|
|
|
|
|
networkd_bin = ns.networkd_bin
|
|
|
|
|
if ns.resolved_bin:
|
|
|
|
|
resolved_bin = ns.resolved_bin
|
|
|
|
|
if ns.timesyncd_bin:
|
|
|
|
|
timesyncd_bin = ns.timesyncd_bin
|
|
|
|
|
if ns.udevd_bin:
|
|
|
|
|
udevd_bin = ns.udevd_bin
|
|
|
|
|
if ns.wait_online_bin:
|
|
|
|
@@ -5345,6 +5390,8 @@ if __name__ == '__main__':
|
|
|
|
|
resolvectl_bin = ns.resolvectl_bin
|
|
|
|
|
if ns.timedatectl_bin:
|
|
|
|
|
timedatectl_bin = ns.timedatectl_bin
|
|
|
|
|
if ns.udevadm_bin:
|
|
|
|
|
udevadm_bin = ns.udevadm_bin
|
|
|
|
|
|
|
|
|
|
use_valgrind = ns.use_valgrind
|
|
|
|
|
enable_debug = ns.enable_debug
|
|
|
|
@@ -5354,15 +5401,14 @@ if __name__ == '__main__':
|
|
|
|
|
with_coverage = ns.with_coverage
|
|
|
|
|
|
|
|
|
|
if use_valgrind:
|
|
|
|
|
networkctl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', networkctl_bin]
|
|
|
|
|
resolvectl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', resolvectl_bin]
|
|
|
|
|
timedatectl_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', timedatectl_bin]
|
|
|
|
|
wait_online_cmd = ['valgrind', '--track-origins=yes', '--leak-check=full', '--show-leak-kinds=all', wait_online_bin]
|
|
|
|
|
else:
|
|
|
|
|
networkctl_cmd = [networkctl_bin]
|
|
|
|
|
resolvectl_cmd = [resolvectl_bin]
|
|
|
|
|
timedatectl_cmd = [timedatectl_bin]
|
|
|
|
|
wait_online_cmd = [wait_online_bin]
|
|
|
|
|
# Do not forget the trailing space.
|
|
|
|
|
valgrind_cmd = 'valgrind --track-origins=yes --leak-check=full --show-leak-kinds=all '
|
|
|
|
|
|
|
|
|
|
networkctl_cmd = valgrind_cmd.split() + [networkctl_bin]
|
|
|
|
|
resolvectl_cmd = valgrind_cmd.split() + [resolvectl_bin]
|
|
|
|
|
timedatectl_cmd = valgrind_cmd.split() + [timedatectl_bin]
|
|
|
|
|
udevadm_cmd = valgrind_cmd.split() + [udevadm_bin]
|
|
|
|
|
wait_online_cmd = valgrind_cmd.split() + [wait_online_bin]
|
|
|
|
|
|
|
|
|
|
if asan_options:
|
|
|
|
|
env.update({'ASAN_OPTIONS': asan_options})
|
|
|
|
@@ -5370,6 +5416,8 @@ if __name__ == '__main__':
|
|
|
|
|
env.update({'LSAN_OPTIONS': lsan_options})
|
|
|
|
|
if ubsan_options:
|
|
|
|
|
env.update({'UBSAN_OPTIONS': ubsan_options})
|
|
|
|
|
if use_valgrind:
|
|
|
|
|
env.update({'SYSTEMD_MEMPOOL': '0'})
|
|
|
|
|
|
|
|
|
|
wait_online_env = env.copy()
|
|
|
|
|
if enable_debug:
|
|
|
|
|