Added EAPOL to testcase and outlined 2nd test

Change-Id: Ib199986cb603d4b23e62153207fdd139903794a5
diff --git a/olt-complex.py b/olt-complex.py
index 4a3e579..db8f33f 100644
--- a/olt-complex.py
+++ b/olt-complex.py
@@ -28,12 +28,14 @@
 
 class TestScenario1SingleOnu(OltBaseTest):
     """
-    Run a comprehensive test scenrario on the OLT.
+    Run a comprehensive test scenrario on the OLT, with one ONU.
 
     Plan:
 
-    1.  Reset the OLT into a clean state
-    2.  Setup the OLT to pass authentication (L2/Unicast) traffic for the ONU1
+    0.  Reset the OLT into a clean state
+    1.  Setup the OLT to pass authentication (EAPOL) to controller
+        from any port, and test it.
+    2.  Setup the OLT to pass unicast traffic for the ONU
     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
@@ -78,10 +80,15 @@
             s_vlan_id=13
         )
 
-        # 1.  Reset the OLT into a clean state
+        # 0.  Reset the OLT into a clean state
         self.resetOlt()
 
-        # 2.  Setup the OLT to pass authentication (L2/Unicast) traffic for the ONU1
+        # 1.  Setup the OLT to pass authentication (EAPOL) to controller
+        #     from any port, and test it.
+        self.installEapolRule()
+        self.sendEapolIn()
+
+        # 2.  Setup the OLT to pass 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)
@@ -89,7 +96,7 @@
         self.testSustainedPacketFlow(onu1.s_vlan_id, c_vlan_id, 100)
 
         # 4.  Setup IGMP forwarding toward the controller
-        self.setupIgmpCaptureFlowRules(self.getCookieBlock())
+        self.installIgmpRule(self.getCookieBlock())
         self.testSustainedPacketFlow(onu1.s_vlan_id, c_vlan_id, 10) # to check that unicast still flows
 
         # 5.  Send periodic IGMP queries out toward the ONU and verify its arrival
@@ -170,3 +177,70 @@
 
         # 14. Tear down the test.
         self.resetOlt()
+
+
+class TestScenario2TwoOnus(OltBaseTest):
+    """
+    Run a comprehensive test scenario involving the OLT and two ONUs.
+
+    Plan:
+
+    0.  Reset the OLT into a clean state
+
+    1.  Setup the OLT to pass authentication (EAPOL) to controller from ONU1
+        and test it.
+    2.  Setup the OLT to pass 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 ONU1 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 ONU1
+    8.  Verify that multicast packets can reach ONU1
+    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) - at this point ONU1 is tuned into ch2 and ch3
+
+    12. Setup the OLT to pass authentication (EAPOL) to controller from ONU2
+        and test it.
+    13. Setup the OLT to pass unicast traffic for the ONU2
+    14. Verify that unicast traffic works in both directions (use a few hundred frames in both ways)
+
+    15. Verify that both ONUs can send/receive unicast and ONU1 can still see its 2 channels
+
+    16. Setup IGMP forwarding toward the controller
+    17. Send periodic IGMP queries out toward the ONU2 and verify its arrival
+    18. Send in an IGMP join request for one channel (specific multicast address) and verify that
+        the controller receives it.
+    19. Setup flows for forwarding multicast traffic from the OLT port toward ONU2
+    20. Verify that multicast packets can reach ONU2
+    21. Verify that bidirectional unicast traffic still works across the PON for both ONUs
+    22. 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
+        - verify everything for ONU1 too
+    23. Add a second channel while keeping the existing one. Verify all what needs to be verified
+        (similar as above) - at this point ONU1 is tuned into ch2 and ch3 and ONU2 is
+        tuned to ch2 and ch5
+
+    24. Flip a channel for ONU1 and verify everything
+    25. Tear down the test.
+
+    """
+
+    # TODO
\ No newline at end of file
diff --git a/olt.py b/olt.py
index 42ee55d..7330177 100644
--- a/olt.py
+++ b/olt.py
@@ -720,7 +720,7 @@
     def runTest(self):
         logging.info("Testing Rule removal")
         delete_all_flows(self.controller)
-        self.processEapolRule(onu_port)
+        self.installEapolRule(onu_port)
 
         #wait for the rule to settle
         time.sleep(3)
@@ -735,7 +735,7 @@
         self.assertTrue(len(stats) == 5, \
                         "Wrong number of rules reports; reported %s, expected 5\n\n %s" % (len(stats), stats))
 
-        self.processEapolRule(onu_port, install=False)
+        self.installEapolRule(onu_port, install=False)
         time.sleep(3)
 
         stats = get_flow_stats(self, ofp.match())
@@ -758,7 +758,7 @@
         logging.info("Testing multiple Q-in-Q rules")
         delete_all_flows(self.controller)
 
-        self.processEapolRule(onu_port)
+        self.installEapolRule(onu_port)
 
         time.sleep(1)
 
diff --git a/oltbase.py b/oltbase.py
index 1118054..2baf37c 100644
--- a/oltbase.py
+++ b/oltbase.py
@@ -57,7 +57,8 @@
             verify_packet_in(self, pkt, of_port, ofp.OFPR_ACTION)
             verify_packets(self, pkt, [])
 
-    def processEapolRule(self, in_port, install=True):
+    def installEapolRule(self, in_port=None, install=True):
+        in_port = onu_port if in_port is None else in_port
         match = ofp.match()
         match.oxm_list.append(ofp.oxm.eth_type(0x888e))
         match.oxm_list.append(ofp.oxm.in_port(in_port))
@@ -91,6 +92,15 @@
         self.controller.message_send(request)
         do_barrier(self.controller)
 
+    def sendEapolIn(self, in_port=None):
+        """Send in an EAPOL frame and verify that the controller receives it"""
+
+        in_port = onu_port if in_port is None else in_port
+        pkt = str(simple_eth_packet(eth_dst='01:00:5e:7f:ff:ff', eth_type=0x888e, pktlen=60))
+        self.dataplane.send(in_port, pkt)
+        verify_packet_in(self, pkt, in_port, ofp.OFPR_ACTION)
+        verify_packets(self, pkt, [])
+
     def testPacketFlow(self,
                        s_vlan_id,
                        c_vlan_id,
@@ -248,7 +258,7 @@
         do_barrier(self.controller)
         verify_no_errors(self.controller)
 
-    def setupIgmpCaptureFlowRules(self, cookie):
+    def installIgmpRule(self, cookie):
         """Etsablish flow rules that will forward any incoming
            IGMP packets to controller (from any port, OLT and ONUs)
         """