refactor verify_portstats and move to testutils
diff --git a/src/python/oftest/testutils.py b/src/python/oftest/testutils.py
index 0edcfb2..58d2ffb 100644
--- a/src/python/oftest/testutils.py
+++ b/src/python/oftest/testutils.py
@@ -1163,6 +1163,13 @@
                                           out_port=out_port)
     return get_stats(test, req)
 
+def get_port_stats(test, port_no):
+    """
+    Retrieve a list of port stats entries.
+    """
+    req = of10.message.port_stats_request(port_no=port_no)
+    return get_stats(test, req)
+
 def verify_flow_stats(test, match, table_id=0xff,
                       out_port=of10.cstruct.OFPP_NONE,
                       initial=[],
@@ -1201,5 +1208,53 @@
     if bytes != None:
         test.assertEquals(byte_diff, bytes, "Flow byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))
 
+def verify_port_stats(test, port,
+                      initial=[],
+                      tx_pkts=None, rx_pkts=None,
+                      tx_bytes=None, rx_bytes=None):
+    """
+    Verify that port stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_port_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+    def accumulate(stats):
+        tx_pkts_acc = rx_pkts_acc = tx_bytes_acc = rx_bytes_acc = 0
+        for stat in stats:
+            tx_pkts_acc += stat.tx_packets
+            rx_pkts_acc += stat.rx_packets
+            tx_bytes_acc += stat.tx_bytes
+            rx_bytes_acc += stat.rx_bytes
+        return (tx_pkts_acc, rx_pkts_acc, tx_bytes_acc, rx_bytes_acc)
+
+    tx_pkts_before, rx_pkts_before, \
+        tx_bytes_before, rx_bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    for i in range(0, 100):
+        stats = get_port_stats(test, port)
+        tx_pkts_after, rx_pkts_after, \
+            tx_bytes_after, rx_bytes_after = accumulate(stats)
+        tx_pkts_diff = tx_pkts_after - tx_pkts_before
+        rx_pkts_diff = rx_pkts_after - rx_pkts_before
+        tx_bytes_diff = tx_bytes_after - tx_bytes_before
+        rx_bytes_diff = rx_bytes_after - rx_bytes_before
+        if (tx_pkts == None or tx_pkts == tx_pkts_diff) and \
+           (rx_pkts == None or rx_pkts == rx_pkts_diff) and \
+           (tx_bytes == None or tx_bytes == tx_bytes_diff) and \
+           (rx_bytes == None or rx_bytes == rx_bytes_diff):
+            break
+        time.sleep(0.1)
+
+    if (tx_pkts != None):
+        test.assertEqual(tx_pkts,tx_pkts_diff,"Port TX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_pkts, tx_pkts_diff))
+    if (rx_pkts != None):
+        test.assertEqual(rx_pkts,rx_pkts_diff,"Port RX packet counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_pkts, rx_pkts_diff))
+    if (tx_bytes != None):
+        test.assertEqual(tx_bytes,tx_bytes_diff,"Port TX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (tx_bytes, tx_bytes_diff))
+    if (rx_bytes != None):
+        test.assertEqual(rx_bytes,rx_bytes_diff,"Port RX byte counter is not updated correctly (expected increase of %d, got increase of %d)" % (rx_bytes, rx_bytes_diff))
+
 
 __all__ = list(set(locals()) - _import_blacklist)
diff --git a/tests/FuncUtils.py b/tests/FuncUtils.py
index aa35221..0c55de6 100644
--- a/tests/FuncUtils.py
+++ b/tests/FuncUtils.py
@@ -512,56 +512,6 @@
         self.assertEqual(expect_active, active ,"active counter is not incremented properly")
 
 
-def verify_portstats(self, port,tx_packets=None,rx_packets=None,rx_byte=None,tx_byte=None):
-
-    
-    stat_req = message.port_stats_request()
-    stat_req.port_no = port
-    
-    for i in range(0,100):
-        logging.info("Sending stats request")
-        response, pkt = self.controller.transact(stat_req,
-                                                timeout=5)
-        self.assertTrue(response is not None, 
-                       "No response to stats request")
-        self.assertTrue(len(response.stats) == 1,
-                       "Did not receive port stats reply")
-
-        sentp = recvp = 0
-        sentb = recvb = 0
-        
-        for item in response.stats:
-            sentp += item.tx_packets
-            recvp += item.rx_packets
-            recvb += item.rx_bytes
-            sentb += item.tx_bytes
-           
-            
-            logging.info("Sent " + str(sentp) + " packets")
-            logging.info("Received " + str(recvp) + " packets")
-            logging.info("Received " + str(recvb) + "bytes")
-            logging.info("Sent" + str(sentb) + "bytes")
-
-        if (tx_packets == None or tx_packets == sentp) and \
-           (rx_packets == None or rx_packets == recvp) and \
-           (tx_byte == None or tx_byte == sentb) and \
-           (rx_byte == None or rx_byte == recvb):
-            break
-
-        sleep(0.1)
-        
-        
-
-    if (tx_packets != None):
-        self.assertEqual(tx_packets,item.tx_packets,"rx_packets counter is not incremented correctly")
-    if (rx_packets != None):
-        self.assertEqual(rx_packets,item.rx_packets,"tx_packets counter is not incremented correctly")
-    if (rx_byte != None):
-        self.assertEqual(rx_byte,item.rx_bytes,"rx_bytes counter is not incremented correctly")
-    if (tx_byte != None):
-        self.assertEqual(tx_byte,item.tx_bytes,"tx_bytes counter is not incremented correctly")
-
-
 def verify_queuestats(self,port_num,queue_id,expect_packet=None,expect_byte=None):
     
     # Verify queue counters : tx_packets and tx_bytes
diff --git a/tests/counters.py b/tests/counters.py
index d23cf75..c30ba51 100644
--- a/tests/counters.py
+++ b/tests/counters.py
@@ -164,17 +164,15 @@
         (pkt, match ) = wildcard_all_except_ingress(self,of_ports)
 
         # Send Port_Stats request for the ingress port (retrieve old counter state)
-        (counter) = get_portstats(self,of_ports[0])
+        initial_stats = get_port_stats(self, of_ports[0])
 
         # Send packets matching the flow
         num_pkts = 5 
         for pkt_cnt in range(num_pkts):
             self.dataplane.send(of_ports[0],str(pkt))
 
-        pkts = num_pkts+counter[0]
-
         #Verify recieved packet counters 
-        verify_portstats(self,of_ports[0],rx_packets=pkts)
+        verify_port_stats(self, of_ports[0], initial=initial_stats, rx_pkts=num_pkts)
 
 class TxPktPerPort(base_tests.SimpleDataPlane):
 
@@ -198,18 +196,17 @@
         #Insert a flow with match on all ingress port
         (pkt,match) = wildcard_all_except_ingress(self,of_ports)
         
-        # Send Port_Stats request for the ingress port (retrieve old counter state)
-        (counter) = get_portstats(self,of_ports[1])
+        # Send Port_Stats request for the egress port (retrieve old counter state)
+        initial_stats = get_port_stats(self, of_ports[1])
         
         #Send packets matching the flow
         num_pkts = 5
         for pkt_cnt in range(num_pkts):
             self.dataplane.send(of_ports[0],str(pkt))
-
-        pkts = num_pkts+counter[1]
         
         #Verify transmitted_packet counters 
-        verify_portstats(self,of_ports[1],tx_packets=pkts)
+        verify_port_stats(self, of_ports[1], initial=initial_stats,
+                          tx_pkts=num_pkts)
 
 
 
@@ -236,7 +233,7 @@
         (pkt, match ) = wildcard_all_except_ingress(self,of_ports)
 
         # Send Port_Stats request for the ingress port (retrieve current counter state)
-        (counter) = get_portstats(self,of_ports[0])
+        initial_stats = get_port_stats(self, of_ports[0])
            
         #Send packets matching the flow.
         num_pkts = 5
@@ -244,10 +241,9 @@
         for pkt_cnt in range(num_pkts):
             self.dataplane.send(of_ports[0],str(pkt))
 
-        byt_count = byte_count+counter[2]
-
         #Verify recieved_bytes counters 
-        verify_portstats(self,of_ports[0],rx_byte=byt_count)
+        verify_port_stats(self, of_ports[0], initial=initial_stats,
+                          rx_bytes=byte_count)
 
 
 class TxBytPerPort(base_tests.SimpleDataPlane):
@@ -272,19 +268,18 @@
         #Insert a flow with match on all ingress port
         (pkt, match ) = wildcard_all_except_ingress(self,of_ports)
 
-        # Send Port_Stats request for the ingress port (retrieve current counter state)
-        (counter) = get_portstats(self,of_ports[1])
+        # Send Port_Stats request for the egress port (retrieve current counter state)
+        initial_stats = get_port_stats(self, of_ports[1])
         
         #Send packets matching the flow.
         num_pkts = 5
         byte_count = num_pkts*len(str(pkt))
         for pkt_cnt in range(num_pkts):
             self.dataplane.send(of_ports[0],str(pkt))
-
-        byt_count = byte_count+counter[3]
         
         #Verify trasmitted_bytes counters 
-        verify_portstats(self,of_ports[1],tx_byte=byt_count)
+        verify_port_stats(self, of_ports[1], initial=initial_stats,
+                          tx_bytes=byte_count)
 
 class ActiveCount(base_tests.SimpleDataPlane):