Add unittests for validator/interface.py

This commit is contained in:
Pim van Pelt
2022-03-20 21:49:08 +00:00
parent e46cf3d3a8
commit 8445140842
3 changed files with 232 additions and 2 deletions

View File

@ -0,0 +1,62 @@
interfaces:
GigabitEthernet1/0/0:
sub-interfaces:
100:
description: "This sub-int is invalid because it has both dot1q and dot1ad"
encapsulation:
dot1q: 1000
dot1ad: 1000
101:
description: "This sub-int is invalid because it has no outer dot1q and dot1ad"
encapsulation:
inner-dot1q: 1000
102:
description: "This sub-int is has the same encap as 103"
103:
description: "This sub-int is has the same encap as 102"
encapsulation:
dot1q: 102
GigabitEthernet1/0/1:
mtu: 9216
lcp: "e1"
addresses: [ "192.0.2.1/30", "2001:db8:1::1/64" ]
sub-interfaces:
100:
lcp: "foo"
addresses: [ "10.0.0.1/24", "10.0.0.2/24", "2001:db8:2::1/64" ]
200:
mtu: 9000
encapsulation:
dot1q: 1000
addresses: [ "10.0.1.1/30" ]
201:
encapsulation:
dot1ad: 1000
addresses: [ "10.0.2.1/30" ]
202:
encapsulation:
dot1q: 1000
inner-dot1q: 1234
addresses: [ "10.0.3.1/30" ]
203:
encapsulation:
dot1ad: 1000
inner-dot1q: 1000
addresses: [ "10.0.4.1/30" ]
204:
encapsulation:
dot1ad: 1000
inner-dot1q: 1000
exact-match: True
addresses: [ "10.0.5.1/30" ]
GigabitEthernet2/0/0:
description: "This interface has no sub-ints"
lcp: "e2"
GigabitEthernet3/0/0:
l2xc: GigabitEthernet3/0/1
GigabitEthernet3/0/1:
l2xc: GigabitEthernet3/0/0

View File

@ -126,11 +126,11 @@ def get_l2xc_interfaces(yaml):
return ret return ret
for ifname, iface in yaml['interfaces'].items(): for ifname, iface in yaml['interfaces'].items():
if 'l2xc' in iface: if 'l2xc' in iface:
ret.extend(ifname) ret.append(ifname)
if 'sub-interfaces' in iface: if 'sub-interfaces' in iface:
for sub_ifname, sub_iface in iface['sub-interfaces'].items(): for sub_ifname, sub_iface in iface['sub-interfaces'].items():
if 'l2xc' in sub_iface: if 'l2xc' in sub_iface:
ret.extend(sub_ifname) ret.append(sub_ifname)
return ret return ret
@ -239,6 +239,52 @@ def get_encapsulation(yaml, ifname):
} }
def get_interfaces(yaml):
""" Return a list of all interface and sub-interface names """
ret = []
if not 'interfaces' in yaml:
return ret
for ifname, iface in yaml['interfaces'].items():
ret.append(ifname)
if not 'sub-interfaces' in iface:
continue
for subid, sub_iface in iface['sub-interfaces'].items():
ret.append("%s.%d" % (ifname, subid))
return ret
def get_sub_interfaces(yaml):
""" Return all interfaces which are a subinterface. """
ret = []
for ifname in get_interfaces(yaml):
if is_sub(yaml, ifname):
ret.append(ifname)
return ret
def get_qinx_interfaces(yaml):
""" Return all interfaces which are double-tagged, either QinAD or QinQ.
These interfaces will always have a valid encapsulation with 'inner-dot1q'
set to non-zero.
Note: this is always a strict subset of get_sub_interfaces()
"""
ret = []
for ifname in get_interfaces(yaml):
if not is_sub(yaml, ifname):
continue
encap = get_encapsulation(yaml, ifname)
if not encap:
continue
if encap['inner-dot1q'] > 0:
ret.append(ifname)
return ret
def is_qinx(yaml, ifname):
""" Returns True if the interface is a double-tagged (QinQ or QinAD) interface """
return ifname in get_qinx_interfaces(yaml)
def unique_encapsulation(yaml, sub_ifname): def unique_encapsulation(yaml, sub_ifname):
""" Ensures that for the sub_ifname specified, there exist no other sub-ints on the """ Ensures that for the sub_ifname specified, there exist no other sub-ints on the
parent with the same encapsulation. """ parent with the same encapsulation. """

122
validator/test_interface.py Normal file
View File

@ -0,0 +1,122 @@
import unittest
import yaml
import validator.interface as interface
import validator.lcp as lcp
class TestInterfaceMethods(unittest.TestCase):
def setUp(self):
with open("unittest/TestInterfaceMethods.yaml", "r") as f:
self.cfg = yaml.load(f, Loader = yaml.FullLoader)
def test_enumerators(self):
ifs = interface.get_interfaces(self.cfg)
self.assertEquals(len(ifs), 15)
self.assertIn("GigabitEthernet1/0/1", ifs)
self.assertIn("GigabitEthernet1/0/1.200", ifs)
self.assertIn("GigabitEthernet1/0/1.204", ifs)
ifs = interface.get_sub_interfaces(self.cfg)
self.assertEquals(len(ifs), 10)
self.assertNotIn("GigabitEthernet1/0/1", ifs)
self.assertIn("GigabitEthernet1/0/1.200", ifs)
self.assertIn("GigabitEthernet1/0/1.204", ifs)
ifs = interface.get_qinx_interfaces(self.cfg)
self.assertEquals(len(ifs), 3)
self.assertNotIn("GigabitEthernet1/0/1.200", ifs)
self.assertIn("GigabitEthernet1/0/1.204", ifs)
def test_mtu(self):
self.assertEquals(interface.get_mtu(self.cfg, "GigabitEthernet1/0/1"), 9216)
self.assertEquals(interface.get_mtu(self.cfg, "GigabitEthernet1/0/1.200"), 9000)
self.assertEquals(interface.get_mtu(self.cfg, "GigabitEthernet1/0/1.201"), 1500)
def test_encapsulation(self):
self.assertTrue(interface.valid_encapsulation(self.cfg, "GigabitEthernet1/0/1.200"))
self.assertTrue(interface.unique_encapsulation(self.cfg, "GigabitEthernet1/0/1.200"))
self.assertEqual(interface.get_encapsulation(self.cfg, "GigabitEthernet1/0/1.200"),
{ 'dot1q': 1000, 'dot1ad': 0, 'inner-dot1q': 0, 'exact-match': False })
self.assertEqual(interface.get_encapsulation(self.cfg, "GigabitEthernet1/0/1.201"),
{ 'dot1q': 0, 'dot1ad': 1000, 'inner-dot1q': 0, 'exact-match': False })
self.assertEqual(interface.get_encapsulation(self.cfg, "GigabitEthernet1/0/1.202"),
{ 'dot1q': 1000, 'dot1ad': 0, 'inner-dot1q': 1234, 'exact-match': False })
self.assertEqual(interface.get_encapsulation(self.cfg, "GigabitEthernet1/0/1.203"),
{ 'dot1q': 0, 'dot1ad': 1000, 'inner-dot1q': 1000, 'exact-match': False })
self.assertEqual(interface.get_encapsulation(self.cfg, "GigabitEthernet1/0/1.204"),
{ 'dot1q': 0, 'dot1ad': 1000, 'inner-dot1q': 1000, 'exact-match': True })
self.assertFalse(interface.valid_encapsulation(self.cfg, "GigabitEthernet1/0/0.100"))
self.assertFalse(interface.valid_encapsulation(self.cfg, "GigabitEthernet1/0/0.101"))
self.assertFalse(interface.unique_encapsulation(self.cfg, "GigabitEthernet1/0/0.102"))
self.assertFalse(interface.unique_encapsulation(self.cfg, "GigabitEthernet1/0/0.103"))
def test_has_sub(self):
self.assertTrue(interface.has_sub(self.cfg, "GigabitEthernet1/0/1"))
self.assertFalse(interface.has_sub(self.cfg, "GigabitEthernet1/0/1.200"))
self.assertFalse(interface.has_sub(self.cfg, "GigabitEthernet2/0/0"))
self.assertFalse(interface.has_sub(self.cfg, "GigabitEthernet3/0/0"))
def test_is_sub(self):
self.assertFalse(interface.is_sub(self.cfg, "GigabitEthernet1/0/1"))
self.assertTrue(interface.is_sub(self.cfg, "GigabitEthernet1/0/1.200"))
def test_is_qinx(self):
self.assertTrue(interface.is_qinx(self.cfg, "GigabitEthernet1/0/1.202"))
self.assertTrue(interface.is_qinx(self.cfg, "GigabitEthernet1/0/1.203"))
self.assertTrue(interface.is_qinx(self.cfg, "GigabitEthernet1/0/1.204"))
self.assertFalse(interface.is_qinx(self.cfg, "GigabitEthernet1/0/1"))
self.assertFalse(interface.is_qinx(self.cfg, "GigabitEthernet1/0/1.200"))
self.assertFalse(interface.is_qinx(self.cfg, "GigabitEthernet1/0/1.201"))
def test_lcp(self):
self.assertIsNone(interface.get_lcp(self.cfg, "GigabitEthernet1/0/0"))
self.assertIsNone(interface.get_lcp(self.cfg, "GigabitEthernet1/0/0.100"))
self.assertEquals(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1"), "e1")
self.assertEquals(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.100"), "foo")
self.assertTrue(lcp.is_unique(self.cfg, "e1"))
self.assertTrue(lcp.is_unique(self.cfg, "foo"))
## TODO(pim) - ensure that is_unique also takes synthesized LCPs into account
## self.assertFalse(lcp.is_unique(self.cfg, "e1.1000"))
self.assertEquals(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.200"), "e1.1000")
self.assertEquals(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.201"), "e1.1000")
## TODO(pim) - sub 201-203 cannot have an LCP, their encap is not exact-match
## self.assertIsNone(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.200"))
## self.assertIsNone(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.201"))
## self.assertIsNone(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.202"))
## self.assertIsNone(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.203"))
self.assertEquals(interface.get_lcp(self.cfg, "GigabitEthernet1/0/1.204"), "e1.1000.1000")
def test_address(self):
self.assertFalse(interface.has_address(self.cfg, "GigabitEthernet1/0/0"))
self.assertFalse(interface.has_address(self.cfg, "GigabitEthernet1/0/0.100"))
self.assertTrue(interface.has_address(self.cfg, "GigabitEthernet1/0/1"))
self.assertTrue(interface.has_address(self.cfg, "GigabitEthernet1/0/1.100"))
def test_lx2c(self):
l2xc_ifs = interface.get_l2xc_interfaces(self.cfg)
l2xc_target_ifs = interface.get_l2xc_target_interfaces(self.cfg)
self.assertIn("GigabitEthernet3/0/0", l2xc_ifs)
self.assertIn("GigabitEthernet3/0/0", l2xc_target_ifs)
self.assertTrue(interface.is_l2xc_interface(self.cfg, "GigabitEthernet3/0/0"))
self.assertTrue(interface.is_l2xc_target_interface(self.cfg, "GigabitEthernet3/0/0"))
self.assertNotIn("GigabitEthernet2/0/0", l2xc_ifs)
self.assertNotIn("GigabitEthernet2/0/0", l2xc_target_ifs)
self.assertFalse(interface.is_l2xc_interface(self.cfg, "GigabitEthernet2/0/0"))
self.assertFalse(interface.is_l2xc_target_interface(self.cfg, "GigabitEthernet2/0/0"))
def test_l2(self):
self.assertTrue(interface.is_l2(self.cfg, "GigabitEthernet3/0/0"))
self.assertFalse(interface.is_l2(self.cfg, "GigabitEthernet1/0/0"))
def test_l3(self):
self.assertTrue(interface.is_l3(self.cfg, "GigabitEthernet1/0/0"))
self.assertFalse(interface.is_l3(self.cfg, "GigabitEthernet3/0/0"))