Merge "Outline and 1st pass on 1st complex case"
diff --git a/olt-complex.py b/olt-complex.py
new file mode 100644
index 0000000..bf4486d
--- /dev/null
+++ b/olt-complex.py
@@ -0,0 +1,108 @@
+'''
+More complex (composite) test-cases for the OLT
+'''
+
+import logging
+from oftest.testutils import *
+from oltbase import OltBaseTest
+
+class Thing(object):
+ """An object we can stash arbitrary attributes for easy reach"""
+ def __init__(self, **kws):
+ self.__dict__.update(kws)
+
+
+class ControllerAccess(OltBaseTest):
+ """Verify openflow access from OLT device"""
+
+ def runTest(self):
+ logging.info("Running ControllerAccess test")
+
+ # implicitly testing access to the openflow device
+ # and deleting all residual flows and groups
+ delete_all_flows(self.controller)
+ delete_all_groups(self.controller)
+
+
+class TestScenario1SingleOnu(OltBaseTest):
+ """
+ Run a comprehensive test scenrario on the OLT.
+
+ Plan:
+
+ 1. Reset the OLT into a clean state
+ 2. Setup the OLT to pass authentication (L2/Unicast) traffic for the ONU1
+ 3. Verify that unicast traffic works in both directions (use a few hundred frames in both ways)
+ 4. Setup IGMP forwarding toward the controller
+ 5. Send periodic IGMP queries out toward the ONU and verify its arrival
+ 6. Send in an IGMP join request for one channel (specific multicast address) and verify that
+ the controller receives it.
+ 7. Setup flows for forwarding multicast traffic from the OLT port toward the ONU(s)
+ 8. Verify that multicast packets can reach the ONU
+ 9. Verify that bidirectional unicast traffic still works across the PON
+ 10. Change channel to a new multicast group and verify both multicast receiption as well as
+ unicast traffic works. This step involves:
+ - sending a leave message by the ONU to the controller and verify its reception
+ - sending a join message and verify its reception
+ - removing the existing multicast flow
+ - adding a new multicast flow
+ - verify that original flow no longer flows
+ - verify new flow
+ - verify that unicast still works
+ 11. Add a second channel while keeping the existing one. Verify all what needs to be verified
+ (similar as above)
+ 12. Add two more multicast channels, and verify everything
+ 13. Flip a channel for one of the multicast channels, and verify everything
+ 14. Tear down the test.
+ """
+
+ def runTest(self):
+ logging.info("Running %s" % self.__class__.__name__)
+
+ # Some constants
+ c_vlan_id = 111
+ mcast_groups = Thing(
+ ch1="230.10.10.10",
+ ch2="231.11.11.11",
+ ch3="232.12.12.12",
+ ch4="233.13.13.13"
+ )
+ onu1 = Thing(
+ ip="13.14.14.13",
+ mac="b6:b8:3e:fb:1a:3f",
+ s_vlan_id=13
+ )
+
+ # 1. Reset the OLT into a clean state
+ self.resetOlt()
+
+ # 2. Setup the OLT to pass authentication (L2/Unicast) traffic for the ONU1
+ self.installDoubleTaggingRules(onu1.s_vlan_id, c_vlan_id, self.getCookieBlock())
+
+ # 3. Verify that unicast traffic works in both directions (use a few hundred frames in both ways)
+ self.testPacketFlow(onu1.s_vlan_id, c_vlan_id) # this tests just one packet in each way
+ self.testSustainedPacketFlow(onu1.s_vlan_id, c_vlan_id, 100)
+
+ # 4. Setup IGMP forwarding toward the controller
+ # 5. Send periodic IGMP queries out toward the ONU and verify its arrival
+ # 6. Send in an IGMP join request for one channel (specific multicast address) and verify that
+ # the controller receives it.
+ # 7. Setup flows for forwarding multicast traffic from the OLT port toward the ONU(s)
+ # 8. Verify that multicast packets can reach the ONU
+ # 9. Verify that bidirectional unicast traffic still works across the PON
+ # 10. Change channel to a new multicast group and verify both multicast receiption as well as
+ # unicast traffic works. This step involves:
+ # - sending a leave message by the ONU to the controller and verify its reception
+ # - sending a join message and verify its reception
+ # - removing the existing multicast flow
+ # - adding a new multicast flow
+ # - verify that original flow no longer flows
+ # - verify new flow
+ # - verify that unicast still works
+ # 11. Add a second channel while keeping the existing one. Verify all what needs to be verified
+ # (similar as above)
+ # 12. Add two more multicast channels, and verify everything
+ # 13. Flip a channel for one of the multicast channels, and verify everything
+
+ # 14. Tear down the test.
+ self.resetOlt()
diff --git a/oltbase.py b/oltbase.py
index fff3740..6ff4bc4 100644
--- a/oltbase.py
+++ b/oltbase.py
@@ -9,6 +9,20 @@
class OltBaseTest(base_tests.SimpleDataPlane):
+ next_cookie_block = 40
+
+ def getCookieBlock(self):
+ """Returns the starting value of the next 100 cookies"""
+ c = self.next_cookie_block
+ OltBaseTest.next_cookie_block += 100
+ return c
+
+ def resetOlt(self):
+ """Reset the OLT into a clean healthy state"""
+ delete_all_flows(self.controller)
+ do_barrier(self.controller)
+ verify_no_errors(self.controller)
+
def testPacketIn(self, match, parsed_pkt):
delete_all_flows(self.controller)
@@ -73,16 +87,21 @@
self.controller.message_send(request)
do_barrier(self.controller)
- def testPacketFlow(self, s_vlan_id, c_vlan_id, onu = None):
+ def testPacketFlow(self,
+ s_vlan_id,
+ c_vlan_id,
+ onu=None,
+ verify_blocked_flows=True,
+ pktlen=96):
- incorrectTagPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=100, vlan_pcp=1)
- zeroTaggedPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
- untaggedPkt = simple_udp_packet(pktlen=96)
-
- upstreamDoubleTaggedPkt = double_vlan_udp_packet(pktlen=104, dl_vlan_enable=True,
- c_vlan_vid=c_vlan_id,
- s_vlan_vid=s_vlan_id,
- c_vlan_pcp=0, s_vlan_pcp=0)
+ incorrectTagPkt = simple_udp_packet(
+ pktlen=pktlen+4, dl_vlan_enable=True, vlan_vid=s_vlan_id, vlan_pcp=1)
+ zeroTaggedPkt = simple_udp_packet(
+ pktlen=pktlen+4, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
+ untaggedPkt = simple_udp_packet(pktlen=pktlen)
+ upstreamDoubleTaggedPkt = double_vlan_udp_packet(
+ pktlen=pktlen+8, dl_vlan_enable=True, c_vlan_vid=c_vlan_id, s_vlan_vid=s_vlan_id,
+ c_vlan_pcp=0, s_vlan_pcp=0)
inport = onu_port if onu is None else onu
@@ -99,17 +118,23 @@
else:
verify_packet(self, untaggedPkt, inport)
- # test upstream doubletagged packet got dropped
- self.dataplane.send(inport, str(upstreamDoubleTaggedPkt))
- verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
+ if verify_blocked_flows:
+ # test upstream doubletagged packet got dropped
+ self.dataplane.send(inport, str(upstreamDoubleTaggedPkt))
+ verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
- # test downstream untagged packet got dropped at ONU
- self.dataplane.send(olt_port, str(untaggedPkt))
- verify_no_packet(self, untaggedPkt, inport)
+ # test downstream untagged packet got dropped at ONU
+ self.dataplane.send(olt_port, str(untaggedPkt))
+ verify_no_packet(self, untaggedPkt, inport)
- # test upstream icorrectly tagged packet; should get dropped
- self.dataplane.send(inport, str(incorrectTagPkt))
- verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
+ # test upstream icorrectly tagged packet; should get dropped
+ self.dataplane.send(inport, str(incorrectTagPkt))
+ verify_no_packet(self, upstreamDoubleTaggedPkt, olt_port)
+
+ def testSustainedPacketFlow(self, s_vlan_id, c_vlan_id, number_of_roundtrips=10, onu=None):
+ for i in xrange(number_of_roundtrips):
+ print "loop %d" % i
+ self.testPacketFlow(s_vlan_id, c_vlan_id, onu=onu, verify_blocked_flows=False)
def installDoubleTaggingRules(self, s_vlan_id, c_vlan_id, cookie=42, onu = None):