"""
Test cases for testing actions taken on packets

See basic.py for other info.

It is recommended that these definitions be kept in their own
namespace as different groups of tests will likely define 
similar identifiers.

  The function test_set_init is called with a complete configuration
dictionary prior to the invocation of any tests from this file.

  The switch is actively attempting to contact the controller at the address
indicated oin oft_config

"""

import logging

import unittest

import oftest.controller as controller
import oftest.cstruct as ofp
import oftest.message as message
import oftest.dataplane as dataplane
import oftest.action as action
import oftest.parse as parse
import basic

from testutils import *

#@var port_map Local copy of the configuration map from OF port
# numbers to OS interfaces
pa_port_map = None
#@var pa_logger Local logger object
pa_logger = None
#@var pa_config Local copy of global configuration data
pa_config = None

def test_set_init(config):
    """
    Set up function for packet action test classes

    @param config The configuration dictionary; see oft
    """

    global pa_port_map
    global pa_logger
    global pa_config

    pa_logger = logging.getLogger("pkt_act")
    pa_logger.info("Initializing test set")
    pa_port_map = config["port_map"]
    pa_config = config

class DirectPacket(basic.SimpleDataPlane):
    """
    Send packet to single egress port

    Generate a packet
    Generate and install a matching flow
    Add action to direct the packet to an egress port
    Send the packet to ingress dataplane port
    Verify the packet is received at the egress port only
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 1, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            egress_port = of_ports[(idx + 1) % len(of_ports)]
            pa_logger.info("Ingress " + str(ingress_port) + 
                        " to egress " + str(egress_port))

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            act.port = egress_port
            self.assertTrue(request.actions.add(act), "Could not add action")

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + 
                           str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(timeout=1)
            self.assertTrue(rcv_pkt is not None, "Did not receive packet")
            pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on " + 
                         str(rcv_port))
            self.assertEqual(rcv_port, egress_port, "Unexpected receive port")
            self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet')
            
        

class DirectTwoPorts(basic.SimpleDataPlane):
    """
    Send packet to two egress ports

    Generate a packet
    Generate and install a matching flow
    Add action to direct the packet to two egress ports
    Send the packet to ingress dataplane port
    Verify the packet is received at the two egress ports
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 2, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            egress_port1 = of_ports[(idx + 1) % len(of_ports)]
            egress_port2 = of_ports[(idx + 2) % len(of_ports)]
            pa_logger.info("Ingress " + str(ingress_port) + 
                           " to egress " + str(egress_port1) + " and " +
                           str(egress_port2))

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            act.port = egress_port1
            self.assertTrue(request.actions.add(act), "Could not add action1")
            act.port = egress_port2
            self.assertTrue(request.actions.add(act), "Could not add action2")
            # pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + 
                           str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            (rcv_port1, rcv_pkt1, pkt_time1) = self.dataplane.poll(timeout=1)
            (rcv_port2, rcv_pkt2, pkt_time2) = self.dataplane.poll(timeout=1)
            self.assertTrue(rcv_pkt1 is not None, "Did not receive packet 1")
            self.assertTrue(rcv_pkt2 is not None, "Did not receive packet 2")
            pa_logger.debug("Packet len " + str(len(rcv_pkt1)) + " in on " + 
                         str(rcv_port1))
            pa_logger.debug("Packet len " + str(len(rcv_pkt2)) + " in on " + 
                         str(rcv_port2))

            # Check if ports swapped
            if (rcv_port1 == egress_port2 and rcv_port2 == egress_port1):
                (rcv_port2, rcv_port1) = (rcv_port1, rcv_port2)
                (rcv_pkt2, rcv_pkt1) = (rcv_pkt1, rcv_pkt2)
            self.assertEqual(rcv_port1, egress_port1,
                             "Unexpected receive port 1")
            self.assertEqual(rcv_port2, egress_port2,
                             "Unexpected receive port 2")
            self.assertEqual(str(pkt), str(rcv_pkt1),
                             'Response packet does not match send packet 1')
            self.assertEqual(str(pkt), str(rcv_pkt2),
                             'Response packet does not match send packet 2')

class DirectMCNonIngress(basic.SimpleDataPlane):
    """
    Multicast to all non-ingress ports

    Generate a packet
    Generate and install a matching flow
    Add action to direct the packet to all non-ingress ports
    Send the packet to ingress dataplane port
    Verify the packet is received at all non-ingress ports

    Does not use the flood action
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 2, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + 
                           " all non-ingress ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            for egr_idx in range(len(of_ports)):
                if egr_idx == idx:
                    continue
                egress_port = of_ports[egr_idx]
                act.port = egress_port
                self.assertTrue(request.actions.add(act), 
                                "Could not add output to " + str(egress_port))
            pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + 
                           str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            for egr_idx in range(len(of_ports)):
                if egr_idx == idx:
                    continue
                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                    port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None, 
                                "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                                + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet ' +
                                 "on port " + str(ofport))

class DirectMC(basic.SimpleDataPlane):
    """
    Multicast to all ports including ingress

    Generate a packet
    Generate and install a matching flow
    Add action to direct the packet to all non-ingress ports
    Send the packet to ingress dataplane port
    Verify the packet is received at all ports

    Does not use the flood action
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 2, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + " to all ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            for egr_idx in range(len(of_ports)):
                egress_port = of_ports[egr_idx]
                if egr_idx == idx:
                    act.port = ofp.OFPP_IN_PORT
                else:
                    act.port = egress_port
                self.assertTrue(request.actions.add(act), 
                                "Could not add output to " + str(egress_port))
            # pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            for egr_idx in range(len(of_ports)):
                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                    port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None, 
                                "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                                + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet ' +
                                 "on port " + str(ofport))

class Flood(basic.SimpleDataPlane):
    """
    Flood to all ports except ingress

    Generate a packet
    Generate and install a matching flow
    Add action to flood the packet
    Send the packet to ingress dataplane port
    Verify the packet is received at all other ports
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 1, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + " to all ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            act.port = ofp.OFPP_FLOOD
            self.assertTrue(request.actions.add(act), 
                            "Could not add flood port action")
            pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            for egr_idx in range(len(of_ports)):
                if egr_idx == idx:
                    continue
                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                    port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None, 
                                "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                                + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet ' +
                                 "on port " + str(ofport))


class FloodPlusIngress(basic.SimpleDataPlane):
    """
    Flood to all ports plus send to ingress port

    Generate a packet
    Generate and install a matching flow
    Add action to flood the packet
    Add action to send to ingress port
    Send the packet to ingress dataplane port
    Verify the packet is received at all other ports
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 1, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + " to all ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            act.port = ofp.OFPP_FLOOD
            self.assertTrue(request.actions.add(act), 
                            "Could not add flood port action")
            act.port = ofp.OFPP_IN_PORT
            self.assertTrue(request.actions.add(act), 
                            "Could not add ingress port for output")
            pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            for egr_idx in range(len(of_ports)):
                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                    port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None, 
                                "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                                + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet ' +
                                 "on port " + str(ofport))

class All(basic.SimpleDataPlane):
    """
    Send to OFPP_ALL port

    Generate a packet
    Generate and install a matching flow
    Add action to forward to OFPP_ALL
    Send the packet to ingress dataplane port
    Verify the packet is received at all other ports
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 1, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + " to all ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            act.port = ofp.OFPP_ALL
            self.assertTrue(request.actions.add(act), 
                            "Could not add ALL port action")
            pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            for egr_idx in range(len(of_ports)):
                if egr_idx == idx:
                    continue
                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                    port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None, 
                                "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                                + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet ' +
                                 "on port " + str(ofport))

class AllPlusIngress(basic.SimpleDataPlane):
    """
    Send to OFPP_ALL port and ingress port

    Generate a packet
    Generate and install a matching flow
    Add action to forward to OFPP_ALL
    Add action to forward to ingress port
    Send the packet to ingress dataplane port
    Verify the packet is received at all other ports
    """
    def runTest(self):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 1, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        match.wildcards &= ~ofp.OFPFW_IN_PORT
        self.assertTrue(match is not None, 
                        "Could not generate flow match from pkt")
        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + " to all ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            act.port = ofp.OFPP_ALL
            self.assertTrue(request.actions.add(act), 
                            "Could not add ALL port action")
            act.port = ofp.OFPP_IN_PORT
            self.assertTrue(request.actions.add(act), 
                            "Could not add ingress port for output")
            pa_logger.info(request.show())

            pa_logger.info("Inserting flow")
            rv = self.controller.message_send(request)
            self.assertTrue(rv != -1, "Error installing flow mod")
            do_barrier(self.controller)

            pa_logger.info("Sending packet to dp port " + str(ingress_port))
            self.dataplane.send(ingress_port, str(pkt))
            for egr_idx in range(len(of_ports)):
                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                    port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None, 
                                "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                                + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                             'Response packet does not match send packet ' +
                                 "on port " + str(ofport))

class SimpleExactMatch(basic.SimpleDataPlane):
    """
    Exercise exact matching for all ports

    Generate a packet
    Generate and install a matching flow without wildcard mask
    Add action to forward to a port
    Send the packet to the port
    Verify the packet is received at all other ports (one port at a time)
    Verify flow_expiration message is correct when command option is set
    """
    IP_ETHTYPE = 0x800
    TCP_PROTOCOL = 0x6
    UDP_PROTOCOL = 0x11

    def runTest(self):
        self.flowMatchTest()

    def flowMatchTest(self, wildcards=0, check_expire=False):
        global pa_port_map
        of_ports = pa_port_map.keys()
        of_ports.sort()
        self.assertTrue(len(of_ports) > 1, "Not enough ports for test")

        pkt = simple_tcp_packet()
        match = parse.packet_to_flow_match(pkt)
        self.assertTrue(match is not None,
                        "Could not generate flow match from pkt")
        match.dl_vlan = ofp.OFP_VLAN_NONE
        match.nw_proto = self.TCP_PROTOCOL
        match.wildcards = wildcards

        act = action.action_output()

        for idx in range(len(of_ports)):
            rc = delete_all_flows(self.controller, pa_logger)
            self.assertEqual(rc, 0, "Failed to delete all flows")

            ingress_port = of_ports[idx]
            pa_logger.info("Ingress " + str(ingress_port) + " to all the other ports")

            match.in_port = ingress_port

            request = message.flow_mod()
            request.match = match
            request.buffer_id = 0xffffffff
            #@todo Need UI to setup FLAGS parameter for flow_mod
            if(check_expire):
                request.flags |= ofp.OFPFF_SEND_FLOW_REM
                request.hard_timeout = 1

            for egr_idx in range(len(of_ports)):
                if egr_idx == idx:
                    continue
                act.port = of_ports[egr_idx]
                self.assertTrue(request.actions.add(act),
                                "Could not add output action")
                pa_logger.info(request.show())

                pa_logger.info("Inserting flow")
                rv = self.controller.message_send(request)
                self.assertTrue(rv != -1, "Error installing flow mod")
                do_barrier(self.controller)

                pa_logger.info("Sending packet to dp port " +str(ingress_port))
                self.dataplane.send(ingress_port, str(pkt))

                ofport = of_ports[egr_idx]
                (rcv_port, rcv_pkt, pkt_time) = self.dataplane.poll(
                port_number=ofport, timeout=1)
                self.assertTrue(rcv_pkt is not None,
                            "Did not receive packet port " + str(ofport))
                pa_logger.debug("Packet len " + str(len(rcv_pkt)) + " in on "
                            + str(rcv_port))

                self.assertEqual(str(pkt), str(rcv_pkt),
                    'Response packet does not match send packet ' +
                    "on port " + str(ofport))

                #@todo Need UI for enabling response-verification
                if(check_expire):
                    (response, raw) \
                        = self.controller.poll(ofp.OFPT_FLOW_REMOVED, 2)
                    self.assertTrue(response is not None,
                                    'Flow removed message not received')

                    req_match = request.match
                    res_match = response.match
                    if(req_match != res_match):
                        self.verifMatchField(req_match, res_match)

                    self.assertEqual(request.cookie, response.cookie,
                        self.matchErrStr('cookie'))
                    if (wildcards != 0):
                        self.assertEqual(request.priority, response.priority,
                            self.matchErrStr('priority'))
                    self.assertEqual(response.reason, ofp.OFPRR_HARD_TIMEOUT,
                        'Reason is not HARD TIMEOUT')
                    self.assertEqual(response.packet_count, 1,
                        'Packet count is not correct')
                    self.assertEqual(response.byte_count, len(pkt),
                        'Packet length is not correct')

    def verifMatchField(self, req_match, res_match):
        self.assertEqual(str(req_match.wildcards), str(res_match.wildcards),
            self.matchErrStr('wildcards'))
        self.assertEqual(str(req_match.in_port), str(res_match.in_port),
            self.matchErrStr('in_port'))
        self.assertEqual(str(req_match.dl_src), str(res_match.dl_src),
            self.matchErrStr('dl_src'))
        self.assertEqual(str(req_match.dl_dst), str(res_match.dl_dst),
            self.matchErrStr('dl_dst'))
        self.assertEqual(str(req_match.dl_vlan), str(res_match.dl_vlan),
            self.matchErrStr('dl_vlan'))
        self.assertEqual(str(req_match.dl_vlan_pcp), str(res_match.dl_vlan_pcp),
            self.matchErrStr('dl_vlan_pcp'))
        self.assertEqual(str(req_match.dl_type), str(res_match.dl_type),
            self.matchErrStr('dl_type'))
        if(not(req_match.wildcards & ofp.OFPFW_DL_TYPE)
           and (req_match.dl_type == self.IP_ETHERTYPE)):
            self.assertEqual(str(req_match.nw_tos), str(res_match.nw_tos),
                self.matchErrStr('nw_tos'))
            self.assertEqual(str(req_match.nw_proto), str(res_match.nw_proto),
                self.matchErrStr('nw_proto'))
            self.assertEqual(str(req_match.nw_src), str(res_match.nw_src),
                self.matchErrStr('nw_src'))
            self.assertEqual(str(req_match.nw_dst), str(res_match.nw_dst),
                self.matchErrStr('nw_dst'))
            if(not(req_match.wildcards & ofp.OFPFW_NW_PROTO)
               and ((req_match.nw_proto == self.TCP_PROTOCOL)
                    or (req_match.nw_proto == self.UDP_PROTOCOL))):
                self.assertEqual(str(req_match.tp_src), str(res_match.tp_src),
                    self.matchErrStr('tp_src'))
                self.assertEqual(str(req_match.tp_dst), str(res_match.tp_dst),
                    self.matchErrStr('tp_dst'))

    def matchErrStr(self, field):
        return ('Response Match_' + field + ' does not match send message')

class SingleWildcardMatch(SimpleExactMatch):
    """
    Exercise wildcard matching for all ports

    Generate a packet
    Generate and install a matching flow with wildcard mask
    Add action to forward to a port
    Send the packet to the port
    Verify the packet is received at all other ports (one port at a time)
    Verify flow_expiration message is correct when command option is set
    """
    def __init__(self):
        SimpleExactMatch.__init__(self)
        self.wildcards = [ofp.OFPFW_IN_PORT,
                          ofp.OFPFW_DL_VLAN,
                          ofp.OFPFW_DL_SRC,
                          ofp.OFPFW_DL_DST,
                          ofp.OFPFW_DL_TYPE,
                          ofp.OFPFW_NW_PROTO,
                          ofp.OFPFW_TP_SRC,
                          ofp.OFPFW_TP_DST,
                          0x3F << ofp.OFPFW_NW_SRC_SHIFT,
                          0x3F << ofp.OFPFW_NW_DST_SHIFT,
                          ofp.OFPFW_DL_VLAN_PCP,
                          ofp.OFPFW_NW_TOS]

    def runTest(self):
        for exec_wildcard in range(len(self.wildcards)):
            self.flowMatchTest(exec_wildcard)

class AllExceptOneWildcardMatch(SingleWildcardMatch):
    """
    Create All-execpt-one-field wildcard and exercise for all ports

    Generate a packet
    Generate and install a matching flow with wildcard all except one filed
    Add action to forward to a port
    Send the packet to the port
    Verify the packet is received at all other ports (one port at a time)
    Verify flow_expiration message is correct when command option is set
    """
    def runTest(self):
        for exec_wildcard in range(len(self.wildcards)):
            all_exp_one_wildcard = ofp.OFPFW_ALL ^ self.wildcards[exec_wildcard]
            self.flowMatchTest(all_exp_one_wildcard)
