test: add a mock ModemManager for basic coverage of sd-networkd's integration
Just the minimal setup and test case required to cover https://github.com/systemd/systemd/issues/41389 for now, can be expanded in the future Boring boilerplate is bot-made, don't @ me Co-developed-by: Claude Opus 4.6 noreply@anthropic.com
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=dummy98
|
||||
|
||||
[Network]
|
||||
LLDP=no
|
||||
LinkLocalAddressing=no
|
||||
IPv6AcceptRA=no
|
||||
|
||||
[MobileNetwork]
|
||||
APN=internet.test
|
||||
IPFamily=both
|
||||
@@ -0,0 +1,13 @@
|
||||
<!DOCTYPE busconfig PUBLIC
|
||||
"-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
|
||||
"http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
|
||||
<busconfig>
|
||||
<!-- Allow root to own and interact with the mock ModemManager service -->
|
||||
<policy user="root">
|
||||
<allow own="org.freedesktop.ModemManager1"/>
|
||||
<allow send_destination="org.freedesktop.ModemManager1"/>
|
||||
</policy>
|
||||
<policy context="default">
|
||||
<allow send_destination="org.freedesktop.ModemManager1"/>
|
||||
</policy>
|
||||
</busconfig>
|
||||
@@ -73,6 +73,7 @@ resolvectl_bin = shutil.which('resolvectl', path=which_paths)
|
||||
timedatectl_bin = shutil.which('timedatectl', path=which_paths)
|
||||
udevadm_bin = shutil.which('udevadm', path=which_paths)
|
||||
test_ndisc_send = None
|
||||
test_modem_manager_mock = None
|
||||
build_dir = None
|
||||
source_dir = None
|
||||
|
||||
@@ -973,6 +974,28 @@ def start_radvd(*additional_options, config_file):
|
||||
def stop_radvd():
|
||||
stop_by_pid_file(radvd_pid_file)
|
||||
|
||||
def start_modem_manager_mock(*additional_options):
|
||||
dbus_policy_src = os.path.join(networkd_ci_temp_dir, 'mock-modem-manager.conf')
|
||||
cp(dbus_policy_src, '/etc/dbus-1/system.d/mock-modem-manager.conf')
|
||||
check_output('systemctl reload dbus.service')
|
||||
|
||||
command = ' '.join([test_modem_manager_mock] + list(additional_options))
|
||||
with open('/run/systemd/system/test-modem-manager-mock.service', mode='w', encoding='utf-8') as f:
|
||||
f.write('[Unit]\n'
|
||||
'Description=Mock ModemManager for networkd testing\n'
|
||||
'[Service]\n'
|
||||
'Type=notify\n'
|
||||
'BusName=org.freedesktop.ModemManager1\n'
|
||||
f'ExecStart={command}\n')
|
||||
check_output('systemctl daemon-reload')
|
||||
check_output('systemctl start test-modem-manager-mock.service')
|
||||
|
||||
def stop_modem_manager_mock():
|
||||
call('systemctl stop test-modem-manager-mock.service')
|
||||
rm_f('/run/systemd/system/test-modem-manager-mock.service')
|
||||
call('systemctl daemon-reload')
|
||||
rm_f('/etc/dbus-1/system.d/mock-modem-manager.conf')
|
||||
|
||||
def radvd_check_config(config_file):
|
||||
if not shutil.which('radvd'):
|
||||
print('radvd is not installed, assuming the config check failed')
|
||||
@@ -1099,6 +1122,7 @@ def tear_down_common():
|
||||
stop_dnsmasq()
|
||||
stop_isc_dhcpd()
|
||||
stop_radvd()
|
||||
stop_modem_manager_mock()
|
||||
|
||||
# 2. remove modules
|
||||
call_quiet('rmmod netdevsim')
|
||||
@@ -9567,6 +9591,54 @@ class NetworkdSysctlTest(unittest.TestCase, Utilities):
|
||||
self.assertNotIn("changed sysctl '/proc/sys/net/ipv6/conf/dummy98/max_addresses'", log)
|
||||
self.assertNotIn("Sysctl monitor BPF returned error", log)
|
||||
|
||||
class NetworkdWWANTests(unittest.TestCase, Utilities):
|
||||
|
||||
def setUp(self):
|
||||
setup_common()
|
||||
|
||||
def tearDown(self):
|
||||
tear_down_common()
|
||||
|
||||
def test_wwan_ipv4v6_static(self):
|
||||
"""Test WWAN bearer with both IPv4 and IPv6 static configuration.
|
||||
|
||||
Regression test for https://github.com/systemd/systemd/issues/41389
|
||||
"""
|
||||
if not os.path.exists(test_modem_manager_mock):
|
||||
self.skipTest(f'{test_modem_manager_mock} does not exist.')
|
||||
|
||||
copy_network_unit('12-dummy.netdev', '25-wwan-ipv4v6.network')
|
||||
try:
|
||||
start_modem_manager_mock(
|
||||
'--ifname', 'dummy98',
|
||||
'--ipv4-address', '100.120.244.160',
|
||||
'--ipv4-gateway', '100.120.244.161',
|
||||
'--ipv4-prefix', '26',
|
||||
'--ipv6-address', '2001:db8::1',
|
||||
'--ipv6-gateway', '2001:db8::2',
|
||||
'--ipv6-prefix', '64',
|
||||
)
|
||||
except (subprocess.CalledProcessError, PermissionError, OSError) as e:
|
||||
self.skipTest(f'Failed to start mock ModemManager: {e}')
|
||||
start_networkd()
|
||||
self.wait_online('dummy98:routable')
|
||||
|
||||
output = check_output('ip -4 address show dev dummy98')
|
||||
print(output)
|
||||
self.assertIn('100.120.244.160/26', output)
|
||||
|
||||
output = check_output('ip -6 address show dev dummy98')
|
||||
print(output)
|
||||
self.assertIn('2001:db8::1/64', output)
|
||||
|
||||
output = check_output('ip -4 route show dev dummy98')
|
||||
print(output)
|
||||
self.assertIn('default via 100.120.244.161', output)
|
||||
|
||||
output = check_output('ip -6 route show dev dummy98')
|
||||
print(output)
|
||||
self.assertIn('default via 2001:db8::2', output)
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('--build-dir', help='Path to build dir', dest='build_dir')
|
||||
@@ -9626,6 +9698,11 @@ if __name__ == '__main__':
|
||||
else:
|
||||
test_ndisc_send = '/usr/lib/tests/test-ndisc-send'
|
||||
|
||||
if build_dir:
|
||||
test_modem_manager_mock = os.path.normpath(os.path.join(build_dir, 'test-modem-manager-mock'))
|
||||
else:
|
||||
test_modem_manager_mock = '/usr/lib/systemd/tests/unit-tests/manual/test-modem-manager-mock'
|
||||
|
||||
if asan_options:
|
||||
env.update({'ASAN_OPTIONS': asan_options})
|
||||
if lsan_options:
|
||||
|
||||
Reference in New Issue
Block a user