'''
OFTests for functionality needed from the OLT.
'''

import logging
from __builtin__ import xrange
from oltbase import OltBaseTest
import oftest.packet as scapy
import ofp
import time

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 """

    def runTest(self):
        logging.info("Running EAPOL Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x888e))
        # Use ethertype 0x888e and multicast destination MAC address
        pkt = simple_eth_packet(pktlen=60, eth_dst='01:00:5E:7F:FF:FF', eth_type=0x888e)

        self.testPacketIn(match, pkt)


class ARPPacketIn(OltBaseTest):
    """Verify packet-ins are sent for ARP packets """

    def runTest(self):
        logging.info("Running ARP Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x0806))

        # Use ethertype 0x0806
        pkt = simple_eth_packet(eth_type=0x0806)

        self.testPacketIn(match, pkt)


class IGMPPacketIn(OltBaseTest):
    """Verify packet-ins are sent for IGMP packets """

    def runTest(self):
        logging.info("Running IGMP Packet In test")

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.eth_type(0x800))
        match.oxm_list.append(ofp.oxm.ip_proto(2))

        igmp = IGMPv3(type=IGMP_TYPE_V3_MEMBERSHIP_REPORT, max_resp_code=30, gaddr="224.0.0.1")
        igmp.grps = [IGMPv3gr(rtype=IGMP_V3_GR_TYPE_EXCLUDE, mcaddr="229.10.20.30")]
        pkt = IGMPv3.fixup( scapy.Ether(src='00:00:00:00:be:ef') / scapy.IP() / igmp )
        pkt = pkt / ("0" * (100 - len(pkt)))

        self.testPacketIn(match, pkt)


class IGMPQueryPacketOut(OltBaseTest):
    """Verify sending multicast membership queries down to onu_ports"""

    def runTest(self):
        logging.info("Running IGMP query packet out")

        igmp = IGMPv3()  # by default this is a query
        pkt = buildIgmp(igmp)

        msg = ofp.message.packet_out(
            in_port=ofp.OFPP_CONTROLLER,
            actions=[ofp.action.output(port=onu_port)],
            buffer_id=ofp.OFP_NO_BUFFER,
            data=str(pkt))

        self.controller.message_send(msg)

        rv = self.controller.message_send(msg)
        self.assertTrue(rv == 0, "Error sending put message")
        verify_no_errors(self.controller)

        verify_packet(self, pkt, onu_port)


class TestMeter(OltBaseTest):

    def runTest(self):
        logging.info("Running Meter tests")
        dropMeterBand = ofp.meter_band.drop(rate=640)
        meter_mod = ofp.message.meter_mod(xid=1, command=ofp.OFPMC_ADD, meter_id=1, meters=[dropMeterBand])
        self.controller.message_send(meter_mod)

        time.sleep(1)

        verify_no_errors(self.controller)

        vlan_id = 201
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.output(port=olt_port)]),
                ofp.instruction.meter(meter_id = 1)
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        time.sleep(1)
        verify_no_errors(self.controller)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.output(port=onu_port)]),
                ofp.instruction.meter(meter_id = 1)
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        time.sleep(1)
        verify_no_errors(self.controller)
        do_barrier(self.controller)
        time.sleep(5)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)
        # downstream
        # self.dataplane.send(olt_port, str(inPkt))
        # verify_packet(self, inPkt, onu_port)
        # upstream
        # for i in range(1,400):
        #	self.dataplane.send(onu_port, str(inPkt))
        # verify_packet(self, inPkt, olt_port)

        # clean up the test
        meter_mod = ofp.message.meter_mod(xid=2, command=ofp.OFPMC_DELETE, meter_id=1)
        self.controller.message_send(meter_mod)
        time.sleep(1)
        delete_all_flows(self.controller)
        verify_no_errors(self.controller)


class TestDuplicateMeter(OltBaseTest):
    def runTest(self):
        logging.info("Running Duplicate Meter Test")
        dropMeterBand = ofp.meter_band.drop(rate=500)
        meter_mod = ofp.message.meter_mod(xid=1, command=ofp.OFPMC_ADD, meter_id=1, meters=[dropMeterBand])
        self.controller.message_send(meter_mod)
        self.controller.message_send(meter_mod)

        time.sleep(1)

        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            if (not e.message == "unexpected error type=12 code=1"):
                raise AssertionError("Incorrect error type: %s" % e.message)


class VlanTest(OltBaseTest):
    """Verify the switch can push/pop a VLAN tag and forward out a port """

    def runTest(self):
        logging.info("Running push VLAN test")

        vlan_id = 200

        delete_all_flows(self.controller)

        # PUSH
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        if device_type == "cpqd":
            match.oxm_list.append(ofp.oxm.vlan_vid(value=ofp.OFPVID_NONE))
            actions = [
                ofp.action.push_vlan(ethertype=0x8100),
                ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id)),
                ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                ofp.action.output(port=olt_port)
            ]
        else:  # pmc, normal
            match.oxm_list.append(ofp.oxm.vlan_vid_masked(value=ofp.OFPVID_PRESENT, value_mask=ofp.OFPVID_PRESENT))
            match.oxm_list.append(ofp.oxm.vlan_pcp(value = 0))
            actions = [
                ofp.action.set_field(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id)),
                ofp.action.set_field(ofp.oxm.vlan_pcp(0)),
                ofp.action.output(port=olt_port)
            ]

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[ofp.instruction.apply_actions(actions=actions)],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        logging.info("Inserting flow tagging upstream")
        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # POP
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.pop_vlan(),
                        ofp.action.output(port=onu_port)])],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        logging.info("Inserting flow tagging downstream")
        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        time.sleep(5)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
        outPkt = simple_udp_packet(pktlen=100, dl_vlan_enable=True,
                                   vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)

        # Send untagged packet in the ONU port and expect tagged packet out the OLT port
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, outPkt, olt_port)

        # Send untagged packet in the OLT port and expect no packets to come out
        self.dataplane.send(olt_port, str(inPkt))
        verify_packets(self, outPkt, [])

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0)
        if device_type == 'pmc':
            outPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True, vlan_vid=0, vlan_pcp=0)
        else:  # "normal", "cpqd""
            outPkt = simple_udp_packet(pktlen=100)

        # Send tagged packet in the OLT port and expect untagged packet out the OLT port
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)

        # Send tagged packet in the ONU port and expect no packets to come out
        self.dataplane.send(onu_port, str(inPkt))
        verify_packets(self, outPkt, [])





class TestGroupAdd(OltBaseTest):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1

        # output to two ONU
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Remove the group and then readd it.
        group_delete = ofp.message.group_delete(group_id=test_group_id)
        self.controller.message_send(group_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])
        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


        # clean up the test
        group_delete = ofp.message.group_delete(group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupMod(OltBaseTest):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1

        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Modifying the group
        group_mod = createAllGroupMod(test_group_id, [onu_port2])

        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add a bucket into the group
        group_mod = createAllGroupMod(test_group_id, [onu_port, onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Modifying a non-existing group
        group_mod = createAllGroupMod(777, [onu_port2])

        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        errorExperienced = 0
        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            errorExperienced = 1
            if (not (e.message == "unexpected error type=6 code=8")):
                raise AssertionError("Incorrect error type: %s" % e.message)
        if not errorExperienced:
            raise AssertionError("An error message is expected, but not shown.")


        # clean up the test
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestDuplicateGroup(OltBaseTest):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add the same group id
        duplicate_group_fail = 0

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        try:
            verify_no_errors(self.controller)
        except AssertionError as e:
            duplicate_group_fail = 1
            if (not e.message == "unexpected error type=6 code=0"):
                raise AssertionError("Incorrect error type: %s" % e.message)
        if not duplicate_group_fail:
            raise AssertionError("Adding duplicate groups didn't raise an error.")

        # clean up the test
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupAndFlow(OltBaseTest):

    def runTest(self):
        logging.info("Running Group tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, ports=[onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | 201))

        flow_pointing_to_group = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)])],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(flow_pointing_to_group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # After letting a flow rule point to the group, test we can do group_mod
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Test we can remove flows and then remove group
        flow_delete = ofp.message.flow_delete(table_id=test_param_get("table", 0))
        self.controller.message_send(flow_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_delete = ofp.message.group_delete(xid=3, group_id=test_group_id)
        self.controller.message_send(group_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Add the group and flow back, test it we can first remove group and then remove the flow.
        '''group_add = createAllGroupAdd(test_group_id, ports=[onu_port])
        self.controller.message_send(group_add)

        self.controller.message_send(flow_pointing_to_group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        group_delete = ofp.message.group_delete(xid = 4, group_id = test_group_id)
        self.controller.message_send(group_delete)'''

        self.controller.message_send(flow_delete)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupForwarding(OltBaseTest):

    def runTest(self):
        logging.info("Running Group datapath forwarding tests")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        vlan_id = 201

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, [onu_port])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0, eth_dst="01:01:11:12:11:12")
        outPkt = inPkt
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)


        # Now put 2 ONU ports in the group and test that the input packet is
        # duplicated out both ports
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port, onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port2)
        verify_packet(self, outPkt, onu_port)
        # verify_packets(self, outPkt, [onu_port,onu_port2])

        # clean up the test
        request = ofp.message.flow_delete(table_id=test_param_get("table", 0))
        self.controller.message_send(request)
        group_delete = ofp.message.group_delete(xid=2, group_id=test_group_id)
        self.controller.message_send(group_delete)

        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestGroupModForwarding(OltBaseTest):

    def runTest(self):
        logging.info("Running datapath forwarding tests for group mod")
        delete_all_flows(self.controller)
        delete_all_groups(self.controller)

        vlan_id = 201

        # Create a group
        test_group_id = 1
        group_add = createAllGroupAdd(test_group_id, [onu_port, onu_port2])

        self.controller.message_send(group_add)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=test_group_id)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        inPkt = simple_udp_packet(pktlen=104, dl_vlan_enable=True,
                                  vlan_vid=vlan_id, vlan_pcp=0, dl_vlan_cfi=0, eth_dst="01:01:11:12:11:12")
        outPkt = inPkt
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, onu_port2)

        # Now remove onu port 1 from the group and test that the input packet is no longer forwarded to onu port 1
        group_mod = createAllGroupMod(test_group_id, ports=[onu_port2])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        time.sleep(10)
        self.dataplane.send(olt_port, str(inPkt))
        verify_no_packet(self, outPkt, onu_port)
        verify_packet(self, outPkt, onu_port2)

        # Now remove all ports in the group and test that the input packet is no longer forwarded to any port
        group_mod = createAllGroupMod(test_group_id, ports=[])
        self.controller.message_send(group_mod)
        do_barrier(self.controller)
        verify_no_errors(self.controller)
        time.sleep(10)
        self.dataplane.send(olt_port, str(inPkt))
        verify_packets(self, outPkt, [])


class TransparentVlanTest(OltBaseTest):

    def runTest(self):
        logging.info("Running transparent vlan tests")
        delete_all_flows(self.controller)

        vlan_id = 201
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(onu_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=42,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(port=olt_port)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)

        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[
                        ofp.action.output(port=onu_port)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER,
            priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(2)

        inPkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0)

        # upstream
        self.dataplane.send(onu_port, str(inPkt))
        verify_packet(self, inPkt, olt_port)

        # downstream
        self.dataplane.send(olt_port, str(inPkt))
        verify_packet(self, inPkt, onu_port)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

class TestMulticastForwarding(IGMPPacketIn):

    def runTest(self):
        delete_all_groups(self.controller)
        # send igmp join packet
        super(TestMulticastForwarding, self).runTest()

        vlan_id = 201

        group = createAllGroupAdd(1, [onu_port])

        self.controller.message_send(group)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # Create a flow rule matching olt port and vlan id
        match = ofp.match()
        match.oxm_list.append(ofp.oxm.in_port(olt_port))
        match.oxm_list.append(ofp.oxm.vlan_vid(ofp.OFPVID_PRESENT | vlan_id))

        request = ofp.message.flow_add(
            table_id=test_param_get("table", 0),
            cookie=43,
            match=match,
            instructions=[
                ofp.instruction.apply_actions(
                    actions=[ofp.action.group(group_id=1)]),
            ],
            buffer_id=ofp.OFP_NO_BUFFER, priority=1000)

        self.controller.message_send(request)
        do_barrier(self.controller)
        verify_no_errors(self.controller)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(5)

        pkt = simple_udp_packet(dl_vlan_enable=True, vlan_vid=vlan_id, vlan_pcp=0, \
                                eth_dst = "01:00:5E:00:00:01", ip_dst = "229.10.20.30")

        # downstream
        self.dataplane.send(olt_port, str(pkt))
        verify_packet(self, pkt, onu_port)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)
        delete_all_groups(self.controller)


class RemoveRuleTest(OltBaseTest):

    def runTest(self):
        logging.info("Testing Rule removal")
        delete_all_flows(self.controller)
        self.processEapolRule(onu_port)

        #wait for the rule to settle
        time.sleep(3)

        self.installDoubleTaggingRules(1, 2)

        #wait for the rules to settle
        time.sleep(3)

        stats = get_flow_stats(self, ofp.match())

        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)
        time.sleep(3)

        stats = get_flow_stats(self, ofp.match())

        self.assertTrue(len(stats) == 4, \
                        "Wrong number of rules reports; reported %s, expected 4\n\n %s" % (len(stats), stats))

        eapol = ofp.oxm.eth_type(0x888e)
        found = False
        for fe in stats:
            if eapol in fe.match.oxm_list:
                found = True

        self.assertFalse(found, "Removed incorrect flow rule")


class MultipleDoubleTaggingForwarding(OltBaseTest):

    def runTest(self):
        logging.info("Testing multiple Q-in-Q rules")
        delete_all_flows(self.controller)

        self.installDoubleTaggingRules(10, 5, cookie=42, onu = onu_port)

        time.sleep(1)

        self.installDoubleTaggingRules(10, 30, cookie=50, onu = onu_port2)

        time.sleep(1)

        self.testPacketFlow(10, 5, onu=onu_port)
        self.testPacketFlow(10, 30, onu=onu_port2)

        delete_all_flows(self.controller)


class DoubleVlanTest(OltBaseTest):

    def runTest(self):
        logging.info("Running double vlan tests")
        delete_all_flows(self.controller)

        c_vlan_id = 100
        s_vlan_id = 102

        self.installDoubleTaggingRules(s_vlan_id, c_vlan_id)

        # It takes some time for flows to propagate down to the data plane
        time.sleep(10)

        # Test packet flows
        self.testPacketFlow(s_vlan_id, c_vlan_id)

        # clean up the test
        delete_all_flows(self.controller)
        do_barrier(self.controller)
        verify_no_errors(self.controller)


class TestCyclingDoubleVlan(OltBaseTest):
    """Cycle through vlans and test traffic flow"""

    def runTest(self):
        logging.info("Running cycling vlan test")

        for stag in xrange(2, 4000, 100):
            for ctag in xrange(2, 4000, 100):
                delete_all_flows(self.controller)
                time.sleep(5)
                self.installDoubleTaggingRules(stag, ctag)
                time.sleep(5)
                self.testPacketFlow(stag, ctag)










