summaryrefslogtreecommitdiff
path: root/smoketest/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest/scripts')
-rwxr-xr-xsmoketest/scripts/cli/test_configd_inspect.py7
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcp-relay.py8
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcp-server.py295
-rwxr-xr-xsmoketest/scripts/cli/test_service_dhcpv6-relay.py112
4 files changed, 412 insertions, 10 deletions
diff --git a/smoketest/scripts/cli/test_configd_inspect.py b/smoketest/scripts/cli/test_configd_inspect.py
index 5181187e9..4ebee8cc5 100755
--- a/smoketest/scripts/cli/test_configd_inspect.py
+++ b/smoketest/scripts/cli/test_configd_inspect.py
@@ -15,6 +15,7 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
+import re
import json
import unittest
import warnings
@@ -78,7 +79,8 @@ class TestConfigdInclude(unittest.TestCase):
if not f:
continue
str_f = getsource(f)
- n = str_f.count('Config()')
+ # Regex not XXXConfig() T3108
+ n = len(re.findall(r'[^a-zA-Z]Config\(\)', str_f))
if i == 'get_config':
self.assertEqual(n, 1,
f"'{s}': '{i}' no instance of Config")
@@ -91,7 +93,8 @@ class TestConfigdInclude(unittest.TestCase):
for s in self.inc_list:
m = import_script(s)
str_m = getsource(m)
- n = str_m.count('Config()')
+ # Regex not XXXConfig T3108
+ n = len(re.findall(r'[^a-zA-Z]Config\(\)', str_m))
self.assertEqual(n, 1,
f"'{s}' more than one instance of Config")
diff --git a/smoketest/scripts/cli/test_service_dhcp-relay.py b/smoketest/scripts/cli/test_service_dhcp-relay.py
index d56f6aa16..4b020db72 100755
--- a/smoketest/scripts/cli/test_service_dhcp-relay.py
+++ b/smoketest/scripts/cli/test_service_dhcp-relay.py
@@ -29,17 +29,9 @@ PROCESS_NAME = 'dhcrelay'
RELAY_CONF = '/run/dhcp-relay/dhcrelay.conf'
base_path = ['service', 'dhcp-relay']
-def get_config_value(key):
- tmp = read_file(SSHD_CONF)
- tmp = re.findall(f'\n?{key}\s+(.*)', tmp)
- return tmp
-
class TestServiceDHCPRelay(unittest.TestCase):
def setUp(self):
self.session = ConfigSession(os.getpid())
- # ensure we can also run this test on a live system - so lets clean
- # out the current configuration :)
- self.session.delete(base_path)
def tearDown(self):
self.session.delete(base_path)
diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py
new file mode 100755
index 000000000..4493534be
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_dhcp-server.py
@@ -0,0 +1,295 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2019-2020 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.util import cmd
+from vyos.util import process_named_running
+from vyos.util import read_file
+from vyos.template import inc_ip
+from vyos.template import address_from_cidr
+from vyos.template import netmask_from_cidr
+
+PROCESS_NAME = 'dhcpd'
+DHCPD_CONF = '/run/dhcp-server/dhcpd.conf'
+base_path = ['service', 'dhcp-server']
+subnet = '192.0.2.0/25'
+router = inc_ip(subnet, 1)
+dns_1 = inc_ip(subnet, 2)
+dns_2 = inc_ip(subnet, 3)
+domain_name = 'vyos.net'
+
+class TestServiceDHCPServer(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+ cidr_mask = subnet.split('/')[-1]
+ self.session.set(['interfaces', 'dummy', 'dum8765', 'address', f'{router}/{cidr_mask}'])
+
+ def tearDown(self):
+ self.session.delete(['interfaces', 'dummy', 'dum8765'])
+ self.session.delete(base_path)
+ self.session.commit()
+ del self.session
+
+ def test_single_pool_range(self):
+ shared_net_name = 'SMOKE-1'
+
+ range_0_start = inc_ip(subnet, 10)
+ range_0_stop = inc_ip(subnet, 20)
+ range_1_start = inc_ip(subnet, 40)
+ range_1_stop = inc_ip(subnet, 50)
+
+ self.session.set(base_path + ['dynamic-dns-update'])
+
+ pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
+ # we use the first subnet IP address as default gateway
+ self.session.set(pool + ['default-router', router])
+ self.session.set(pool + ['dns-server', dns_1])
+ self.session.set(pool + ['dns-server', dns_2])
+ self.session.set(pool + ['domain-name', domain_name])
+
+ # check validate() - No DHCP address range or active static-mapping set
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+ self.session.set(pool + ['range', '0', 'start', range_0_start])
+ self.session.set(pool + ['range', '0', 'stop', range_0_stop])
+ self.session.set(pool + ['range', '1', 'start', range_1_start])
+ self.session.set(pool + ['range', '1', 'stop', range_1_stop])
+
+ # commit changes
+ self.session.commit()
+
+ config = read_file(DHCPD_CONF)
+ network = address_from_cidr(subnet)
+ netmask = netmask_from_cidr(subnet)
+ self.assertIn(f'ddns-update-style interim;', config)
+ self.assertIn(f'subnet {network} netmask {netmask}' + r' {', config)
+ self.assertIn(f'option domain-name-servers {dns_1}, {dns_2};', config)
+ self.assertIn(f'option routers {router};', config)
+ self.assertIn(f'option domain-name "{domain_name}";', config)
+ self.assertIn(f'default-lease-time 86400;', config)
+ self.assertIn(f'max-lease-time 86400;', config)
+ self.assertIn(f'range {range_0_start} {range_0_stop};', config)
+ self.assertIn(f'range {range_1_start} {range_1_stop};', config)
+ self.assertIn(f'set shared-networkname = "{shared_net_name}";', config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_single_pool_options(self):
+ shared_net_name = 'SMOKE-0815'
+
+ range_0_start = inc_ip(subnet, 10)
+ range_0_stop = inc_ip(subnet, 20)
+ smtp_server = '1.2.3.4'
+ time_server = '4.3.2.1'
+ tftp_server = 'tftp.vyos.io'
+ search_domain = 'foo.vyos.net'
+ bootfile_name = 'vyos'
+ bootfile_server = '192.0.2.1'
+ wpad = 'http://wpad.vyos.io/foo/bar'
+ server_identifier = bootfile_server
+
+ pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
+ # we use the first subnet IP address as default gateway
+ self.session.set(pool + ['default-router', router])
+ self.session.set(pool + ['dns-server', dns_1])
+ self.session.set(pool + ['dns-server', dns_2])
+ self.session.set(pool + ['domain-name', domain_name])
+ self.session.set(pool + ['ip-forwarding'])
+ self.session.set(pool + ['smtp-server', smtp_server])
+ self.session.set(pool + ['pop-server', smtp_server])
+ self.session.set(pool + ['time-server', time_server])
+ self.session.set(pool + ['tftp-server-name', tftp_server])
+ self.session.set(pool + ['domain-search', search_domain])
+ self.session.set(pool + ['bootfile-name', bootfile_name])
+ self.session.set(pool + ['bootfile-server', bootfile_server])
+ self.session.set(pool + ['wpad-url', wpad])
+ self.session.set(pool + ['server-identifier', server_identifier])
+
+ self.session.set(pool + ['static-route', 'destination-subnet', '10.0.0.0/24'])
+ self.session.set(pool + ['static-route', 'router', '192.0.2.1'])
+
+
+ # check validate() - No DHCP address range or active static-mapping set
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+ self.session.set(pool + ['range', '0', 'start', range_0_start])
+ self.session.set(pool + ['range', '0', 'stop', range_0_stop])
+
+ # commit changes
+ self.session.commit()
+
+ config = read_file(DHCPD_CONF)
+ network = address_from_cidr(subnet)
+ netmask = netmask_from_cidr(subnet)
+ self.assertIn(f'ddns-update-style none;', config)
+ self.assertIn(f'subnet {network} netmask {netmask}' + r' {', config)
+ self.assertIn(f'option domain-name-servers {dns_1}, {dns_2};', config)
+ self.assertIn(f'option routers {router};', config)
+ self.assertIn(f'option domain-name "{domain_name}";', config)
+ self.assertIn(f'option domain-search "{search_domain}";', config)
+ self.assertIn(f'option ip-forwarding true;', config)
+ self.assertIn(f'option smtp-server {smtp_server};', config)
+ self.assertIn(f'option pop-server {smtp_server};', config)
+ self.assertIn(f'option time-servers {time_server};', config)
+ self.assertIn(f'option wpad-url "{wpad}";', config)
+ self.assertIn(f'option dhcp-server-identifier {server_identifier};', config)
+ self.assertIn(f'option tftp-server-name "{tftp_server}";', config)
+ self.assertIn(f'option bootfile-name "{bootfile_name}";', config)
+ self.assertIn(f'filename "{bootfile_name}";', config)
+ self.assertIn(f'next-server {bootfile_server};', config)
+ self.assertIn(f'default-lease-time 86400;', config)
+ self.assertIn(f'max-lease-time 86400;', config)
+ self.assertIn(f'range {range_0_start} {range_0_stop};', config)
+ self.assertIn(f'set shared-networkname = "{shared_net_name}";', config)
+
+ # weird syntax for those static routes
+ self.assertIn(f'option rfc3442-static-route 24,10,0,0,192,0,2,1, 0,192,0,2,1;', config)
+ self.assertIn(f'option windows-static-route 24,10,0,0,192,0,2,1;', config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_single_pool_static_mapping(self):
+ shared_net_name = 'SMOKE-2'
+
+ pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
+ # we use the first subnet IP address as default gateway
+ self.session.set(pool + ['default-router', router])
+ self.session.set(pool + ['dns-server', dns_1])
+ self.session.set(pool + ['dns-server', dns_2])
+ self.session.set(pool + ['domain-name', domain_name])
+
+ # check validate() - No DHCP address range or active static-mapping set
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+
+ client_base = 10
+ for client in ['client1', 'client2', 'client3']:
+ mac = '00:50:00:00:00:{}'.format(client_base)
+ self.session.set(pool + ['static-mapping', client, 'mac-address', mac])
+ self.session.set(pool + ['static-mapping', client, 'ip-address', inc_ip(subnet, client_base)])
+ client_base += 1
+
+ # commit changes
+ self.session.commit()
+
+ config = read_file(DHCPD_CONF)
+ network = address_from_cidr(subnet)
+ netmask = netmask_from_cidr(subnet)
+ self.assertIn(f'ddns-update-style none;', config)
+ self.assertIn(f'subnet {network} netmask {netmask}' + r' {', config)
+ self.assertIn(f'option domain-name-servers {dns_1}, {dns_2};', config)
+ self.assertIn(f'option routers {router};', config)
+ self.assertIn(f'option domain-name "{domain_name}";', config)
+ self.assertIn(f'default-lease-time 86400;', config)
+ self.assertIn(f'max-lease-time 86400;', config)
+
+ client_base = 10
+ for client in ['client1', 'client2', 'client3']:
+ mac = '00:50:00:00:00:{}'.format(client_base)
+ ip = inc_ip(subnet, client_base)
+ self.assertIn(f'host {shared_net_name}_{client}' + ' {', config)
+ self.assertIn(f'fixed-address {ip};', config)
+ self.assertIn(f'hardware ethernet {mac};', config)
+ client_base += 1
+
+ self.assertIn(f'set shared-networkname = "{shared_net_name}";', config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def test_multi_pools(self):
+ lease_time = '14400'
+
+ for network in ['0', '1', '2', '3']:
+ shared_net_name = f'VyOS-SMOKETEST-{network}'
+ subnet = f'192.0.{network}.0/24'
+ router = inc_ip(subnet, 1)
+ dns_1 = inc_ip(subnet, 2)
+
+ range_0_start = inc_ip(subnet, 10)
+ range_0_stop = inc_ip(subnet, 20)
+ range_1_start = inc_ip(subnet, 30)
+ range_1_stop = inc_ip(subnet, 40)
+
+ pool = base_path + ['shared-network-name', shared_net_name, 'subnet', subnet]
+ # we use the first subnet IP address as default gateway
+ self.session.set(pool + ['default-router', router])
+ self.session.set(pool + ['dns-server', dns_1])
+ self.session.set(pool + ['domain-name', domain_name])
+ self.session.set(pool + ['lease', lease_time])
+
+ self.session.set(pool + ['range', '0', 'start', range_0_start])
+ self.session.set(pool + ['range', '0', 'stop', range_0_stop])
+ self.session.set(pool + ['range', '1', 'start', range_1_start])
+ self.session.set(pool + ['range', '1', 'stop', range_1_stop])
+
+ client_base = 60
+ for client in ['client1', 'client2', 'client3', 'client4']:
+ mac = '02:50:00:00:00:{}'.format(client_base)
+ self.session.set(pool + ['static-mapping', client, 'mac-address', mac])
+ self.session.set(pool + ['static-mapping', client, 'ip-address', inc_ip(subnet, client_base)])
+ client_base += 1
+
+ # commit changes
+ self.session.commit()
+
+ config = read_file(DHCPD_CONF)
+ for network in ['0', '1', '2', '3']:
+ shared_net_name = f'VyOS-SMOKETEST-{network}'
+ subnet = f'192.0.{network}.0/24'
+ router = inc_ip(subnet, 1)
+ dns_1 = inc_ip(subnet, 2)
+
+ range_0_start = inc_ip(subnet, 10)
+ range_0_stop = inc_ip(subnet, 20)
+ range_1_start = inc_ip(subnet, 30)
+ range_1_stop = inc_ip(subnet, 40)
+
+ network = address_from_cidr(subnet)
+ netmask = netmask_from_cidr(subnet)
+
+ self.assertIn(f'ddns-update-style none;', config)
+ self.assertIn(f'subnet {network} netmask {netmask}' + r' {', config)
+ self.assertIn(f'option domain-name-servers {dns_1};', config)
+ self.assertIn(f'option routers {router};', config)
+ self.assertIn(f'option domain-name "{domain_name}";', config)
+ self.assertIn(f'default-lease-time {lease_time};', config)
+ self.assertIn(f'max-lease-time {lease_time};', config)
+ self.assertIn(f'range {range_0_start} {range_0_stop};', config)
+ self.assertIn(f'range {range_1_start} {range_1_stop};', config)
+ self.assertIn(f'set shared-networkname = "{shared_net_name}";', config)
+
+ client_base = 60
+ for client in ['client1', 'client2', 'client3', 'client4']:
+ mac = '02:50:00:00:00:{}'.format(client_base)
+ ip = inc_ip(subnet, client_base)
+ self.assertIn(f'host {shared_net_name}_{client}' + ' {', config)
+ self.assertIn(f'fixed-address {ip};', config)
+ self.assertIn(f'hardware ethernet {mac};', config)
+ client_base += 1
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/smoketest/scripts/cli/test_service_dhcpv6-relay.py b/smoketest/scripts/cli/test_service_dhcpv6-relay.py
new file mode 100755
index 000000000..ccc849a4f
--- /dev/null
+++ b/smoketest/scripts/cli/test_service_dhcpv6-relay.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2020 VyOS maintainers and contributors
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 or later as
+# published by the Free Software Foundation.
+#
+# This program 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 General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+import re
+import os
+import unittest
+
+from vyos.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.template import address_from_cidr
+from vyos.util import cmd
+from vyos.util import process_named_running
+from vyos.util import read_file
+
+PROCESS_NAME = 'dhcrelay'
+RELAY_CONF = '/run/dhcp-relay/dhcrelay6.conf'
+base_path = ['service', 'dhcpv6-relay']
+
+upstream_if = 'eth0'
+upstream_if_addr = '2001:db8::1/64'
+listen_addr = '2001:db8:ffff::1/64'
+interfaces = []
+
+class TestServiceDHCPv6Relay(unittest.TestCase):
+ def setUp(self):
+ self.session = ConfigSession(os.getpid())
+ for tmp in interfaces:
+ listen = listen_addr
+ if tmp == upstream_if:
+ listen = upstream_if_addr
+ self.session.set(['interfaces', 'ethernet', tmp, 'address', listen])
+
+ def tearDown(self):
+ self.session.delete(base_path)
+ for tmp in interfaces:
+ listen = listen_addr
+ if tmp == upstream_if:
+ listen = upstream_if_addr
+ self.session.delete(['interfaces', 'ethernet', tmp, 'address', listen])
+
+ self.session.commit()
+ del self.session
+
+ def test_relay_default(self):
+ dhcpv6_server = '2001:db8::ffff'
+ hop_count = '20'
+
+ self.session.set(base_path + ['use-interface-id-option'])
+ self.session.set(base_path + ['max-hop-count', hop_count])
+
+ # check validate() - Must set at least one listen and upstream
+ # interface addresses.
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+ self.session.set(base_path + ['upstream-interface', upstream_if, 'address', dhcpv6_server])
+
+ # check validate() - Must set at least one listen and upstream
+ # interface addresses.
+ with self.assertRaises(ConfigSessionError):
+ self.session.commit()
+
+ # add listener on all ethernet interfaces except the upstream interface
+ for tmp in interfaces:
+ if tmp == upstream_if:
+ continue
+ self.session.set(base_path + ['listen-interface', tmp, 'address', listen_addr.split('/')[0]])
+
+ # commit changes
+ self.session.commit()
+
+ # Check configured port
+ config = read_file(RELAY_CONF)
+
+ # Test configured upstream interfaces
+ self.assertIn(f'-u {dhcpv6_server}%{upstream_if}', config)
+
+ # Check listener on all ethernet interfaces
+ for tmp in interfaces:
+ if tmp == upstream_if:
+ continue
+ addr = listen_addr.split('/')[0]
+ self.assertIn(f'-l {addr}%{tmp}', config)
+
+ # Check hop count
+ self.assertIn(f'-c {hop_count}', config)
+ # Check Interface ID option
+ self.assertIn('-I', config)
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+if __name__ == '__main__':
+ for tmp in Section.interfaces('ethernet'):
+ if '.' not in tmp:
+ interfaces.append(tmp)
+
+ unittest.main()
+