summaryrefslogtreecommitdiff
path: root/smoketest/scripts/cli
diff options
context:
space:
mode:
Diffstat (limited to 'smoketest/scripts/cli')
-rw-r--r--smoketest/scripts/cli/base_interfaces_test.py34
-rw-r--r--smoketest/scripts/cli/base_vyostest_shim.py21
-rwxr-xr-xsmoketest/scripts/cli/test_interfaces_bridge.py53
-rw-r--r--[-rwxr-xr-x]smoketest/scripts/cli/test_nat.py0
-rwxr-xr-xsmoketest/scripts/cli/test_protocols_isis.py170
-rwxr-xr-xsmoketest/scripts/cli/test_system_login.py41
6 files changed, 291 insertions, 28 deletions
diff --git a/smoketest/scripts/cli/base_interfaces_test.py b/smoketest/scripts/cli/base_interfaces_test.py
index 6f8eda26a..4acde99d3 100644
--- a/smoketest/scripts/cli/base_interfaces_test.py
+++ b/smoketest/scripts/cli/base_interfaces_test.py
@@ -246,11 +246,19 @@ class BasicInterfaceTest:
for intf in self._interfaces:
base = self._base_path + [intf]
self.cli_set(base + ['mtu', self._mtu])
- self.cli_set(base + ['ipv6', 'address', 'no-default-link-local'])
for option in self._options.get(intf, []):
self.cli_set(base + option.split())
+ # check validate() - can not set low MTU if 'no-default-link-local'
+ # is not set on CLI
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ for intf in self._interfaces:
+ base = self._base_path + [intf]
+ self.cli_set(base + ['ipv6', 'address', 'no-default-link-local'])
+
# commit interface changes
self.cli_commit()
@@ -438,28 +446,30 @@ class BasicInterfaceTest:
tmp = read_file(f'/proc/sys/net/ipv4/neigh/{interface}/base_reachable_time_ms')
self.assertEqual(tmp, str((int(arp_tmo) * 1000))) # tmo value is in milli seconds
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_filter')
+ proc_base = f'/proc/sys/net/ipv4/conf/{interface}'
+
+ tmp = read_file(f'{proc_base}/arp_filter')
self.assertEqual('0', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_accept')
+ tmp = read_file(f'{proc_base}/arp_accept')
self.assertEqual('1', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_announce')
+ tmp = read_file(f'{proc_base}/arp_announce')
self.assertEqual('1', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/arp_ignore')
+ tmp = read_file(f'{proc_base}/arp_ignore')
self.assertEqual('1', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/forwarding')
+ tmp = read_file(f'{proc_base}/forwarding')
self.assertEqual('0', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/proxy_arp')
+ tmp = read_file(f'{proc_base}/proxy_arp')
self.assertEqual('1', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/proxy_arp_pvlan')
+ tmp = read_file(f'{proc_base}/proxy_arp_pvlan')
self.assertEqual('1', tmp)
- tmp = read_file(f'/proc/sys/net/ipv4/conf/{interface}/rp_filter')
+ tmp = read_file(f'{proc_base}/rp_filter')
self.assertEqual('2', tmp)
def test_interface_ipv6_options(self):
@@ -479,10 +489,12 @@ class BasicInterfaceTest:
self.cli_commit()
for interface in self._interfaces:
- tmp = read_file(f'/proc/sys/net/ipv6/conf/{interface}/forwarding')
+ proc_base = f'/proc/sys/net/ipv6/conf/{interface}'
+
+ tmp = read_file(f'{proc_base}/forwarding')
self.assertEqual('0', tmp)
- tmp = read_file(f'/proc/sys/net/ipv6/conf/{interface}/dad_transmits')
+ tmp = read_file(f'{proc_base}/dad_transmits')
self.assertEqual(dad_transmits, tmp)
def test_dhcpv6_client_options(self):
diff --git a/smoketest/scripts/cli/base_vyostest_shim.py b/smoketest/scripts/cli/base_vyostest_shim.py
index 18e4e567e..93b2ca150 100644
--- a/smoketest/scripts/cli/base_vyostest_shim.py
+++ b/smoketest/scripts/cli/base_vyostest_shim.py
@@ -20,7 +20,9 @@ from time import sleep
from vyos.configsession import ConfigSession
from vyos.configsession import ConfigSessionError
from vyos import ConfigError
+from vyos.defaults import commit_lock
from vyos.util import cmd
+from vyos.util import run
save_config = '/tmp/vyos-smoketest-save'
@@ -70,21 +72,16 @@ class VyOSUnitTestSHIM:
def cli_commit(self):
self._session.commit()
+ # during a commit there is a process opening commit_lock, and run() returns 0
+ while run(f'sudo lsof | grep -q {commit_lock}') == 0:
+ sleep(0.250)
def getFRRconfig(self, string, end='$'):
""" Retrieve current "running configuration" from FRR """
command = f'vtysh -c "show run" | sed -n "/^{string}{end}/,/^!/p"'
-
- count = 0
- tmp = ''
- while count < 10 and tmp == '':
- # Let FRR settle after a config change first before harassing it again
- sleep(1)
- tmp = cmd(command)
- count += 1
-
- if self.debug or tmp == '':
+ out = cmd(command)
+ if self.debug:
import pprint
print(f'\n\ncommand "{command}" returned:\n')
- pprint.pprint(tmp)
- return tmp
+ pprint.pprint(out)
+ return out
diff --git a/smoketest/scripts/cli/test_interfaces_bridge.py b/smoketest/scripts/cli/test_interfaces_bridge.py
index 4014c1a4c..2152dba72 100755
--- a/smoketest/scripts/cli/test_interfaces_bridge.py
+++ b/smoketest/scripts/cli/test_interfaces_bridge.py
@@ -63,6 +63,32 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
super().tearDown()
+ def test_isolated_interfaces(self):
+ # Add member interfaces to bridge and set STP cost/priority
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ self.cli_set(base + ['stp'])
+
+ # assign members to bridge interface
+ for member in self._members:
+ base_member = base + ['member', 'interface', member]
+ self.cli_set(base_member + ['isolated'])
+
+ # commit config
+ self.cli_commit()
+
+ for interface in self._interfaces:
+ tmp = get_interface_config(interface)
+ # STP must be enabled as configured above
+ self.assertEqual(1, tmp['linkinfo']['info_data']['stp_state'])
+
+ # validate member interface configuration
+ for member in self._members:
+ tmp = get_interface_config(member)
+ # Isolated must be enabled as configured above
+ self.assertTrue(tmp['linkinfo']['info_slave_data']['isolated'])
+
+
def test_add_remove_bridge_member(self):
# Add member interfaces to bridge and set STP cost/priority
for interface in self._interfaces:
@@ -97,12 +123,34 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
cost += 1
priority += 1
+
+ def test_vif_8021q_interfaces(self):
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ self.cli_set(base + ['enable-vlan'])
+ super().test_vif_8021q_interfaces()
+
+ def test_vif_8021q_lower_up_down(self):
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ self.cli_set(base + ['enable-vlan'])
+ super().test_vif_8021q_lower_up_down()
+
+ def test_vif_8021q_mtu_limits(self):
+ for interface in self._interfaces:
+ base = self._base_path + [interface]
+ self.cli_set(base + ['enable-vlan'])
+ super().test_vif_8021q_mtu_limits()
+
def test_bridge_vlan_filter(self):
+ vif_vlan = 2
# Add member interface to bridge and set VLAN filter
for interface in self._interfaces:
base = self._base_path + [interface]
- self.cli_set(base + ['vif', '1', 'address', '192.0.2.1/24'])
- self.cli_set(base + ['vif', '2', 'address', '192.0.3.1/24'])
+ self.cli_set(base + ['enable-vlan'])
+ self.cli_set(base + ['address', '192.0.2.1/24'])
+ self.cli_set(base + ['vif', str(vif_vlan), 'address', '192.0.3.1/24'])
+ self.cli_set(base + ['vif', str(vif_vlan), 'mtu', self._mtu])
vlan_id = 101
allowed_vlan = 2
@@ -174,6 +222,7 @@ class BridgeInterfaceTest(BasicInterfaceTest.TestCase):
for interface in self._interfaces:
self.cli_delete(self._base_path + [interface, 'member'])
+
def test_bridge_vlan_members(self):
# T2945: ensure that VIFs are not dropped from bridge
vifs = ['300', '400']
diff --git a/smoketest/scripts/cli/test_nat.py b/smoketest/scripts/cli/test_nat.py
index 0706f234e..0706f234e 100755..100644
--- a/smoketest/scripts/cli/test_nat.py
+++ b/smoketest/scripts/cli/test_nat.py
diff --git a/smoketest/scripts/cli/test_protocols_isis.py b/smoketest/scripts/cli/test_protocols_isis.py
new file mode 100755
index 000000000..482162b0e
--- /dev/null
+++ b/smoketest/scripts/cli/test_protocols_isis.py
@@ -0,0 +1,170 @@
+#!/usr/bin/env python3
+#
+# Copyright (C) 2021 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.configsession import ConfigSession
+from vyos.configsession import ConfigSessionError
+from vyos.ifconfig import Section
+from vyos.util import process_named_running
+
+PROCESS_NAME = 'isisd'
+base_path = ['protocols', 'isis']
+
+domain = 'VyOS'
+net = '49.0001.1921.6800.1002.00'
+
+class TestProtocolsISIS(VyOSUnitTestSHIM.TestCase):
+ @classmethod
+ def setUpClass(cls):
+ cls._interfaces = Section.interfaces('ethernet')
+
+ # call base-classes classmethod
+ super(cls, cls).setUpClass()
+
+ def tearDown(self):
+ self.cli_delete(base_path)
+ self.cli_commit()
+
+ # Check for running process
+ self.assertTrue(process_named_running(PROCESS_NAME))
+
+ def isis_base_config(self):
+ self.cli_set(base_path + ['net', net])
+ for interface in self._interfaces:
+ self.cli_set(base_path + ['interface', interface])
+
+ def test_isis_01_redistribute(self):
+ prefix_list = 'EXPORT-ISIS'
+ route_map = 'EXPORT-ISIS'
+ rule = '10'
+
+ self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'action', 'permit'])
+ self.cli_set(['policy', 'prefix-list', prefix_list, 'rule', rule, 'prefix', '203.0.113.0/24'])
+ self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'action', 'permit'])
+ self.cli_set(['policy', 'route-map', route_map, 'rule', rule, 'match', 'ip', 'address', 'prefix-list', prefix_list])
+
+ self.cli_set(base_path)
+
+ # verify() - net id and interface are mandatory
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+
+ self.isis_base_config()
+ self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map])
+ self.cli_set(base_path + ['log-adjacency-changes'])
+
+ # Commit all changes
+ self.cli_commit()
+
+ # Verify all changes
+ tmp = self.getFRRconfig(f'router isis {domain}')
+ self.assertIn(f' net {net}', tmp)
+ self.assertIn(f' log-adjacency-changes', tmp)
+ self.assertIn(f' redistribute ipv4 connected level-2 route-map {route_map}', tmp)
+
+ for interface in self._interfaces:
+ tmp = self.getFRRconfig(f'interface {interface}')
+ self.assertIn(f' ip router isis {domain}', tmp)
+ self.assertIn(f' ipv6 router isis {domain}', tmp)
+
+ self.cli_delete(['policy', 'route-map', route_map])
+ self.cli_delete(['policy', 'prefix-list', prefix_list])
+
+ def test_isis_02_zebra_route_map(self):
+ # Implemented because of T3328
+ route_map = 'foo-isis-in'
+
+ self.cli_set(['policy', 'route-map', route_map, 'rule', '10', 'action', 'permit'])
+
+ self.isis_base_config()
+ self.cli_set(base_path + ['redistribute', 'ipv4', 'connected', 'level-2', 'route-map', route_map])
+ self.cli_set(base_path + ['route-map', route_map])
+
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR configuration
+ zebra_route_map = f'ip protocol isis route-map {route_map}'
+ frrconfig = self.getFRRconfig(zebra_route_map)
+ self.assertIn(zebra_route_map, frrconfig)
+
+ # Remove the route-map again
+ self.cli_delete(base_path + ['route-map'])
+ # commit changes
+ self.cli_commit()
+
+ # Verify FRR configuration
+ frrconfig = self.getFRRconfig(zebra_route_map)
+ self.assertNotIn(zebra_route_map, frrconfig)
+
+ self.cli_delete(['policy', 'route-map', route_map])
+
+ def test_isis_03_default_information(self):
+ metric = '50'
+ route_map = 'default-foo-'
+
+ self.isis_base_config()
+ for afi in ['ipv4', 'ipv6']:
+ for level in ['level-1', 'level-2']:
+ self.cli_set(base_path + ['default-information', 'originate', afi, level, 'always'])
+ self.cli_set(base_path + ['default-information', 'originate', afi, level, 'metric', metric])
+ self.cli_set(base_path + ['default-information', 'originate', afi, level, 'route-map', route_map + level + afi])
+
+ # Commit all changes
+ self.cli_commit()
+
+ # Verify all changes
+ tmp = self.getFRRconfig(f'router isis {domain}')
+ self.assertIn(f' net {net}', tmp)
+
+ for afi in ['ipv4', 'ipv6']:
+ for level in ['level-1', 'level-2']:
+ route_map_name = route_map + level + afi
+ self.assertIn(f' default-information originate {afi} {level} always route-map {route_map_name} metric {metric}', tmp)
+
+ def test_isis_04_password(self):
+ password = 'foo'
+
+ self.isis_base_config()
+
+ self.cli_set(base_path + ['area-password', 'plaintext-password', password])
+ self.cli_set(base_path + ['area-password', 'md5', password])
+ self.cli_set(base_path + ['domain-password', 'plaintext-password', password])
+ self.cli_set(base_path + ['domain-password', 'md5', password])
+
+ # verify() - can not use both md5 and plaintext-password for area-password
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['area-password', 'md5', password])
+
+ # verify() - can not use both md5 and plaintext-password for domain-password
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_delete(base_path + ['domain-password', 'md5', password])
+
+ # Commit all changes
+ self.cli_commit()
+
+ # Verify all changes
+ tmp = self.getFRRconfig(f'router isis {domain}')
+ self.assertIn(f' net {net}', tmp)
+ self.assertIn(f' domain-password clear {password}', tmp)
+ self.assertIn(f' area-password clear {password}', tmp)
+
+if __name__ == '__main__':
+ unittest.main(verbosity=2)
diff --git a/smoketest/scripts/cli/test_system_login.py b/smoketest/scripts/cli/test_system_login.py
index 8327235fb..af3a5851c 100755
--- a/smoketest/scripts/cli/test_system_login.py
+++ b/smoketest/scripts/cli/test_system_login.py
@@ -31,7 +31,19 @@ from vyos.util import read_file
from vyos.template import inc_ip
base_path = ['system', 'login']
-users = ['vyos1', 'vyos2']
+users = ['vyos1', 'vyos-roxx123', 'VyOS-123_super.Nice']
+
+ssh_pubkey = """
+AAAAB3NzaC1yc2EAAAADAQABAAABgQD0NuhUOEtMIKnUVFIHoFatqX/c4mjerXyF
+TlXYfVt6Ls2NZZsUSwHbnhK4BKDrPvVZMW/LycjQPzWW6TGtk6UbZP1WqdviQ9hP
+jsEeKJSTKciMSvQpjBWyEQQPXSKYQC7ryQQilZDqnJgzqwzejKEe+nhhOdBvjuZc
+uukxjT69E0UmWAwLxzvfiurwiQaC7tG+PwqvtfHOPL3i6yRO2C5ORpFarx8PeGDS
+IfIXJCr3LoUbLHeuE7T2KaOKQcX0UsWJ4CoCapRLpTVYPDB32BYfgq7cW1Sal1re
+EGH2PzuXBklinTBgCHA87lHjpwDIAqdmvMj7SXIW9LxazLtP+e37sexE7xEs0cpN
+l68txdDbY2P2Kbz5mqGFfCvBYKv9V2clM5vyWNy/Xp5TsCis89nn83KJmgFS7sMx
+pHJz8umqkxy3hfw0K7BRFtjWd63sbOP8Q/SDV7LPaIfIxenA9zv2rY7y+AIqTmSr
+TTSb0X1zPGxPIRFy5GoGtO9Mm5h4OZk=
+"""
class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
def tearDown(self):
@@ -42,6 +54,8 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
self.cli_commit()
def test_add_linux_system_user(self):
+ # We are not allowed to re-use a username already taken by the Linux
+ # base system
system_user = 'backup'
self.cli_set(base_path + ['user', system_user, 'authentication', 'plaintext-password', system_user])
@@ -75,9 +89,30 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
(stdout, stderr) = proc.communicate()
# stdout is something like this:
- # b'Linux vyos 4.19.101-amd64-vyos #1 SMP Sun Feb 2 10:18:07 UTC 2020 x86_64 GNU/Linux\n'
+ # b'Linux LR1.wue3 5.10.61-amd64-vyos #1 SMP Fri Aug 27 08:55:46 UTC 2021 x86_64 GNU/Linux\n'
self.assertTrue(len(stdout) > 40)
+ def test_system_user_ssh_key(self):
+ ssh_user = 'ssh-test_user'
+ public_keys = 'vyos'
+ type = 'ssh-rsa'
+
+ self.cli_set(base_path + ['user', ssh_user, 'authentication', 'public-keys', public_keys, 'key', ssh_pubkey.replace('\n','')])
+
+ # check validate() - missing type for public-key
+ with self.assertRaises(ConfigSessionError):
+ self.cli_commit()
+ self.cli_set(base_path + ['user', ssh_user, 'authentication', 'public-keys', public_keys, 'type', type])
+
+ self.cli_commit()
+
+ # Check that SSH key was written properly
+ tmp = cmd(f'sudo cat /home/{ssh_user}/.ssh/authorized_keys')
+ key = f'{type} ' + ssh_pubkey.replace('\n','')
+ self.assertIn(key, tmp)
+
+ self.cli_delete(base_path + ['user', ssh_user])
+
def test_radius_kernel_features(self):
# T2886: RADIUS requires some Kernel options to be present
kernel = platform.release()
@@ -201,4 +236,4 @@ class TestSystemLogin(VyOSUnitTestSHIM.TestCase):
self.assertTrue(tmp)
if __name__ == '__main__':
- unittest.main(verbosity=2)
+ unittest.main(verbosity=2, failfast=True)