move base test classes to oftest.base_tests

This lets them be shared between separate directories of tests.
diff --git a/src/python/oftest/base_tests.py b/src/python/oftest/base_tests.py
new file mode 100644
index 0000000..3664d9f
--- /dev/null
+++ b/src/python/oftest/base_tests.py
@@ -0,0 +1,142 @@
+"""
+Base classes for test cases
+
+Tests will usually inherit from one of these classes to have the controller
+and/or dataplane automatically set up.
+"""
+
+import logging
+import unittest
+
+from oftest import config
+import oftest.controller as controller
+import oftest.cstruct as ofp
+import oftest.message as message
+import oftest.dataplane as dataplane
+import oftest.action as action
+
+from oftest.testutils import *
+
+class SimpleProtocol(unittest.TestCase):
+    """
+    Root class for setting up the controller
+    """
+
+    def setUp(self):
+        logging.info("** START TEST CASE " + str(self))
+        self.controller = controller.Controller(
+            host=config["controller_host"],
+            port=config["controller_port"])
+        # clean_shutdown should be set to False to force quit app
+        self.clean_shutdown = True
+        self.controller.start()
+        #@todo Add an option to wait for a pkt transaction to ensure version
+        # compatibilty?
+        self.controller.connect(timeout=20)
+
+        # By default, respond to echo requests
+        self.controller.keep_alive = True
+        
+        if not self.controller.active:
+            raise Exception("Controller startup failed")
+        if self.controller.switch_addr is None: 
+            raise Exception("Controller startup failed (no switch addr)")
+        logging.info("Connected " + str(self.controller.switch_addr))
+        request = message.features_request()
+        reply, pkt = self.controller.transact(request)
+        self.assertTrue(reply is not None,
+                        "Did not complete features_request for handshake")
+        self.supported_actions = reply.actions
+        logging.info("Supported actions: " + hex(self.supported_actions))
+
+    def inheritSetup(self, parent):
+        """
+        Inherit the setup of a parent
+
+        This allows running at test from within another test.  Do the
+        following:
+
+        sub_test = SomeTestClass()  # Create an instance of the test class
+        sub_test.inheritSetup(self) # Inherit setup of parent
+        sub_test.runTest()          # Run the test
+
+        Normally, only the parent's setUp and tearDown are called and
+        the state after the sub_test is run must be taken into account
+        by subsequent operations.
+        """
+        logging.info("** Setup " + str(self) + " inheriting from "
+                          + str(parent))
+        self.controller = parent.controller
+        self.supported_actions = parent.supported_actions
+        
+    def tearDown(self):
+        logging.info("** END TEST CASE " + str(self))
+        self.controller.shutdown()
+        #@todo Review if join should be done on clean_shutdown
+        if self.clean_shutdown:
+            self.controller.join()
+
+    def runTest(self):
+        # Just a simple sanity check as illustration
+        logging.info("Running simple proto test")
+        self.assertTrue(self.controller.switch_socket is not None,
+                        str(self) + 'No connection to switch')
+
+    def assertTrue(self, cond, msg):
+        if not cond:
+            logging.error("** FAILED ASSERTION: " + msg)
+        unittest.TestCase.assertTrue(self, cond, msg)
+
+class SimpleDataPlane(SimpleProtocol):
+    """
+    Root class that sets up the controller and dataplane
+    """
+    def setUp(self):
+        SimpleProtocol.setUp(self)
+        self.dataplane = dataplane.DataPlane(config)
+        for of_port, ifname in config["port_map"].items():
+            self.dataplane.port_add(ifname, of_port)
+
+    def inheritSetup(self, parent):
+        """
+        Inherit the setup of a parent
+
+        See SimpleProtocol.inheritSetup
+        """
+        SimpleProtocol.inheritSetup(self, parent)
+        self.dataplane = parent.dataplane
+
+    def tearDown(self):
+        logging.info("Teardown for simple dataplane test")
+        SimpleProtocol.tearDown(self)
+        if hasattr(self, 'dataplane'):
+            self.dataplane.kill(join_threads=self.clean_shutdown)
+        logging.info("Teardown done")
+
+    def runTest(self):
+        self.assertTrue(self.controller.switch_socket is not None,
+                        str(self) + 'No connection to switch')
+        # self.dataplane.show()
+        # Would like an assert that checks the data plane
+
+class DataPlaneOnly(unittest.TestCase):
+    """
+    Root class that sets up only the dataplane
+    """
+
+    def setUp(self):
+        self.clean_shutdown = True
+        logging.info("** START DataPlaneOnly CASE " + str(self))
+        self.dataplane = dataplane.DataPlane(config)
+        for of_port, ifname in config["port_map"].items():
+            self.dataplane.port_add(ifname, of_port)
+
+    def tearDown(self):
+        logging.info("Teardown for simple dataplane test")
+        self.dataplane.kill(join_threads=self.clean_shutdown)
+        logging.info("Teardown done")
+
+    def runTest(self):
+        logging.info("DataPlaneOnly")
+        # self.dataplane.show()
+        # Would like an assert that checks the data plane
diff --git a/tests/FuncUtils.py b/tests/FuncUtils.py
index d12c388..5cfcb6a 100644
--- a/tests/FuncUtils.py
+++ b/tests/FuncUtils.py
@@ -12,7 +12,7 @@
 import oftest.parse as parse
 import logging
 import types
-import basic
+import oftest.base_tests as base_tests
 from oftest.testutils import *
 from time import sleep
 
diff --git a/tests/actions.py b/tests/actions.py
index 068eaa8..0712302 100644
--- a/tests/actions.py
+++ b/tests/actions.py
@@ -10,6 +10,7 @@
 
 import unittest
 import random
+import time
 
 from oftest import config
 import oftest.controller as controller
@@ -18,14 +19,13 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
-import time
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
 from FuncUtils import *
 
-class NoAction(basic.SimpleDataPlane):
+class NoAction(base_tests.SimpleDataPlane):
 
     """NoActionDrop : no action added to flow , drops the packet."""
 
@@ -76,7 +76,7 @@
                         'Packets not received on control plane')
 
 
-class Announcement(basic.SimpleDataPlane):
+class Announcement(base_tests.SimpleDataPlane):
     
     """Announcement : Get all supported actions by the switch.
     Send OFPT_FEATURES_REQUEST to get features supported by sw."""
@@ -123,7 +123,7 @@
         logging.info(supported_actions)
         
 
-class ForwardAll(basic.SimpleDataPlane):
+class ForwardAll(base_tests.SimpleDataPlane):
     
     """ForwardAll : Packet is sent to all dataplane ports
     except ingress port when output action.port = OFPP_ALL"""
@@ -177,7 +177,7 @@
                       self, config)
 
 
-class ForwardController(basic.SimpleDataPlane):
+class ForwardController(base_tests.SimpleDataPlane):
     
     """ForwardController : Packet is sent to controller 
     output.port = OFPP_CONTROLLER"""
@@ -232,7 +232,7 @@
     
 
 
-class ForwardLocal(basic.SimpleDataPlane):
+class ForwardLocal(base_tests.SimpleDataPlane):
    
     """ForwardLocal : Packet is sent to  OFPP_LOCAL port . 
         TBD : To verify packet recieved in the local networking stack of switch"""
@@ -282,7 +282,7 @@
             #TBD: Verification of packets being recieved.
 
 
-class ForwardFlood(basic.SimpleDataPlane):
+class ForwardFlood(base_tests.SimpleDataPlane):
     
     """Forward:Flood : Packet is sent to all dataplane ports
     except ingress port when output action.port = OFPP_FLOOD 
@@ -336,7 +336,7 @@
         receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
                       self, config)
 
-class ForwardInport(basic.SimpleDataPlane):
+class ForwardInport(base_tests.SimpleDataPlane):
     
     """ ForwardInPort : Packet sent to virtual port IN_PORT
     If the output.port = OFPP.INPORT then the packet is sent to the input port itself"""
@@ -388,7 +388,7 @@
         receive_pkt_check(self.dataplane, pkt, yes_ports,set(of_ports).difference([ingress_port]),
                           self, config)
 
-class ForwardTable(basic.SimpleDataPlane):
+class ForwardTable(base_tests.SimpleDataPlane):
    
     """ForwardTable : Perform actions in flow table. Only for packet-out messages.
         If the output action.port in the packetout message = OFP.TABLE , then 
@@ -429,7 +429,7 @@
         self.assertTrue(pkt is not None, 'Packet not received')
 
 
-class AddVlanTag(basic.SimpleDataPlane):
+class AddVlanTag(base_tests.SimpleDataPlane):
     
     """AddVlanTag : Adds VLAN Tag to untagged packet."""
 
@@ -469,7 +469,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, 
                         exp_pkt=exp_pkt, action_list=[vid_act])
 
-class ModifyVlanTag(basic.SimpleDataPlane):
+class ModifyVlanTag(base_tests.SimpleDataPlane):
 
     """ModifyVlanTag : Modifies VLAN Tag to tagged packet."""
     
@@ -507,7 +507,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt,
                         action_list=[vid_act])
         
-class VlanPrio1(basic.SimpleDataPlane):
+class VlanPrio1(base_tests.SimpleDataPlane):
    
     """AddVlanPrioUntaggedPkt : Add VLAN priority to untagged packet."""
     
@@ -546,7 +546,7 @@
                                 action_list=[act])
 
 
-class VlanPrio2(basic.SimpleDataPlane):
+class VlanPrio2(base_tests.SimpleDataPlane):
     
     """ModifyVlanPrio : Modify VLAN priority to tagged packet."""
     
@@ -586,7 +586,7 @@
                         action_list=[vid_act])
 
 
-class ModifyL2Src(basic.SimpleDataPlane):
+class ModifyL2Src(base_tests.SimpleDataPlane):
     
     """ModifyL2Src :Modify the source MAC address"""
 
@@ -621,7 +621,7 @@
                         action_list=acts, max_test=2)
 
 
-class ModifyL2Dst(basic.SimpleDataPlane):
+class ModifyL2Dst(base_tests.SimpleDataPlane):
     
     """ModifyL2SDSt :Modify the dest MAC address"""
 
@@ -655,7 +655,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt, 
                         action_list=acts, max_test=2)
 
-class ModifyL3Src(basic.SimpleDataPlane):
+class ModifyL3Src(base_tests.SimpleDataPlane):
     
     """ModifyL3Src : Modify the source IP address of an IP packet """
 
@@ -689,7 +689,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt, 
                         action_list=acts, max_test=2)
 
-class ModifyL3Dst(basic.SimpleDataPlane):
+class ModifyL3Dst(base_tests.SimpleDataPlane):
     
     """ModifyL3Dst :Modify the dest IP address of an IP packet"""
     
@@ -724,7 +724,7 @@
                         action_list=acts, max_test=2)
 
 
-class ModifyL4Src(basic.SimpleDataPlane):
+class ModifyL4Src(base_tests.SimpleDataPlane):
     
     """ModifyL4Src : Modify the source TCP port of a TCP packet"""
     
@@ -758,7 +758,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt, 
                         action_list=acts, max_test=2)
 
-class ModifyL4Dst(basic.SimpleDataPlane):
+class ModifyL4Dst(base_tests.SimpleDataPlane):
     
     """ ModifyL4Dst: Modify the dest TCP port of a TCP packet """
 
@@ -792,7 +792,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, exp_pkt=exp_pkt, 
                         action_list=acts, max_test=2)
 
-class ModifyTos(basic.SimpleDataPlane):
+class ModifyTos(base_tests.SimpleDataPlane):
     
     """ModifyTOS :Modify the IP type of service of an IP packet"""
    
diff --git a/tests/basic.py b/tests/basic.py
index db05320..5681ed8 100644
--- a/tests/basic.py
+++ b/tests/basic.py
@@ -25,6 +25,7 @@
 import oftest.message as message
 import oftest.dataplane as dataplane
 import oftest.action as action
+import oftest.base_tests as base_tests
 
 import oftest.illegal_message as illegal_message
 
@@ -32,135 +33,7 @@
 
 TEST_VID_DEFAULT = 2
 
-class SimpleProtocol(unittest.TestCase):
-    """
-    Root class for setting up the controller
-    """
-
-    priority = 1
-
-    def setUp(self):
-        logging.info("** START TEST CASE " + str(self))
-        self.controller = controller.Controller(
-            host=config["controller_host"],
-            port=config["controller_port"])
-        # clean_shutdown should be set to False to force quit app
-        self.clean_shutdown = True
-        self.controller.start()
-        #@todo Add an option to wait for a pkt transaction to ensure version
-        # compatibilty?
-        self.controller.connect(timeout=20)
-
-        # By default, respond to echo requests
-        self.controller.keep_alive = True
-        
-        if not self.controller.active:
-            raise Exception("Controller startup failed")
-        if self.controller.switch_addr is None: 
-            raise Exception("Controller startup failed (no switch addr)")
-        logging.info("Connected " + str(self.controller.switch_addr))
-        request = message.features_request()
-        reply, pkt = self.controller.transact(request)
-        self.assertTrue(reply is not None,
-                        "Did not complete features_request for handshake")
-        self.supported_actions = reply.actions
-        logging.info("Supported actions: " + hex(self.supported_actions))
-
-    def inheritSetup(self, parent):
-        """
-        Inherit the setup of a parent
-
-        This allows running at test from within another test.  Do the
-        following:
-
-        sub_test = SomeTestClass()  # Create an instance of the test class
-        sub_test.inheritSetup(self) # Inherit setup of parent
-        sub_test.runTest()          # Run the test
-
-        Normally, only the parent's setUp and tearDown are called and
-        the state after the sub_test is run must be taken into account
-        by subsequent operations.
-        """
-        logging.info("** Setup " + str(self) + " inheriting from "
-                          + str(parent))
-        self.controller = parent.controller
-        self.supported_actions = parent.supported_actions
-        
-    def tearDown(self):
-        logging.info("** END TEST CASE " + str(self))
-        self.controller.shutdown()
-        #@todo Review if join should be done on clean_shutdown
-        if self.clean_shutdown:
-            self.controller.join()
-
-    def runTest(self):
-        # Just a simple sanity check as illustration
-        logging.info("Running simple proto test")
-        self.assertTrue(self.controller.switch_socket is not None,
-                        str(self) + 'No connection to switch')
-
-    def assertTrue(self, cond, msg):
-        if not cond:
-            logging.error("** FAILED ASSERTION: " + msg)
-        unittest.TestCase.assertTrue(self, cond, msg)
-
-class SimpleDataPlane(SimpleProtocol):
-    """
-    Root class that sets up the controller and dataplane
-    """
-    def setUp(self):
-        SimpleProtocol.setUp(self)
-        self.dataplane = dataplane.DataPlane(config)
-        for of_port, ifname in config["port_map"].items():
-            self.dataplane.port_add(ifname, of_port)
-
-    def inheritSetup(self, parent):
-        """
-        Inherit the setup of a parent
-
-        See SimpleProtocol.inheritSetup
-        """
-        SimpleProtocol.inheritSetup(self, parent)
-        self.dataplane = parent.dataplane
-
-    def tearDown(self):
-        logging.info("Teardown for simple dataplane test")
-        SimpleProtocol.tearDown(self)
-        if hasattr(self, 'dataplane'):
-            self.dataplane.kill(join_threads=self.clean_shutdown)
-        logging.info("Teardown done")
-
-    def runTest(self):
-        self.assertTrue(self.controller.switch_socket is not None,
-                        str(self) + 'No connection to switch')
-        # self.dataplane.show()
-        # Would like an assert that checks the data plane
-
-class DataPlaneOnly(unittest.TestCase):
-    """
-    Root class that sets up only the dataplane
-    """
-
-    priority = -1
-
-    def setUp(self):
-        self.clean_shutdown = True
-        logging.info("** START DataPlaneOnly CASE " + str(self))
-        self.dataplane = dataplane.DataPlane(config)
-        for of_port, ifname in config["port_map"].items():
-            self.dataplane.port_add(ifname, of_port)
-
-    def tearDown(self):
-        logging.info("Teardown for simple dataplane test")
-        self.dataplane.kill(join_threads=self.clean_shutdown)
-        logging.info("Teardown done")
-
-    def runTest(self):
-        logging.info("DataPlaneOnly")
-        # self.dataplane.show()
-        # Would like an assert that checks the data plane
-
-class Echo(SimpleProtocol):
+class Echo(base_tests.SimpleProtocol):
     """
     Test echo response with no data
     """
@@ -175,7 +48,7 @@
                          'response xid != request xid')
         self.assertEqual(len(response.data), 0, 'response data non-empty')
 
-class EchoWithData(SimpleProtocol):
+class EchoWithData(base_tests.SimpleProtocol):
     """
     Test echo response with short string data
     """
@@ -192,7 +65,7 @@
         self.assertEqual(request.data, response.data,
                          'response data does not match request')
 
-class PacketIn(SimpleDataPlane):
+class PacketIn(base_tests.SimpleDataPlane):
     """
     Test packet in function
 
@@ -244,7 +117,7 @@
                                    'Response packet does not match send packet' +
                                    ' for port ' + str(of_port))
 
-class PacketInDefaultDrop(SimpleDataPlane):
+class PacketInDefaultDrop(base_tests.SimpleDataPlane):
     """
     Test packet in function
 
@@ -279,7 +152,7 @@
                             'Packet in message received on port ' + 
                             str(of_port))
 
-class PacketInBroadcastCheck(SimpleDataPlane):
+class PacketInBroadcastCheck(base_tests.SimpleDataPlane):
     """
     Check if bcast pkts leak when no flows are present
 
@@ -309,7 +182,7 @@
         self.assertTrue(pkt_in is None,
                         'BCast packet received on port ' + str(of_port))
 
-class PacketOut(SimpleDataPlane):
+class PacketOut(base_tests.SimpleDataPlane):
     """
     Test packet out function
 
@@ -363,7 +236,7 @@
                self.assertEqual(str(outpkt), str(pkt)[:len(str(outpkt))],
                                 'Response packet does not match send packet')
 
-class PacketOutMC(SimpleDataPlane):
+class PacketOutMC(base_tests.SimpleDataPlane):
     """
     Test packet out to multiple output ports
 
@@ -406,7 +279,7 @@
                                  set(of_ports).difference(dp_ports),
                                  self, config)
 
-class FlowStatsGet(SimpleProtocol):
+class FlowStatsGet(base_tests.SimpleProtocol):
     """
     Get stats 
 
@@ -432,7 +305,7 @@
                         "Did not get response for flow stats")
         logging.debug(response.show())
 
-class TableStatsGet(SimpleProtocol):
+class TableStatsGet(base_tests.SimpleProtocol):
     """
     Get table stats 
 
@@ -452,7 +325,7 @@
                         "Did not get reply for table stats")
         logging.debug(response.show())
 
-class DescStatsGet(SimpleProtocol):
+class DescStatsGet(base_tests.SimpleProtocol):
     """
     Get stats 
 
@@ -468,7 +341,7 @@
                         "Did not get reply for desc stats")
         logging.debug(response.show())
 
-class FlowMod(SimpleProtocol):
+class FlowMod(base_tests.SimpleProtocol):
     """
     Insert a flow
 
@@ -481,7 +354,7 @@
         rv = self.controller.message_send(request)
         self.assertTrue(rv != -1, "Error installing flow mod")
 
-class PortConfigMod(SimpleProtocol):
+class PortConfigMod(base_tests.SimpleProtocol):
     """
     Modify a bit in port config and verify changed
 
@@ -520,7 +393,7 @@
                              ofp.OFPPC_NO_FLOOD)
         self.assertTrue(rv != -1, "Error sending port mod")
 
-class PortConfigModErr(SimpleProtocol):
+class PortConfigModErr(base_tests.SimpleProtocol):
     """
     Modify a bit in port config on an invalid port and verify
     error message is received.
@@ -558,7 +431,7 @@
 
         self.assertTrue(response is not None, 'Did not receive error message')
 
-class BadMessage(SimpleProtocol):
+class BadMessage(base_tests.SimpleProtocol):
     """
     Send a message with a bad type and verify an error is returned
     """
diff --git a/tests/bsn_ipmask.py b/tests/bsn_ipmask.py
index ce785c9..70ca990 100644
--- a/tests/bsn_ipmask.py
+++ b/tests/bsn_ipmask.py
@@ -8,7 +8,7 @@
 import oftest.controller as controller
 import oftest.cstruct as ofp
 import oftest.message as message
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 
@@ -36,7 +36,7 @@
     else:
         return (1 << (63 - index)) - 1
 
-class BSNConfigIPMask(basic.SimpleDataPlane):
+class BSNConfigIPMask(base_tests.SimpleDataPlane):
     """
     Exercise BSN vendor extension for configuring IP source/dest match mask
     """
diff --git a/tests/caps.py b/tests/caps.py
index ae218f0..fe90310 100644
--- a/tests/caps.py
+++ b/tests/caps.py
@@ -14,7 +14,7 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 
@@ -88,7 +88,7 @@
     logging.error("RESULT: " + str(active_flows) + " flows reported")
 
 
-class FillTableExact(basic.SimpleProtocol):
+class FillTableExact(base_tests.SimpleProtocol):
     """
     Fill the flow table with exact matches; can take a while
 
@@ -112,7 +112,7 @@
         logging.info("Running " + str(self))
         flow_caps_common(self)
 
-class FillTableWC(basic.SimpleProtocol):
+class FillTableWC(base_tests.SimpleProtocol):
     """
     Fill the flow table with wildcard matches
 
diff --git a/tests/detailed_contr_sw_messages.py b/tests/detailed_contr_sw_messages.py
index c99b9b7..c969030 100644
--- a/tests/detailed_contr_sw_messages.py
+++ b/tests/detailed_contr_sw_messages.py
@@ -16,13 +16,13 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
 from FuncUtils import *
 
-class OverlapChecking(basic.SimpleDataPlane):
+class OverlapChecking(base_tests.SimpleDataPlane):
     
     """Verify that if overlap check flag is set in the flow entry and an overlapping flow is inserted then an error 
         is generated and switch refuses flow entry"""
@@ -83,7 +83,7 @@
                                'Error Message code is not overlap')
 
 
-class NoOverlapChecking(basic.SimpleDataPlane):
+class NoOverlapChecking(base_tests.SimpleDataPlane):
 
     """Verify that without overlap check flag set, overlapping flows can be created."""  
     
@@ -115,7 +115,7 @@
         Verify_TableStats(self,active_entries=2)
 
 
-class IdenticalFlows(basic.SimpleDataPlane):
+class IdenticalFlows(base_tests.SimpleDataPlane):
     
     """Verify that adding two identical flows overwrites the existing one and clears counters"""
 
@@ -156,7 +156,7 @@
         Verify_FlowStats(self,match,byte_count=0,packet_count=0)
 
    
-class EmerFlowTimeout(basic.SimpleProtocol): 
+class EmerFlowTimeout(base_tests.SimpleProtocol): 
 
     """Timeout values are not allowed for emergency flows"""
 
@@ -208,7 +208,7 @@
                                'Error Message code is not bad emergency timeout')
 
 
-class MissingModifyAdd(basic.SimpleDataPlane):
+class MissingModifyAdd(base_tests.SimpleDataPlane):
 
     """If a modify does not match an existing flow, the flow gets added """
     
@@ -248,7 +248,7 @@
         Verify_TableStats(self,active_entries=1)
 
 
-class ModifyAction(basic.SimpleDataPlane):
+class ModifyAction(base_tests.SimpleDataPlane):
 
     """A modified flow preserves counters"""
     
@@ -286,7 +286,7 @@
         Verify_FlowStats(self,match,byte_count=(2*len(str(pkt))),packet_count=2)
 
 
-class StrictModifyAction(basic.SimpleDataPlane):
+class StrictModifyAction(base_tests.SimpleDataPlane):
 
     """Strict Modify Flow also changes action preserves counters"""
 
@@ -330,7 +330,7 @@
         Verify_FlowStats(self,match,byte_count=(2*len(str(pkt))),packet_count=2)
 
 
-class DeleteNonexistingFlow(basic.SimpleDataPlane):
+class DeleteNonexistingFlow(base_tests.SimpleDataPlane):
     
     """Request deletion of non-existing flow"""
     
@@ -364,7 +364,7 @@
 
 
         
-class SendFlowRem(basic.SimpleDataPlane):
+class SendFlowRem(base_tests.SimpleDataPlane):
     
     """Check deletion of flows happens and generates messages as configured.
     If Send Flow removed message Flag is set in the flow entry, the flow deletion of that respective flow should generate the flow removed message, 
@@ -425,7 +425,7 @@
                         'Did not receive flow removed message for this flow')
 
 
-class DeleteEmerFlow(basic.SimpleProtocol):
+class DeleteEmerFlow(base_tests.SimpleProtocol):
 
     """Delete emergency flow and verify no message is generated.An emergency flow deletion will not generate flow-removed messages even if 
     Send Flow removed message flag was set during the emergency flow entry"""
@@ -468,7 +468,7 @@
                         'Test Failed ')
 
 
-class StrictVsNonstrict(basic.SimpleDataPlane):
+class StrictVsNonstrict(base_tests.SimpleDataPlane):
 
     """Delete and verify strict and non-strict behaviors
     This test compares the behavior of delete strict and non-strict"""
@@ -555,7 +555,7 @@
 
         
    
-class Outport1(basic.SimpleDataPlane):
+class Outport1(base_tests.SimpleDataPlane):
 
     """Delete flows filtered by action outport.If the out_port field in the delete command contains a value other than OFPP_NONE,
     it introduces a constraint when matching. This constraint is that the rule must contain an output action directed at that port."""
@@ -614,7 +614,7 @@
         Verify_TableStats(self,active_entries=0)
 
 
-class IdleTimeout(basic.SimpleDataPlane):
+class IdleTimeout(base_tests.SimpleDataPlane):
 
     """ Verify that idle timeout is implemented"""
 
@@ -658,7 +658,7 @@
                          'Flow was not alive for 1 sec')
 
 
-class Outport2(basic.SimpleDataPlane):
+class Outport2(base_tests.SimpleDataPlane):
 
     """Add, modify flows with outport set. This field is ignored by ADD, MODIFY, and MODIFY STRICT messages."""
 
@@ -698,7 +698,7 @@
 
 
 
-class HardTimeout(basic.SimpleDataPlane):
+class HardTimeout(base_tests.SimpleDataPlane):
 
     """ Verify that hard timeout is implemented """
 
@@ -742,7 +742,7 @@
                          'Flow was not alive for 1 sec')
 
 
-class FlowTimeout(basic.SimpleDataPlane):
+class FlowTimeout(base_tests.SimpleDataPlane):
   
     """Verify that Flow removed messages are generated as expected
     Flow removed messages being generated when flag is set, is already tested in the above tests 
diff --git a/tests/flow_expire.py b/tests/flow_expire.py
index 63c0853..ad35f23 100644
--- a/tests/flow_expire.py
+++ b/tests/flow_expire.py
@@ -16,12 +16,12 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
 
-class FlowExpire(basic.SimpleDataPlane):
+class FlowExpire(base_tests.SimpleDataPlane):
     """
     Verify flow expire messages are properly generated.
 
diff --git a/tests/flow_query.py b/tests/flow_query.py
index b6a0000..7d86172 100644
--- a/tests/flow_query.py
+++ b/tests/flow_query.py
@@ -73,7 +73,7 @@
 import oftest.action_list as action_list
 import oftest.parse       as parse
 import pktact
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
@@ -1567,7 +1567,7 @@
 # 7. Test PASSED iff all flows sent to switch in step 3 above are returned
 #    in step 5 above; else test FAILED
 
-class Flow_Add_5(basic.SimpleProtocol):
+class Flow_Add_5(base_tests.SimpleProtocol):
     """
     Test FLOW_ADD_5 from draft top-half test plan
     
@@ -1668,7 +1668,7 @@
 # Disabled.
 # Should be DUT dependent.
 
-class Flow_Add_5_1(basic.SimpleProtocol):
+class Flow_Add_5_1(base_tests.SimpleProtocol):
     """
     Test FLOW_ADD_5.1 from draft top-half test plan
 
@@ -1786,7 +1786,7 @@
 # Disabled because of bogus capacity reported by OVS.
 # Should be DUT dependent.
 
-class Flow_Add_6(basic.SimpleProtocol):
+class Flow_Add_6(base_tests.SimpleProtocol):
     """
     Test FLOW_ADD_6 from draft top-half test plan
     
@@ -1920,7 +1920,7 @@
 # 6. Test PASSED iff 1 flow returned by switch, matching configuration of F2;
 #    else test FAILED
 
-class Flow_Add_7(basic.SimpleProtocol):
+class Flow_Add_7(base_tests.SimpleProtocol):
     """
     Test FLOW_ADD_7 from draft top-half test plan
     
@@ -2042,7 +2042,7 @@
 #    - overlapping flow is not in flow table
 #    else test FAILED
 
-class Flow_Add_8(basic.SimpleProtocol):
+class Flow_Add_8(base_tests.SimpleProtocol):
     """
     Test FLOW_ADD_8 from draft top-half test plan
     
@@ -2169,7 +2169,7 @@
 # 6. Verify flow table in switch
 # 7. Test PASSED iff flow returned by switch is F'; else FAILED
 
-class Flow_Mod_1(basic.SimpleProtocol):
+class Flow_Mod_1(base_tests.SimpleProtocol):
     """
     Test FLOW_MOD_1 from draft top-half test plan
     
@@ -2294,7 +2294,7 @@
 #    action list;
 #    else test FAILED
         
-class Flow_Mod_2(basic.SimpleProtocol):
+class Flow_Mod_2(base_tests.SimpleProtocol):
     """
     Test FLOW_MOD_2 from draft top-half test plan
     
@@ -2447,7 +2447,7 @@
 # 3. Verify flow table in switch
 # 4. Test PASSED iff flow defined in step 2 above verified; else FAILED
 
-class Flow_Mod_3(basic.SimpleProtocol):
+class Flow_Mod_3(base_tests.SimpleProtocol):
     """
     Test FLOW_MOD_3 from draft top-half test plan
     
@@ -2540,7 +2540,7 @@
 # 5. Verify flow table in switch
 # 6. Test PASSED iff flow defined in step 2 and 4 above verified; else FAILED
 
-class Flow_Mod_3_1(basic.SimpleProtocol):
+class Flow_Mod_3_1(base_tests.SimpleProtocol):
     """
     Test FLOW_MOD_3_1 from draft top-half test plan
     
@@ -2656,7 +2656,7 @@
 #    less flow removed in step 3 above, are returned in step 4 above;
 #    else test FAILED
 
-class Flow_Del_1(basic.SimpleProtocol):
+class Flow_Del_1(base_tests.SimpleProtocol):
     """
     Test FLOW_DEL_1 from draft top-half test plan
     
@@ -2778,7 +2778,7 @@
 #    in step 7 above;
 #    else test FAILED
 
-class Flow_Del_2(basic.SimpleProtocol):
+class Flow_Del_2(base_tests.SimpleProtocol):
     """
     Test FLOW_DEL_2 from draft top-half test plan
     
@@ -2937,7 +2937,7 @@
 #    asynch message was received; else test FAILED
 
 
-class Flow_Del_4(basic.SimpleProtocol):
+class Flow_Del_4(base_tests.SimpleProtocol):
     """
     Test FLOW_DEL_4 from draft top-half test plan
     
diff --git a/tests/flow_stats.py b/tests/flow_stats.py
index 4b3c8e1..2144278 100644
--- a/tests/flow_stats.py
+++ b/tests/flow_stats.py
@@ -16,7 +16,7 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
@@ -61,7 +61,7 @@
     obj.assertEqual(str(pkt), str(rcv_pkt),
                     'Response packet does not match send packet')
 
-class SingleFlowStats(basic.SimpleDataPlane):
+class SingleFlowStats(base_tests.SimpleDataPlane):
     """
     Verify flow stats are properly retrieved.
 
@@ -162,7 +162,7 @@
             self.verifyStats(match, egress_port, test_timeout, num_sends)
 
 
-class TwoFlowStats(basic.SimpleDataPlane):
+class TwoFlowStats(base_tests.SimpleDataPlane):
     """
     Verify flow stats are properly retrieved.
 
@@ -292,7 +292,7 @@
         # TODO: sweep through the wildcards to verify matching?
 
 
-class AggregateStats(basic.SimpleDataPlane):
+class AggregateStats(base_tests.SimpleDataPlane):
     """
     Verify aggregate flow stats are properly retrieved.
 
diff --git a/tests/load.py b/tests/load.py
index a44b555..a05a373 100644
--- a/tests/load.py
+++ b/tests/load.py
@@ -26,12 +26,12 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 import time
 
 from oftest.testutils import *
 
-class LoadBarrier(basic.SimpleProtocol):
+class LoadBarrier(base_tests.SimpleProtocol):
     """
     Test barrier under load with loopback
 
diff --git a/tests/openflow_protocol_messages.py b/tests/openflow_protocol_messages.py
index 785ab14..43ce062 100644
--- a/tests/openflow_protocol_messages.py
+++ b/tests/openflow_protocol_messages.py
@@ -17,13 +17,13 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
 from FuncUtils import *
 
-class FeaturesRequest(basic.SimpleProtocol): 
+class FeaturesRequest(base_tests.SimpleProtocol): 
 
     """Verify Features_Request-Reply is implemented 
     a) Send OFPT_FEATURES_REQUEST
@@ -52,7 +52,7 @@
                         'Did not receive Features Reply')
 
 
-class ConfigurationRequest(basic.SimpleProtocol):
+class ConfigurationRequest(base_tests.SimpleProtocol):
     
     """Check basic Get Config request is implemented
     a) Send OFPT_GET_CONFIG_REQUEST
@@ -81,7 +81,7 @@
         self.assertTrue(response is not None, 
                         'Did not receive OFPT_GET_CONFIG_REPLY')
 
-class ModifyStateAdd(basic.SimpleProtocol):
+class ModifyStateAdd(base_tests.SimpleProtocol):
     
     """Check basic Flow Add request is implemented
     a) Send  OFPT_FLOW_MOD , command = OFPFC_ADD 
@@ -108,7 +108,7 @@
         Verify_TableStats(self,active_entries=1)
 
 
-class ModifyStateDelete(basic.SimpleProtocol):
+class ModifyStateDelete(base_tests.SimpleProtocol):
     
     """Check Basic Flow Delete request is implemented
     a) Send OFPT_FLOW_MOD, command = OFPFC_ADD
@@ -144,7 +144,7 @@
 
       
 
-class ModifyStateModify(basic.SimpleDataPlane):
+class ModifyStateModify(base_tests.SimpleDataPlane):
     
     """Verify basic Flow Modify request is implemented
     a) Send OFPT_FLOW_MOD, command = OFPFC_ADD, Action A 
@@ -175,7 +175,7 @@
         SendPacket(self,pkt,of_ports[0],of_ports[2])
                        
 
-class ReadState(basic.SimpleProtocol):
+class ReadState(base_tests.SimpleProtocol):
     
     """Test that a basic Read state request (like flow_stats_get request) does not generate an error
     a) Send OFPT_FLOW_MOD, command = OFPFC_ADD
@@ -202,7 +202,7 @@
         #Verify Flow_Stats request does not generate errors
         Verify_FlowStats(self,match)
         
-class PacketOut(basic.SimpleDataPlane):
+class PacketOut(base_tests.SimpleDataPlane):
     
     """Test packet out function
     a) Send packet out message for each dataplane port.
@@ -259,7 +259,7 @@
                                     'Response packet does not match send packet')
 
         
-class PacketIn(basic.SimpleDataPlane):
+class PacketIn(base_tests.SimpleDataPlane):
     
     """Test basic packet_in function
     a) Send a simple tcp packet to a dataplane port, without any flow-entry 
@@ -293,7 +293,7 @@
                                'Packet in event is not sent to the controller') 
 
 
-class Hello(basic.SimpleDataPlane):
+class Hello(base_tests.SimpleDataPlane):
     
     """Test Hello messages are implemented
     a) Create Hello messages from controller
@@ -317,7 +317,7 @@
 
 
 
-class EchoWithoutBody(basic.SimpleProtocol):
+class EchoWithoutBody(base_tests.SimpleProtocol):
     
     """Test basic echo-reply is implemented
     a)  Send echo-request from the controller side, note echo body is empty here.
@@ -340,7 +340,7 @@
         self.assertEqual(len(response.data), 0, 'response data non-empty')
 
 
-class BarrierRequestReply(basic.SimpleProtocol):
+class BarrierRequestReply(base_tests.SimpleProtocol):
 
     """ Check basic Barrier request is implemented
     a) Send OFPT_BARRIER_REQUEST
diff --git a/tests/pktact.py b/tests/pktact.py
index 5c1d702..76dea36 100644
--- a/tests/pktact.py
+++ b/tests/pktact.py
@@ -13,9 +13,8 @@
 """
 
 import copy
-
 import logging
-
+import time
 import unittest
 
 from oftest import config
@@ -25,8 +24,8 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
-import time
+import oftest.base_tests as base_tests
+import basic # for IterCases
 
 from oftest.testutils import *
 
@@ -76,7 +75,7 @@
 
 TEST_VID_DEFAULT = 2
 
-class DirectPacket(basic.SimpleDataPlane):
+class DirectPacket(base_tests.SimpleDataPlane):
     """
     Send packet to single egress port
 
@@ -146,7 +145,7 @@
             self.assertEqual(str(pkt), str(rcv_pkt),
                              'Response packet does not match send packet')
 
-class DirectPacketController(basic.SimpleDataPlane):
+class DirectPacketController(base_tests.SimpleDataPlane):
     """
     Send packet to the controller port
 
@@ -209,7 +208,7 @@
                              ' for controller port')
 
 
-class DirectPacketQueue(basic.SimpleDataPlane):
+class DirectPacketQueue(base_tests.SimpleDataPlane):
     """
     Send packet to single queue on single egress port
 
@@ -331,7 +330,7 @@
                                  )
                     
 
-class DirectPacketControllerQueue(basic.SimpleDataPlane):
+class DirectPacketControllerQueue(base_tests.SimpleDataPlane):
     """
     Send a packet from each of the openflow ports
     to each of the queues configured on the controller port.
@@ -482,7 +481,7 @@
     def runTest(self):
         self.handleFlow(pkttype='ICMP')
 
-class DirectTwoPorts(basic.SimpleDataPlane):
+class DirectTwoPorts(base_tests.SimpleDataPlane):
     """
     Send packet to two egress ports
 
@@ -540,7 +539,7 @@
             receive_pkt_check(self.dataplane, pkt, yes_ports, no_ports,
                               self, config)
 
-class DirectMCNonIngress(basic.SimpleDataPlane):
+class DirectMCNonIngress(base_tests.SimpleDataPlane):
     """
     Multicast to all non-ingress ports
 
@@ -595,7 +594,7 @@
                               self, config)
 
 
-class DirectMC(basic.SimpleDataPlane):
+class DirectMC(base_tests.SimpleDataPlane):
     """
     Multicast to all ports including ingress
 
@@ -647,7 +646,7 @@
             self.dataplane.send(ingress_port, str(pkt))
             receive_pkt_check(self.dataplane, pkt, of_ports, [], self, config)
 
-class Flood(basic.SimpleDataPlane):
+class Flood(base_tests.SimpleDataPlane):
     """
     Flood to all ports except ingress
 
@@ -695,7 +694,7 @@
             receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
                               self, config)
 
-class FloodPlusIngress(basic.SimpleDataPlane):
+class FloodPlusIngress(base_tests.SimpleDataPlane):
     """
     Flood to all ports plus send to ingress port
 
@@ -745,7 +744,7 @@
             self.dataplane.send(ingress_port, str(pkt))
             receive_pkt_check(self.dataplane, pkt, of_ports, [], self, config)
 
-class All(basic.SimpleDataPlane):
+class All(base_tests.SimpleDataPlane):
     """
     Send to OFPP_ALL port
 
@@ -793,7 +792,7 @@
             receive_pkt_check(self.dataplane, pkt, yes_ports, [ingress_port],
                               self, config)
 
-class AllPlusIngress(basic.SimpleDataPlane):
+class AllPlusIngress(base_tests.SimpleDataPlane):
     """
     Send to OFPP_ALL port and ingress port
 
@@ -843,7 +842,7 @@
             self.dataplane.send(ingress_port, str(pkt))
             receive_pkt_check(self.dataplane, pkt, of_ports, [], self, config)
             
-class FloodMinusPort(basic.SimpleDataPlane):
+class FloodMinusPort(base_tests.SimpleDataPlane):
     """
     Config port with No_Flood and test Flood action
 
@@ -911,9 +910,9 @@
 
 ################################################################
 
-class BaseMatchCase(basic.SimpleDataPlane):
+class BaseMatchCase(base_tests.SimpleDataPlane):
     def setUp(self):
-        basic.SimpleDataPlane.setUp(self)
+        base_tests.SimpleDataPlane.setUp(self)
     def runTest(self):
         logging.info("BaseMatchCase")
 
@@ -1270,7 +1269,7 @@
         flow_match_test(self, config["port_map"], pkt=pkt, 
                         exp_pkt=exp_pkt, action_list=[vid_act])
 
-class PacketOnly(basic.DataPlaneOnly):
+class PacketOnly(base_tests.DataPlaneOnly):
     """
     Just send a packet thru the switch
     """
@@ -1286,7 +1285,7 @@
         logging.debug("Data: " + str(pkt).encode('hex'))
         self.dataplane.send(ing_port, str(pkt))
 
-class PacketOnlyTagged(basic.DataPlaneOnly):
+class PacketOnlyTagged(base_tests.DataPlaneOnly):
     """
     Just send a packet thru the switch
     """
@@ -1849,7 +1848,7 @@
 
     priority = -1
 
-class MatchEach(basic.SimpleDataPlane):
+class MatchEach(base_tests.SimpleDataPlane):
     """
     Check that each match field is actually matched on.
     Installs two flows that differ in one field. The flow that should not
diff --git a/tests/port_stats.py b/tests/port_stats.py
index 0de8de5..670e31f 100644
--- a/tests/port_stats.py
+++ b/tests/port_stats.py
@@ -16,7 +16,7 @@
 import oftest.dataplane as dataplane
 import oftest.action as action
 import oftest.parse as parse
-import basic
+import oftest.base_tests as base_tests
 
 from oftest.testutils import *
 from time import sleep
@@ -114,7 +114,7 @@
     obj.assertTrue(all_packets_received,
                    "Packet received does not match number sent")
 
-class SingleFlowStats(basic.SimpleDataPlane):
+class SingleFlowStats(base_tests.SimpleDataPlane):
     """
     Verify flow stats are properly retrieved.
 
@@ -180,7 +180,7 @@
         verifyStats(self, egress_port, test_timeout, initTxOutPort + num_sends, initRxOutPort)
 
 
-class MultiFlowStats(basic.SimpleDataPlane):
+class MultiFlowStats(base_tests.SimpleDataPlane):
     """
     Verify flow stats are properly retrieved.