diff --git a/tests/ipv4-tests/dhcpcd-domain-dns.conf b/tests/ipv4-tests/dhcpcd-domain-dns.conf new file mode 100644 index 0000000..a620283 --- /dev/null +++ b/tests/ipv4-tests/dhcpcd-domain-dns.conf @@ -0,0 +1,20 @@ +debug +# Inform the DHCP server of our hostname for DDNS. +hostname + +# Use the hardware address of the interface for the Client ID. +clientid + +# Persist interface configuration when dhcpcd exits. +persistent + +# A list of options to request from the DHCP server. +option domain_name_servers, domain_name, domain_search, host_name +option classless_static_routes +# Most distributions have NTP support. +option ntp_servers +# Respect the network MTU. This is applied to DHCP routes. +option interface_mtu + +# A ServerID is required by RFC2131. +require dhcp_server_identifier diff --git a/tests/ipv4-tests/dhcpcd-mtu.conf b/tests/ipv4-tests/dhcpcd-mtu.conf new file mode 100644 index 0000000..a620283 --- /dev/null +++ b/tests/ipv4-tests/dhcpcd-mtu.conf @@ -0,0 +1,20 @@ +debug +# Inform the DHCP server of our hostname for DDNS. +hostname + +# Use the hardware address of the interface for the Client ID. +clientid + +# Persist interface configuration when dhcpcd exits. +persistent + +# A list of options to request from the DHCP server. +option domain_name_servers, domain_name, domain_search, host_name +option classless_static_routes +# Most distributions have NTP support. +option ntp_servers +# Respect the network MTU. This is applied to DHCP routes. +option interface_mtu + +# A ServerID is required by RFC2131. +require dhcp_server_identifier diff --git a/tests/ipv4-tests/dhcpcd-tests.py b/tests/ipv4-tests/dhcpcd-tests.py new file mode 100755 index 0000000..041b450 --- /dev/null +++ b/tests/ipv4-tests/dhcpcd-tests.py @@ -0,0 +1,213 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~ +# Description: Tests for dhcpcd - a DHCP client +# +# Author: Susant Sahani +# Copyright (c) 2018 Red Hat, Inc. +# ~~~ + +import errno +import os +import sys +import time +import unittest +import subprocess +import signal +import shutil +import psutil +import socket +from pyroute2 import IPRoute + +DHCPCD_CI_DIR="/var/run/dhcpcd-ci" +DHCPCD_LOG_FILE='/var/run/dhcpcd-ci/dhcpcd-test-log' +DHCPCD_PID_FILE='/var/run/dhcpcd.pid' + +DHCPCD_TCP_DUMP_FILE='/tmp/dhcpcd-tcp-dump.pcap' + +DNSMASQ_PID_FILE='/var/run/dhcpcd-ci/test-dnsmasq.pid' +DNSMASQ_LOG_FILE='/var/run/dhcpcd-ci/dnsmasq-log-file' + +def setUpModule(): + """Initialize the environment, and perform sanity checks on it.""" + + if shutil.which('dhcpcd') is None: + raise OSError(errno.ENOENT, 'dhcpcd not found') + + if shutil.which('dnsmasq') is None: + raise OSError(errno.ENOENT, 'dnsmasq not found') + + +def tearDownModule(): + pass + +class GenericUtilities(): + """Provide a set of utility functions start stop daemons. write config files etc """ + + def StartDnsMasq(self, conf): + """Start DnsMasq""" + + conf_file=os.path.join(DHCPCD_CI_DIR, conf) + + subprocess.check_output(['dnsmasq', '-8', DNSMASQ_LOG_FILE, '--log-dhcp', '--pid-file=/var/run/dhcpcd-ci/test-dnsmasq.pid', + '-C', conf_file, '-i', 'veth-peer', '-R']) + + def StartDhcpcd(self, conf): + """ Start dnsmaq """ + + conf_file=os.path.join(DHCPCD_CI_DIR, conf) + subprocess.check_output(['dhcpcd', '-4', '-M', '-d', '--logfile', DHCPCD_LOG_FILE, '-f', conf_file, 'veth-test']) + + def StopDaemon(self, pid_file): + + with open(pid_file, 'r') as f: + pid = f.read().rstrip(' \t\r\n\0') + os.kill(int(pid), signal.SIGTERM) + + os.remove(pid_file) + + def findTextInDaemonLogs(self, log_file, **kwargs): + """dnsmasq server logs.""" + + if kwargs is not None: + with open (log_file, 'rt') as in_file: + contents = in_file.read() + for key in kwargs: + self.assertRegex(contents, kwargs[key]) + + def FindProtocolFieldsinTCPDump(self, **kwargs): + """Look attributes in tcpdump.""" + + contents = subprocess.check_output(['tcpdump', '-vv', '-r', DHCPCD_TCP_DUMP_FILE]).rstrip().decode('utf-8') + if kwargs is not None: + for key in kwargs: + self.assertRegex(contents, kwargs[key]) + + def SetupVethInterface(self): + """Setup veth interface""" + + ip = IPRoute() + + ip.link('add', ifname='veth-test', peer='veth-peer', kind='veth') + idx_veth_test = ip.link_lookup(ifname='veth-test')[0] + idx_veth_peer = ip.link_lookup(ifname='veth-peer')[0] + + ip.link('set', index=idx_veth_test, address='02:01:02:03:04:08') + ip.link('set', index=idx_veth_peer, address='02:01:02:03:04:09') + ip.link('set', index=idx_veth_test, state='up') + ip.link('set', index=idx_veth_peer, state='up') + ip.addr('add', index=idx_veth_peer, address='192.168.111.50') + ip.close() + + def TearDownVethInterface(self): + + ip = IPRoute() + ip.link('del', index=ip.link_lookup(ifname='veth-test')[0]) + ip.close() + + def StartCaptureBOOTPPackets(self): + """Start tcpdump to capture dhcp packets""" + + subprocess.check_output(['systemctl','restart', 'tcpdumpd.service']) + + def StopCapturingPackets(self): + subprocess.check_output(['systemctl', 'stop', 'tcpdumpd.service']) + time.sleep(3); + +class DhcpcdTests(unittest.TestCase, GenericUtilities): + + def setUp(self): + """ setup veth and write radvd and dhcpv6configs """ + self.SetupVethInterface() + + def tearDown(self): + self.StopDaemon(DHCPCD_PID_FILE) + self.StopDaemon(DNSMASQ_PID_FILE) + + self.TearDownVethInterface() + + def test_dhcpcd_ipv4(self): + """ dhcpcd gets address """ + + self.StartDnsMasq('dnsmasq-ipv4.conf') + time.sleep(1) + self.StartDhcpcd('dhcpcd-domain-dns.conf') + + time.sleep(5) + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + + # Address prefix + self.assertRegex(output, "192.168.111.*") + + # Default route + output=subprocess.check_output(['ip','route', 'show', 'dev', 'veth-test']).rstrip().decode('utf-8') + self.assertRegex(output, "default via 192.168.1.1*") + + def test_dhcpcd_dns_domain(self): + """ dhcpcd request DNS and domain name """ + + self.StartDnsMasq('dnsmasq-ipv4.conf') + time.sleep(1) + self.StartDhcpcd('dhcpcd-domain-dns.conf') + + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + + # Address prefix + self.assertRegex(output, "192.168.111.*") + + # Default route + output=subprocess.check_output(['ip','route', 'show', 'dev', 'veth-test']).rstrip().decode('utf-8') + self.assertRegex(output, "default via 192.168.1.1*") + + # Dump the lease file + output=subprocess.check_output(['dhcpcd','-U', '-4', 'veth-test'], stderr=subprocess.STDOUT).rstrip().decode('utf-8') + self.assertRegex(output, 'domain_name=example-test.com') + self.assertRegex(output, 'domain_name_servers=\'8.8.8.8 8.8.4.4\'') + self.assertRegex(output, 'routers=192.168.1.1') + + def test_dhcpcd_mtu(self): + """ dhcpcd gets MTU 1492 """ + + self.StartDnsMasq('dnsmasq-mtu.conf') + time.sleep(1) + + self.StartDhcpcd('dhcpcd-mtu.conf') + time.sleep(5) + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + + # Address prefix + self.assertRegex(output, "192.168.111.*") + + # Dump the lease file + output=subprocess.check_output(['dhcpcd','-U', '-4', 'veth-test'], stderr=subprocess.STDOUT).rstrip().decode('utf-8') + self.assertRegex(output, 'interface_mtu=1492') + + def test_dhcpcd_clientid_vendorclassid_userclass(self): + """ verify dhcpcd sends custom clientid vendor class id and userclass """ + + self.StartDnsMasq('dnsmasq-vendorclass.conf') + time.sleep(1) + + self.StartCaptureBOOTPPackets() + + self.StartDhcpcd('dhcpcd-vendorclass.conf') + time.sleep(5) + self.StopCapturingPackets() + + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + # Address prefix + self.assertRegex(output, "192.168.111.*") + + self.findTextInDaemonLogs(DNSMASQ_LOG_FILE, vendor_class='vendor class: Zeus_dhcpcd_vendorclass_id', + user_class='user class: AAAA BBBB CCCC DDDD', + host_name='client provides name: Zeus') + self.findTextInDaemonLogs(DHCPCD_LOG_FILE, client_id='using ClientID 00:11:11:12:12:13:13:14:14:15:15:16:16') + self.FindProtocolFieldsinTCPDump(vendor='Vendor-Option Option 43, length 11: 104.101.108.108.111.32.119.111.114.108.100', + user_class='instance#1:.*AAAA BBBB CCCC DDDD", length 19', + vendor_class='Vendor-Class Option 60, length 26:.*Zeus_dhcpcd_vendorclass_id', + host_name='Hostname.*Zeus') + os.remove(DHCPCD_TCP_DUMP_FILE) + +if __name__ == '__main__': + unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, + verbosity=3)) diff --git a/tests/ipv4-tests/dhcpcd-vendorclass.conf b/tests/ipv4-tests/dhcpcd-vendorclass.conf new file mode 100644 index 0000000..51b2223 --- /dev/null +++ b/tests/ipv4-tests/dhcpcd-vendorclass.conf @@ -0,0 +1,9 @@ +debug +hostname Zeus +# Use custom Client ID. +clientid 00:11:11:12:12:13:13:14:14:15:15:16:16 +vendorclassid Zeus_dhcpcd_vendorclass_id +userclass "AAAA BBBB CCCC DDDD" +vendor ,"hello world" +# A ServerID is required by RFC2131. +require dhcp_server_identifier diff --git a/tests/ipv4-tests/dnsmasq-ipv4.conf b/tests/ipv4-tests/dnsmasq-ipv4.conf new file mode 100644 index 0000000..cc912e2 --- /dev/null +++ b/tests/ipv4-tests/dnsmasq-ipv4.conf @@ -0,0 +1,15 @@ +interface=veth-peer +bind-interfaces + +# Optionally set a domain name +domain=example-test.com + +# Set default gateway +dhcp-option=3,192.168.1.1 + +# Set DNS servers to announce +dhcp-option=6,8.8.8.8,8.8.4.4 + +# Dynamic range of IPs to make available to LAN PC and the lease time. +# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records. +dhcp-range=192.168.111.50,192.168.111.100,255.255.255.0,1h diff --git a/tests/ipv4-tests/dnsmasq-mtu.conf b/tests/ipv4-tests/dnsmasq-mtu.conf new file mode 100644 index 0000000..35ce534 --- /dev/null +++ b/tests/ipv4-tests/dnsmasq-mtu.conf @@ -0,0 +1,18 @@ +interface=veth-peer +bind-interfaces + +# Optionally set a domain name +domain=example-test.com + +# Set default gateway +dhcp-option=3,192.168.1.1 + +# Set DNS servers to announce +dhcp-option=6,8.8.8.8,8.8.4.4 + +# MTU +dhcp-option=26,1492 + +# Dynamic range of IPs to make available to LAN PC and the lease time. +# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records. +dhcp-range=192.168.111.50,192.168.111.100,255.255.255.0,1h diff --git a/tests/ipv4-tests/dnsmasq-vendorclass.conf b/tests/ipv4-tests/dnsmasq-vendorclass.conf new file mode 100644 index 0000000..2b2cf55 --- /dev/null +++ b/tests/ipv4-tests/dnsmasq-vendorclass.conf @@ -0,0 +1,6 @@ +interface=veth-peer +bind-interfaces + +# Dynamic range of IPs to make available to LAN PC and the lease time. +# Ideally set the lease time to 5m only at first to test everything works okay before you set long-lasting records. +dhcp-range=192.168.111.50,192.168.111.100,255.255.255.0,1h diff --git a/tests/ipv4-tests/runtest.sh b/tests/ipv4-tests/runtest.sh new file mode 100755 index 0000000..24a4294 --- /dev/null +++ b/tests/ipv4-tests/runtest.sh @@ -0,0 +1,63 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~ +# runtest.sh of dhcpcd +# Description: a DHCP and DHCPv6 client. It's also an IPv4LL (aka ZeroConf) client. +# +# Author: Susant Sahani +# Copyright (c) 2018 Red Hat, Inc. +# ~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="dhcpcd" +DHCPCD_CI_DIR="/var/run/dhcpcd-ci" + +SERVICE_UNITDIR="/var/run/systemd/system" +RESOLVE_CONF="/etc/resolv.conf" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm $PACKAGE + rlRun "systemctl stop firewalld" 0,5 + rlRun "setenforce 0" 0,1 + + rlFileBackup "$RESOLVE_CONF" + + rlRun "[ -e /sys/class/net/veth-test ] && ip link del veth-test" 0,1 + + rlLog "Create work dir ..." + rlRun "mkdir -p $DHCPCD_CI_DIR" + rlRun "cp *.conf $DHCPCD_CI_DIR" + + rlRun "cp tcpdumpd.service $SERVICE_UNITDIR" + rlRun "cp dhcpcd-tests.py /usr/bin/" + + rlRun "systemctl daemon-reload" + rlPhaseEnd + + rlPhaseStartTest + rlLog "Starting dhcpcd tests ..." + rlRun "/usr/bin/python3 /usr/bin/dhcpcd-tests.py" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm /usr/bin/dhcpcd-tests.py" + rlRun "[ -e /sys/class/net/veth-test ] && ip link del veth-test" 0,1 + + rlFileRestore + + rlLog "remove work dir" + rlRun "rm -rf $DHCPCD_CI_DIR" + + rlRun "rm $SERVICE_UNITDIR/tcpdumpd.service" + rlRun "systemctl daemon-reload" + + rlRun "setenforce 1" 0,1 + rlLog "dhcpcd tests done" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd + +rlGetTestState diff --git a/tests/ipv4-tests/tcpdumpd.service b/tests/ipv4-tests/tcpdumpd.service new file mode 100644 index 0000000..ec325dc --- /dev/null +++ b/tests/ipv4-tests/tcpdumpd.service @@ -0,0 +1,10 @@ +[Unit] +Description=TCPDumpd +After=multi-user.target network.target + +[Service] +Type=simple +ExecStart=/usr/sbin/tcpdump -i veth-peer port 67 or port 68 -vvv -w "/tmp/dhcpcd-tcp-dump.pcap" + +[Install] +WantedBy=multi-user.target diff --git a/tests/ipv6-tests/dhcp6s.conf b/tests/ipv6-tests/dhcp6s.conf new file mode 100644 index 0000000..a2b42fe --- /dev/null +++ b/tests/ipv6-tests/dhcp6s.conf @@ -0,0 +1,20 @@ +option domain-name-servers 2001:888:0db8:1::a 2001:888:db8:1::d; +option domain-name "test.com"; + +host zeus { + duid 00:01:00:01:22:8a:88:26:08:00:27:87:00:7e; + address 2001:888:db8:1::b infinity; +}; + +host test { + duid 00:01:00:01:22:8d:cb:58:0a:00:27:00:00:00; + address 2001:888:db8:1::c infinity; +}; + +interface veth-peer { + address-pool pool1 10; +}; + +pool pool1 { + range 2001:888:0db8:1::1000 to 2001:888:0db8:1::2000; +}; diff --git a/tests/ipv6-tests/dhcpcd-test.conf b/tests/ipv6-tests/dhcpcd-test.conf new file mode 100644 index 0000000..272a0ce --- /dev/null +++ b/tests/ipv6-tests/dhcpcd-test.conf @@ -0,0 +1,8 @@ +debug +interface veth-test +# Inform the DHCP server of our hostname for DDNS. +hostname +dhcp6 +ipv6only +# Persist interface configuration when dhcpcd exits. +persistent diff --git a/tests/ipv6-tests/dhcpcd-tests.py b/tests/ipv6-tests/dhcpcd-tests.py new file mode 100755 index 0000000..9c8f794 --- /dev/null +++ b/tests/ipv6-tests/dhcpcd-tests.py @@ -0,0 +1,192 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~ +# Description: DHCPv6 Tests for dhcpcd - a DHCP client +# +# Author: Susant Sahani +# Copyright (c) 2018 Red Hat, Inc. +# ~~~ + +import errno +import os +import sys +import time +import unittest +import subprocess +import signal +import shutil +import psutil +import socket +from pyroute2 import IPRoute + +DHCPCD_CI_DIR="/var/run/dhcpcd-ci" +DHCPCD_LOG_FILE='/var/run/dhcpcd-ci/dhcpcd-test-log' +DHCPCD_CONF_FILE='/var/run/dhcpcd-ci/dhcpcd-test.conf' + +DHCPCD_PID_FILE='/var/run/dhcpcd.pid' +DHCPCD_DUID_FILE='/etc/dhcpcd.duid' + +RADVD_LOG_FILE ='/var/run/dhcpcd-ci/radvd.log' +RADVD_CONFIG_FILE ='/var/run/dhcpcd-ci/radvd-ci.conf' +RADVD_PID_FILE='/var/run/dhcpcd-ci/radvd.pid' + +DHCP6S_CONFIG_FILE='/var/run/dhcpcd-ci/dhcp6s.conf' +DHCP6S_PID_FILE='/var/run/dhcp6s.pid' + +RESOLVE_CONF='/etc/resolv.conf' + +def setUpModule(): + """Initialize the environment, and perform sanity checks on it.""" + + if shutil.which('dhcpcd') is None: + raise OSError(errno.ENOENT, 'dhcpcd not found') + if shutil.which('dhcp6s') is None: + raise OSError(errno.ENOENT, 'dhcdp6s not found') + if shutil.which('radvd') is None: + raise OSError(errno.ENOENT, 'radvd not found') + +def tearDownModule(): + pass + +class GenericUtilities(): + """Provide a set of utility functions start stop daemons. write config files etc """ + + def StartDhcp6s(self): + """Start dhcp6s""" + + subprocess.check_output(['dhcp6s', '-c', DHCP6S_CONFIG_FILE, 'veth-peer', '-dD']) + + def StartRadvd(self): + """Start radvd""" + + subprocess.check_output(['radvd', '-d5', '-C', RADVD_CONFIG_FILE, '-p', RADVD_PID_FILE, '-l', RADVD_LOG_FILE]) + + def StartDhcpcd(self): + subprocess.check_output(['dhcpcd', '-6', '-M', '-d', '--logfile', DHCPCD_LOG_FILE, '-f', DHCPCD_CONF_FILE, 'veth-test']) + + def StopDaemon(self, pid_file): + + with open(pid_file, 'r') as f: + pid = f.read().rstrip(' \t\r\n\0') + os.kill(int(pid), signal.SIGTERM) + + os.remove(pid_file) + + def WriteConfigFile(self, path, contents): + """Write a config file, and queue it to be removed.""" + + with open(path, 'w') as unit: + unit.write(contents) + + self.addCleanup(os.remove, path) + + def findTextInDaemonLogs(self, log_file, **kwargs): + """dnsmasq server logs.""" + + if kwargs is not None: + with open (log_file, 'rt') as in_file: + contents = in_file.read() + for key in kwargs: + self.assertRegex(contents, kwargs[key]) + + def SetupVethInterface(self): + """Setup veth interface""" + + ip = IPRoute() + + ip.link('add', ifname='veth-test', peer='veth-peer', kind='veth') + idx_veth_test = ip.link_lookup(ifname='veth-test')[0] + idx_veth_peer = ip.link_lookup(ifname='veth-peer')[0] + + ip.link('set', index=idx_veth_test, address='02:01:02:03:04:08') + ip.link('set', index=idx_veth_peer, address='02:01:02:03:04:09') + ip.link('set', index=idx_veth_test, state='up') + ip.link('set', index=idx_veth_peer, state='up') + ip.addr('add', index=idx_veth_peer, address='192.168.111.50') + + ip.close() + + def TearDownVethInterface(self): + + ip = IPRoute() + ip.link('del', index=ip.link_lookup(ifname='veth-test')[0]) + ip.close() + +class DhcpcdTests(unittest.TestCase, GenericUtilities): + + def setUp(self): + """ setup veth and write radvd and dhcpv6configs """ + self.SetupVethInterface() + + def tearDown(self): + self.StopDaemon(DHCPCD_PID_FILE) + self.StopDaemon(RADVD_PID_FILE) + self.StopDaemon(DHCP6S_PID_FILE) + + self.TearDownVethInterface() + + def test_dhcp6s_gets_rdnss_dnssl(self): + """ DHCP6c gets the RDNSS DNSSL """ + + self.StartDhcp6s() + self.StartRadvd() + + time.sleep(1) + + self.WriteConfigFile(DHCPCD_DUID_FILE, '''00:01:00:01:22:8a:88:26:08:00:27:87:00:7e\n''') + + self.StartDhcpcd() + + time.sleep(10) + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + + # Address prefix + self.assertRegex(output, "2001:888:db8:1::b") + self.findTextInDaemonLogs(RESOLVE_CONF, + dns1='2001:888:db8:1::a', + dns2='2001:888:db8:1::d', + search='test.com') + + def test_dhcp6s_assigns_static_address_using_duid2(self): + """ 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 """ + + self.StartDhcp6s() + self.StartRadvd() + + time.sleep(1) + + self.WriteConfigFile(DHCPCD_DUID_FILE, '''00:01:00:01:22:8d:cb:58:0a:00:27:00:00:00\n''') + + self.StartDhcpcd() + time.sleep(10) + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + + # Address + self.assertRegex(output, "2001:888:db8:1::c") + self.findTextInDaemonLogs(RESOLVE_CONF, + dns='2001:888:db8:1::a', + search='test.com') + + def test_dhcp6s_assigns_static_address_using_duid1(self): + """ 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 """ + + self.StartDhcp6s() + self.StartRadvd() + + time.sleep(1) + + self.WriteConfigFile(DHCPCD_DUID_FILE, '''00:01:00:01:22:8a:88:26:08:00:27:87:00:7e\n''') + + self.StartDhcpcd() + time.sleep(10) + output=subprocess.check_output(['ip','address', 'show', 'veth-test']).rstrip().decode('utf-8') + + # Address prefix + self.assertRegex(output, "2001:888:db8:1::b") + self.findTextInDaemonLogs(RESOLVE_CONF, + dns='2001:888:db8:1::a', + search='test.com') + +if __name__ == '__main__': + unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, + verbosity=3)) diff --git a/tests/ipv6-tests/radvd-ci.conf b/tests/ipv6-tests/radvd-ci.conf new file mode 100644 index 0000000..cdd18de --- /dev/null +++ b/tests/ipv6-tests/radvd-ci.conf @@ -0,0 +1,9 @@ +interface veth-peer +{ + AdvSendAdvert on; + AdvManagedFlag on; + AdvOtherConfigFlag on; + prefix 2001:888:0db8:1::/64 { + AdvAutonomous off; + }; +}; diff --git a/tests/ipv6-tests/runtest.sh b/tests/ipv6-tests/runtest.sh new file mode 100755 index 0000000..aa44415 --- /dev/null +++ b/tests/ipv6-tests/runtest.sh @@ -0,0 +1,59 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1+ +# ~~~ +# runtest.sh of dhcpcd +# Description: a DHCP and DHCPv6 client. It's also an IPv4LL (aka ZeroConf) client. +# +# Author: Susant Sahani +# Copyright (c) 2018 Red Hat, Inc. +# ~~~ + +# Include Beaker environment +. /usr/share/beakerlib/beakerlib.sh || exit 1 + +PACKAGE="dhcpcd" + +DHCPCD_CI_DIR="/var/run/dhcpcd-ci" +DHCPCD_DUID_FILE="/etc/dhcpcd.duid" + +RESOLVE_CONF="/etc/resolv.conf" + +rlJournalStart + rlPhaseStartSetup + rlAssertRpm $PACKAGE + + rlRun "systemctl stop firewalld" 0,5 + rlRun "setenforce 0" 0,1 + + rlFileBackup "$RESOLVE_CONF" + rlFileBackup "$DHCPCD_DUID_FILE" + rlRun "[ -e /sys/class/net/veth-test ] && ip link del veth-test" 0,1 + + rlLog "Create work dir ..." + rlRun "mkdir -p $DHCPCD_CI_DIR" + rlRun "cp *.conf $DHCPCD_CI_DIR" + + rlRun "cp dhcpcd-tests.py /usr/bin/" + rlPhaseEnd + + rlPhaseStartTest + rlLog "Starting dhcpcd tests ..." + rlRun "/usr/bin/python3 /usr/bin/dhcpcd-tests.py" + rlPhaseEnd + + rlPhaseStartCleanup + rlRun "rm /usr/bin/dhcpcd-tests.py" + rlRun "[ -e /sys/class/net/veth-test ] && ip link del veth-test" 0,1 + + rlFileRestore + + rlLog "remove work dir" + rlRun "rm -rf $DHCPCD_CI_DIR" + + rlRun "setenforce 1" 0,1 + rlLog "dhcpcd tests done" + rlPhaseEnd +rlJournalPrintText +rlJournalEnd + +rlGetTestState diff --git a/tests/tests.yml b/tests/tests.yml new file mode 100644 index 0000000..86858cb --- /dev/null +++ b/tests/tests.yml @@ -0,0 +1,18 @@ +- hosts: localhost + roles: + - role: standard-test-beakerlib + tags: + - classic + tests: + - ipv4-tests + - ipv6-tests + required_packages: + - radvd + - dnsmasq + - python3 + - tcpdump + - systemd + - iproute + - dhcpcd + - wide-dhcpv6 + - python3-pyroute2