diff options
Diffstat (limited to 'smoketest/scripts/cli')
-rwxr-xr-x | smoketest/scripts/cli/test_container.py | 16 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_protocols_babel.py | 218 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_qos.py | 241 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_dhcp-server.py | 23 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_service_mdns_repeater.py | 76 | ||||
-rwxr-xr-x | smoketest/scripts/cli/test_vpn_ipsec.py | 7 |
6 files changed, 558 insertions, 23 deletions
diff --git a/smoketest/scripts/cli/test_container.py b/smoketest/scripts/cli/test_container.py index c03b9eb44..0541384da 100755 --- a/smoketest/scripts/cli/test_container.py +++ b/smoketest/scripts/cli/test_container.py @@ -224,6 +224,22 @@ class TestContainer(VyOSUnitTestSHIM.TestCase): n = cmd_to_json(f'sudo podman network inspect {net_name}') self.assertEqual(n['dns_enabled'], False) + def test_network_mtu(self): + prefix = '192.0.2.0/24' + base_name = 'ipv4' + net_name = 'NET01' + + self.cli_set(base_path + ['network', net_name, 'prefix', prefix]) + self.cli_set(base_path + ['network', net_name, 'mtu', '1280']) + + name = f'{base_name}-2' + self.cli_set(base_path + ['name', name, 'image', cont_image]) + self.cli_set(base_path + ['name', name, 'network', net_name, 'address', str(ip_interface(prefix).ip + 2)]) + self.cli_commit() + + n = cmd_to_json(f'sudo podman network inspect {net_name}') + self.assertEqual(n['options']['mtu'], '1280') + def test_uid_gid(self): cont_name = 'uid-test' gid = '100' diff --git a/smoketest/scripts/cli/test_protocols_babel.py b/smoketest/scripts/cli/test_protocols_babel.py new file mode 100755 index 000000000..606c1efd3 --- /dev/null +++ b/smoketest/scripts/cli/test_protocols_babel.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python3 +# +# Copyright (C) 2024 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 unittest + +from base_vyostest_shim import VyOSUnitTestSHIM + +from vyos.ifconfig import Section +from vyos.utils.process import process_named_running +from vyos.xml_ref import default_value + +PROCESS_NAME = 'babeld' +base_path = ['protocols', 'babel'] + +class TestProtocolsBABEL(VyOSUnitTestSHIM.TestCase): + @classmethod + def setUpClass(cls): + cls._interfaces = Section.interfaces('ethernet', vlan=False) + # call base-classes classmethod + super(TestProtocolsBABEL, cls).setUpClass() + # Retrieve FRR daemon PID - it is not allowed to crash, thus PID must remain the same + cls.daemon_pid = process_named_running(PROCESS_NAME) + # ensure we can also run this test on a live system - so lets clean + # out the current configuration :) + cls.cli_delete(cls, base_path) + cls.cli_delete(cls, ['policy', 'prefix-list']) + cls.cli_delete(cls, ['policy', 'prefix-list6']) + + def tearDown(self): + # always destroy the entire babel configuration to make the processes + # life as hard as possible + self.cli_delete(base_path) + self.cli_delete(['policy', 'prefix-list']) + self.cli_delete(['policy', 'prefix-list6']) + self.cli_commit() + + # check process health and continuity + self.assertEqual(self.daemon_pid, process_named_running(PROCESS_NAME)) + + def test_babel_interfaces(self): + def_update_interval = default_value(base_path + ['interface', 'eth0', 'update-interval']) + channel = '20' + hello_interval = '1000' + max_rtt_penalty = '100' + rtt_decay = '23' + rtt_max = '119' + rtt_min = '11' + rxcost = '40000' + type = 'wired' + + for interface in self._interfaces: + self.cli_set(base_path + ['interface', interface]) + self.cli_set(base_path + ['interface', interface, 'channel', channel]) + self.cli_set(base_path + ['interface', interface, 'enable-timestamps']) + self.cli_set(base_path + ['interface', interface, 'hello-interval', hello_interval]) + self.cli_set(base_path + ['interface', interface, 'max-rtt-penalty', max_rtt_penalty]) + self.cli_set(base_path + ['interface', interface, 'rtt-decay', rtt_decay]) + self.cli_set(base_path + ['interface', interface, 'rtt-max', rtt_max]) + self.cli_set(base_path + ['interface', interface, 'rtt-min', rtt_min]) + self.cli_set(base_path + ['interface', interface, 'enable-timestamps']) + self.cli_set(base_path + ['interface', interface, 'rxcost', rxcost]) + self.cli_set(base_path + ['interface', interface, 'split-horizon', 'disable']) + self.cli_set(base_path + ['interface', interface, 'type', type]) + + self.cli_commit() + + frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) + for interface in self._interfaces: + self.assertIn(f' network {interface}', frrconfig) + + iface_config = self.getFRRconfig(f'interface {interface}', daemon=PROCESS_NAME) + self.assertIn(f' babel channel {channel}', iface_config) + self.assertIn(f' babel enable-timestamps', iface_config) + self.assertIn(f' babel update-interval {def_update_interval}', iface_config) + self.assertIn(f' babel hello-interval {hello_interval}', iface_config) + self.assertIn(f' babel rtt-decay {rtt_decay}', iface_config) + self.assertIn(f' babel rtt-max {rtt_max}', iface_config) + self.assertIn(f' babel rtt-min {rtt_min}', iface_config) + self.assertIn(f' babel rxcost {rxcost}', iface_config) + self.assertIn(f' babel max-rtt-penalty {max_rtt_penalty}', iface_config) + self.assertIn(f' no babel split-horizon', iface_config) + self.assertIn(f' babel {type}', iface_config) + + def test_babel_redistribute(self): + ipv4_protos = ['bgp', 'connected', 'isis', 'kernel', 'ospf', 'rip', 'static'] + ipv6_protos = ['bgp', 'connected', 'isis', 'kernel', 'ospfv3', 'ripng', 'static'] + + for protocol in ipv4_protos: + self.cli_set(base_path + ['redistribute', 'ipv4', protocol]) + for protocol in ipv6_protos: + self.cli_set(base_path + ['redistribute', 'ipv6', protocol]) + + self.cli_commit() + + frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) + for protocol in ipv4_protos: + self.assertIn(f' redistribute ipv4 {protocol}', frrconfig) + for protocol in ipv6_protos: + if protocol == 'ospfv3': + protocol = 'ospf6' + self.assertIn(f' redistribute ipv6 {protocol}', frrconfig) + + def test_babel_basic(self): + diversity_factor = '64' + resend_delay = '100' + smoothing_half_life = '400' + + self.cli_set(base_path + ['parameters', 'diversity']) + self.cli_set(base_path + ['parameters', 'diversity-factor', diversity_factor]) + self.cli_set(base_path + ['parameters', 'resend-delay', resend_delay]) + self.cli_set(base_path + ['parameters', 'smoothing-half-life', smoothing_half_life]) + + self.cli_commit() + + frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) + self.assertIn(f' babel diversity', frrconfig) + self.assertIn(f' babel diversity-factor {diversity_factor}', frrconfig) + self.assertIn(f' babel resend-delay {resend_delay}', frrconfig) + self.assertIn(f' babel smoothing-half-life {smoothing_half_life}', frrconfig) + + def test_babel_distribute_list(self): + access_list_in4 = '40' + access_list_out4 = '50' + access_list_in4_iface = '44' + access_list_out4_iface = '55' + access_list_in6 = 'AL-foo-in6' + access_list_out6 = 'AL-foo-out6' + + prefix_list_in4 = 'PL-foo-in4' + prefix_list_out4 = 'PL-foo-out4' + prefix_list_in6 = 'PL-foo-in6' + prefix_list_out6 = 'PL-foo-out6' + + self.cli_set(['policy', 'access-list', access_list_in4]) + self.cli_set(['policy', 'access-list', access_list_out4]) + self.cli_set(['policy', 'access-list6', access_list_in6]) + self.cli_set(['policy', 'access-list6', access_list_out6]) + + self.cli_set(['policy', 'access-list', f'{access_list_in4_iface}']) + self.cli_set(['policy', 'access-list', f'{access_list_out4_iface}']) + + self.cli_set(['policy', 'prefix-list', prefix_list_in4]) + self.cli_set(['policy', 'prefix-list', prefix_list_out4]) + self.cli_set(['policy', 'prefix-list6', prefix_list_in6]) + self.cli_set(['policy', 'prefix-list6', prefix_list_out6]) + + self.cli_set(base_path + ['distribute-list', 'ipv4', 'access-list', 'in', access_list_in4]) + self.cli_set(base_path + ['distribute-list', 'ipv4', 'access-list', 'out', access_list_out4]) + self.cli_set(base_path + ['distribute-list', 'ipv6', 'access-list', 'in', access_list_in6]) + self.cli_set(base_path + ['distribute-list', 'ipv6', 'access-list', 'out', access_list_out6]) + + self.cli_set(base_path + ['distribute-list', 'ipv4', 'prefix-list', 'in', prefix_list_in4]) + self.cli_set(base_path + ['distribute-list', 'ipv4', 'prefix-list', 'out', prefix_list_out4]) + self.cli_set(base_path + ['distribute-list', 'ipv6', 'prefix-list', 'in', prefix_list_in6]) + self.cli_set(base_path + ['distribute-list', 'ipv6', 'prefix-list', 'out', prefix_list_out6]) + + for interface in self._interfaces: + self.cli_set(base_path + ['interface', interface]) + + self.cli_set(['policy', 'access-list6', f'{access_list_in6}-{interface}']) + self.cli_set(['policy', 'access-list6', f'{access_list_out6}-{interface}']) + + self.cli_set(['policy', 'prefix-list', f'{prefix_list_in4}-{interface}']) + self.cli_set(['policy', 'prefix-list', f'{prefix_list_out4}-{interface}']) + self.cli_set(['policy', 'prefix-list6', f'{prefix_list_in6}-{interface}']) + self.cli_set(['policy', 'prefix-list6', f'{prefix_list_out6}-{interface}']) + + tmp_path = base_path + ['distribute-list', 'ipv4', 'interface', interface] + self.cli_set(tmp_path + ['access-list', 'in', f'{access_list_in4_iface}']) + self.cli_set(tmp_path + ['access-list', 'out', f'{access_list_out4_iface}']) + self.cli_set(tmp_path + ['prefix-list', 'in', f'{prefix_list_in4}-{interface}']) + self.cli_set(tmp_path + ['prefix-list', 'out', f'{prefix_list_out4}-{interface}']) + + tmp_path = base_path + ['distribute-list', 'ipv6', 'interface', interface] + self.cli_set(tmp_path + ['access-list', 'in', f'{access_list_in6}-{interface}']) + self.cli_set(tmp_path + ['access-list', 'out', f'{access_list_out6}-{interface}']) + self.cli_set(tmp_path + ['prefix-list', 'in', f'{prefix_list_in6}-{interface}']) + self.cli_set(tmp_path + ['prefix-list', 'out', f'{prefix_list_out6}-{interface}']) + + self.cli_commit() + + frrconfig = self.getFRRconfig('router babel', daemon=PROCESS_NAME) + self.assertIn(f' distribute-list {access_list_in4} in', frrconfig) + self.assertIn(f' distribute-list {access_list_out4} out', frrconfig) + self.assertIn(f' ipv6 distribute-list {access_list_in6} in', frrconfig) + self.assertIn(f' ipv6 distribute-list {access_list_out6} out', frrconfig) + + self.assertIn(f' distribute-list prefix {prefix_list_in4} in', frrconfig) + self.assertIn(f' distribute-list prefix {prefix_list_out4} out', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in6} in', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out6} out', frrconfig) + + for interface in self._interfaces: + self.assertIn(f' distribute-list {access_list_in4_iface} in {interface}', frrconfig) + self.assertIn(f' distribute-list {access_list_out4_iface} out {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list {access_list_in6}-{interface} in {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list {access_list_out6}-{interface} out {interface}', frrconfig) + + self.assertIn(f' distribute-list prefix {prefix_list_in4}-{interface} in {interface}', frrconfig) + self.assertIn(f' distribute-list prefix {prefix_list_out4}-{interface} out {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_in6}-{interface} in {interface}', frrconfig) + self.assertIn(f' ipv6 distribute-list prefix {prefix_list_out6}-{interface} out {interface}', frrconfig) + +if __name__ == '__main__': + unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_qos.py b/smoketest/scripts/cli/test_qos.py index 77d384024..79b791288 100755 --- a/smoketest/scripts/cli/test_qos.py +++ b/smoketest/scripts/cli/test_qos.py @@ -21,7 +21,8 @@ from json import loads from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError -from vyos.ifconfig import Section +from vyos.ifconfig import Section, Interface +from vyos.qos import CAKE from vyos.utils.process import cmd base_path = ['qos'] @@ -871,6 +872,68 @@ class TestQoS(VyOSUnitTestSHIM.TestCase): self.cli_set(['qos', 'traffic-match-group', '3', 'match-group', 'unexpected']) self.cli_commit() + def test_17_cake_updates(self): + bandwidth = 1000000 + rtt = 200 + interface = self._interfaces[0] + policy_name = f'qos-policy-{interface}' + + self.cli_set(base_path + ['interface', interface, 'egress', policy_name]) + self.cli_set( + base_path + ['policy', 'cake', policy_name, 'bandwidth', str(bandwidth)] + ) + self.cli_set(base_path + ['policy', 'cake', policy_name, 'rtt', str(rtt)]) + + # commit changes + self.cli_commit() + + tmp = get_tc_qdisc_json(interface) + + self.assertEqual('cake', tmp['kind']) + # TC store rates as a 32-bit unsigned integer in bps (Bytes per second) + self.assertEqual(int(bandwidth * 125), tmp['options']['bandwidth']) + # RTT internally is in us + self.assertEqual(int(rtt * 1000), tmp['options']['rtt']) + self.assertEqual('triple-isolate', tmp['options']['flowmode']) + self.assertFalse(tmp['options']['ingress']) + self.assertFalse(tmp['options']['nat']) + self.assertTrue(tmp['options']['raw']) + + nat = True + for flow_isolation in [ + 'blind', + 'src-host', + 'dst-host', + 'dual-dst-host', + 'dual-src-host', + 'triple-isolate', + 'flow', + 'host', + ]: + self.cli_set( + base_path + + ['policy', 'cake', policy_name, 'flow-isolation', flow_isolation] + ) + + if nat: + self.cli_set( + base_path + ['policy', 'cake', policy_name, 'flow-isolation-nat'] + ) + else: + self.cli_delete( + base_path + ['policy', 'cake', policy_name, 'flow-isolation-nat'] + ) + + self.cli_commit() + + tmp = get_tc_qdisc_json(interface) + self.assertEqual( + CAKE.flow_isolation_map.get(flow_isolation), tmp['options']['flowmode'] + ) + + self.assertEqual(nat, tmp['options']['nat']) + nat = not nat + def test_20_round_robin_policy_default(self): interface = self._interfaces[0] policy_name = f'qos-policy-{interface}' @@ -922,6 +985,182 @@ class TestQoS(VyOSUnitTestSHIM.TestCase): tmp[2]['options'], ) + def test_21_shaper_hfsc(self): + interface = self._interfaces[0] + policy_name = f'qos-policy-{interface}' + ul = { + 'm1': '100kbit', + 'm2': '150kbit', + 'd': '100', + } + ls = {'m2': '120kbit'} + rt = { + 'm1': '110kbit', + 'm2': '130kbit', + 'd': '75', + } + self.cli_set(base_path + ['interface', interface, 'egress', policy_name]) + self.cli_set(base_path + ['policy', 'shaper-hfsc', policy_name]) + + # Policy {policy_name} misses "default" class! + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'default', 'upperlimit'] + ) + + # At least one m2 value needs to be set for class: {class_name} + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'default', 'upperlimit', 'm1', ul['m1']] + ) + # {class_name} upperlimit m1 value is set, but no m2 was found! + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'default', 'upperlimit', 'm2', ul['m2']] + ) + # {class_name} upperlimit m1 value is set, but no d was found! + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'default', 'upperlimit', 'd', ul['d']] + ) + # Linkshare m2 needs to be defined to use upperlimit m2 for class: {class_name} + with self.assertRaises(ConfigSessionError): + self.cli_commit() + + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'default', 'linkshare', 'm2', ls['m2']] + ) + self.cli_commit() + + # use raw because tc json is incorrect here + tmp = cmd(f'tc -details qdisc show dev {interface}') + for rec in tmp.split('\n'): + rec = rec.strip() + if 'root' in rec: + self.assertEqual(rec, 'qdisc hfsc 1: root refcnt 2 default 2') + else: + self.assertRegex( + rec, + r'qdisc sfq \S+: parent 1:2 limit 127p quantum 1514b depth 127 flows 128 divisor 1024 perturb 10sec', + ) + # use raw because tc json is incorrect here + tmp = cmd(f'tc -details class show dev {interface}') + for rec in tmp.split('\n'): + rec = rec.strip().lower() + if 'root' in rec: + self.assertEqual(rec, 'class hfsc 1: root') + elif 'hfsc 1:1' in rec: + # m2 \S+bit is auto bandwidth + self.assertRegex( + rec, + r'class hfsc 1:1 parent 1: sc m1 0bit d 0us m2 \S+bit ul m1 0bit d 0us m2 \S+bit', + ) + else: + self.assertRegex( + rec, + rf'class hfsc 1:2 parent 1:1 leaf \S+: ls m1 0bit d 0us m2 {ls["m2"]} ul m1 {ul["m1"]} d {ul["d"]}ms m2 {ul["m2"]}', + ) + + for key, val in rt.items(): + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'default', 'realtime', key, val] + ) + self.cli_commit() + + tmp = cmd(f'tc -details class show dev {interface}') + for rec in tmp.split('\n'): + rec = rec.strip().lower() + if 'hfsc 1:2' in rec: + self.assertTrue( + f'rt m1 {rt["m1"]} d {rt["d"]}ms m2 {rt["m2"]} ls m1 0bit d 0us m2 {ls["m2"]} ul m1 {ul["m1"]} d {ul["d"]}ms m2 {ul["m2"]}' + in rec + ) + + # add some class + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'class', '10', 'linkshare', 'm2', '300kbit'] + ) + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'class', '10', 'match', 'tst', 'ip', 'dscp', 'internet'] + ) + + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'class', '30', 'realtime', 'm2', '250kbit'] + ) + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'class', '30', 'realtime', 'd', '77'] + ) + self.cli_set( + base_path + ['policy', 'shaper-hfsc', policy_name, 'class', '30', 'match', 'tst30', 'ip', 'dscp', 'critical'] + ) + self.cli_commit() + + tmp = cmd(f'tc -details qdisc show dev {interface}') + self.assertEqual(4, len(tmp.split('\n'))) + + tmp = cmd(f'tc -details class show dev {interface}') + tmp = tmp.lower() + + self.assertTrue( + f'rt m1 {rt["m1"]} d {rt["d"]}ms m2 {rt["m2"]} ls m1 0bit d 0us m2 {ls["m2"]} ul m1 {ul["m1"]} d {ul["d"]}ms m2 {ul["m2"]}' + in tmp + ) + self.assertTrue(': ls m1 0bit d 0us m2 300kbit' in tmp) + self.assertTrue(': rt m1 0bit d 77ms m2 250kbit' in tmp) + + def test_22_rate_control_default(self): + interface = self._interfaces[0] + policy_name = f'qos-policy-{interface}' + bandwidth = 5000 + + self.cli_set(base_path + ['interface', interface, 'egress', policy_name]) + self.cli_set(base_path + ['policy', 'rate-control', policy_name]) + with self.assertRaises(ConfigSessionError): + # Bandwidth not defined + self.cli_commit() + + self.cli_set(base_path + ['policy', 'rate-control', policy_name, 'bandwidth', str(bandwidth)]) + # commit changes + self.cli_commit() + + tmp = get_tc_qdisc_json(interface) + + self.assertEqual('tbf', tmp['kind']) + # TC store rates as a 32-bit unsigned integer in bps (Bytes per second) + self.assertEqual(int(bandwidth * 125), tmp['options']['rate']) + + def test_23_policy_limiter_iif_filter(self): + policy_name = 'smoke_test' + base_policy_path = ['qos', 'policy', 'limiter', policy_name] + + self.cli_set(['qos', 'interface', self._interfaces[0], 'ingress', policy_name]) + self.cli_set(base_policy_path + ['class', '100', 'bandwidth', '20gbit']) + self.cli_set(base_policy_path + ['class', '100', 'burst', '3760k']) + self.cli_set(base_policy_path + ['class', '100', 'match', 'test', 'interface', self._interfaces[0]]) + self.cli_set(base_policy_path + ['class', '100', 'priority', '20']) + self.cli_set(base_policy_path + ['default', 'bandwidth', '1gbit']) + self.cli_set(base_policy_path + ['default', 'burst', '125000000b']) + self.cli_commit() + + iif = Interface(self._interfaces[0]).get_ifindex() + tc_filters = cmd(f'tc filter show dev {self._interfaces[0]} ingress') + + # class 100 + self.assertIn('filter parent ffff: protocol all pref 20 basic chain 0', tc_filters) + self.assertIn(f'meta(rt_iif eq {iif})', tc_filters) + self.assertIn('action order 1: police 0x1 rate 20Gbit burst 3847500b mtu 2Kb action drop overhead 0b', tc_filters) + # default + self.assertIn('filter parent ffff: protocol all pref 255 basic chain 0', tc_filters) + self.assertIn('action order 1: police 0x2 rate 1Gbit burst 125000000b mtu 2Kb action drop overhead 0b', tc_filters) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_service_dhcp-server.py b/smoketest/scripts/cli/test_service_dhcp-server.py index 46c4e25a1..f891bf295 100755 --- a/smoketest/scripts/cli/test_service_dhcp-server.py +++ b/smoketest/scripts/cli/test_service_dhcp-server.py @@ -557,6 +557,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): self.cli_set(pool + ['subnet-id', '1']) self.cli_set(pool + ['option', 'default-router', router]) self.cli_set(pool + ['exclude', router]) + self.cli_set(pool + ['range', '0', 'option', 'default-router', router]) self.cli_set(pool + ['range', '0', 'start', range_0_start]) self.cli_set(pool + ['range', '0', 'stop', range_0_stop]) @@ -569,6 +570,11 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'name', 'EXCLUDE-TEST') self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'subnet', subnet) + pool_obj = { + 'pool': f'{range_0_start} - {range_0_stop}', + 'option-data': [{'name': 'routers', 'data': router}] + } + # Verify options self.verify_config_object( obj, @@ -579,7 +585,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): self.verify_config_object( obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools'], - {'pool': f'{range_0_start} - {range_0_stop}'}) + pool_obj) # Check for running process self.assertTrue(process_named_running(PROCESS_NAME)) @@ -600,6 +606,7 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): self.cli_set(pool + ['subnet-id', '1']) self.cli_set(pool + ['option', 'default-router', router]) self.cli_set(pool + ['exclude', exclude_addr]) + self.cli_set(pool + ['range', '0', 'option', 'default-router', router]) self.cli_set(pool + ['range', '0', 'start', range_0_start]) self.cli_set(pool + ['range', '0', 'stop', range_0_stop]) @@ -612,6 +619,16 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): self.verify_config_value(obj, ['Dhcp4', 'shared-networks'], 'name', 'EXCLUDE-TEST-2') self.verify_config_value(obj, ['Dhcp4', 'shared-networks', 0, 'subnet4'], 'subnet', subnet) + pool_obj = { + 'pool': f'{range_0_start} - {range_0_stop_excl}', + 'option-data': [{'name': 'routers', 'data': router}] + } + + pool_exclude_obj = { + 'pool': f'{range_0_start_excl} - {range_0_stop}', + 'option-data': [{'name': 'routers', 'data': router}] + } + # Verify options self.verify_config_object( obj, @@ -621,12 +638,12 @@ class TestServiceDHCPServer(VyOSUnitTestSHIM.TestCase): self.verify_config_object( obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools'], - {'pool': f'{range_0_start} - {range_0_stop_excl}'}) + pool_obj) self.verify_config_object( obj, ['Dhcp4', 'shared-networks', 0, 'subnet4', 0, 'pools'], - {'pool': f'{range_0_start_excl} - {range_0_stop}'}) + pool_exclude_obj) # Check for running process self.assertTrue(process_named_running(PROCESS_NAME)) diff --git a/smoketest/scripts/cli/test_service_mdns_repeater.py b/smoketest/scripts/cli/test_service_mdns_repeater.py index f2fb3b509..30e48683f 100755 --- a/smoketest/scripts/cli/test_service_mdns_repeater.py +++ b/smoketest/scripts/cli/test_service_mdns_repeater.py @@ -21,36 +21,45 @@ from base_vyostest_shim import VyOSUnitTestSHIM from configparser import ConfigParser from vyos.configsession import ConfigSessionError from vyos.utils.process import process_named_running +from vyos.xml_ref import default_value base_path = ['service', 'mdns', 'repeater'] intf_base = ['interfaces', 'dummy'] config_file = '/run/avahi-daemon/avahi-daemon.conf' - class TestServiceMDNSrepeater(VyOSUnitTestSHIM.TestCase): - def setUp(self): - # Start with a clean CLI instance - self.cli_delete(base_path) + @classmethod + def setUpClass(cls): + super(TestServiceMDNSrepeater, cls).setUpClass() - # Service required a configured IP address on the interface - self.cli_set(intf_base + ['dum10', 'address', '192.0.2.1/30']) - self.cli_set(intf_base + ['dum10', 'ipv6', 'address', 'no-default-link-local']) - self.cli_set(intf_base + ['dum20', 'address', '192.0.2.5/30']) - self.cli_set(intf_base + ['dum20', 'address', '2001:db8:0:2::5/64']) - self.cli_set(intf_base + ['dum30', 'address', '192.0.2.9/30']) - self.cli_set(intf_base + ['dum30', 'address', '2001:db8:0:2::9/64']) - self.cli_set(intf_base + ['dum40', 'address', '2001:db8:0:2::11/64']) - self.cli_commit() + # ensure we can also run this test on a live system - so lets clean + # out the current configuration :) + cls.cli_delete(cls, base_path) + + cls.cli_set(cls, intf_base + ['dum10', 'address', '192.0.2.1/30']) + cls.cli_set(cls, intf_base + ['dum10', 'ipv6', 'address', 'no-default-link-local']) + cls.cli_set(cls, intf_base + ['dum20', 'address', '192.0.2.5/30']) + cls.cli_set(cls, intf_base + ['dum20', 'address', '2001:db8:0:2::5/64']) + cls.cli_set(cls, intf_base + ['dum30', 'address', '192.0.2.9/30']) + cls.cli_set(cls, intf_base + ['dum30', 'address', '2001:db8:0:2::9/64']) + cls.cli_set(cls, intf_base + ['dum40', 'address', '2001:db8:0:2::11/64']) + + cls.cli_commit(cls) + + @classmethod + def tearDownClass(cls): + cls.cli_delete(cls, intf_base + ['dum10']) + cls.cli_delete(cls, intf_base + ['dum20']) + cls.cli_delete(cls, intf_base + ['dum30']) + cls.cli_delete(cls, intf_base + ['dum40']) + + cls.cli_commit(cls) def tearDown(self): # Check for running process self.assertTrue(process_named_running('avahi-daemon')) self.cli_delete(base_path) - self.cli_delete(intf_base + ['dum10']) - self.cli_delete(intf_base + ['dum20']) - self.cli_delete(intf_base + ['dum30']) - self.cli_delete(intf_base + ['dum40']) self.cli_commit() # Check that there is no longer a running process @@ -130,5 +139,38 @@ class TestServiceMDNSrepeater(VyOSUnitTestSHIM.TestCase): self.assertEqual(conf['server']['allow-interfaces'], 'dum30, dum40') self.assertEqual(conf['reflector']['enable-reflector'], 'yes') + def test_service_max_cache_entries(self): + cli_default_max_cache = default_value(base_path + ['cache-entries']) + self.cli_set(base_path) + + # Need at least two interfaces + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(base_path + ['interface', 'dum20']) + + # Need at least two interfaces + with self.assertRaises(ConfigSessionError): + self.cli_commit() + self.cli_set(base_path + ['interface', 'dum30']) + + self.cli_commit() + + # Validate configuration values + conf = ConfigParser(delimiters='=') + conf.read(config_file) + self.assertEqual(conf['server']['cache-entries-max'], cli_default_max_cache) + + # Set max cache entries + cache_entries = '1234' + self.cli_set(base_path + ['cache-entries', cache_entries]) + + self.cli_commit() + + # Validate configuration values + conf = ConfigParser(delimiters='=') + conf.read(config_file) + + self.assertEqual(conf['server']['cache-entries-max'], cache_entries) + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/smoketest/scripts/cli/test_vpn_ipsec.py b/smoketest/scripts/cli/test_vpn_ipsec.py index de18d0427..f2bea58d1 100755 --- a/smoketest/scripts/cli/test_vpn_ipsec.py +++ b/smoketest/scripts/cli/test_vpn_ipsec.py @@ -21,6 +21,7 @@ from base_vyostest_shim import VyOSUnitTestSHIM from vyos.configsession import ConfigSessionError from vyos.ifconfig import Interface +from vyos.utils.convert import encode_to_base64 from vyos.utils.process import process_named_running from vyos.utils.file import read_file @@ -495,6 +496,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase): local_id = 'vyos-r1' remote_id = 'vyos-r2' peer_base_path = base_path + ['site-to-site', 'peer', connection_name] + secret_base64 = encode_to_base64(secret) self.cli_set(tunnel_path + ['tun1', 'encapsulation', 'gre']) self.cli_set(tunnel_path + ['tun1', 'source-address', local_address]) @@ -509,7 +511,8 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase): self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', remote_id]) self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', local_address]) self.cli_set(base_path + ['authentication', 'psk', connection_name, 'id', peer_ip]) - self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret', secret]) + self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret', secret_base64]) + self.cli_set(base_path + ['authentication', 'psk', connection_name, 'secret-type', 'base64']) self.cli_set(peer_base_path + ['authentication', 'local-id', local_id]) self.cli_set(peer_base_path + ['authentication', 'mode', 'pre-shared-secret']) @@ -546,7 +549,7 @@ class TestVPNIPsec(VyOSUnitTestSHIM.TestCase): f'id-{regex_uuid4} = "{remote_id}"', f'id-{regex_uuid4} = "{peer_ip}"', f'id-{regex_uuid4} = "{local_address}"', - f'secret = "{secret}"', + f'secret = 0s{secret_base64}', ] for line in swanctl_secrets_lines: |