Added DirectTwoPorts

Added a test to egress a packet out two ports from a specified
ingress port.

Passes on SW and LB6B
diff --git a/tests/pktact.py b/tests/pktact.py
index 31c56ce..89d9a96 100644
--- a/tests/pktact.py
+++ b/tests/pktact.py
@@ -55,7 +55,7 @@
 
 class DirectPacket(basic.SimpleDataPlane):
     """
-    Test case that checks single port direction action
+    Send packet to single egress port
 
     Generate a packet
     Generate and install a matching flow
@@ -103,10 +103,87 @@
             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(pkt)) + " in on " + 
+            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")
+
+        rc = delete_all_flows(self.controller, pa_logger)
+        self.assertEqual(rc, 0, "Failed to delete all flows")
+
+        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)):
+            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')
+            
+