diff options
Diffstat (limited to 'smoketest')
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_openvpn.py | 44 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_interfaces_tunnel.py | 6 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_policy_local-route.py | 61 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_igmp-proxy.py | 83 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_dhcp-relay.py | 93 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_dhcpv6-relay.py | 112 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_pppoe-server.py | 3 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_system_ntp.py | 7 |
8 files changed, 399 insertions, 10 deletions
diff --git a/smoketest/scripts/cli/test_interfaces_openvpn.py b/smoketest/scripts/cli/test_interfaces_openvpn.py index 41e48c2f8..e636e107d 100755 --- a/smoketest/scripts/cli/test_interfaces_openvpn.py +++ b/smoketest/scripts/cli/test_interfaces_openvpn.py @@ -131,6 +131,12 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.session.set(path + ['tls', 'cert-file', ssl_cert]) self.session.set(path + ['tls', 'key-file', ssl_key]) + # check validate() - can not have auth username without a password + self.session.set(path + ['authentication', 'username', 'vyos']) + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.set(path + ['authentication', 'password', 'vyos']) + # client commit must pass self.session.commit() @@ -162,6 +168,8 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.session.set(path + ['tls', 'cert-file', ssl_cert]) self.session.set(path + ['tls', 'key-file', ssl_key]) self.session.set(path + ['vrf', vrf_name]) + self.session.set(path + ['authentication', 'username', interface+'user']) + self.session.set(path + ['authentication', 'password', interface+'secretpw']) self.session.commit() @@ -169,6 +177,7 @@ class TestInterfacesOpenVPN(unittest.TestCase): interface = f'vtun{ii}' remote_host = f'192.0.2.{ii}' config_file = f'/run/openvpn/{interface}.conf' + pw_file = f'/run/openvpn/{interface}.pw' config = read_file(config_file) self.assertIn(f'dev {interface}', config) @@ -180,6 +189,7 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.assertIn(f'persist-tun', config) self.assertIn(f'auth {auth_hash}', config) self.assertIn(f'cipher aes-256-cbc', config) + # TLS options self.assertIn(f'ca {ca_cert}', config) self.assertIn(f'cert {ssl_cert}', config) @@ -189,6 +199,10 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.assertEqual(get_vrf(interface), vrf_name) self.assertIn(interface, interfaces()) + pw = cmd(f'sudo cat {pw_file}') + self.assertIn(f'{interface}user', pw) + self.assertIn(f'{interface}secretpw', pw) + # check that no interface remained after deleting them self.session.delete(base_path) self.session.commit() @@ -330,6 +344,8 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.session.set(path + ['local-port', port]) self.session.set(path + ['server', 'subnet', subnet]) self.session.set(path + ['server', 'topology', 'subnet']) + self.session.set(path + ['keep-alive', 'failure-count', '5']) + self.session.set(path + ['keep-alive', 'interval', '5']) # clients self.session.set(path + ['server', 'client', 'client1', 'ip', client_ip]) @@ -370,6 +386,7 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.assertIn(f'topology subnet', config) self.assertIn(f'lport {port}', config) self.assertIn(f'push "redirect-gateway def1"', config) + self.assertIn(f'keepalive 5 25', config) # TLS options self.assertIn(f'ca {ca_cert}', config) @@ -423,6 +440,8 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.session.set(path + ['server', 'subnet', subnet]) self.session.set(path + ['server', 'topology', 'net30']) self.session.set(path + ['replace-default-route']) + self.session.set(path + ['keep-alive', 'failure-count', '10']) + self.session.set(path + ['keep-alive', 'interval', '5']) self.session.set(path + ['tls', 'ca-cert-file', ca_cert]) self.session.set(path + ['tls', 'cert-file', ssl_cert]) self.session.set(path + ['tls', 'key-file', ssl_key]) @@ -450,6 +469,7 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.assertIn(f'topology net30', config) self.assertIn(f'lport {port}', config) self.assertIn(f'push "redirect-gateway def1"', config) + self.assertIn(f'keepalive 5 50', config) # TLS options self.assertIn(f'ca {ca_cert}', config) @@ -534,7 +554,7 @@ class TestInterfacesOpenVPN(unittest.TestCase): self.session.commit() - def test_site2site_interfaces(self): + def test_site2site_interfaces_tun(self): """ Create two OpenVPN site-to-site interfaces """ @@ -546,13 +566,22 @@ class TestInterfacesOpenVPN(unittest.TestCase): for ii in num_range: interface = f'vtun{ii}' local_address = f'192.0.{ii}.1' + local_address_subnet = '255.255.255.252' remote_address = f'172.16.{ii}.1' path = base_path + [interface] port = str(3000 + ii) + self.session.set(path + ['local-address', local_address]) + + # even numbers use tun type, odd numbers use tap type + if ii % 2 == 0: + self.session.set(path + ['device-type', 'tun']) + else: + self.session.set(path + ['device-type', 'tap']) + self.session.set(path + ['local-address', local_address, 'subnet-mask', local_address_subnet]) + self.session.set(path + ['mode', 'site-to-site']) self.session.set(path + ['local-port', port]) - self.session.set(path + ['local-address', local_address]) self.session.set(path + ['remote-port', port]) self.session.set(path + ['shared-secret-key-file', s2s_key]) self.session.set(path + ['remote-address', remote_address]) @@ -569,12 +598,19 @@ class TestInterfacesOpenVPN(unittest.TestCase): config_file = f'/run/openvpn/{interface}.conf' config = read_file(config_file) + # even numbers use tun type, odd numbers use tap type + if ii % 2 == 0: + self.assertIn(f'dev-type tun', config) + self.assertIn(f'ifconfig {local_address} {remote_address}', config) + else: + self.assertIn(f'dev-type tap', config) + self.assertIn(f'ifconfig {local_address} {local_address_subnet}', config) + self.assertIn(f'dev {interface}', config) - self.assertIn(f'dev-type tun', config) self.assertIn(f'secret {s2s_key}', config) self.assertIn(f'lport {port}', config) self.assertIn(f'rport {port}', config) - self.assertIn(f'ifconfig {local_address} {remote_address}', config) + self.assertTrue(process_named_running(PROCESS_NAME)) self.assertEqual(get_vrf(interface), vrf_name) diff --git a/smoketest/scripts/cli/test_interfaces_tunnel.py b/smoketest/scripts/cli/test_interfaces_tunnel.py index 4817321cf..aaff92dea 100755 --- a/smoketest/scripts/cli/test_interfaces_tunnel.py +++ b/smoketest/scripts/cli/test_interfaces_tunnel.py @@ -168,12 +168,12 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): self.session.set(self._base_path + [interface, 'local-ip', self.local_v6]) self.session.set(self._base_path + [interface, 'remote-ip', remote_ip6]) - # Encapsulation mode requires IPv6 local-ip + # Encapsulation mode requires IPv4 local-ip with self.assertRaises(ConfigSessionError): self.session.commit() self.session.set(self._base_path + [interface, 'local-ip', self.local_v4]) - # Encapsulation mode requires IPv6 local-ip + # Encapsulation mode requires IPv4 local-ip with self.assertRaises(ConfigSessionError): self.session.commit() self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) @@ -360,7 +360,7 @@ class TunnelInterfaceTest(BasicInterfaceTest.BaseTest): # No assertion is raised for GRE remote-ip when missing self.session.set(self._base_path + [interface, 'remote-ip', remote_ip4]) - # Source interface can not be used with si + # Source interface can not be used with sit self.session.set(self._base_path + [interface, 'source-interface', source_if]) with self.assertRaises(ConfigSessionError): self.session.commit() diff --git a/smoketest/scripts/cli/test_policy_local-route.py b/smoketest/scripts/cli/test_policy_local-route.py new file mode 100755 index 000000000..490bf6b47 --- /dev/null +++ b/smoketest/scripts/cli/test_policy_local-route.py @@ -0,0 +1,61 @@ +#!/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 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 + +class PolicyLocalRouteTest(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + self._sources = ['203.0.113.1', '203.0.113.2'] + + def tearDown(self): + # Delete all policies + self.session.delete(['policy', 'local-route']) + self.session.commit() + del self.session + + # Test set table for some sources + def test_table_id(self): + base = ['policy', 'local-route'] + rule = '50' + table = '23' + for src in self._sources: + self.session.set(base + ['rule', rule, 'set', 'table', table]) + self.session.set(base + ['rule', rule, 'source', src]) + + self.session.commit() + + # Check generated configuration + + # Expected values + original = """ + 50: from 203.0.113.1 lookup 23 + 50: from 203.0.113.2 lookup 23 + """ + tmp = cmd('ip rule show prio 50') + original = original.split() + tmp = tmp.split() + + self.assertEqual(tmp, original) + +if __name__ == '__main__': + unittest.main() diff --git a/smoketest/scripts/cli/test_protocols_igmp-proxy.py b/smoketest/scripts/cli/test_protocols_igmp-proxy.py new file mode 100755 index 000000000..f78581fea --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_igmp-proxy.py @@ -0,0 +1,83 @@ +#!/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 os +import unittest + +from vyos.configsession import ConfigSession +from vyos.configsession import ConfigSessionError +from vyos.util import read_file +from vyos.util import process_named_running + +PROCESS_NAME = 'igmpproxy' +IGMP_PROXY_CONF = '/etc/igmpproxy.conf' +base_path = ['protocols', 'igmp-proxy'] +upstream_if = 'eth1' +downstream_if = 'eth2' + +class TestProtocolsIGMPProxy(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + self.session.set(['interfaces', 'ethernet', upstream_if, 'address', '172.16.1.1/24']) + + def tearDown(self): + self.session.delete(['interfaces', 'ethernet', upstream_if, 'address']) + self.session.delete(base_path) + self.session.commit() + del self.session + + def test_igmpproxy(self): + threshold = '20' + altnet = '192.0.2.0/24' + whitelist = '10.0.0.0/8' + + self.session.set(base_path + ['disable-quickleave']) + self.session.set(base_path + ['interface', upstream_if, 'threshold', threshold]) + self.session.set(base_path + ['interface', upstream_if, 'alt-subnet', altnet]) + self.session.set(base_path + ['interface', upstream_if, 'whitelist', whitelist]) + + # Must define an upstream and at least 1 downstream interface! + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.set(base_path + ['interface', upstream_if, 'role', 'upstream']) + + # Interface does not exist + self.session.set(base_path + ['interface', 'eth20', 'role', 'upstream']) + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.delete(base_path + ['interface', 'eth20']) + + # Only 1 upstream interface allowed + self.session.set(base_path + ['interface', downstream_if, 'role', 'upstream']) + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.set(base_path + ['interface', downstream_if, 'role', 'downstream']) + + # commit changes + self.session.commit() + + # Check generated configuration + config = read_file(IGMP_PROXY_CONF) + self.assertIn(f'phyint {upstream_if} upstream ratelimit 0 threshold {threshold}', config) + self.assertIn(f'altnet {altnet}', config) + self.assertIn(f'whitelist {whitelist}', config) + self.assertIn(f'phyint {downstream_if} downstream ratelimit 0 threshold 1', config) + + # Check for running process + self.assertTrue(process_named_running(PROCESS_NAME)) + +if __name__ == '__main__': + unittest.main() diff --git a/smoketest/scripts/cli/test_service_dhcp-relay.py b/smoketest/scripts/cli/test_service_dhcp-relay.py new file mode 100755 index 000000000..4b020db72 --- /dev/null +++ b/smoketest/scripts/cli/test_service_dhcp-relay.py @@ -0,0 +1,93 @@ +#!/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.util import cmd +from vyos.util import process_named_running +from vyos.util import read_file + +PROCESS_NAME = 'dhcrelay' +RELAY_CONF = '/run/dhcp-relay/dhcrelay.conf' +base_path = ['service', 'dhcp-relay'] + +class TestServiceDHCPRelay(unittest.TestCase): + def setUp(self): + self.session = ConfigSession(os.getpid()) + + def tearDown(self): + self.session.delete(base_path) + self.session.commit() + del self.session + + def test_relay_default(self): + max_size = '800' + hop_count = '20' + agents_packets = 'append' + servers = ['192.0.2.1', '192.0.2.2'] + + self.session.set(base_path + ['interface', 'lo']) + # check validate() - DHCP relay does not support the loopback interface + with self.assertRaises(ConfigSessionError): + self.session.commit() + self.session.delete(base_path + ['interface', 'lo']) + + # activate DHCP relay on all ethernet interfaces + for tmp in Section.interfaces("ethernet"): + self.session.set(base_path + ['interface', tmp]) + + # check validate() - No DHCP relay server(s) configured + with self.assertRaises(ConfigSessionError): + self.session.commit() + for server in servers: + self.session.set(base_path + ['server', server]) + + self.session.set(base_path + ['relay-options', 'max-size', max_size]) + self.session.set(base_path + ['relay-options', 'hop-count', hop_count]) + self.session.set(base_path + ['relay-options', 'relay-agents-packets', agents_packets]) + + # commit changes + self.session.commit() + + # Check configured port + config = read_file(RELAY_CONF) + + # Test configured relay interfaces + for tmp in Section.interfaces("ethernet"): + self.assertIn(f'-i {tmp}', config) + + # Test relay servers + for server in servers: + self.assertIn(f' {server}', config) + + # Test max-size + self.assertIn(f'-A {max_size}', config) + # Hop count + self.assertIn(f'-c {hop_count}', config) + # relay-agents-packets + self.assertIn(f'-a -m {agents_packets}', config) + + # 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() + diff --git a/smoketest/scripts/cli/test_service_pppoe-server.py b/smoketest/scripts/cli/test_service_pppoe-server.py index f0c71e2de..ed006f16c 100755 --- a/smoketest/scripts/cli/test_service_pppoe-server.py +++ b/smoketest/scripts/cli/test_service_pppoe-server.py @@ -22,12 +22,9 @@ from base_accel_ppp_test import BasicAccelPPPTest from configparser import ConfigParser from vyos.configsession import ConfigSessionError from vyos.util import process_named_running -from vyos.util import cmd local_if = ['interfaces', 'dummy', 'dum667'] - ac_name = 'ACN' - interface = 'eth0' class TestServicePPPoEServer(BasicAccelPPPTest.BaseTest): diff --git a/smoketest/scripts/cli/test_system_ntp.py b/smoketest/scripts/cli/test_system_ntp.py index 822a9aff2..e2744c936 100755 --- a/smoketest/scripts/cli/test_system_ntp.py +++ b/smoketest/scripts/cli/test_system_ntp.py @@ -51,11 +51,15 @@ class TestSystemNTP(unittest.TestCase): """ Test basic NTP support with multiple servers and their options """ servers = ['192.0.2.1', '192.0.2.2'] options = ['noselect', 'preempt', 'prefer'] + ntp_pool = 'pool.vyos.io' for server in servers: for option in options: self.session.set(base_path + ['server', server, option]) + # Test NTP pool + self.session.set(base_path + ['server', ntp_pool, 'pool']) + # commit changes self.session.commit() @@ -65,6 +69,9 @@ class TestSystemNTP(unittest.TestCase): test = f'{server} iburst ' + ' '.join(options) self.assertTrue(test in tmp) + tmp = get_config_value('pool') + self.assertTrue(f'{ntp_pool} iburst' in tmp) + # Check for running process self.assertTrue(process_named_running(PROCESS_NAME)) |