Added iterate-test-case test

The list of tests in the array iter_classes are iterated over.
The number of iterations is 10 by default and can be overridden
by the iter_count test parameter.
diff --git a/tests/pktact.py b/tests/pktact.py
index 9230afd..57a5a20 100644
--- a/tests/pktact.py
+++ b/tests/pktact.py
@@ -28,6 +28,7 @@
 import oftest.action as action
 import oftest.parse as parse
 import basic
+import time
 
 from testutils import *
 
@@ -79,8 +80,6 @@
     @param config The configuration dictionary; see oft
     """
 
-    basic.test_set_init(config)
-
     global pa_port_map
     global pa_logger
     global pa_config
@@ -1052,6 +1051,57 @@
         flow_match_test(self, pa_port_map, pkt=pkt, exp_pkt=exp_pkt, 
                         action_list=acts, max_test=2, egr_count=-1)
 
+# You can pick and choose these by commenting tests in or out
+iter_classes = [
+    basic.PacketIn,
+    basic.PacketOut,
+    DirectPacket,
+    DirectTwoPorts,
+    DirectMC,
+    AllWildcardMatch,
+    AllWildcardMatchTagged,
+    SingleWildcardMatch,
+    SingleWildcardMatchTagged,
+    ExactMatch,
+    ExactMatchTagged,
+    SingleWildcardMatch,
+    ModifyL2Src,
+    ModifyL2Dst,
+    ModifyL2SrcMC,
+    ModifyL2DstMC,
+    ModifyL2SrcDstMC
+    ]
+
+class IterCases(BaseMatchCase):
+    def runTest(self):
+        count = test_param_get(self.config, 'iter_count', default=10)
+        tests_done = 0
+        pa_logger.info("Running iteration test " + str(count) + " times")
+        start = time.time()
+        last = start
+        for idx in range(count):
+            pa_logger.info("Iteration " + str(idx + 1))
+            for cls in iter_classes:
+                test = cls()
+                test.inheritSetup(self)
+                test.runTest()
+                tests_done += 1
+                if time.time() - last > 60:
+                    last = time.time()
+                    print("IterCases: Ran %d tests in %d " %
+                          (tests_done, last - start) + 
+                          "seconds so far")
+        stats = all_stats_get(self)
+        last = time.time()
+        pa_logger.info("\nIterCases ran %d tests in %d seconds." %
+                       (tests_done, last - start))
+        pa_logger.info("    flows: %d. packets: %d. bytes: %d" %
+                       (stats["flows"], stats["packets"], stats["bytes"]))
+        pa_logger.info("    active: %d. lookups: %d. matched %d." %
+                       (stats["active"], stats["lookups"], stats["matched"]))
+
+# Don't run by default
+test_prio["IterCases"] = -1
 
 #@todo Need to implement tagged versions of the above tests
 #
diff --git a/tests/testutils.py b/tests/testutils.py
index 5a99a00..221fc67 100644
--- a/tests/testutils.py
+++ b/tests/testutils.py
@@ -455,7 +455,7 @@
 
     return request
 
-def flow_msg_install(parent, request, clear_table=True):
+def flow_msg_install(parent, request):
     """
     Install a flow mod message in the switch
 
@@ -463,6 +463,8 @@
     @param request The request, all set to go
     @param clear_table If true, clear the flow table before installing
     """
+
+    clear_table = test_param_get(parent.config, 'clear_table', default=True)
     if clear_table:
         parent.logger.debug("Clear flow table")
         rc = delete_all_flows(parent.controller, parent.logger)
@@ -777,3 +779,38 @@
     else:
         sys.stderr.write("(S)")
 
+
+def all_stats_get(parent):
+    """
+    Get the aggregate stats for all flows in the table
+    @param parent Test instance with controller connection and assert
+    @returns dict with keys flows, packets, bytes, active (flows), 
+    lookups, matched
+    """
+    stat_req = message.aggregate_stats_request()
+    stat_req.match = ofp.ofp_match()
+    stat_req.match.wildcards = ofp.OFPFW_ALL
+    stat_req.table_id = 0xff
+    stat_req.out_port = ofp.OFPP_NONE
+
+    rv = {}
+
+    (reply, pkt) = parent.controller.transact(stat_req, timeout=2)
+    parent.assertTrue(len(reply.stats) == 1, "Did not receive flow stats reply")
+
+    for obj in reply.stats:
+        (rv["flows"], rv["packets"], rv["bytes"]) = (obj.flow_count, 
+                                                  obj.packet_count, obj.byte_count)
+        break
+
+    request = message.table_stats_request()
+    (reply , pkt) = parent.controller.transact(request, timeout=2)
+
+    
+    (rv["active"], rv["lookups"], rv["matched"]) = (0,0,0)
+    for obj in reply.stats:
+        rv["active"] += obj.active_count
+        rv["lookups"] += obj.lookup_count
+        rv["matched"] += obj.matched_count
+
+    return rv