ssahani / rpms / dhcpcd

Forked from rpms/dhcpcd a year ago
Clone

Blame tests/ipv6-tests/dhcpcd-tests.py

Susant Sahani 97d0b2
#!/usr/bin/env python3
Susant Sahani 97d0b2
# SPDX-License-Identifier: LGPL-2.1+
Susant Sahani 97d0b2
# ~~~
Susant Sahani 97d0b2
#   Description: DHCPv6 Tests for dhcpcd - a DHCP client
Susant Sahani 97d0b2
#
Susant Sahani 97d0b2
#   Author: Susant Sahani <susant@redhat.com>
Susant Sahani 97d0b2
#   Copyright (c) 2018 Red Hat, Inc.
Susant Sahani 97d0b2
# ~~~
Susant Sahani 97d0b2
Susant Sahani 97d0b2
import errno
Susant Sahani 97d0b2
import os
Susant Sahani 97d0b2
import sys
Susant Sahani 97d0b2
import time
Susant Sahani 97d0b2
import unittest
Susant Sahani 97d0b2
import subprocess
Susant Sahani 97d0b2
import signal
Susant Sahani 97d0b2
import shutil
Susant Sahani 97d0b2
import psutil
Susant Sahani 97d0b2
import socket
Susant Sahani 97d0b2
from pyroute2 import IPRoute
Susant Sahani 97d0b2
Susant Sahani 97d0b2
DHCPCD_CI_DIR="/var/run/dhcpcd-ci"
Susant Sahani 97d0b2
DHCPCD_LOG_FILE='/var/run/dhcpcd-ci/dhcpcd-test-log'
Susant Sahani 97d0b2
DHCPCD_CONF_FILE='/var/run/dhcpcd-ci/dhcpcd-test.conf'
Susant Sahani 97d0b2
Susant Sahani 97d0b2
DHCPCD_PID_FILE='/var/run/dhcpcd.pid'
Susant Sahani 97d0b2
DHCPCD_DUID_FILE='/etc/dhcpcd.duid'
Susant Sahani 97d0b2
Susant Sahani 97d0b2
RADVD_LOG_FILE ='/var/run/dhcpcd-ci/radvd.log'
Susant Sahani 97d0b2
RADVD_CONFIG_FILE ='/var/run/dhcpcd-ci/radvd-ci.conf'
Susant Sahani 97d0b2
RADVD_PID_FILE='/var/run/dhcpcd-ci/radvd.pid'
Susant Sahani 97d0b2
Susant Sahani 97d0b2
DHCP6S_CONFIG_FILE='/var/run/dhcpcd-ci/dhcp6s.conf'
Susant Sahani 97d0b2
DHCP6S_PID_FILE='/var/run/dhcp6s.pid'
Susant Sahani 97d0b2
Susant Sahani 97d0b2
RESOLVE_CONF='/etc/resolv.conf'
Susant Sahani 97d0b2
Susant Sahani 97d0b2
def setUpModule():
Susant Sahani 97d0b2
    """Initialize the environment, and perform sanity checks on it."""
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    if shutil.which('dhcpcd') is None:
Susant Sahani 97d0b2
        raise OSError(errno.ENOENT, 'dhcpcd not found')
Susant Sahani 97d0b2
    if shutil.which('dhcp6s') is None:
Susant Sahani 97d0b2
        raise OSError(errno.ENOENT, 'dhcdp6s not found')
Susant Sahani 97d0b2
    if shutil.which('radvd') is None:
Susant Sahani 97d0b2
        raise OSError(errno.ENOENT, 'radvd not found')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
def tearDownModule():
Susant Sahani 97d0b2
    pass
Susant Sahani 97d0b2
Susant Sahani 97d0b2
class GenericUtilities():
Susant Sahani 97d0b2
    """Provide a set of utility functions start stop daemons. write config files etc """
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def StartDhcp6s(self):
Susant Sahani 97d0b2
        """Start dhcp6s"""
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        subprocess.check_output(['dhcp6s', '-c', DHCP6S_CONFIG_FILE, 'veth-peer', '-dD'])
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def StartRadvd(self):
Susant Sahani 97d0b2
        """Start radvd"""
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        subprocess.check_output(['radvd', '-d5', '-C', RADVD_CONFIG_FILE, '-p', RADVD_PID_FILE, '-l', RADVD_LOG_FILE])
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def StartDhcpcd(self):
Susant Sahani 97d0b2
        subprocess.check_output(['dhcpcd', '-6', '-M', '-d', '--logfile', DHCPCD_LOG_FILE, '-f', DHCPCD_CONF_FILE, 'veth-test'])
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def StopDaemon(self, pid_file):
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        with open(pid_file, 'r') as f:
Susant Sahani 97d0b2
            pid = f.read().rstrip(' \t\r\n\0')
Susant Sahani 97d0b2
            os.kill(int(pid), signal.SIGTERM)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        os.remove(pid_file)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def WriteConfigFile(self, path, contents):
Susant Sahani 97d0b2
        """Write a config file, and queue it to be removed."""
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        with open(path, 'w') as unit:
Susant Sahani 97d0b2
            unit.write(contents)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.addCleanup(os.remove, path)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def findTextInDaemonLogs(self, log_file, **kwargs):
Susant Sahani 97d0b2
        """dnsmasq server logs."""
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        if kwargs is not None:
Susant Sahani 97d0b2
            with open (log_file, 'rt') as in_file:
Susant Sahani 97d0b2
                contents = in_file.read()
Susant Sahani 97d0b2
                for key in kwargs:
Susant Sahani 97d0b2
                    self.assertRegex(contents, kwargs[key])
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def SetupVethInterface(self):
Susant Sahani 97d0b2
        """Setup veth interface"""
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        ip = IPRoute()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        ip.link('add', ifname='veth-test', peer='veth-peer', kind='veth')
Susant Sahani 97d0b2
        idx_veth_test = ip.link_lookup(ifname='veth-test')[0]
Susant Sahani 97d0b2
        idx_veth_peer = ip.link_lookup(ifname='veth-peer')[0]
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        ip.link('set', index=idx_veth_test, address='02:01:02:03:04:08')
Susant Sahani 97d0b2
        ip.link('set', index=idx_veth_peer, address='02:01:02:03:04:09')
Susant Sahani 97d0b2
        ip.link('set', index=idx_veth_test, state='up')
Susant Sahani 97d0b2
        ip.link('set', index=idx_veth_peer, state='up')
Susant Sahani 97d0b2
        ip.addr('add', index=idx_veth_peer, address='192.168.111.50')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        ip.close()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def TearDownVethInterface(self):
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        ip = IPRoute()
Susant Sahani 97d0b2
        ip.link('del', index=ip.link_lookup(ifname='veth-test')[0])
Susant Sahani 97d0b2
        ip.close()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
class DhcpcdTests(unittest.TestCase, GenericUtilities):
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def setUp(self):
Susant Sahani 97d0b2
        """ setup veth and write radvd and dhcpv6configs """
Susant Sahani 97d0b2
        self.SetupVethInterface()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def tearDown(self):
Susant Sahani 97d0b2
        self.StopDaemon(DHCPCD_PID_FILE)
Susant Sahani 97d0b2
        self.StopDaemon(RADVD_PID_FILE)
Susant Sahani 97d0b2
        self.StopDaemon(DHCP6S_PID_FILE)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.TearDownVethInterface()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def test_dhcp6s_gets_rdnss_dnssl(self):
Susant Sahani 97d0b2
        """ DHCP6c gets the RDNSS DNSSL """
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.StartDhcp6s()
Susant Sahani 97d0b2
        self.StartRadvd()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        time.sleep(1)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.WriteConfigFile(DHCPCD_DUID_FILE, '''00:01:00:01:22:8a:88:26:08:00:27:87:00:7e\n''')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.StartDhcpcd()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        time.sleep(10)
Susant Sahani 97d0b2
        output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        # Address prefix
Susant Sahani 97d0b2
        self.assertRegex(output, "2001:888:db8:1::b")
Susant Sahani 97d0b2
        self.findTextInDaemonLogs(RESOLVE_CONF,
Susant Sahani 97d0b2
                                  dns1='2001:888:db8:1::a',
Susant Sahani 97d0b2
                                  dns2='2001:888:db8:1::d',
Susant Sahani 97d0b2
                                  search='test.com')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def test_dhcp6s_assigns_static_address_using_duid2(self):
Susant Sahani 97d0b2
        """ DHCP6c gets the (static) addresses to hosts using known DUID value 00:01:00:01:22:8d:cb:58:0a:00:27:00:00:00 """
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.StartDhcp6s()
Susant Sahani 97d0b2
        self.StartRadvd()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        time.sleep(1)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.WriteConfigFile(DHCPCD_DUID_FILE, '''00:01:00:01:22:8d:cb:58:0a:00:27:00:00:00\n''')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.StartDhcpcd()
Susant Sahani 97d0b2
        time.sleep(10)
Susant Sahani 97d0b2
        output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        # Address
Susant Sahani 97d0b2
        self.assertRegex(output, "2001:888:db8:1::c")
Susant Sahani 97d0b2
        self.findTextInDaemonLogs(RESOLVE_CONF,
Susant Sahani 97d0b2
                                  dns='2001:888:db8:1::a',
Susant Sahani 97d0b2
                                  search='test.com')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
    def test_dhcp6s_assigns_static_address_using_duid1(self):
Susant Sahani 97d0b2
        """ DHCP6c gets the (static) addresses to hosts using known DUID value 00:01:00:01:22:8a:88:26:08:00:27:87:00:7e """
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.StartDhcp6s()
Susant Sahani 97d0b2
        self.StartRadvd()
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        time.sleep(1)
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.WriteConfigFile(DHCPCD_DUID_FILE, '''00:01:00:01:22:8a:88:26:08:00:27:87:00:7e\n''')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        self.StartDhcpcd()
Susant Sahani 97d0b2
        time.sleep(10)
Susant Sahani 97d0b2
        output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
        # Address prefix
Susant Sahani 97d0b2
        self.assertRegex(output, "2001:888:db8:1::b")
Susant Sahani 97d0b2
        self.findTextInDaemonLogs(RESOLVE_CONF,
Susant Sahani 97d0b2
                                  dns='2001:888:db8:1::a',
Susant Sahani 97d0b2
                                  search='test.com')
Susant Sahani 97d0b2
Susant Sahani 97d0b2
if __name__ == '__main__':
Susant Sahani 97d0b2
    unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout,
Susant Sahani 97d0b2
                                                     verbosity=3))