refactor verify_queuestats and move to testutils
diff --git a/src/python/oftest/testutils.py b/src/python/oftest/testutils.py
index 58d2ffb..638cd52 100644
--- a/src/python/oftest/testutils.py
+++ b/src/python/oftest/testutils.py
@@ -1170,6 +1170,13 @@
     req = of10.message.port_stats_request(port_no=port_no)
     return get_stats(test, req)
 
+def get_queue_stats(test, port_no, queue_id):
+    """
+    Retrieve a list of queue stats entries.
+    """
+    req = of10.message.queue_stats_request(port_no=port_no, queue_id=queue_id)
+    return get_stats(test, req)
+
 def verify_flow_stats(test, match, table_id=0xff,
                       out_port=of10.cstruct.OFPP_NONE,
                       initial=[],
@@ -1256,5 +1263,41 @@
     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))
 
+def verify_queue_stats(test, port_no, queue_id,
+                       initial=[],
+                       pkts=None, bytes=None):
+    """
+    Verify that queue stats changed as expected.
+
+    Optionally takes an 'initial' list of stats entries, as returned by
+    get_queue_stats(). If 'initial' is not given the counters are assumed to
+    begin at 0.
+    """
+    def accumulate(stats):
+        pkts_acc = bytes_acc = 0
+        for stat in stats:
+            pkts_acc += stat.tx_packets
+            bytes_acc += stat.tx_bytes
+        return (pkts_acc, bytes_acc)
+
+    pkts_before, bytes_before = accumulate(initial)
+
+    # Wait 10s for counters to update
+    pkt_diff = byte_diff = None
+    for i in range(0, 100):
+        stats = get_queue_stats(test, port_no, queue_id)
+        pkts_after, bytes_after = accumulate(stats)
+        pkt_diff = pkts_after - pkts_before
+        byte_diff = bytes_after - bytes_before
+        if (pkts == None or pkt_diff >= pkts) and \
+           (bytes == None or byte_diff >= bytes):
+            break
+        sleep(0.1)
+
+    if pkts != None:
+        test.assertEquals(pkt_diff, pkts, "Queue packet counter not updated properly (expected increase of %d, got increase of %d)" % (pkts, pkt_diff))
+
+    if bytes != None:
+        test.assertEquals(byte_diff, bytes, "Queue byte counter not updated properly (expected increase of %d, got increase of %d)" % (bytes, byte_diff))
 
 __all__ = list(set(locals()) - _import_blacklist)
diff --git a/tests/FuncUtils.py b/tests/FuncUtils.py
index 0c55de6..cbbf87e 100644
--- a/tests/FuncUtils.py
+++ b/tests/FuncUtils.py
@@ -512,43 +512,6 @@
         self.assertEqual(expect_active, active ,"active counter is not incremented properly")
 
 
-def verify_queuestats(self,port_num,queue_id,expect_packet=None,expect_byte=None):
-    
-    # Verify queue counters : tx_packets and tx_bytes
-
-    request = message.queue_stats_request()
-    request.port_no  = port_num
-    request.queue_id = queue_id
-    
-    for i in range(0,100):
-
-        logging.info("Sending stats request")
-     
-        (queue_stats, p) = self.controller.transact(request)
-        self.assertNotEqual(queue_stats, None, "Queue stats request failed")
-        packet_counter = 0
-        byte_counter = 0 
-        
-        for item in queue_stats.stats:
-            packet_counter += item.tx_packets
-            byte_counter += item.tx_bytes
-
-            logging.info("Transmitted" + str(packet_counter) + " packets")
-            logging.info("Transmitted" + str(byte_counter) + "bytes")
-           
-        if (expect_packet == None or packet_counter == expect_packet) and \
-           (expect_byte == None or byte_counter == expect_byte):
-            break
-
-        sleep(0.1)
-    
-    if expect_packet != None :
-        self.assertEqual(packet_counter,expect_packet,"tx_packets counter is not incremented correctly")
-
-    if expect_byte != None :   
-        self.assertEqual(byte_counter,expect_byte,"tx_bytes counter is not incremented correctly")
-
-
 ############################## Various delete commands #############################################################################################
 
 def strict_delete(self,match,priority=None):
diff --git a/tests/counters.py b/tests/counters.py
index c30ba51..be6c979 100644
--- a/tests/counters.py
+++ b/tests/counters.py
@@ -374,7 +374,7 @@
                 delete_all_flows(self.controller)
 
                 # Get Queue stats for selected egress queue only
-                (qs_before,p) = get_queuestats(self,egress_port,egress_queue_id)
+                initial_stats = get_queue_stats(self, egress_port, egress_queue_id)
 
                 #Insert a flow with enqueue action to queues configured on egress_port
                 (pkt,match) = enqueue(self,ingress_port,egress_port,egress_queue_id)
@@ -382,9 +382,8 @@
                 #Send packet on the ingress_port and verify its received on egress_port
                 send_packet(self,pkt,ingress_port,egress_port)
                 
-                expected_packets = qs_before.stats[0].tx_packets+1
-
-                verify_queuestats(self,egress_port,egress_queue_id,expect_packet=expected_packets)
+                verify_queue_stats(self, egress_port, egress_queue_id,
+                                   initial=initial_stats, pkts=1)
        
 
 class TxBytPerQueue(base_tests.SimpleDataPlane):
@@ -413,7 +412,7 @@
                 delete_all_flows(self.controller)
 
                 # Get Queue stats for selected egress queue only
-                (qs_before,p) = get_queuestats(self,egress_port,egress_queue_id)
+                initial_stats = get_queue_stats(self, egress_port, egress_queue_id)
 
                 #Insert a flow with enqueue action to queues configured on egress_port
                 (pkt,match) = enqueue(self,ingress_port,egress_port,egress_queue_id)
@@ -421,9 +420,9 @@
                 #Send packet on the ingress_port and verify its received on egress_port
                 send_packet(self,pkt,ingress_port,egress_port)
                 
-                expected_bytes = qs_before.stats[0].tx_bytes+len(str(pkt))
-
-                verify_queuestats(self,egress_port,egress_queue_id,expect_byte=expected_bytes)
+                verify_queue_stats(self, egress_port, egress_queue_id,
+                                   initial=initial_stats,
+                                   bytes=len(str(pkt)))
        
        
 class RxDrops(base_tests.SimpleDataPlane):