aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/lb
diff options
context:
space:
mode:
authorDave Wallace <dwallacelf@gmail.com>2019-08-22 00:32:29 +0000
committerDave Barach <openvpp@barachs.net>2019-08-22 15:33:59 +0000
commita43c93f8554ad7418e31be3791b3fb71232f60ac (patch)
tree50382fdf248809eac59580d8901ff7aef02a8f17 /src/plugins/lb
parent34af0ccf5cf27d8a72119626d2d009222e4ff0a6 (diff)
tests: move plugin tests to src/plugins/*/test
- Relocate plugin tests for 'make test' into src/plugins/*/test so that plugin test cases are co-located with the plugin source code. Type: refactor Signed-off-by: Dave Wallace <dwallacelf@gmail.com> Change-Id: I503e6a43528e14981799b735fa65674155713f67 Signed-off-by: Dave Wallace <dwallacelf@gmail.com>
Diffstat (limited to 'src/plugins/lb')
-rw-r--r--src/plugins/lb/test/test_lb.py502
-rw-r--r--src/plugins/lb/test/test_lb_api.py76
-rw-r--r--src/plugins/lb/test/vpp_lb.py84
3 files changed, 662 insertions, 0 deletions
diff --git a/src/plugins/lb/test/test_lb.py b/src/plugins/lb/test/test_lb.py
new file mode 100644
index 00000000000..4603bd10db8
--- /dev/null
+++ b/src/plugins/lb/test/test_lb.py
@@ -0,0 +1,502 @@
+import socket
+
+import scapy.compat
+from scapy.layers.inet import IP, UDP
+from scapy.layers.inet6 import IPv6
+from scapy.layers.l2 import Ether, GRE
+from scapy.packet import Raw
+from scapy.data import IP_PROTOS
+
+from framework import VppTestCase
+from util import ppp
+from vpp_ip_route import VppIpRoute, VppRoutePath
+from vpp_ip import INVALID_INDEX
+
+""" TestLB is a subclass of VPPTestCase classes.
+
+ TestLB class defines Load Balancer test cases for:
+ - IP4 to GRE4 encap on per-port vip case
+ - IP4 to GRE6 encap on per-port vip case
+ - IP6 to GRE4 encap on per-port vip case
+ - IP6 to GRE6 encap on per-port vip case
+ - IP4 to L3DSR encap on vip case
+ - IP4 to L3DSR encap on per-port vip case
+ - IP4 to NAT4 encap on per-port vip case
+ - IP6 to NAT6 encap on per-port vip case
+
+ As stated in comments below, GRE has issues with IPv6.
+ All test cases involving IPv6 are executed, but
+ received packets are not parsed and checked.
+
+"""
+
+
+class TestLB(VppTestCase):
+ """ Load Balancer Test Case """
+
+ @classmethod
+ def setUpClass(cls):
+ super(TestLB, cls).setUpClass()
+
+ cls.ass = range(5)
+ cls.packets = range(1)
+
+ try:
+ cls.create_pg_interfaces(range(2))
+ cls.interfaces = list(cls.pg_interfaces)
+
+ for i in cls.interfaces:
+ i.admin_up()
+ i.config_ip4()
+ i.config_ip6()
+ i.disable_ipv6_ra()
+ i.resolve_arp()
+ i.resolve_ndp()
+
+ dst4 = VppIpRoute(cls, "10.0.0.0", 24,
+ [VppRoutePath(cls.pg1.remote_ip4,
+ INVALID_INDEX)],
+ register=False)
+ dst4.add_vpp_config()
+ dst6 = VppIpRoute(cls, "2002::", 16,
+ [VppRoutePath(cls.pg1.remote_ip6,
+ INVALID_INDEX)],
+ register=False)
+ dst6.add_vpp_config()
+ cls.vapi.lb_conf(ip4_src_address="39.40.41.42",
+ ip6_src_address="2004::1")
+ except Exception:
+ super(TestLB, cls).tearDownClass()
+ raise
+
+ @classmethod
+ def tearDownClass(cls):
+ super(TestLB, cls).tearDownClass()
+
+ def tearDown(self):
+ super(TestLB, self).tearDown()
+
+ def show_commands_at_teardown(self):
+ self.logger.info(self.vapi.cli("show lb vip verbose"))
+
+ def getIPv4Flow(self, id):
+ return (IP(dst="90.0.%u.%u" % (id / 255, id % 255),
+ src="40.0.%u.%u" % (id / 255, id % 255)) /
+ UDP(sport=10000 + id, dport=20000))
+
+ def getIPv6Flow(self, id):
+ return (IPv6(dst="2001::%u" % (id), src="fd00:f00d:ffff::%u" % (id)) /
+ UDP(sport=10000 + id, dport=20000))
+
+ def generatePackets(self, src_if, isv4):
+ self.reset_packet_infos()
+ pkts = []
+ for pktid in self.packets:
+ info = self.create_packet_info(src_if, self.pg1)
+ payload = self.info_to_payload(info)
+ ip = self.getIPv4Flow(pktid) if isv4 else self.getIPv6Flow(pktid)
+ packet = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
+ ip /
+ Raw(payload))
+ self.extend_packet(packet, 128)
+ info.data = packet.copy()
+ pkts.append(packet)
+ return pkts
+
+ def checkInner(self, gre, isv4):
+ IPver = IP if isv4 else IPv6
+ self.assertEqual(gre.proto, 0x0800 if isv4 else 0x86DD)
+ self.assertEqual(gre.flags, 0)
+ self.assertEqual(gre.version, 0)
+ inner = IPver(scapy.compat.raw(gre.payload))
+ payload_info = self.payload_to_info(inner[Raw])
+ self.info = self.packet_infos[payload_info.index]
+ self.assertEqual(payload_info.src, self.pg0.sw_if_index)
+ self.assertEqual(scapy.compat.raw(inner),
+ scapy.compat.raw(self.info.data[IPver]))
+
+ def checkCapture(self, encap, isv4):
+ self.pg0.assert_nothing_captured()
+ out = self.pg1.get_capture(len(self.packets))
+
+ load = [0] * len(self.ass)
+ self.info = None
+ for p in out:
+ try:
+ asid = 0
+ gre = None
+ if (encap == 'gre4'):
+ ip = p[IP]
+ asid = int(ip.dst.split(".")[3])
+ self.assertEqual(ip.version, 4)
+ self.assertEqual(ip.flags, 0)
+ self.assertEqual(ip.src, "39.40.41.42")
+ self.assertEqual(ip.dst, "10.0.0.%u" % asid)
+ self.assertEqual(ip.proto, 47)
+ self.assertEqual(len(ip.options), 0)
+ gre = p[GRE]
+ self.checkInner(gre, isv4)
+ elif (encap == 'gre6'):
+ ip = p[IPv6]
+ asid = ip.dst.split(":")
+ asid = asid[len(asid) - 1]
+ asid = 0 if asid == "" else int(asid)
+ self.assertEqual(ip.version, 6)
+ self.assertEqual(ip.tc, 0)
+ self.assertEqual(ip.fl, 0)
+ self.assertEqual(ip.src, "2004::1")
+ self.assertEqual(
+ socket.inet_pton(socket.AF_INET6, ip.dst),
+ socket.inet_pton(socket.AF_INET6, "2002::%u" % asid)
+ )
+ self.assertEqual(ip.nh, 47)
+ # self.assertEqual(len(ip.options), 0)
+ gre = GRE(scapy.compat.raw(p[IPv6].payload))
+ self.checkInner(gre, isv4)
+ elif (encap == 'l3dsr'):
+ ip = p[IP]
+ asid = int(ip.dst.split(".")[3])
+ self.assertEqual(ip.version, 4)
+ self.assertEqual(ip.flags, 0)
+ self.assertEqual(ip.dst, "10.0.0.%u" % asid)
+ self.assertEqual(ip.tos, 0x1c)
+ self.assertEqual(len(ip.options), 0)
+ self.assert_ip_checksum_valid(p)
+ if ip.proto == IP_PROTOS.tcp:
+ self.assert_tcp_checksum_valid(p)
+ elif ip.proto == IP_PROTOS.udp:
+ self.assert_udp_checksum_valid(p)
+ elif (encap == 'nat4'):
+ ip = p[IP]
+ asid = int(ip.dst.split(".")[3])
+ self.assertEqual(ip.version, 4)
+ self.assertEqual(ip.flags, 0)
+ self.assertEqual(ip.dst, "10.0.0.%u" % asid)
+ self.assertEqual(ip.proto, 17)
+ self.assertEqual(len(ip.options), 0)
+ udp = p[UDP]
+ self.assertEqual(udp.dport, 3307)
+ elif (encap == 'nat6'):
+ ip = p[IPv6]
+ asid = ip.dst.split(":")
+ asid = asid[len(asid) - 1]
+ asid = 0 if asid == "" else int(asid)
+ self.assertEqual(ip.version, 6)
+ self.assertEqual(ip.tc, 0)
+ self.assertEqual(ip.fl, 0)
+ self.assertEqual(
+ socket.inet_pton(socket.AF_INET6, ip.dst),
+ socket.inet_pton(socket.AF_INET6, "2002::%u" % asid)
+ )
+ self.assertEqual(ip.nh, 17)
+ self.assertGreaterEqual(ip.hlim, 63)
+ udp = UDP(scapy.compat.raw(p[IPv6].payload))
+ self.assertEqual(udp.dport, 3307)
+ load[asid] += 1
+ except:
+ self.logger.error(ppp("Unexpected or invalid packet:", p))
+ raise
+
+ # This is just to roughly check that the balancing algorithm
+ # is not completely biased.
+ for asid in self.ass:
+ if load[asid] < len(self.packets) / (len(self.ass) * 2):
+ self.logger.error(
+ "ASS is not balanced: load[%d] = %d" % (asid, load[asid]))
+ raise Exception("Load Balancer algorithm is biased")
+
+ def test_lb_ip4_gre4(self):
+ """ Load Balancer IP4 GRE4 on vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 encap gre4")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap='gre4', isv4=True)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 encap gre4 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip6_gre4(self):
+ """ Load Balancer IP6 GRE4 on vip case """
+
+ try:
+ self.vapi.cli(
+ "lb vip 2001::/16 encap gre4")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ self.checkCapture(encap='gre4', isv4=False)
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 2001::/16 encap gre4 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip4_gre6(self):
+ """ Load Balancer IP4 GRE6 on vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 encap gre6")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 2002::%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ self.checkCapture(encap='gre6', isv4=True)
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 2002::%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 encap gre6 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip6_gre6(self):
+ """ Load Balancer IP6 GRE6 on vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 2001::/16 encap gre6")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 2002::%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ self.checkCapture(encap='gre6', isv4=False)
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 2002::%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 2001::/16 encap gre6 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip4_gre4_port(self):
+ """ Load Balancer IP4 GRE4 on per-port-vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap gre4")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap='gre4', isv4=True)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap gre4 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip6_gre4_port(self):
+ """ Load Balancer IP6 GRE4 on per-port-vip case """
+
+ try:
+ self.vapi.cli(
+ "lb vip 2001::/16 protocol udp port 20000 encap gre4")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 protocol udp port 20000 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ self.checkCapture(encap='gre4', isv4=False)
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 protocol udp port 20000 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 2001::/16 protocol udp port 20000 encap gre4 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip4_gre6_port(self):
+ """ Load Balancer IP4 GRE6 on per-port-vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap gre6")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 2002::%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ self.checkCapture(encap='gre6', isv4=True)
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 2002::%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap gre6 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip6_gre6_port(self):
+ """ Load Balancer IP6 GRE6 on per-port-vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 2001::/16 protocol udp port 20000 encap gre6")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 protocol udp port 20000 2002::%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+
+ self.checkCapture(encap='gre6', isv4=False)
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 protocol udp port 20000 2002::%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 2001::/16 protocol udp port 20000 encap gre6 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip4_l3dsr(self):
+ """ Load Balancer IP4 L3DSR on vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 encap l3dsr dscp 7")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap='l3dsr', isv4=True)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 encap l3dsr"
+ " dscp 7 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip4_l3dsr_port(self):
+ """ Load Balancer IP4 L3DSR on per-port-vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap l3dsr dscp 7")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap='l3dsr', isv4=True)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap l3dsr"
+ " dscp 7 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip4_nat4_port(self):
+ """ Load Balancer IP4 NAT4 on per-port-vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap nat4"
+ " type clusterip target_port 3307")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=True))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap='nat4', isv4=True)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 90.0.0.0/8 protocol udp port 20000 10.0.0.%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 90.0.0.0/8 protocol udp port 20000 encap nat4"
+ " type clusterip target_port 3307 del")
+ self.vapi.cli("test lb flowtable flush")
+
+ def test_lb_ip6_nat6_port(self):
+ """ Load Balancer IP6 NAT6 on per-port-vip case """
+ try:
+ self.vapi.cli(
+ "lb vip 2001::/16 protocol udp port 20000 encap nat6"
+ " type clusterip target_port 3307")
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 protocol udp port 20000 2002::%u"
+ % (asid))
+
+ self.pg0.add_stream(self.generatePackets(self.pg0, isv4=False))
+ self.pg_enable_capture(self.pg_interfaces)
+ self.pg_start()
+ self.checkCapture(encap='nat6', isv4=False)
+
+ finally:
+ for asid in self.ass:
+ self.vapi.cli(
+ "lb as 2001::/16 protocol udp port 20000 2002::%u del"
+ % (asid))
+ self.vapi.cli(
+ "lb vip 2001::/16 protocol udp port 20000 encap nat6"
+ " type clusterip target_port 3307 del")
+ self.vapi.cli("test lb flowtable flush")
diff --git a/src/plugins/lb/test/test_lb_api.py b/src/plugins/lb/test/test_lb_api.py
new file mode 100644
index 00000000000..70d41d432a7
--- /dev/null
+++ b/src/plugins/lb/test/test_lb_api.py
@@ -0,0 +1,76 @@
+# Copyright (c) 2019. Vinci Consulting Corp. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import framework
+import ipaddress
+
+DEFAULT_VIP = "lb_vip_details(_0=978, context=12, vip=vl_api_lb_ip_addr_t(pfx=IPv6Network(u'::/0'), protocol=<vl_api_ip_proto_t.IP_API_PROTO_RESERVED: 255>, port=0), encap=<vl_api_lb_encap_type_t.LB_API_ENCAP_TYPE_GRE4: 0>, dscp=<vl_api_ip_dscp_t.IP_API_DSCP_CS0: 0>, srv_type=<vl_api_lb_srv_type_t.LB_API_SRV_TYPE_CLUSTERIP: 0>, target_port=0, flow_table_length=0)" # noqa
+
+
+class TestLbEmptyApi(framework.VppTestCase):
+ """TestLbEmptyApi """
+
+ def test_lb_empty_vip_dump(self):
+
+ # no records should normally return [], but
+ # lb initializes with a default VIP
+ rv = self.vapi.lb_vip_dump()
+ # print(rv)
+ self.assertEqual(rv, [], 'Expected: [] Received: %r.' % rv)
+
+ def test_lb_empty_as_dump(self):
+
+ # no records should return []
+ rv = self.vapi.lb_as_dump()
+ # print(rv)
+ self.assertEqual(rv, [], 'Expected: [] Received: %r.' % rv)
+
+
+class TestLbApi(framework.VppTestCase):
+ """TestLbApi """
+
+ def test_lb_vip_dump(self):
+ # add some vips
+ # rv = self.vapi.lb_add_del_vip(pfx=ipaddress.IPv4Network(u'1.2.3.0/24'), # noqa
+ # protocol=17,
+ # encap=0)
+ # print(rv)
+ self.vapi.cli("lb vip 2001::/16 encap gre6")
+ rv = self.vapi.lb_vip_dump()
+ # print(rv)
+ self.assertEqual(str(rv[-1].vip.pfx), "2001::/16",
+ 'Expected: 2001::/16 Received: %r.' % rv[-1].vip.pfx)
+
+ self.vapi.cli("lb vip 2001::/16 del")
+
+
+class TestLbAsApi(framework.VppTestCase):
+ """TestLbAsApi """
+
+ def test_lb_as_dump(self):
+ # add some vips
+ self.vapi.cli("lb vip 2001::/16 encap gre6")
+ self.vapi.cli("lb as 2001::/16 2000::1")
+ # add some as's for the vips
+ # rv = self.vapi.lb_add_del_as(
+ # pfx=ipaddress.IPv4Network(u"10.0.0.0/24"),
+ # as_address=ipaddress.IPv4Address(u"192.168.1.1"))
+
+ # print(rv)
+ rv = self.vapi.lb_as_dump()
+ # print(rv)
+ self.assertEqual(str(rv[0].vip.pfx), "2001::/16",
+ 'Expected: "2001::/16" Received: %r.' % rv[0].vip.pfx)
+ self.assertEqual(str(rv[0].app_srv), "2000::1",
+ 'Expected: "2000::1" Received: %r.' % rv[0].app_srv)
diff --git a/src/plugins/lb/test/vpp_lb.py b/src/plugins/lb/test/vpp_lb.py
new file mode 100644
index 00000000000..d755cef70e5
--- /dev/null
+++ b/src/plugins/lb/test/vpp_lb.py
@@ -0,0 +1,84 @@
+# Copyright (c) 2019. Vinci Consulting Corp. All Rights Reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import vpp_object
+
+
+class VppLbVip(vpp_object.VppObject):
+
+ def __init__(self, test, pfx, sfx, port, protocol):
+ self._test = test
+ self.pfx = pfx
+ self.sfx = sfx
+ self.port = port
+ self.protocol = protocol
+
+ def add_vpp_config(self):
+ self._test_vapi.lb_add_del_vip(pfx=self.pfx,
+ sfx=self.pfx,
+ port=self.port,
+ protocol=self.protocol)
+
+ self._test.registry.register(self, self._test.logger)
+
+ def remove_vpp_config(self):
+ self._test.vapi.lb_add_del_vip(pfx=self.pfx,
+ sfx=self.pfx,
+ port=self.port,
+ protocol=self.protocol,
+ is_del=1)
+
+ def query_vpp_config(self):
+ details = self._test.vapi.lb_add_del_vip(fx=self.pfx,
+ sfx=self.pfx,
+ port=self.port,
+ protocol=self.protocol)
+ return True if self == details else False
+
+
+class VppLbAs(vpp_object.VppObject):
+ def __init__(self, test, pfx, port, protocol, app_srv, is_del, is_flush):
+ self._test = test
+ # this is the vip
+ self.pfx = pfx
+ self.port = port
+ self.protocol = protocol
+
+ self.app_srv = app_srv
+ self.is_del = is_del
+ self.is_flush = is_flush
+
+ def add_vpp_config(self):
+ self._test_vapi.lb_add_del_as(pfx=self.pfx,
+ port=self.port,
+ protocol=self.protocol,
+ app_srv=self.app_srv,
+ is_flush=self.is_flush,
+ )
+
+ self._test.registry.register(self, self._test.logger)
+
+ def remove_vpp_config(self):
+ self._test.vapi.lb_add_del_as(pfx=self.pfx,
+ port=self.port,
+ protocol=self.protocol,
+ app_srv=self.app_srv,
+ is_flush=self.is_flush,
+ is_del=1)
+
+ def query_vpp_config(self):
+ details = self._test.vapi.lb_as_dump(pfx=self.pfx,
+ port=self.port,
+ protocol=self.protocol)
+ return True if self == details else False