Updates according to comments for Operational and Functional tests for CORD certification

Change-Id: I3e972fe7f6f85f1b95dd729d6d41f6319a52c8b4
diff --git a/Fabric/Tests/functional.py b/Fabric/Tests/functional.py
index aa3a5bb..663fc2f 100755
--- a/Fabric/Tests/functional.py
+++ b/Fabric/Tests/functional.py
@@ -19,6 +19,7 @@
 """
 import Queue
 
+import os
 from oftest import config
 import inspect
 import logging
@@ -29,6 +30,8 @@
 from oftest.testutils import *
 from accton_util import *
 from oftest.utils import *
+import pexpect
+import json
 
    
 class FabricSW_OF_PacketInUDP_TC_0010( base_tests.SimpleDataPlane ):
@@ -51,7 +54,9 @@
             logging.info( "Inserting packet in flow to controller" )
             self.controller.message_send( request )
 
-            for of_port in config[ "port_map" ].keys( ):
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for of_port in pair:
                 logging.info( "PacketInMiss test, port %d", of_port )
                 self.dataplane.send( of_port, vlan_pkt )
 
@@ -136,6 +141,8 @@
 
     def runTest( self ):
         try:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             parsed_arp_pkt = simple_arp_packet( )
             arp_pkt = str( parsed_arp_pkt )
             # create match
@@ -150,7 +157,7 @@
             self.controller.message_send( request )
             do_barrier( self.controller )
 
-            for of_port in config[ "port_map" ].keys( ):
+            for of_port in pair:
                 logging.info( "PacketInArp test, sending arp packet to port %d", of_port )
                 self.dataplane.send( of_port, arp_pkt )
 
@@ -227,20 +234,21 @@
         Groups = Queue.LifoQueue( )
         try:
             ports = sorted( config[ "port_map" ].keys( ) )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_id = 100
 
-            for port in ports:
+            for port in pair:
                 L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
                 add_one_vlan_table_flow( self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 Groups.put( L2gid )
 
-            msg = add_l2_flood_group( self.controller, ports, vlan_id, vlan_id )
+            msg = add_l2_flood_group( self.controller, pair, vlan_id, vlan_id )
             Groups.put( msg.group_id )
             add_bridge_flow( self.controller, None, vlan_id, msg.group_id, True )
             do_barrier( self.controller )
 
             # verify flood
-            for ofport in ports:
+            for ofport in pair:
                 # change dest based on port number
                 mac_src = '00:12:34:56:78:%02X' % ofport
                 parsed_pkt = simple_tcp_packet_two_vlan( pktlen=108, out_dl_vlan_enable=True,
@@ -251,7 +259,7 @@
                 # self won't rx packet
                 verify_no_packet( self, pkt, ofport )
                 # others will rx packet
-                tmp_ports = list( ports )
+                tmp_ports = list( pair )
                 tmp_ports.remove( ofport )
                 verify_packets( self, pkt, tmp_ports )
 
@@ -312,8 +320,9 @@
         Groups = Queue.LifoQueue( )
         try:
             ports = sorted( config[ "port_map" ].keys( ) )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_id = 1;
-            for port in ports:
+            for port in pair:
                 L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
                 add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 Groups.put( L2gid )
@@ -321,15 +330,15 @@
                         True )
             do_barrier( self.controller )
 
-            for out_port in ports:
+            for out_port in pair:
                 # change dest based on port number
                 mac_dst = '00:12:34:56:78:%02X' % out_port
-                for in_port in ports:
+                for in_port in pair:
                     if in_port == out_port:
                         continue
                     pkt = str( simple_tcp_packet( dl_vlan_enable=True, vlan_vid=vlan_id, eth_dst=mac_dst ) )
                     self.dataplane.send( in_port, pkt )
-                    for ofport in ports:
+                    for ofport in pair:
                         if ofport in [ out_port ]:
                             verify_packet( self, pkt, ofport )
                         else:
@@ -358,6 +367,7 @@
                 logging.info( "Port count less than 2, can't run this case" )
                 return
             ports = sorted( config[ "port_map" ].keys() )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_p0_untagged = 31
             vlan_p1_tagged = 31
             vlan_p1_native = 41
@@ -376,7 +386,7 @@
             add_one_vlan_table_flow( self.controller, ports[1], vlan_id=vlan_p1_native, flag=VLAN_TABLE_FLAG_ONLY_BOTH,
                                      send_barrier=True)
             #flooding groups
-            Floodmsg31 = add_l2_flood_group( self.controller, ports, vlan_p0_untagged, id=0 )
+            Floodmsg31 = add_l2_flood_group( self.controller, pair, vlan_p0_untagged, id=0 )
             Floodmsg41 = add_l2_flood_group( self.controller, [ ports[1] ], vlan_p1_native, id=0 )
 
             #add bridging flows for flooding groups
@@ -478,24 +488,75 @@
             arp_pkt_dest = str( parsed_arp_pkt_tagged )
             verify_packet( self, arp_pkt_dest, ports[1] )
 
+            # Send and verify VLAN 31 tagged unicast packets
+            mac_src = '00:12:34:56:78:%02X' % pair[1]
+            unicast_to_send = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                         out_vlan_vid=vlan_p1_tagged, in_dl_vlan_enable=False,
+                                                         eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+            unicast_to_expect = simple_tcp_packet_two_vlan(pktlen=104, out_dl_vlan_enable=False,
+                                                           in_dl_vlan_enable=False,
+                                                           eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+
+            tmp_ports = list(pair)
+            tmp_ports.remove(pair[1])
+            pkt_s = str(unicast_to_send)
+            pkt_e = str(unicast_to_expect)
+            self.dataplane.send(pair[1], pkt_s)
+            verify_no_packet(self, pkt_s, pair[1])
+            verify_packets(self, pkt_e, tmp_ports)
+
+            # Send and verify untagged unicast packets
+            mac_src = '00:12:34:56:78:%02X' % pair[0]
+            unicast_to_expect = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
+                                                         out_vlan_vid=vlan_p1_tagged, out_vlan_pcp=0, in_dl_vlan_enable=False,
+                                                         eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+            unicast_to_send = simple_tcp_packet_two_vlan(pktlen=104, out_dl_vlan_enable=False,
+                                                           in_dl_vlan_enable=False,
+                                                           eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
+
+            tmp_ports = list(pair)
+            tmp_ports.remove(pair[0])
+            pkt_s = str(unicast_to_send)
+            pkt_e = str(unicast_to_expect)
+            self.dataplane.send(pair[0], pkt_s)
+            verify_no_packet(self, pkt_s, pair[0])
+            verify_packets(self, pkt_e, tmp_ports)
+
         finally:
             delete_all_flows( self.controller )
             delete_all_groups( self.controller )
             #print("done")
 
 
-
 class FabricSW_OF_Mtu1500_TC_0035( base_tests.SimpleDataPlane ):
     """
     Verifies basic mtu limits
     """
+    # Read config parameters from JSON file
+    ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
+    with open(ROOT_DIR + '/' + 'global_vars.json') as f:
+        data = json.load(f)
+
+    switch_ip = data['switch_ip']
+    switch_user = data['switch_user']
+    switch_passwd = data['switch_passwd']
+    controller_ip = data['controller_ip']
+    controller_port = data['controller_port']
+    onos_server_ip = data['onos_server_ip']
+    onos_port = data['onos_port']
+    onos_user = data['onos_user']
+    onos_passwd = data['onos_passwd']
 
     def runTest( self ):
         Groups = Queue.LifoQueue( )
         try:
             ports = sorted( config[ "port_map" ].keys( ) )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_id = 18
-            for port in ports:
+            for port in pair:
                 L2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 Groups.put( L2gid )
@@ -503,22 +564,50 @@
                         True )
             do_barrier( self.controller )
 
-            for out_port in ports:
+            # Send 1500 packet length, default MTU
+            for out_port in pair:
                 # change dest based on port number
                 mac_dst = '00:12:34:56:78:%02X' % out_port
-                for in_port in ports:
+                for in_port in pair:
                     if in_port == out_port:
                         continue
                     pkt = str( simple_tcp_packet( pktlen=1500, dl_vlan_enable=True, vlan_vid=vlan_id,
                             eth_dst=mac_dst ) )
                     self.dataplane.send( in_port, pkt )
-                    for ofport in ports:
+                    for ofport in pair:
                         if ofport in [ out_port ]:
                             verify_packet( self, pkt, ofport )
                         else:
                             verify_no_packet( self, pkt, ofport )
                     verify_no_other_packets( self )
+
+            # Change MTU of server's data ports to 2000 bytes
+            self.dataplane.port_mtu(pair[0], 2000)
+            self.dataplane.port_mtu(pair[1], 2000)
+            time.sleep(1)
+
+            # Change MTU of switch's data ports to 1500 bytes
+            switch_port_set_mtu(self, pair[0], 1500)
+            switch_port_set_mtu(self, pair[1], 1500)
+
+            time.sleep(1)
+
+            # Send 2000 packet length
+            # change dest based on port number
+            mac_dst = '00:12:34:56:78:%02X' % pair[1]
+            pkt = str( simple_tcp_packet( pktlen=2000, dl_vlan_enable=True, vlan_vid=vlan_id, eth_dst=mac_dst ) )
+            self.dataplane.send( pair[0], pkt )
+            tmp_ports = list(pair)
+            tmp_ports.remove(pair[0])
+            verify_no_packet(self, pkt, pair[0])
+            verify_no_packet(self, pkt, pair[1])
+
         finally:
+            self.dataplane.port_mtu(pair[0], 1500)
+            self.dataplane.port_mtu(pair[1], 1500)
+            time.sleep(1)
+            switch_port_set_mtu(self, pair[0], 9412)
+            switch_port_set_mtu(self, pair[1], 9412)
             delete_all_flows( self.controller )
             delete_groups( self.controller, Groups )
             delete_all_groups( self.controller )
@@ -537,8 +626,9 @@
             intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
-            ports = config[ "port_map" ].keys( )
-            for port in ports:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 vlan_id = port + test_id
                 # add l2 interface group and l3 unicast group
                 l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
@@ -561,10 +651,10 @@
             do_barrier( self.controller )
 
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
-            for in_port in ports:
+            for in_port in pair:
                 mac_src = '00:00:00:22:32:%02X' % (test_id + in_port)
                 ip_src = '192.168.%02d.1' % (test_id + in_port)
-                for out_port in ports:
+                for out_port in pair:
                     if in_port == out_port:
                         continue
                     ip_dst = '192.168.%02d.1' % (test_id + out_port)
@@ -831,8 +921,9 @@
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
             # Hashes Test Name and uses it as id for installing unique groups
-            ports = config[ "port_map" ].keys( )
-            for port in ports:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 vlan_id = port
                 id = port
                 # add l2 interface group
@@ -858,10 +949,10 @@
             do_barrier( self.controller )
 
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
-            for in_port in ports:
+            for in_port in pair:
                 mac_src = '00:00:00:22:22:%02X' % in_port
                 ip_src = '192.168.%02d.1' % in_port
-                for out_port in ports:
+                for out_port in pair:
                     if in_port == out_port:
                         continue
                     ip_dst = '192.168.%02d.1' % out_port
@@ -1104,20 +1195,21 @@
     def runTest( self ):
         Groups = Queue.LifoQueue( )
         try:
-            ports = sorted( config[ "port_map" ].keys( ) )
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_id = 1
 
-            for port in ports:
+            for port in pair:
                 L2gid, l2msg = add_one_l2_interface_group( self.controller, port, vlan_id, True, False )
                 add_one_vlan_table_flow( self.controller, port, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 Groups.put( L2gid )
 
-            msg = add_l2_flood_group( self.controller, ports, vlan_id, vlan_id )
+            msg = add_l2_flood_group( self.controller, pair, vlan_id, vlan_id )
             Groups.put( msg.group_id )
             add_bridge_flow( self.controller, None, vlan_id, msg.group_id, True )
             do_barrier( self.controller )
             # verify flood
-            for ofport in ports:
+            for ofport in pair:
                 # change dest based on port number
                 mac_src = '00:12:34:56:78:%02X' % ofport
                 parsed_pkt = simple_tcp_packet_two_vlan( pktlen=108, out_dl_vlan_enable=True,
@@ -1128,18 +1220,18 @@
                 # self won't rx packet
                 verify_no_packet( self, pkt, ofport )
                 # others will rx packet
-                tmp_ports = list( ports )
+                tmp_ports = list( pair )
                 tmp_ports.remove( ofport )
                 verify_packets( self, pkt, tmp_ports )
             verify_no_other_packets( self )
-            msg = mod_l2_flood_group( self.controller, [ ports[ 0 ] ], vlan_id, vlan_id )
-            mac_src = '00:12:34:56:78:%02X' % ports[ 1 ]
+            msg = mod_l2_flood_group( self.controller, [ pair[ 0 ] ], vlan_id, vlan_id )
+            mac_src = '00:12:34:56:78:%02X' % pair[ 1 ]
             parsed_pkt = simple_tcp_packet_two_vlan( pktlen=108, out_dl_vlan_enable=True,
                     out_vlan_vid=vlan_id, in_dl_vlan_enable=True, in_vlan_vid=10, eth_dst='00:12:34:56:78:9a',
                     eth_src=mac_src )
             pkt = str( parsed_pkt )
-            self.dataplane.send( ports[ 1 ], pkt )
-            verify_packets( self, pkt, [ ports[ 0 ] ] )
+            self.dataplane.send( pair[ 1 ], pkt )
+            verify_packets( self, pkt, [ pair[ 0 ] ] )
         finally:
             delete_all_flows( self.controller )
             delete_groups( self.controller, Groups )
@@ -1160,8 +1252,9 @@
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
             # Hashes Test Name and uses it as id for installing unique groups
-            ports = config[ "port_map" ].keys( )
-            for port in ports:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 vlan_id = port
                 id = port
                 # add l2 interface group
@@ -1187,10 +1280,10 @@
             do_barrier( self.controller )
 
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
-            for in_port in ports:
+            for in_port in pair:
                 mac_src = '00:00:00:22:22:%02X' % in_port
                 ip_src = '192.168.%02d.1' % in_port
-                for out_port in ports:
+                for out_port in pair:
                     if in_port == out_port:
                         continue
                     ip_dst = '192.168.%02d.1' % out_port
@@ -1305,7 +1398,8 @@
                 logging.info( "Port count less than 1, can't run this case" )
                 assert (False)
                 return
-            ports      = config[ "port_map" ].keys( )
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             dst_ip_str = "224.0.0.1"
             (
                 port_to_in_vlan,
@@ -1318,14 +1412,14 @@
                 Groups) = fill_mcast_pipeline_L3toL3(
                 self.controller,
                 logging,
-                ports,
+                pair,
                 is_ingress_tagged   = True,
                 is_egress_tagged    = True,
                 is_vlan_translated  = True,
                 is_max_vlan         = False
                 )
 
-            for in_port in ports:
+            for in_port in pair:
 
                 parsed_pkt = simple_udp_packet(
                     pktlen         = 100,
@@ -1340,7 +1434,7 @@
                 pkt = str( parsed_pkt )
                 self.dataplane.send( in_port, pkt )
 
-                for out_port in ports:
+                for out_port in pair:
 
                     parsed_pkt = simple_udp_packet(
                         pktlen         = 100,
@@ -1378,6 +1472,7 @@
                 assert (False)
                 return
             ports      = config[ "port_map" ].keys( )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             dst_ip_str = "224.0.0.1"
             (
                 port_to_in_vlan,
@@ -1389,14 +1484,14 @@
                 Groups) = fill_mcast_pipeline_L3toL2(
                 self.controller,
                 logging,
-                ports,
+                pair,
                 is_ingress_tagged   = False,
                 is_egress_tagged    = False,
                 is_vlan_translated  = False,
                 is_max_vlan         = True
                 )
 
-            for in_port in ports:
+            for in_port in pair:
 
                 parsed_pkt = simple_udp_packet(
                     pktlen  = 96,
@@ -1409,7 +1504,7 @@
                 pkt = str( parsed_pkt )
                 self.dataplane.send( in_port, pkt )
 
-                for out_port in ports:
+                for out_port in pair:
 
                     parsed_pkt = simple_udp_packet(
                         pktlen  = 96,
@@ -1444,6 +1539,7 @@
                 assert (False)
                 return
             ports      = config[ "port_map" ].keys( )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             dst_ip_str = "224.0.0.1"
             (
                 port_to_in_vlan,
@@ -1455,14 +1551,14 @@
                 Groups) = fill_mcast_pipeline_L3toL2(
                 self.controller,
                 logging,
-                ports,
+                pair,
                 is_ingress_tagged   = False,
                 is_egress_tagged    = True,
                 is_vlan_translated  = False,
                 is_max_vlan         = False
                 )
 
-            for in_port in ports:
+            for in_port in pair:
 
                 parsed_pkt = simple_udp_packet(
                     pktlen  = 96,
@@ -1475,7 +1571,7 @@
                 pkt = str( parsed_pkt )
                 self.dataplane.send( in_port, pkt )
 
-                for out_port in ports:
+                for out_port in pair:
 
                     parsed_pkt = simple_udp_packet(
                         pktlen          = 100,
@@ -1513,6 +1609,7 @@
                 assert (False)
                 return
             ports      = config[ "port_map" ].keys( )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             dst_ip_str = "224.0.0.1"
             (
                 port_to_in_vlan,
@@ -1524,14 +1621,14 @@
                 Groups) = fill_mcast_pipeline_L3toL2(
                 self.controller,
                 logging,
-                ports,
+                pair,
                 is_ingress_tagged   = True,
                 is_egress_tagged    = False,
                 is_vlan_translated  = False,
                 is_max_vlan         = False
                 )
 
-            for in_port in ports:
+            for in_port in pair:
 
                 parsed_pkt = simple_udp_packet(
                     pktlen         = 100,
@@ -1546,7 +1643,7 @@
                 pkt = str( parsed_pkt )
                 self.dataplane.send( in_port, pkt )
 
-                for out_port in ports:
+                for out_port in pair:
 
                     parsed_pkt = simple_udp_packet(
                         pktlen          = 96,
@@ -1579,7 +1676,8 @@
                 logging.info( "Port count less than 2, can't run this case" )
                 assert (False)
                 return
-            ports      = config[ "port_map" ].keys( )
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             dst_ip_str = "224.0.0.1"
             (
                 port_to_in_vlan,
@@ -1591,14 +1689,14 @@
                 Groups) = fill_mcast_pipeline_L3toL2(
                 self.controller,
                 logging,
-                ports,
+                pair,
                 is_ingress_tagged   = True,
                 is_egress_tagged    = True,
                 is_vlan_translated  = False,
                 is_max_vlan         = False
                 )
 
-            for in_port in ports:
+            for in_port in pair:
 
                 parsed_pkt = simple_udp_packet(
                     pktlen         = 100,
@@ -1613,7 +1711,7 @@
                 pkt = str( parsed_pkt )
                 self.dataplane.send( in_port, pkt )
 
-                for out_port in ports:
+                for out_port in pair:
 
                     parsed_pkt = simple_udp_packet(
                         pktlen         = 100,
@@ -1650,6 +1748,7 @@
                 assert (False)
                 return
             ports      = config[ "port_map" ].keys( )
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             dst_ip_str = "224.0.0.1"
             (
                 port_to_in_vlan,
@@ -1661,14 +1760,14 @@
                 Groups) = fill_mcast_pipeline_L3toL2(
                 self.controller,
                 logging,
-                ports,
+                pair,
                 is_ingress_tagged   = True,
                 is_egress_tagged    = True,
                 is_vlan_translated  = True,
                 is_max_vlan         = False
                 )
 
-            for in_port in ports:
+            for in_port in pair:
 
                 parsed_pkt = simple_udp_packet(
                     pktlen         = 100,
@@ -1683,7 +1782,7 @@
                 pkt = str( parsed_pkt )
                 self.dataplane.send( in_port, pkt )
 
-                for out_port in ports:
+                for out_port in pair:
 
                     parsed_pkt = simple_udp_packet(
                         pktlen         = 100,
@@ -2064,7 +2163,9 @@
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
             ports = config[ "port_map" ].keys( )
-            for port in ports:
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+
+            for port in pair:
                 # add l2 interface group
                 vlan_id = port + test_id
                 l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id,
@@ -2088,10 +2189,10 @@
             do_barrier( self.controller )
 
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
-            for in_port in ports:
+            for in_port in pair:
                 mac_src = '00:00:00:22:22:%02X' % (test_id + in_port)
                 ip_src = '192.168.%02d.1' % (test_id + in_port)
-                for out_port in ports:
+                for out_port in pair:
                     if in_port == out_port:
                         continue
                     ip_dst = '192.168.%02d.1' % (test_id + out_port)
@@ -2126,8 +2227,9 @@
             intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
-            ports = config[ "port_map" ].keys( )
-            for port in ports:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 # add l2 interface group
                 vlan_id = port + test_id
                 # add vlan flow table
@@ -2144,10 +2246,10 @@
             do_barrier( self.controller )
 
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
-            for in_port in ports:
+            for in_port in pair:
                 mac_src = '00:00:00:22:22:%02X' % (test_id + in_port)
                 ip_src = '192.168.%02d.1' % (test_id + in_port)
-                for out_port in ports:
+                for out_port in pair:
                     if in_port == out_port:
                         continue
                     ip_dst = '192.168.%02d.1' % (test_id + out_port)
@@ -2183,8 +2285,9 @@
             intf_src_mac = [ 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc ]
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
-            ports = config[ "port_map" ].keys( )
-            for port in ports:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 # add l2 interface group
                 vlan_id = port
                 l2gid, msg = add_one_l2_interface_group( self.controller, port, vlan_id=vlan_id + 1,
@@ -2204,16 +2307,16 @@
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffffff, l3_msg.group_id, priority=2 )
                 Groups.put( l2gid )
                 Groups.put( l3_msg.group_id )
-            l3_gid = encode_l3_unicast_group_id( ports[ 0 ] )
+            l3_gid = encode_l3_unicast_group_id( pair[ 0 ] )
             dst_ip = 0x0
             add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0x0, l3_gid )
             do_barrier( self.controller )
 
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
-            for in_port in ports:
+            for in_port in pair:
                 mac_src = '00:00:00:22:22:%02X' % (in_port)
                 ip_src = '192.168.%02d.1' % (in_port)
-                for out_port in ports:
+                for out_port in pair:
                     if in_port == out_port:
                         continue
                     ip_dst = '192.168.%02d.1' % (out_port)
@@ -2228,17 +2331,17 @@
                     pkt = str( exp_pkt )
                     verify_packet( self, pkt, out_port )
                     verify_no_other_packets( self )
-                    ip_dst = '1.168.%02d.1' % ports[ 0 ]
+                    ip_dst = '1.168.%02d.1' % pair[ 0 ]
                     parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=in_port,
                             eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src, ip_dst=ip_dst )
                     pkt = str( parsed_pkt )
                     self.dataplane.send( in_port, pkt )
                     # build expect packet
-                    mac_dst = '00:00:00:22:22:%02X' % ports[ 0 ]
+                    mac_dst = '00:00:00:22:22:%02X' % pair[ 0 ]
                     exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ] + 1,
                             ip_ttl=63, ip_src=ip_src, ip_dst=ip_dst, eth_dst=mac_dst, eth_src=switch_mac )
                     pkt = str( exp_pkt )
-                    verify_packet( self, pkt, ports[ 0 ] )
+                    verify_packet( self, pkt, pair[ 0 ] )
                     verify_no_other_packets( self )
         finally:
             delete_all_flows( self.controller )
@@ -2391,12 +2494,13 @@
             dst_mac = [ 0x00, 0x00, 0x00, 0x22, 0x22, 0x00 ]
             dip = 0xc0a80001
             # Hashes Test Name and uses it as id for installing unique groups
-            ports = config[ "port_map" ].keys( )
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             ecmp = [ ]
             dst_ips = []
             # add flows for all ports but include only the egress switchport (connected to ports[1])
             # in the ecmp group
-            for port in ports:
+            for port in pair:
                 vlan_id = port
                 id = port
                 # add l2 interface group
@@ -2405,11 +2509,11 @@
                 dst_mac[ 5 ] = vlan_id
                 l3_msg = add_l3_unicast_group( self.controller, port, vlanid=vlan_id, id=id,
                         src_mac=intf_src_mac, dst_mac=dst_mac )
-                if port == ports[1]:
+                if port == pair[1]:
                     ecmp += [ l3_msg.group_id ]
                 Groups._put( l2_gid )
                 Groups._put( l3_msg.group_id )
-                ecmp_msg = add_l3_ecmp_group( self.controller, ports[ 0 ], [ l3_msg.group_id ] )
+                ecmp_msg = add_l3_ecmp_group( self.controller, pair[ 0 ], [ l3_msg.group_id ] )
                 # add vlan flow table
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 # add termination flow
@@ -2421,7 +2525,7 @@
                 dst_ip = dip + (vlan_id << 8)
                 dst_ips += [dst_ip]
                 Groups._put( ecmp_msg.group_id )
-            mod_l3_ecmp_group( self.controller, ports[ 0 ], ecmp )
+            mod_l3_ecmp_group( self.controller, pair[ 0 ], ecmp )
             for dst_ip in dst_ips:
                 add_unicast_routing_flow( self.controller, 0x0800, dst_ip, 0xffffff00, ecmp_msg.group_id )
             do_barrier(self.controller)
@@ -2429,14 +2533,14 @@
             # first part of the test: send packet from ingress switchport and expect it at egress switchport
             switch_mac = ':'.join( [ '%02X' % x for x in intf_src_mac ] )
             parsed_pkt = exp_pkt = 0
-            in_port = ports[0]
-            out_port = ports[1]
+            in_port = pair[0]
+            out_port = pair[1]
             logging.info("\nSending packet to port: " + str(in_port) + ", expected egress on port: " + str(out_port))
-            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
-            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
-            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            mac_src = '00:00:00:22:22:%02X' % pair[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (pair[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (pair[ 1 ], 1)
             tcp = out_port if out_port == 24 else 25
-            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=pair[ 0 ],
                                             eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
                                             ip_dst=ip_dst, tcp_dport=tcp )
             pkt = str( parsed_pkt )
@@ -2453,63 +2557,63 @@
             # second part of the test - edit the ecmp group to remove the orginal egress switchport
             # and instead add the ingress switchport. Send packet from ingress switchport, and expect
             # it back on the ingress switchport
-            l3_gid = encode_l3_unicast_group_id( ports[ 0 ] )
-            mod_l3_ecmp_group( self.controller, ports[ 0 ], [ l3_gid ] )
+            l3_gid = encode_l3_unicast_group_id( pair[ 0 ] )
+            mod_l3_ecmp_group( self.controller, pair[ 0 ], [ l3_gid ] )
             time.sleep(0.1)
-            logging.info("Sending packet to port: " + str(ports[0]) + ", expected egress on port: " + str(ports[0]))
-            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
-            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
-            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            logging.info("Sending packet to port: " + str(pair[0]) + ", expected egress on port: " + str(pair[0]))
+            mac_src = '00:00:00:22:22:%02X' % pair[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (pair[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (pair[ 1 ], 1)
             tcp = port if port == 24 else 25
-            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=pair[ 0 ],
                                             eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
                                             ip_dst=ip_dst,tcp_dport=tcp )
             pkt = str( parsed_pkt )
-            self.dataplane.send( ports[ 0 ], pkt )
+            self.dataplane.send( pair[ 0 ], pkt )
             # build expected packet
-            mac_dst = '00:00:00:22:22:%02X' % ports[ 0 ]
-            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+            mac_dst = '00:00:00:22:22:%02X' % pair[ 0 ]
+            exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=pair[ 0 ],
                                          eth_dst=mac_dst, eth_src=switch_mac, ip_ttl=63, ip_src=ip_src,
                                          ip_dst=ip_dst,tcp_dport=tcp )
             # Expects packet on the input port
             if config["switch_type"] != 'xpliant':
                 pkt = str( exp_pkt )
-                verify_packet( self, pkt, ports[ 0 ] )
+                verify_packet( self, pkt, pair[ 0 ] )
                 verify_no_other_packets( self )
 
             # third part of the test - edit the group to completely remove bucket. Packet sent
             # should be dropped by the switch
-            mod_l3_ecmp_group( self.controller, ports[ 0 ], [ ] )
+            mod_l3_ecmp_group( self.controller, pair[ 0 ], [ ] )
             time.sleep(0.1)
-            logging.info("Sending packet to port: " + str(ports[0]) + ", expected drop")
-            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
-            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
-            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            logging.info("Sending packet to port: " + str(pair[0]) + ", expected drop")
+            mac_src = '00:00:00:22:22:%02X' % pair[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (pair[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (pair[ 1 ], 1)
             tcp = port if port == 24 else 25
-            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=pair[ 0 ],
                                             eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
                                             ip_dst=ip_dst,tcp_dport=tcp )
             pkt = str( parsed_pkt )
-            self.dataplane.send( ports[ 0 ], pkt )
+            self.dataplane.send( pair[ 0 ], pkt )
             verify_no_other_packets( self )
 
             # final part of the test - edit the empty group to add back the bucket for the
             # original egress port, and verify packet is received on egress switch port
-            l3_gid = encode_l3_unicast_group_id( ports[ 1 ] )
-            mod_l3_ecmp_group( self.controller, ports[ 0 ], [ l3_gid ] )
+            l3_gid = encode_l3_unicast_group_id( pair[ 1 ] )
+            mod_l3_ecmp_group( self.controller, pair[ 0 ], [ l3_gid ] )
             do_barrier(self.controller)
-            in_port = ports[0]
-            out_port = ports[1]
+            in_port = pair[0]
+            out_port = pair[1]
             logging.info("Sending packet to port: " + str(in_port) + ", expected egress on port: " + str(out_port))
-            mac_src = '00:00:00:22:22:%02X' % ports[ 0 ]
-            ip_src = '192.168.%02d.%02d' % (ports[ 0 ], 1)
-            ip_dst = '192.168.%02d.%02d' % (ports[ 1 ], 1)
+            mac_src = '00:00:00:22:22:%02X' % pair[ 0 ]
+            ip_src = '192.168.%02d.%02d' % (pair[ 0 ], 1)
+            ip_dst = '192.168.%02d.%02d' % (pair[ 1 ], 1)
             tcp = out_port if out_port == 24 else 25
-            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=ports[ 0 ],
+            parsed_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=pair[ 0 ],
                                             eth_dst=switch_mac, eth_src=mac_src, ip_ttl=64, ip_src=ip_src,
                                             ip_dst=ip_dst, tcp_dport=tcp )
             pkt = str( parsed_pkt )
-            self.dataplane.send( ports[ 0 ], pkt )
+            self.dataplane.send( pair[ 0 ], pkt )
             # build expected packet at egress switchport
             mac_dst = '00:00:00:22:22:%02X' % out_port
             exp_pkt = simple_tcp_packet( pktlen=100, dl_vlan_enable=True, vlan_vid=out_port,
@@ -2548,12 +2652,13 @@
                 logging.info( "Port count less than 2, can't run this case" )
                 return
 
-            ports = sorted( config[ "port_map" ].keys( ) )
-            for port in ports:
+            ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 vlan_id = Untagged.MAX_INTERNAL_VLAN - port
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG )
                 add_one_vlan_table_flow( self.controller, port, 1, vlan_id, flag=VLAN_TABLE_FLAG_ONLY_UNTAG )
-                for other_port in ports:
+                for other_port in pair:
                     if other_port == port:
                         continue
                     L2gid, l2msg = add_one_l2_interface_group( self.controller, other_port, vlan_id, False, False )
@@ -2562,15 +2667,15 @@
 
             do_barrier( self.controller )
 
-            for out_port in ports:
+            for out_port in pair:
                 # change dest based on port number
                 mac_dst = '00:12:34:56:78:%02X' % out_port
-                for in_port in ports:
+                for in_port in pair:
                     if in_port == out_port:
                         continue
                     pkt = str( simple_tcp_packet( eth_dst=mac_dst ) )
                     self.dataplane.send( in_port, pkt )
-                    for ofport in ports:
+                    for ofport in pair:
                         if ofport in [ out_port ]:
                             verify_packet( self, pkt, ofport )
                         else:
@@ -3940,7 +4045,8 @@
             logging.info("Add a flow to TABLE-10 to match VLAN ID '100' for packets received at Data Port 1 and action transition to TABLE-20.")
 
             ports = sorted(config["port_map"].keys())
-            for port in ports:
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
 
             add_acl_rule(self.controller, eth_type=eth_type_eapol)
@@ -3986,7 +4092,7 @@
 
             logging.info("Step 7")
             logging.info("Add flows again ID=10 and ID=60")
-            for port in ports:
+            for port in pair:
                 add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
 
             add_acl_rule(self.controller, eth_type=eth_type_eapol)
@@ -4026,7 +4132,8 @@
             logging.info("Add a flow to TABLE-10 to match VLAN ID '100' for packets received at Data Port 1 and action transition to TABLE-20.")
 
             ports = sorted(config["port_map"].keys())
-            for port in ports:
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
+            for port in pair:
                 add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
 
             add_acl_rule(self.controller, eth_type=eth_type_arp)
@@ -4072,7 +4179,7 @@
 
             logging.info("Step 7")
             logging.info("Add flows again ID=10 and ID=60")
-            for port in ports:
+            for port in pair:
                 add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id100, flag=VLAN_TABLE_FLAG_ONLY_TAG)
 
             add_acl_rule(self.controller, eth_type=eth_type_arp)
@@ -4273,15 +4380,16 @@
         groups = Queue.LifoQueue()
         try:
             ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_id = 100
             vlan_id101 = 101
 
-            for port in ports:
+            for port in pair:
                 L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id, True, False)
                 add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG)
                 groups.put(L2gid)
 
-            msg = add_l2_flood_group(self.controller, ports, vlan_id, vlan_id)
+            msg = add_l2_flood_group(self.controller, pair, vlan_id, vlan_id)
             groups.put(msg.group_id)
             add_bridge_flow(self.controller, None, vlan_id, msg.group_id, True)
 
@@ -4296,7 +4404,7 @@
 
             # verify flood
             logging.info("Creating a double tagged vlan packet with outer vlan id {}".format(vlan_id))
-            for ofport in ports:
+            for ofport in pair:
                 # change dest based on port number
                 mac_src = '00:12:34:56:78:%02X' % ofport
                 parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
@@ -4308,7 +4416,7 @@
                 # self won't rx packet
                 verify_no_packet(self, pkt, ofport)
                 # others will rx packet
-                tmp_ports = list(ports)
+                tmp_ports = list(pair)
                 tmp_ports.remove(ofport)
                 verify_packets(self, pkt, tmp_ports)
 
@@ -4350,6 +4458,10 @@
     def runTest(self):
         groups = Queue.LifoQueue()
         try:
+            if len( config[ "port_map" ] ) < 4:
+                logging.info( "Port count less than 4, can't run this case" )
+                assert (False)
+                return
             ports = sorted(config["port_map"].keys())
             vlan_id100 = 100
             vlan_id101 = 101
@@ -4597,6 +4709,7 @@
         groups = Queue.LifoQueue()
         try:
             ports = sorted(config["port_map"].keys())
+            pair = [ports[(1 - 1)], ports[(2 - 1)]]
             vlan_id = 100
             vlan_len = 4
             num_pkts = 5
@@ -4607,12 +4720,12 @@
             tx_bytes_expected = rx_bytes_expected
             tx_dropped_expected = 0
 
-            for port in ports:
+            for port in pair:
                 L2gid, l2msg = add_one_l2_interface_group(self.controller, port, vlan_id, True, False)
                 add_one_vlan_table_flow(self.controller, port, vlan_id=vlan_id, flag=VLAN_TABLE_FLAG_ONLY_TAG)
                 groups.put(L2gid)
 
-            msg = add_l2_flood_group(self.controller, ports, vlan_id, vlan_id)
+            msg = add_l2_flood_group(self.controller, pair, vlan_id, vlan_id)
             groups.put(msg.group_id)
             add_bridge_flow(self.controller, None, vlan_id, msg.group_id, True)
 
@@ -4628,6 +4741,7 @@
             initial_stats_rx = get_port_stats(self, ports[0])
             initial_stats_tx = get_port_stats(self, ports[1])
 
+            time.sleep(2)
             logging.info("Get required counter values from port".format(ports[0]))
             rx_bytes_before = get_required_statistic_from_port(self, ports[0], "rx_bytes")
             rx_pkts_before = get_required_statistic_from_port(self, ports[0], "rx_packets")