2015-11-17 20:30:50 +03:00
#!/usr/bin/env python3
#
# networkd integration test
# This uses temporary configuration in /run and temporary veth devices, and
# does not write anything on disk or change any system configuration;
# but it assumes (and checks at the beginning) that networkd is not currently
# running.
2016-04-26 13:16:43 +03:00
#
# This can be run on a normal installation, in QEMU, nspawn (with
# --private-network), LXD (with "--config raw.lxc=lxc.aa_profile=unconfined"),
# or LXC system containers. You need at least the "ip" tool from the iproute
# package; it is recommended to install dnsmasq too to get full test coverage.
#
2015-11-17 20:30:50 +03:00
# ATTENTION: This uses the *installed* networkd, not the one from the built
# source tree.
#
# (C) 2015 Canonical Ltd.
# Author: Martin Pitt <martin.pitt@ubuntu.com>
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
# systemd is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with systemd; If not, see <http://www.gnu.org/licenses/>.
import os
import sys
import time
import unittest
import tempfile
import subprocess
import shutil
networkd_active = subprocess . call ( [ ' systemctl ' , ' is-active ' , ' --quiet ' ,
' systemd-networkd ' ] ) == 0
have_dnsmasq = shutil . which ( ' dnsmasq ' )
2016-06-30 16:44:22 +03:00
RESOLV_CONF = ' /run/systemd/resolve/resolv.conf '
2015-11-17 20:30:50 +03:00
@unittest.skipIf ( networkd_active ,
' networkd is already active ' )
class ClientTestBase :
def setUp ( self ) :
self . iface = ' test_eth42 '
self . if_router = ' router_eth42 '
self . workdir_obj = tempfile . TemporaryDirectory ( )
self . workdir = self . workdir_obj . name
self . config = ' /run/systemd/network/test_eth42.network '
# avoid "Failed to open /dev/tty" errors in containers
os . environ [ ' SYSTEMD_LOG_TARGET ' ] = ' journal '
# determine path to systemd-networkd-wait-online
for p in [ ' /usr/lib/systemd/systemd-networkd-wait-online ' ,
' /lib/systemd/systemd-networkd-wait-online ' ] :
if os . path . exists ( p ) :
self . networkd_wait_online = p
break
else :
self . fail ( ' systemd-networkd-wait-online not found ' )
# get current journal cursor
out = subprocess . check_output ( [ ' journalctl ' , ' -b ' , ' --quiet ' ,
' --no-pager ' , ' -n0 ' , ' --show-cursor ' ] ,
universal_newlines = True )
self . assertTrue ( out . startswith ( ' -- cursor: ' ) )
self . journal_cursor = out . split ( ) [ - 1 ]
def tearDown ( self ) :
self . shutdown_iface ( )
subprocess . call ( [ ' systemctl ' , ' stop ' , ' systemd-networkd ' ] )
2016-09-14 13:52:40 +03:00
def writeConfig ( self , fname , contents ) :
os . makedirs ( os . path . dirname ( fname ) , exist_ok = True )
with open ( fname , ' w ' ) as f :
f . write ( contents )
self . addCleanup ( os . remove , fname )
2015-11-17 20:30:50 +03:00
def show_journal ( self , unit ) :
''' Show journal of given unit since start of the test '''
print ( ' ---- %s ---- ' % unit )
sys . stdout . flush ( )
subprocess . call ( [ ' journalctl ' , ' -b ' , ' --no-pager ' , ' --quiet ' ,
' --cursor ' , self . journal_cursor , ' -u ' , unit ] )
def create_iface ( self , ipv6 = False ) :
''' Create test interface with DHCP server behind it '''
raise NotImplementedError ( ' must be implemented by a subclass ' )
def shutdown_iface ( self ) :
''' Remove test interface and stop DHCP server '''
raise NotImplementedError ( ' must be implemented by a subclass ' )
def print_server_log ( self ) :
''' Print DHCP server log for debugging failures '''
raise NotImplementedError ( ' must be implemented by a subclass ' )
def do_test ( self , coldplug = True , ipv6 = False , extra_opts = ' ' ,
online_timeout = 10 , dhcp_mode = ' yes ' ) :
2016-06-30 16:44:22 +03:00
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-resolved ' ] )
2016-09-14 13:52:40 +03:00
self . writeConfig ( self . config , ''' \
[ Match ]
2015-11-17 20:30:50 +03:00
Name = % s
[ Network ]
DHCP = % s
% s ''' % (self.iface, dhcp_mode, extra_opts))
if coldplug :
# create interface first, then start networkd
self . create_iface ( ipv6 = ipv6 )
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-networkd ' ] )
else :
# start networkd first, then create interface
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-networkd ' ] )
self . create_iface ( ipv6 = ipv6 )
try :
subprocess . check_call ( [ self . networkd_wait_online , ' --interface ' ,
self . iface , ' --timeout= %i ' % online_timeout ] )
if ipv6 :
# check iface state and IP 6 address; FIXME: we need to wait a bit
# longer, as the iface is "configured" already with IPv4 *or*
# IPv6, but we want to wait for both
for timeout in range ( 10 ) :
out = subprocess . check_output ( [ ' ip ' , ' a ' , ' show ' , ' dev ' , self . iface ] )
if b ' state UP ' in out and b ' inet6 2600 ' in out and b ' inet 192.168 ' in out :
break
time . sleep ( 1 )
else :
self . fail ( ' timed out waiting for IPv6 configuration ' )
self . assertRegex ( out , b ' inet6 2600::.* scope global .*dynamic ' )
self . assertRegex ( out , b ' inet6 fe80::.* scope link ' )
else :
# should have link-local address on IPv6 only
out = subprocess . check_output ( [ ' ip ' , ' -6 ' , ' a ' , ' show ' , ' dev ' , self . iface ] )
self . assertRegex ( out , b ' inet6 fe80::.* scope link ' )
self . assertNotIn ( b ' scope global ' , out )
# should have IPv4 address
out = subprocess . check_output ( [ ' ip ' , ' -4 ' , ' a ' , ' show ' , ' dev ' , self . iface ] )
self . assertIn ( b ' state UP ' , out )
self . assertRegex ( out , b ' inet 192.168.5. \ d+/.* scope global dynamic ' )
# check networkctl state
out = subprocess . check_output ( [ ' networkctl ' ] )
self . assertRegex ( out , ( ' %s \ s+ether \ s+routable \ s+unmanaged ' % self . if_router ) . encode ( ) )
self . assertRegex ( out , ( ' %s \ s+ether \ s+routable \ s+configured ' % self . iface ) . encode ( ) )
out = subprocess . check_output ( [ ' networkctl ' , ' status ' , self . iface ] )
self . assertRegex ( out , b ' Type: \ s+ether ' )
self . assertRegex ( out , b ' State: \ s+routable.*configured ' )
self . assertRegex ( out , b ' Address: \ s+192.168.5. \ d+ ' )
if ipv6 :
self . assertRegex ( out , b ' 2600:: ' )
else :
self . assertNotIn ( b ' 2600:: ' , out )
self . assertRegex ( out , b ' fe80:: ' )
self . assertRegex ( out , b ' Gateway: \ s+192.168.5.1 ' )
self . assertRegex ( out , b ' DNS: \ s+192.168.5.1 ' )
except ( AssertionError , subprocess . CalledProcessError ) :
# show networkd status, journal, and DHCP server log on failure
with open ( self . config ) as f :
print ( ' \n ---- %s ---- \n %s ' % ( self . config , f . read ( ) ) )
print ( ' ---- interface status ---- ' )
sys . stdout . flush ( )
subprocess . call ( [ ' ip ' , ' a ' , ' show ' , ' dev ' , self . iface ] )
print ( ' ---- networkctl status %s ---- ' % self . iface )
sys . stdout . flush ( )
subprocess . call ( [ ' networkctl ' , ' status ' , self . iface ] )
self . show_journal ( ' systemd-networkd.service ' )
self . print_server_log ( )
raise
2016-06-30 16:44:22 +03:00
for timeout in range ( 50 ) :
with open ( RESOLV_CONF ) as f :
contents = f . read ( )
if ' nameserver 192.168.5.1 \n ' in contents :
break
time . sleep ( 0.1 )
else :
self . fail ( ' nameserver 192.168.5.1 not found in ' + RESOLV_CONF )
2015-11-17 20:30:50 +03:00
if not coldplug :
# check post-down.d hook
self . shutdown_iface ( )
def test_coldplug_dhcp_yes_ip4 ( self ) :
# we have a 12s timeout on RA, so we need to wait longer
self . do_test ( coldplug = True , ipv6 = False , online_timeout = 15 )
def test_coldplug_dhcp_yes_ip4_no_ra ( self ) :
# with disabling RA explicitly things should be fast
self . do_test ( coldplug = True , ipv6 = False ,
2016-06-07 12:19:26 +03:00
extra_opts = ' IPv6AcceptRA=False ' )
2015-11-17 20:30:50 +03:00
def test_coldplug_dhcp_ip4_only ( self ) :
# we have a 12s timeout on RA, so we need to wait longer
self . do_test ( coldplug = True , ipv6 = False , dhcp_mode = ' ipv4 ' ,
online_timeout = 15 )
def test_coldplug_dhcp_ip4_only_no_ra ( self ) :
# with disabling RA explicitly things should be fast
self . do_test ( coldplug = True , ipv6 = False , dhcp_mode = ' ipv4 ' ,
2016-06-07 12:19:26 +03:00
extra_opts = ' IPv6AcceptRA=False ' )
2015-11-17 20:30:50 +03:00
def test_coldplug_dhcp_ip6 ( self ) :
self . do_test ( coldplug = True , ipv6 = True )
def test_hotplug_dhcp_ip4 ( self ) :
# With IPv4 only we have a 12s timeout on RA, so we need to wait longer
self . do_test ( coldplug = False , ipv6 = False , online_timeout = 15 )
def test_hotplug_dhcp_ip6 ( self ) :
self . do_test ( coldplug = False , ipv6 = True )
2016-06-28 19:18:27 +03:00
def test_route_only_dns ( self ) :
2016-09-14 13:52:40 +03:00
self . writeConfig ( ' /run/systemd/network/myvpn.netdev ' , ''' \
[ NetDev ]
2016-06-28 19:18:27 +03:00
Name = dummy0
Kind = dummy
MACAddress = 12 : 34 : 56 : 78 : 9 a : bc ''' )
2016-09-14 13:52:40 +03:00
self . writeConfig ( ' /run/systemd/network/myvpn.network ' , ''' \
[ Match ]
2016-06-28 19:18:27 +03:00
Name = dummy0
[ Network ]
Address = 192.168 .42 .100
DNS = 192.168 .42 .1
Domains = ~ company ''' )
self . do_test ( coldplug = True , ipv6 = False ,
extra_opts = ' IPv6AcceptRouterAdvertisements=False ' )
2016-06-30 16:44:22 +03:00
with open ( RESOLV_CONF ) as f :
contents = f . read ( )
2016-06-28 19:18:27 +03:00
# ~company is not a search domain, only a routing domain
self . assertNotRegex ( contents , ' search.*company ' )
2016-06-30 16:44:22 +03:00
# our global server should appear
self . assertIn ( ' nameserver 192.168.5.1 \n ' , contents )
2016-09-30 10:30:08 +03:00
# should not have domain-restricted server as global server
self . assertNotIn ( ' nameserver 192.168.42.1 \n ' , contents )
def test_route_only_dns_all_domains ( self ) :
with open ( ' /run/systemd/network/myvpn.netdev ' , ' w ' ) as f :
f . write ( ''' [NetDev]
Name = dummy0
Kind = dummy
MACAddress = 12 : 34 : 56 : 78 : 9 a : bc ''' )
with open ( ' /run/systemd/network/myvpn.network ' , ' w ' ) as f :
f . write ( ''' [Match]
Name = dummy0
[ Network ]
Address = 192.168 .42 .100
DNS = 192.168 .42 .1
Domains = ~ company ~ . ''' )
self . addCleanup ( os . remove , ' /run/systemd/network/myvpn.netdev ' )
self . addCleanup ( os . remove , ' /run/systemd/network/myvpn.network ' )
self . do_test ( coldplug = True , ipv6 = False ,
extra_opts = ' IPv6AcceptRouterAdvertisements=False ' )
with open ( RESOLV_CONF ) as f :
contents = f . read ( )
# ~company is not a search domain, only a routing domain
self . assertNotRegex ( contents , ' search.*company ' )
# our global server should appear
self . assertIn ( ' nameserver 192.168.5.1 \n ' , contents )
# should have company server as global server due to ~.
self . assertIn ( ' nameserver 192.168.42.1 \n ' , contents )
2016-06-28 19:18:27 +03:00
2015-11-17 20:30:50 +03:00
@unittest.skipUnless ( have_dnsmasq , ' dnsmasq not installed ' )
class DnsmasqClientTest ( ClientTestBase , unittest . TestCase ) :
''' Test networkd client against dnsmasq '''
def setUp ( self ) :
super ( ) . setUp ( )
self . dnsmasq = None
2016-09-30 10:30:08 +03:00
def create_iface ( self , ipv6 = False , dnsmasq_opts = None ) :
2015-11-17 20:30:50 +03:00
''' Create test interface with DHCP server behind it '''
# add veth pair
subprocess . check_call ( [ ' ip ' , ' link ' , ' add ' , ' name ' , self . iface , ' type ' ,
' veth ' , ' peer ' , ' name ' , self . if_router ] )
# give our router an IP
subprocess . check_call ( [ ' ip ' , ' a ' , ' flush ' , ' dev ' , self . if_router ] )
subprocess . check_call ( [ ' ip ' , ' a ' , ' add ' , ' 192.168.5.1/24 ' , ' dev ' , self . if_router ] )
if ipv6 :
subprocess . check_call ( [ ' ip ' , ' a ' , ' add ' , ' 2600::1/64 ' , ' dev ' , self . if_router ] )
subprocess . check_call ( [ ' ip ' , ' link ' , ' set ' , self . if_router , ' up ' ] )
# add DHCP server
self . dnsmasq_log = os . path . join ( self . workdir , ' dnsmasq.log ' )
lease_file = os . path . join ( self . workdir , ' dnsmasq.leases ' )
if ipv6 :
extra_opts = [ ' --enable-ra ' , ' --dhcp-range=2600::10,2600::20 ' ]
else :
extra_opts = [ ]
2016-09-30 10:30:08 +03:00
if dnsmasq_opts :
extra_opts + = dnsmasq_opts
2015-11-17 20:30:50 +03:00
self . dnsmasq = subprocess . Popen (
[ ' dnsmasq ' , ' --keep-in-foreground ' , ' --log-queries ' ,
' --log-facility= ' + self . dnsmasq_log , ' --conf-file=/dev/null ' ,
' --dhcp-leasefile= ' + lease_file , ' --bind-interfaces ' ,
' --interface= ' + self . if_router , ' --except-interface=lo ' ,
' --dhcp-range=192.168.5.10,192.168.5.200 ' ] + extra_opts )
def shutdown_iface ( self ) :
''' Remove test interface and stop DHCP server '''
if self . if_router :
subprocess . check_call ( [ ' ip ' , ' link ' , ' del ' , ' dev ' , self . if_router ] )
self . if_router = None
if self . dnsmasq :
self . dnsmasq . kill ( )
self . dnsmasq . wait ( )
self . dnsmasq = None
def print_server_log ( self ) :
''' Print DHCP server log for debugging failures '''
with open ( self . dnsmasq_log ) as f :
sys . stdout . write ( ' \n \n ---- dnsmasq log ---- \n %s \n ------ \n \n ' % f . read ( ) )
2016-09-30 10:30:08 +03:00
def test_resolved_domain_restricted_dns ( self ) :
''' resolved: domain-restricted DNS servers '''
# create interface for generic connections; this will map all DNS names
# to 192.168.42.1
self . create_iface ( dnsmasq_opts = [ ' --address=/#/192.168.42.1 ' ] )
self . writeConfig ( ' /run/systemd/network/general.network ' , ''' \
[ Match ]
Name = % s
[ Network ]
DHCP = ipv4
IPv6AcceptRA = False ''' % s elf.iface)
# create second device/dnsmasq for a .company/.lab VPN interface
# static IPs for simplicity
subprocess . check_call ( [ ' ip ' , ' link ' , ' add ' , ' name ' , ' testvpnclient ' , ' type ' ,
' veth ' , ' peer ' , ' name ' , ' testvpnrouter ' ] )
self . addCleanup ( subprocess . call , [ ' ip ' , ' link ' , ' del ' , ' dev ' , ' testvpnrouter ' ] )
subprocess . check_call ( [ ' ip ' , ' a ' , ' flush ' , ' dev ' , ' testvpnrouter ' ] )
subprocess . check_call ( [ ' ip ' , ' a ' , ' add ' , ' 10.241.3.1/24 ' , ' dev ' , ' testvpnrouter ' ] )
subprocess . check_call ( [ ' ip ' , ' link ' , ' set ' , ' testvpnrouter ' , ' up ' ] )
vpn_dnsmasq_log = os . path . join ( self . workdir , ' dnsmasq-vpn.log ' )
vpn_dnsmasq = subprocess . Popen (
[ ' dnsmasq ' , ' --keep-in-foreground ' , ' --log-queries ' ,
' --log-facility= ' + vpn_dnsmasq_log , ' --conf-file=/dev/null ' ,
' --dhcp-leasefile=/dev/null ' , ' --bind-interfaces ' ,
' --interface=testvpnrouter ' , ' --except-interface=lo ' ,
' --address=/math.lab/10.241.3.3 ' , ' --address=/cantina.company/10.241.4.4 ' ] )
self . addCleanup ( vpn_dnsmasq . wait )
self . addCleanup ( vpn_dnsmasq . kill )
self . writeConfig ( ' /run/systemd/network/vpn.network ' , ''' \
[ Match ]
Name = testvpnclient
[ Network ]
IPv6AcceptRA = False
Address = 10.241 .3 .2 / 24
DNS = 10.241 .3 .1
Domains = ~ company ~ lab ''' )
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-networkd ' ] )
subprocess . check_call ( [ self . networkd_wait_online , ' --interface ' , self . iface ,
' --interface=testvpnclient ' , ' --timeout=20 ' ] )
# ensure we start fresh with every test
subprocess . check_call ( [ ' systemctl ' , ' restart ' , ' systemd-resolved ' ] )
# test vpnclient specific domains; these should *not* be answered by
# the general DNS
out = subprocess . check_output ( [ ' systemd-resolve ' , ' math.lab ' ] )
self . assertIn ( b ' math.lab: 10.241.3.3 ' , out )
out = subprocess . check_output ( [ ' systemd-resolve ' , ' kettle.cantina.company ' ] )
self . assertIn ( b ' kettle.cantina.company: 10.241.4.4 ' , out )
# test general domains
out = subprocess . check_output ( [ ' systemd-resolve ' , ' megasearch.net ' ] )
self . assertIn ( b ' megasearch.net: 192.168.42.1 ' , out )
with open ( self . dnsmasq_log ) as f :
general_log = f . read ( )
with open ( vpn_dnsmasq_log ) as f :
vpn_log = f . read ( )
# VPN domains should only be sent to VPN DNS
self . assertRegex ( vpn_log , ' query.*math.lab ' )
self . assertRegex ( vpn_log , ' query.*cantina.company ' )
self . assertNotIn ( ' lab ' , general_log )
self . assertNotIn ( ' company ' , general_log )
# general domains should not be sent to the VPN DNS
self . assertRegex ( general_log , ' query.*megasearch.net ' )
self . assertNotIn ( ' megasearch.net ' , vpn_log )
2015-11-17 20:30:50 +03:00
class NetworkdClientTest ( ClientTestBase , unittest . TestCase ) :
''' Test networkd client against networkd server '''
def setUp ( self ) :
super ( ) . setUp ( )
self . dnsmasq = None
def create_iface ( self , ipv6 = False ) :
''' Create test interface with DHCP server behind it '''
# run "router-side" networkd in own mount namespace to shield it from
# "client-side" configuration and networkd
( fd , script ) = tempfile . mkstemp ( prefix = ' networkd-router.sh ' )
self . addCleanup ( os . remove , script )
with os . fdopen ( fd , ' w+ ' ) as f :
2016-09-14 13:52:40 +03:00
f . write ( ''' \
#!/bin/sh -eu
2015-11-17 20:30:50 +03:00
mkdir - p / run / systemd / network
mkdir - p / run / systemd / netif
mount - t tmpfs none / run / systemd / network
mount - t tmpfs none / run / systemd / netif
[ ! - e / run / dbus ] | | mount - t tmpfs none / run / dbus
# create router/client veth pair
cat << EOF > / run / systemd / network / test . netdev
[ NetDev ]
Name = % ( ifr ) s
Kind = veth
[ Peer ]
Name = % ( ifc ) s
EOF
cat << EOF > / run / systemd / network / test . network
[ Match ]
Name = % ( ifr ) s
[ Network ]
Address = 192.168 .5 .1 / 24
% ( addr6 ) s
DHCPServer = yes
[ DHCPServer ]
PoolOffset = 10
PoolSize = 50
DNS = 192.168 .5 .1
EOF
# run networkd as in systemd-networkd.service
exec $ ( systemctl cat systemd - networkd . service | sed - n ' /^ExecStart=/ { s/^.*=//; p} ' )
''' % { ' ifr ' : self.if_router, ' ifc ' : self.iface, ' addr6 ' : ipv6 and ' Address=2600::1/64 ' or ' ' })
os . fchmod ( fd , 0o755 )
subprocess . check_call ( [ ' systemd-run ' , ' --unit=networkd-test-router.service ' ,
' -p ' , ' InaccessibleDirectories=-/etc/systemd/network ' ,
' -p ' , ' InaccessibleDirectories=-/run/systemd/network ' ,
' -p ' , ' InaccessibleDirectories=-/run/systemd/netif ' ,
' --service-type=notify ' , script ] )
# wait until devices got created
for timeout in range ( 50 ) :
out = subprocess . check_output ( [ ' ip ' , ' a ' , ' show ' , ' dev ' , self . if_router ] )
if b ' state UP ' in out and b ' scope global ' in out :
break
time . sleep ( 0.1 )
def shutdown_iface ( self ) :
''' Remove test interface and stop DHCP server '''
if self . if_router :
subprocess . check_call ( [ ' systemctl ' , ' stop ' , ' networkd-test-router.service ' ] )
# ensure failed transient unit does not stay around
subprocess . call ( [ ' systemctl ' , ' reset-failed ' , ' networkd-test-router.service ' ] )
subprocess . call ( [ ' ip ' , ' link ' , ' del ' , ' dev ' , self . if_router ] )
self . if_router = None
def print_server_log ( self ) :
''' Print DHCP server log for debugging failures '''
self . show_journal ( ' networkd-test-router.service ' )
@unittest.skip ( ' networkd does not have DHCPv6 server support ' )
def test_hotplug_dhcp_ip6 ( self ) :
pass
@unittest.skip ( ' networkd does not have DHCPv6 server support ' )
def test_coldplug_dhcp_ip6 ( self ) :
pass
2016-06-03 12:15:44 +03:00
def test_search_domains ( self ) :
# we don't use this interface for this test
self . if_router = None
2016-09-14 13:52:40 +03:00
self . writeConfig ( ' /run/systemd/network/test.netdev ' , ''' \
[ NetDev ]
2016-06-03 12:15:44 +03:00
Name = dummy0
Kind = dummy
MACAddress = 12 : 34 : 56 : 78 : 9 a : bc ''' )
2016-09-14 13:52:40 +03:00
self . writeConfig ( ' /run/systemd/network/test.network ' , ''' \
[ Match ]
2016-06-03 12:15:44 +03:00
Name = dummy0
[ Network ]
Address = 192.168 .42 .100
DNS = 192.168 .42 .1
Domains = one two three four five six seven eight nine ten ''' )
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-networkd ' ] )
2016-06-30 16:44:22 +03:00
for timeout in range ( 50 ) :
with open ( RESOLV_CONF ) as f :
contents = f . read ( )
if ' one ' in contents :
break
time . sleep ( 0.1 )
self . assertRegex ( contents , ' search .*one two three four ' )
self . assertNotIn ( ' seven \n ' , contents )
self . assertIn ( ' # Too many search domains configured, remaining ones ignored. \n ' , contents )
2016-06-03 12:15:44 +03:00
def test_search_domains_too_long ( self ) :
# we don't use this interface for this test
self . if_router = None
name_prefix = ' a ' * 60
2016-09-14 13:52:40 +03:00
self . writeConfig ( ' /run/systemd/network/test.netdev ' , ''' \
[ NetDev ]
2016-06-03 12:15:44 +03:00
Name = dummy0
Kind = dummy
MACAddress = 12 : 34 : 56 : 78 : 9 a : bc ''' )
2016-09-14 13:52:40 +03:00
self . writeConfig ( ' /run/systemd/network/test.network ' , ''' \
[ Match ]
2016-06-03 12:15:44 +03:00
Name = dummy0
[ Network ]
Address = 192.168 .42 .100
DNS = 192.168 .42 .1
2016-09-14 13:52:40 +03:00
Domains = { p } 0 { p } 1 { p } 2 { p } 3 { p } 4 ''' .format(p=name_prefix))
2016-06-03 12:15:44 +03:00
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-networkd ' ] )
2016-06-30 16:44:22 +03:00
for timeout in range ( 50 ) :
with open ( RESOLV_CONF ) as f :
contents = f . read ( )
if ' one ' in contents :
break
time . sleep ( 0.1 )
2016-09-14 13:52:40 +03:00
self . assertRegex ( contents , ' search .* {p} 0 {p} 1 {p} 2 ' . format ( p = name_prefix ) )
2016-06-30 16:44:22 +03:00
self . assertIn ( ' # Total length of all search domains is too long, remaining ones ignored. ' , contents )
2016-06-03 12:15:44 +03:00
2016-07-09 17:55:26 +03:00
def test_dropin ( self ) :
# we don't use this interface for this test
self . if_router = None
self . writeConfig ( ' /run/systemd/network/test.netdev ' , ''' \
[ NetDev ]
Name = dummy0
Kind = dummy
MACAddress = 12 : 34 : 56 : 78 : 9 a : bc ''' )
self . writeConfig ( ' /run/systemd/network/test.network ' , ''' \
[ Match ]
Name = dummy0
[ Network ]
Address = 192.168 .42 .100
DNS = 192.168 .42 .1 ''' )
self . writeConfig ( ' /run/systemd/network/test.network.d/dns.conf ' , ''' \
[ Network ]
DNS = 127.0 .0 .1 ''' )
subprocess . check_call ( [ ' systemctl ' , ' start ' , ' systemd-networkd ' ] )
for timeout in range ( 50 ) :
with open ( RESOLV_CONF ) as f :
contents = f . read ( )
if ' 127.0.0.1 ' in contents :
break
time . sleep ( 0.1 )
self . assertIn ( ' nameserver 192.168.42.1 \n ' , contents )
self . assertIn ( ' nameserver 127.0.0.1 \n ' , contents )
2015-11-17 20:30:50 +03:00
if __name__ == ' __main__ ' :
unittest . main ( testRunner = unittest . TextTestRunner ( stream = sys . stdout ,
verbosity = 2 ) )