+In this example, we will describe how to add a new test case which tests
+basic IPv4 forwarding.
+
+1. Add a new file called test_ip4_fwd.py in the test directory, starting
+ with a few imports::
+
+ from framework import VppTestCase
+ from scapy.layers.l2 import Ether
+ from scapy.packet import Raw
+ from scapy.layers.inet import IP, UDP
+ from random import randint
+
+2. Create a class inherited from the VppTestCase::
+
+ class IP4FwdTestCase(VppTestCase):
+ """ IPv4 simple forwarding test case """
+
+2. Add a setUpClass function containing the setup needed for our test to run::
+
+ @classmethod
+ def setUpClass(self):
+ super(IP4FwdTestCase, self).setUpClass()
+ self.create_pg_interfaces(range(2)) # create pg0 and pg1
+ for i in self.pg_interfaces:
+ i.admin_up() # put the interface up
+ i.config_ip4() # configure IPv4 address on the interface
+ i.resolve_arp() # resolve ARP, so that we know VPP MAC
+
+3. Create a helper method to create the packets to send::
+
+ def create_stream(self, src_if, dst_if, count):
+ packets = []
+ for i in range(count):
+ # create packet info stored in the test case instance
+ info = self.create_packet_info(src_if, dst_if)
+ # convert the info into packet payload
+ payload = self.info_to_payload(info)
+ # create the packet itself
+ p = (Ether(dst=src_if.local_mac, src=src_if.remote_mac) /
+ IP(src=src_if.remote_ip4, dst=dst_if.remote_ip4) /
+ UDP(sport=randint(1000, 2000), dport=5678) /
+ Raw(payload))
+ # store a copy of the packet in the packet info
+ info.data = p.copy()
+ # append the packet to the list
+ packets.append(p)
+
+ # return the created packet list
+ return packets
+
+4. Create a helper method to verify the capture::
+
+ def verify_capture(self, src_if, dst_if, capture):
+ packet_info = None
+ for packet in capture:
+ try:
+ ip = packet[IP]
+ udp = packet[UDP]
+ # convert the payload to packet info object
+ payload_info = self.payload_to_info(str(packet[Raw]))
+ # make sure the indexes match
+ self.assert_equal(payload_info.src, src_if.sw_if_index,
+ "source sw_if_index")
+ self.assert_equal(payload_info.dst, dst_if.sw_if_index,
+ "destination sw_if_index")
+ packet_info = self.get_next_packet_info_for_interface2(
+ src_if.sw_if_index,
+ dst_if.sw_if_index,
+ packet_info)
+ # make sure we didn't run out of saved packets
+ self.assertIsNotNone(packet_info)
+ self.assert_equal(payload_info.index, packet_info.index,
+ "packet info index")
+ saved_packet = packet_info.data # fetch the saved packet
+ # assert the values match
+ self.assert_equal(ip.src, saved_packet[IP].src,
+ "IP source address")
+ # ... more assertions here
+ self.assert_equal(udp.sport, saved_packet[UDP].sport,
+ "UDP source port")
+ except:
+ self.logger.error(ppp("Unexpected or invalid packet:",
+ packet))
+ raise
+ remaining_packet = self.get_next_packet_info_for_interface2(
+ src_if.sw_if_index,
+ dst_if.sw_if_index,
+ packet_info)
+ self.assertIsNone(remaining_packet,
+ "Interface %s: Packet expected from interface "
+ "%s didn't arrive" % (dst_if.name, src_if.name))
+
+5. Add the test code to test_basic function::
+
+ def test_basic(self):
+ count = 10
+ # create the packet stream
+ packets = self.create_stream(self.pg0, self.pg1, count)
+ # add the stream to the source interface
+ self.pg0.add_stream(packets)
+ # enable capture on both interfaces
+ self.pg0.enable_capture()
+ self.pg1.enable_capture()
+ # start the packet generator
+ self.pg_start()
+ # get capture - the proper count of packets was saved by
+ # create_packet_info() based on dst_if parameter
+ capture = self.pg1.get_capture()
+ # assert nothing captured on pg0 (always do this last, so that
+ # some time has already passed since pg_start())
+ self.pg0.assert_nothing_captured()
+ # verify capture
+ self.verify_capture(self.pg0, self.pg1, capture)
+
+6. Run the test by issuing 'make test'.