Merge "Completed 2nd complex testcase with 2 ONUs"
diff --git a/olt-complex.py b/olt-complex.py
index 0428f4b..e8ea2e9 100644
--- a/olt-complex.py
+++ b/olt-complex.py
@@ -14,6 +14,19 @@
         self.__dict__.update(kws)
 
 
+class EapolInOnly(OltBaseTest):
+    def runTest(self):
+        self.resetOlt()
+        self.installEapolRule()
+        self.sendEapolIn()
+
+
+class EapolOutOnly(OltBaseTest):
+    def runTest(self):
+        self.resetOlt()
+        self.sendEapolOut()
+
+
 class ControllerAccess(OltBaseTest):
     """Verify openflow access from OLT device"""
 
diff --git a/olt.py b/olt.py
index 7330177..f68c884 100644
--- a/olt.py
+++ b/olt.py
@@ -9,14 +9,13 @@
 import ofp
 import time
 
+from oltconstants import *
 from oftest.testutils import *
 
 from IGMP import IGMPv3, IGMPv3gr, IGMP_TYPE_V3_MEMBERSHIP_REPORT,\
     IGMP_V3_GR_TYPE_INCLUDE,\
     IGMP_V3_GR_TYPE_EXCLUDE
 
-from oltconstants import *
-
 
 class EapolPacketIn(OltBaseTest):
     """Verify packet-ins are sent for EAPOL packets """
diff --git a/oltbase.py b/oltbase.py
index 5797005..56d43a6 100644
--- a/oltbase.py
+++ b/oltbase.py
@@ -1,8 +1,8 @@
 import oftest.base_tests as base_tests
 from oftest import config
 import ofp
-from oftest.testutils import *
 from oltconstants import *
+from oftest.testutils import *
 import copy
 import logging
 from IGMP import IGMPv3, IGMPv3gr, IGMP_TYPE_MEMBERSHIP_QUERY, \
@@ -76,7 +76,7 @@
                     buffer_id=ofp.OFP_NO_BUFFER,
                     priority=1000)
         else:
-            request = ofp.message.flow_delete(
+            request = ofp.message.flow_delete_strict(
                     table_id=test_param_get("table", 0),
                     cookie=42,
                     match=match,
@@ -101,6 +101,24 @@
         verify_packet_in(self, pkt, in_port, ofp.OFPR_ACTION)
         verify_packets(self, pkt, [])
 
+    def sendEapolOut(self, out_port=None):
+        """Send out an EAPOL frame and verify that it is sent out at the given ONU port"""
+        out_port = onu_port if out_port is None else out_port
+        pkt = simple_eth_packet(eth_dst='01:02:03:04:05:06', eth_src='01:02:03:de:ad:be',
+                                eth_type=0x888e, pktlen=300)
+        
+        msg = ofp.message.packet_out(
+            in_port=ofp.OFPP_CONTROLLER,
+            actions=[ofp.action.output(port=out_port)],
+            buffer_id=ofp.OFP_NO_BUFFER,
+            data=str(pkt))
+
+        rv = self.controller.message_send(msg)
+        self.assertTrue(rv == 0, "Error sending output message")
+        verify_no_errors(self.controller)
+
+        verify_packet(self, pkt, out_port)
+
     def testPacketFlow(self,
                        s_vlan_id,
                        c_vlan_id,
diff --git a/oltconstants.py b/oltconstants.py
index b97ab5a..29a6db5 100644
--- a/oltconstants.py
+++ b/oltconstants.py
@@ -1,4 +1,5 @@
-from oftest.testutils import *
+import logging
+from oftest.testutils import test_param_get, MINSIZE
 import oftest.packet as scapy
 from oftest import config
 
@@ -11,7 +12,7 @@
 onu_port2 = test_param_get("onu_port2", 131)
 olt_port = test_param_get("olt_port", 258)
 device_type = test_param_get("device_type", "normal")  # options: "normal", "pmc", "cpqd"
-
+fake_dataplane = test_param_get("fake_dataplane", False)
 
 def createAllGroupAdd(group_id, ports=[]):
     buckets = []
@@ -101,3 +102,28 @@
     pkt = pkt / ("D" * (pktlen - len(pkt)))
 
     return pkt
+
+# Monkey-patch the oftest library to allow faking the data-plane
+# This mode allows oftest to glide through the OF programming steps while
+# passing all packet receiving tests. This is useful when you want to
+# verify that your agent's OF interface handles all OF protocol messages
+# from the controller, but in the absence of actual data-plane tests.
+# In order to achieve this, in this mode the following chnages are made:
+# - All verify_packet_in() tests pass
+if fake_dataplane:
+    logging.info('Monkey-patching for fake-dataplane operations')
+
+    from oftest import testutils
+
+    def patched_verify_packet_in(test, data, in_port, reason, controller=None):
+        logging.debug('Faking verify_packet_in')
+        msg = ofp.message.packet_in(reason=reason, data=data)
+        return msg
+
+    testutils.verify_packet_in = patched_verify_packet_in
+
+    def patched_verify_packet(test, pkt, of_port):
+        logging.debug('Faking verify_packet')
+        return
+
+    testutils.verify_packet = patched_verify_packet