moving to global lazy loaded config

one of the problems we've got with tempest is the fact that config
loading is tied into the class hierarchy. However there is no
reason why it should be. If we instead create a config proxy
object we can lazy load the actual config when we are executing,
and not do it at import time.

This could use future iteration, but it does a huge job in
removing config from the object inheritance tree which massively
simplifies our ability to use config variables throughout the code.

Change-Id: I9b1bbfe231c85c01938bd68be4e5974bd24130d6
diff --git a/tempest/api/compute/__init__.py b/tempest/api/compute/__init__.py
index d20068e..a385f83 100644
--- a/tempest/api/compute/__init__.py
+++ b/tempest/api/compute/__init__.py
@@ -15,13 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest import config
+# from tempest import config
 from tempest.openstack.common import log as logging
 
 LOG = logging.getLogger(__name__)
 
-CONFIG = config.TempestConfig()
-CREATE_IMAGE_ENABLED = CONFIG.compute_feature_enabled.create_image
-RESIZE_AVAILABLE = CONFIG.compute_feature_enabled.resize
-CHANGE_PASSWORD_AVAILABLE = CONFIG.compute_feature_enabled.change_password
-DISK_CONFIG_ENABLED = CONFIG.compute_feature_enabled.disk_config
+# CONFIG = config.CONF
+# CREATE_IMAGE_ENABLED = CONFIG.compute_feature_enabled.create_image
+# RESIZE_AVAILABLE = CONFIG.compute_feature_enabled.resize
+# CHANGE_PASSWORD_AVAILABLE = CONFIG.compute_feature_enabled.change_password
+# DISK_CONFIG_ENABLED = CONFIG.compute_feature_enabled.disk_config
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index f49aae4..66d41b8 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -22,6 +22,8 @@
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest):
     _interface = 'json'
@@ -156,7 +158,7 @@
         self.assertRaises(exceptions.OverLimit, self.create_test_server)
 
     @skip_because(bug="1186354",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
@@ -180,7 +182,7 @@
                           "sg-overlimit", "sg-desc")
 
     @skip_because(bug="1186354",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_groups_rules_exceed_limit(self):
         # Negative test: Creation of Security Group Rules should FAIL
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index 5ed4823..da2a1a1 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -22,6 +22,8 @@
 from tempest import config
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class SecurityGroupsTestAdminJSON(base.BaseV2ComputeAdminTest):
     _interface = 'json'
@@ -40,7 +42,7 @@
 
         self.assertEqual(202, resp.status)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
+    @testtools.skipIf(CONF.service_available.neutron,
                       "Skipped because neutron do not support all_tenants"
                       "search filter.")
     @attr(type='smoke')
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 6e4c8cb..c711bd5 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -17,13 +17,14 @@
 
 import testtools
 
-from tempest.api import compute
 from tempest.api.compute import base
 from tempest import clients
 from tempest.common.utils import data_utils
+from tempest import config
 from tempest.openstack.common import log as logging
 from tempest.test import attr
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -84,7 +85,7 @@
         resp, flavor = self.flavors_client.get_flavor_details(flavor_id)
         return flavor['disk']
 
-    @testtools.skipUnless(compute.CREATE_IMAGE_ENABLED,
+    @testtools.skipUnless(CONF.compute_feature_enabled.create_image,
                           'Environment unable to create images.')
     @attr(type='smoke')
     def test_create_delete_image(self):
diff --git a/tempest/api/compute/security_groups/test_security_group_rules_negative.py b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
index 1c38268..c0b202d 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules_negative.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules_negative.py
@@ -24,6 +24,8 @@
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class SecurityGroupRulesNegativeTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
@@ -34,7 +36,7 @@
         cls.client = cls.security_groups_client
 
     @skip_because(bug="1182384",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'smoke'])
     def test_create_security_group_rule_with_non_existent_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -48,7 +50,7 @@
                           self.client.create_security_group_rule,
                           parent_group_id, ip_protocol, from_port, to_port)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
+    @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron not check the security_group_id")
     @attr(type=['negative', 'smoke'])
     def test_create_security_group_rule_with_invalid_id(self):
@@ -168,7 +170,7 @@
                           secgroup_id, ip_protocol, from_port, to_port)
 
     @skip_because(bug="1182384",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'smoke'])
     def test_delete_security_group_rule_with_non_existent_id(self):
         # Negative test: Deletion of Security Group rule should be FAIL
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 7cb96af..95e9171 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -25,6 +25,8 @@
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class SecurityGroupsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
@@ -129,7 +131,7 @@
                           non_exist_id)
 
     @skip_because(bug="1161411",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_invalid_group_name(self):
         # Negative test: Security Group should not be created with group name
@@ -149,7 +151,7 @@
                           s_description)
 
     @skip_because(bug="1161411",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_invalid_group_description(self):
         # Negative test:Security Group should not be created with description
@@ -167,7 +169,7 @@
                           self.client.create_security_group, s_name,
                           s_description)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
+    @testtools.skipIf(CONF.service_available.neutron,
                       "Neutron allows duplicate names for security groups")
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_duplicate_name(self):
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index cbd0eb1..5d62e1b 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -20,17 +20,18 @@
 import netaddr
 import testtools
 
-from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux.remote_client import RemoteClient
-import tempest.config
+from tempest import config
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class ServersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
-    run_ssh = tempest.config.TempestConfig().compute.run_ssh
+    run_ssh = CONF.compute.run_ssh
     disk_config = 'AUTO'
 
     @classmethod
@@ -113,7 +114,7 @@
 
     @classmethod
     def setUpClass(cls):
-        if not compute.DISK_CONFIG_ENABLED:
+        if not CONF.compute_feature_enabled.disk_config:
             msg = "DiskConfig extension not enabled."
             raise cls.skipException(msg)
         super(ServersTestManualDisk, cls).setUpClass()
diff --git a/tempest/api/compute/servers/test_disk_config.py b/tempest/api/compute/servers/test_disk_config.py
index 0121c42..358728e 100644
--- a/tempest/api/compute/servers/test_disk_config.py
+++ b/tempest/api/compute/servers/test_disk_config.py
@@ -17,17 +17,19 @@
 
 import testtools
 
-from tempest.api import compute
 from tempest.api.compute import base
+from tempest import config
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class ServerDiskConfigTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        if not compute.DISK_CONFIG_ENABLED:
+        if not CONF.compute_feature_enabled.disk_config:
             msg = "DiskConfig extension not enabled."
             raise cls.skipException(msg)
         super(ServerDiskConfigTestJSON, cls).setUpClass()
@@ -85,7 +87,8 @@
         else:
             return self.flavor_ref
 
-    @testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @attr(type='gate')
     def test_resize_server_from_manual_to_auto(self):
         # A server should be resized from manual to auto disk config
@@ -101,7 +104,8 @@
         resp, server = self.client.get_server(self.server_id)
         self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
 
-    @testtools.skipUnless(compute.RESIZE_AVAILABLE, 'Resize not available.')
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @attr(type='gate')
     def test_resize_server_from_auto_to_manual(self):
         # A server should be resized from auto to manual disk config
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 4cbf94d..3748e37 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -23,6 +23,8 @@
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
@@ -210,7 +212,7 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @skip_because(bug="1182883",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type='gate')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index e009888..d985d2b 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -20,21 +20,21 @@
 
 import testtools
 
-from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux.remote_client import RemoteClient
-import tempest.config
+from tempest import config
 from tempest import exceptions
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class ServerActionsTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
-    resize_available = tempest.config.TempestConfig().\
-        compute_feature_enabled.resize
-    run_ssh = tempest.config.TempestConfig().compute.run_ssh
+    resize_available = CONF.compute_feature_enabled.resize
+    run_ssh = CONF.compute.run_ssh
 
     def setUp(self):
         # NOTE(afazekas): Normally we use the same server with all test cases,
@@ -53,7 +53,7 @@
         cls.client = cls.servers_client
         cls.server_id = cls.rebuild_server(None)
 
-    @testtools.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
+    @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
                           'Change password not available.')
     @attr(type='gate')
     def test_change_server_password(self):
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index 77ada0b..164c6df 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -28,7 +28,7 @@
 class VirtualInterfacesTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
 
-    CONF = config.TempestConfig()
+    CONF = config.CONF
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/test_auth_token.py b/tempest/api/compute/test_auth_token.py
index ffeede8..e52c415 100644
--- a/tempest/api/compute/test_auth_token.py
+++ b/tempest/api/compute/test_auth_token.py
@@ -18,6 +18,8 @@
 from tempest.api.compute import base
 import tempest.config as config
 
+CONF = config.CONF
+
 
 class AuthTokenTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
@@ -37,7 +39,7 @@
         # picking list_servers because it's easy.
         self.servers_v2.list_servers()
 
-    @testtools.skipIf(not config.TempestConfig().identity.uri_v3,
+    @testtools.skipIf(not CONF.identity.uri_v3,
                       'v3 auth client not configured')
     def test_v3_token(self):
         # Can get a token using v3 of the identity API and use that to perform
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index a7b6cd2..d2a3d28 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -30,7 +30,7 @@
     _host_key = 'OS-EXT-SRV-ATTR:host'
     _interface = 'json'
 
-    CONF = config.TempestConfig()
+    CONF = config.CONF
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/admin/test_quotas.py b/tempest/api/compute/v3/admin/test_quotas.py
index f49aae4..66d41b8 100644
--- a/tempest/api/compute/v3/admin/test_quotas.py
+++ b/tempest/api/compute/v3/admin/test_quotas.py
@@ -22,6 +22,8 @@
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class QuotasAdminTestJSON(base.BaseV2ComputeAdminTest):
     _interface = 'json'
@@ -156,7 +158,7 @@
         self.assertRaises(exceptions.OverLimit, self.create_test_server)
 
     @skip_because(bug="1186354",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
@@ -180,7 +182,7 @@
                           "sg-overlimit", "sg-desc")
 
     @skip_because(bug="1186354",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_groups_rules_exceed_limit(self):
         # Negative test: Creation of Security Group Rules should FAIL
diff --git a/tempest/api/compute/v3/servers/test_create_server.py b/tempest/api/compute/v3/servers/test_create_server.py
index 24ade96..94175ab 100644
--- a/tempest/api/compute/v3/servers/test_create_server.py
+++ b/tempest/api/compute/v3/servers/test_create_server.py
@@ -20,17 +20,18 @@
 import netaddr
 import testtools
 
-from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux.remote_client import RemoteClient
-import tempest.config
+from tempest import config
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class ServersTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
-    run_ssh = tempest.config.TempestConfig().compute.run_ssh
+    run_ssh = CONF.compute.run_ssh
     disk_config = 'AUTO'
 
     @classmethod
@@ -120,7 +121,7 @@
 
     @classmethod
     def setUpClass(cls):
-        if not compute.DISK_CONFIG_ENABLED:
+        if not CONF.compute_feature_enabled.disk_config:
             msg = "DiskConfig extension not enabled."
             raise cls.skipException(msg)
         super(ServersTestManualDisk, cls).setUpClass()
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index d333a1d..3dd7b0b 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -23,6 +23,8 @@
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class ListServerFiltersV3TestJSON(base.BaseV3ComputeTest):
     _interface = 'json'
@@ -211,7 +213,7 @@
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
     @skip_because(bug="1182883",
-                  condition=config.TempestConfig().service_available.neutron)
+                  condition=CONF.service_available.neutron)
     @attr(type='gate')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index ee37502..8cd6c11 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -20,21 +20,21 @@
 
 import testtools
 
-from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux.remote_client import RemoteClient
-import tempest.config
+from tempest import config
 from tempest import exceptions
 from tempest.test import attr
 from tempest.test import skip_because
 
+CONF = config.CONF
+
 
 class ServerActionsV3TestJSON(base.BaseV3ComputeTest):
     _interface = 'json'
-    resize_available = tempest.config.TempestConfig().\
-        compute_feature_enabled.resize
-    run_ssh = tempest.config.TempestConfig().compute.run_ssh
+    resize_available = CONF.compute_feature_enabled.resize
+    run_ssh = CONF.compute.run_ssh
 
     def setUp(self):
         # NOTE(afazekas): Normally we use the same server with all test cases,
@@ -53,7 +53,7 @@
         cls.client = cls.servers_client
         cls.server_id = cls.rebuild_server(None)
 
-    @testtools.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
+    @testtools.skipUnless(CONF.compute_feature_enabled.change_password,
                           'Change password not available.')
     @attr(type='gate')
     def test_change_server_password(self):
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 660de95..c1ebc08 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -19,13 +19,15 @@
 
 from tempest.api.compute import base
 from tempest.common.utils.linux.remote_client import RemoteClient
-import tempest.config
+from tempest import config
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class AttachVolumeTestJSON(base.BaseV2ComputeTest):
     _interface = 'json'
-    run_ssh = tempest.config.TempestConfig().compute.run_ssh
+    run_ssh = CONF.compute.run_ssh
 
     def __init__(self, *args, **kwargs):
         super(AttachVolumeTestJSON, self).__init__(*args, **kwargs)
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index c1b3391..ac1c7d1 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -23,10 +23,12 @@
 from tempest import exceptions
 from tempest.test import attr
 
+CONF = config.CONF
+
 
 class AccountQuotasTest(base.BaseObjectTest):
     accounts_quotas_available = \
-        config.TempestConfig().object_storage_feature_enabled.accounts_quotas
+        CONF.object_storage_feature_enabled.accounts_quotas
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/object_storage/test_container_quotas.py b/tempest/api/object_storage/test_container_quotas.py
index c7b5e28..513d24a 100644
--- a/tempest/api/object_storage/test_container_quotas.py
+++ b/tempest/api/object_storage/test_container_quotas.py
@@ -24,6 +24,7 @@
 from tempest.test import attr
 from tempest.test import HTTP_SUCCESS
 
+CONF = config.CONF
 QUOTA_BYTES = 10
 QUOTA_COUNT = 3
 SKIP_MSG = "Container quotas middleware not available."
@@ -32,7 +33,7 @@
 class ContainerQuotasTest(base.BaseObjectTest):
     """Attemps to test the perfect behavior of quotas in a container."""
     container_quotas_available = \
-        config.TempestConfig().object_storage_feature_enabled.container_quotas
+        CONF.object_storage_feature_enabled.container_quotas
 
     def setUp(self):
         """Creates and sets a container with quotas.
diff --git a/tempest/api/object_storage/test_crossdomain.py b/tempest/api/object_storage/test_crossdomain.py
index 51ecd16..41430c8 100644
--- a/tempest/api/object_storage/test_crossdomain.py
+++ b/tempest/api/object_storage/test_crossdomain.py
@@ -23,10 +23,12 @@
 from tempest.test import attr
 from tempest.test import HTTP_SUCCESS
 
+CONF = config.CONF
+
 
 class CrossdomainTest(base.BaseObjectTest):
     crossdomain_available = \
-        config.TempestConfig().object_storage_feature_enabled.crossdomain
+        CONF.object_storage_feature_enabled.crossdomain
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index bb03932..9d5a1c0 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -27,11 +27,13 @@
 from tempest.test import attr
 from tempest.test import HTTP_SUCCESS
 
+CONF = config.CONF
+
 
 class ObjectTempUrlTest(base.BaseObjectTest):
 
     tempurl_available = \
-        config.TempestConfig().object_storage_feature_enabled.tempurl
+        CONF.object_storage_feature_enabled.tempurl
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index 0480570..6fbbb5b 100644
--- a/tempest/api/orchestration/stacks/test_server_cfn_init.py
+++ b/tempest/api/orchestration/stacks/test_server_cfn_init.py
@@ -18,18 +18,17 @@
 from tempest.api.orchestration import base
 from tempest.common.utils import data_utils
 from tempest.common.utils.linux.remote_client import RemoteClient
-import tempest.config
+from tempest import config
 from tempest.openstack.common import log as logging
 from tempest.test import attr
 
-
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
 class ServerCfnInitTestJSON(base.BaseOrchestrationTest):
     _interface = 'json'
-    existing_keypair = (tempest.config.TempestConfig().
-                        orchestration.keypair_name is not None)
+    existing_keypair = CONF.orchestration.keypair_name is not None
 
     template = """
 HeatTemplateFormatVersion: '2012-12-12'
diff --git a/tempest/clients.py b/tempest/clients.py
index eeffe2a..3333b9b 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -162,6 +162,7 @@
 from tempest.services.volume.xml.snapshots_client import SnapshotsClientXML
 from tempest.services.volume.xml.volumes_client import VolumesClientXML
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -182,13 +183,12 @@
         :param password: Override of the password
         :param tenant_name: Override of the tenant name
         """
-        self.config = config.TempestConfig()
-
+        self.config = CONF
         # If no creds are provided, we fall back on the defaults
         # in the config file for the Compute API.
-        self.username = username or self.config.identity.username
-        self.password = password or self.config.identity.password
-        self.tenant_name = tenant_name or self.config.identity.tenant_name
+        self.username = username or CONF.identity.username
+        self.password = password or CONF.identity.password
+        self.tenant_name = tenant_name or CONF.identity.tenant_name
 
         if None in (self.username, self.password, self.tenant_name):
             msg = ("Missing required credentials. "
@@ -197,15 +197,15 @@
                    {'u': username, 'p': password, 't': tenant_name})
             raise exceptions.InvalidConfiguration(msg)
 
-        self.auth_url = self.config.identity.uri
-        self.auth_url_v3 = self.config.identity.uri_v3
+        self.auth_url = CONF.identity.uri
+        self.auth_url_v3 = CONF.identity.uri_v3
 
-        client_args = (self.config, self.username, self.password,
+        client_args = (CONF, self.username, self.password,
                        self.auth_url, self.tenant_name)
 
         if self.auth_url_v3:
             auth_version = 'v3'
-            client_args_v3_auth = (self.config, self.username,
+            client_args_v3_auth = (CONF, self.username,
                                    self.password, self.auth_url_v3,
                                    self.tenant_name, auth_version)
         else:
@@ -233,7 +233,7 @@
             self.volume_types_client = VolumeTypesClientXML(*client_args)
             self.identity_client = IdentityClientXML(*client_args)
             self.identity_v3_client = IdentityV3ClientXML(*client_args)
-            self.token_client = TokenClientXML(self.config)
+            self.token_client = TokenClientXML(CONF)
             self.security_groups_client = SecurityGroupsClientXML(
                 *client_args)
             self.interfaces_v3_client = InterfacesV3ClientXML(*client_args)
@@ -288,7 +288,7 @@
             self.volume_types_client = VolumeTypesClientJSON(*client_args)
             self.identity_client = IdentityClientJSON(*client_args)
             self.identity_v3_client = IdentityV3ClientJSON(*client_args)
-            self.token_client = TokenClientJSON(self.config)
+            self.token_client = TokenClientJSON(CONF)
             self.security_groups_client = SecurityGroupsClientJSON(
                 *client_args)
             self.interfaces_v3_client = InterfacesV3ClientJSON(*client_args)
@@ -328,7 +328,7 @@
         # common clients
         self.hosts_client = HostsClientJSON(*client_args)
         self.account_client = AccountClient(*client_args)
-        if self.config.service_available.glance:
+        if CONF.service_available.glance:
             self.image_client = ImageClientJSON(*client_args)
             self.image_client_v2 = ImageClientV2JSON(*client_args)
         self.container_client = ContainerClient(*client_args)
@@ -350,10 +350,9 @@
     """
 
     def __init__(self, interface='json'):
-        conf = config.TempestConfig()
-        super(AltManager, self).__init__(conf.identity.alt_username,
-                                         conf.identity.alt_password,
-                                         conf.identity.alt_tenant_name,
+        super(AltManager, self).__init__(CONF.identity.alt_username,
+                                         CONF.identity.alt_password,
+                                         CONF.identity.alt_tenant_name,
                                          interface=interface)
 
 
@@ -365,10 +364,9 @@
     """
 
     def __init__(self, interface='json'):
-        conf = config.TempestConfig()
-        super(AdminManager, self).__init__(conf.identity.admin_username,
-                                           conf.identity.admin_password,
-                                           conf.identity.admin_tenant_name,
+        super(AdminManager, self).__init__(CONF.identity.admin_username,
+                                           CONF.identity.admin_password,
+                                           CONF.identity.admin_tenant_name,
                                            interface=interface)
 
 
@@ -380,11 +378,10 @@
     """
 
     def __init__(self, interface='json'):
-        conf = config.TempestConfig()
         base = super(ComputeAdminManager, self)
-        base.__init__(conf.compute_admin.username,
-                      conf.compute_admin.password,
-                      conf.compute_admin.tenant_name,
+        base.__init__(CONF.compute_admin.username,
+                      CONF.compute_admin.password,
+                      CONF.compute_admin.tenant_name,
                       interface=interface)
 
 
@@ -394,9 +391,8 @@
     so that heat templates can create users
     """
     def __init__(self, interface='json'):
-        conf = config.TempestConfig()
         base = super(OrchestrationManager, self)
-        base.__init__(conf.identity.admin_username,
-                      conf.identity.admin_password,
-                      conf.identity.tenant_name,
+        base.__init__(CONF.identity.admin_username,
+                      CONF.identity.admin_password,
+                      CONF.identity.tenant_name,
                       interface=interface)
diff --git a/tempest/common/debug.py b/tempest/common/debug.py
index 69c933c..f132f6a 100644
--- a/tempest/common/debug.py
+++ b/tempest/common/debug.py
@@ -19,13 +19,14 @@
 
 from tempest.openstack.common import log as logging
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 tables = ['filter', 'nat', 'mangle']
 
 
 def log_ip_ns():
-    if not config.TempestConfig().debug.enable:
+    if not CONF.debug.enable:
         return
     LOG.info("Host Addr:\n" + commands.ip_addr_raw())
     LOG.info("Host Route:\n" + commands.ip_route_raw())
diff --git a/tempest/common/generate_sample_tempest.py b/tempest/common/generate_sample_tempest.py
index 545703b..22be4aa 100644
--- a/tempest/common/generate_sample_tempest.py
+++ b/tempest/common/generate_sample_tempest.py
@@ -18,7 +18,7 @@
 
 import sys
 
-from tempest import config
+import tempest.config
 from tempest.openstack.common.config import generator
 
 # NOTE(mtreinish): This hack is needed because of how oslo config is used in
@@ -31,5 +31,7 @@
 # the issue by manually loading the config file (which may or may not exist)
 # which will populate all the options before running the generator.
 
-config.TempestConfig()
-generator.generate(sys.argv[1:])
+
+if __name__ == "__main__":
+    CONF = tempest.config.TempestConfig()
+    generator.generate(sys.argv[1:])
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 5dbb3a7..da60318 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -25,6 +25,7 @@
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -36,7 +37,7 @@
         self.isolated_net_resources = {}
         self.ports = []
         self.name = name
-        self.config = config.TempestConfig()
+        self.config = CONF
         self.tempest_client = tempest_client
         self.interface = interface
         self.password = password
@@ -44,11 +45,11 @@
             self._get_admin_clients())
 
     def _get_official_admin_clients(self):
-        username = self.config.identity.admin_username
-        password = self.config.identity.admin_password
-        tenant_name = self.config.identity.admin_tenant_name
-        auth_url = self.config.identity.uri
-        dscv = self.config.identity.disable_ssl_certificate_validation
+        username = CONF.identity.admin_username
+        password = CONF.identity.admin_password
+        tenant_name = CONF.identity.admin_tenant_name
+        auth_url = CONF.identity.uri
+        dscv = CONF.identity.disable_ssl_certificate_validation
         identity_client = keystoneclient.Client(username=username,
                                                 password=password,
                                                 tenant_name=tenant_name,
@@ -164,7 +165,7 @@
             role = None
             try:
                 roles = self._list_roles()
-                admin_role = self.config.identity.admin_role
+                admin_role = CONF.identity.admin_role
                 if self.tempest_client:
                     role = next(r for r in roles if r['name'] == admin_role)
                 else:
@@ -229,8 +230,8 @@
         if not self.tempest_client:
             body = {'subnet': {'name': subnet_name, 'tenant_id': tenant_id,
                                'network_id': network_id, 'ip_version': 4}}
-        base_cidr = netaddr.IPNetwork(self.config.network.tenant_network_cidr)
-        mask_bits = self.config.network.tenant_network_mask_bits
+        base_cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+        mask_bits = CONF.network.tenant_network_mask_bits
         for subnet_cidr in base_cidr.subnet(mask_bits):
             try:
                 if self.tempest_client:
@@ -252,7 +253,7 @@
 
     def _create_router(self, router_name, tenant_id):
         external_net_id = dict(
-            network_id=self.config.network.public_network_id)
+            network_id=CONF.network.public_network_id)
         if self.tempest_client:
             resp, resp_body = self.network_admin_client.create_router(
                 router_name,
@@ -328,7 +329,7 @@
             self.isolated_creds['primary'] = (user, tenant)
             LOG.info("Acquired isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
-            if self.config.service_available.neutron:
+            if CONF.service_available.neutron:
                 network, subnet, router = self._create_network_resources(
                     self._get_tenant_id(tenant))
                 self.isolated_net_resources['primary'] = (
@@ -347,7 +348,7 @@
             self.isolated_creds['admin'] = (user, tenant)
             LOG.info("Acquired admin isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
-            if self.config.service_available.neutron:
+            if CONF.service_available.neutron:
                 network, subnet, router = self._create_network_resources(
                     self._get_tenant_id(tenant))
                 self.isolated_net_resources['admin'] = (
@@ -366,7 +367,7 @@
             self.isolated_creds['alt'] = (user, tenant)
             LOG.info("Acquired alt isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
-            if self.config.service_available.neutron:
+            if CONF.service_available.neutron:
                 network, subnet, router = self._create_network_resources(
                     self._get_tenant_id(tenant))
                 self.isolated_net_resources['alt'] = (
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 144536a..fa59e14 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -17,18 +17,20 @@
 
 from tempest.common.ssh import Client
 from tempest.common import utils
-from tempest.config import TempestConfig
+from tempest import config
 from tempest.exceptions import ServerUnreachable
 
+CONF = config.CONF
+
 
 class RemoteClient():
 
     # NOTE(afazekas): It should always get an address instead of server
     def __init__(self, server, username, password=None, pkey=None):
-        ssh_timeout = TempestConfig().compute.ssh_timeout
-        network = TempestConfig().compute.network_for_ssh
-        ip_version = TempestConfig().compute.ip_version_for_ssh
-        ssh_channel_timeout = TempestConfig().compute.ssh_channel_timeout
+        ssh_timeout = CONF.compute.ssh_timeout
+        network = CONF.compute.network_for_ssh
+        ip_version = CONF.compute.ip_version_for_ssh
+        ssh_channel_timeout = CONF.compute.ssh_channel_timeout
         if isinstance(server, basestring):
             ip_address = server
         else:
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index d2b40c9..aedba15 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -19,7 +19,7 @@
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 
-CONFIG = config.TempestConfig()
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -55,7 +55,7 @@
                 # responses
                 if str(task_state) == "None":
                     # without state api extension 3 sec usually enough
-                    time.sleep(CONFIG.compute.ready_wait)
+                    time.sleep(CONF.compute.ready_wait)
                     return
             else:
                 return
diff --git a/tempest/config.py b/tempest/config.py
index 79c32d0..140c521 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -20,10 +20,8 @@
 import os
 import sys
 
-
 from oslo.config import cfg
 
-from tempest.common.utils.misc import singleton
 from tempest.openstack.common import log as logging
 
 
@@ -646,8 +644,7 @@
 ]
 
 
-@singleton
-class TempestConfig:
+class TempestConfig(object):
     """Provides OpenStack configuration information."""
 
     DEFAULT_CONFIG_DIR = os.path.join(
@@ -658,6 +655,7 @@
 
     def __init__(self):
         """Initialize a configuration from a conf directory and conf file."""
+        super(TempestConfig, self).__init__()
         config_files = []
         failsafe_path = "/etc/tempest/" + self.DEFAULT_CONFIG_FILE
 
@@ -735,3 +733,16 @@
             self.compute_admin.username = self.identity.admin_username
             self.compute_admin.password = self.identity.admin_password
             self.compute_admin.tenant_name = self.identity.admin_tenant_name
+
+
+class TempestConfigProxy(object):
+    _config = None
+
+    def __getattr__(self, attr):
+        if not self._config:
+            self._config = TempestConfig()
+
+        return getattr(self._config, attr)
+
+
+CONF = TempestConfigProxy()
diff --git a/tempest/manager.py b/tempest/manager.py
index e3aeb31..42b8c8f 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -15,7 +15,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import tempest.config
+from tempest import config
 from tempest import exceptions
 
 
@@ -29,7 +29,7 @@
     """
 
     def __init__(self):
-        self.config = tempest.config.TempestConfig()
+        self.config = config.CONF
         self.client_attr_names = []
 
     # we do this everywhere, have it be part of the super class
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 915c642..33dd6c0 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -27,6 +27,7 @@
 from tempest.test import attr
 from tempest.test import services
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -142,8 +143,6 @@
 
     """
 
-    CONF = config.TempestConfig()
-
     @classmethod
     def check_preconditions(cls):
         super(TestNetworkBasicOps, cls).check_preconditions()
@@ -215,13 +214,13 @@
             self._create_server(name, network)
 
     def _check_tenant_network_connectivity(self):
-        if not self.config.network.tenant_networks_reachable:
+        if not CONF.network.tenant_networks_reachable:
             msg = 'Tenant networks not configured to be reachable.'
             LOG.info(msg)
             return
         # The target login is assumed to have been configured for
         # key-based authentication by cloud-init.
-        ssh_login = self.config.compute.image_ssh_user
+        ssh_login = CONF.compute.image_ssh_user
         try:
             for server, key in self.servers.items():
                 for net_name, ip_addresses in server.networks.iteritems():
@@ -239,13 +238,13 @@
 
         self.assertTrue(
             tempest.test.call_until_true(
-                ip_tracker.run_checks, self.config.compute.build_timeout,
-                self.config.compute.build_interval),
+                ip_tracker.run_checks, CONF.compute.build_timeout,
+                CONF.compute.build_interval),
             "Timed out while waiting for the floating IP assignments "
             "to propagate")
 
     def _create_and_associate_floating_ips(self):
-        public_network_id = self.config.network.public_network_id
+        public_network_id = CONF.network.public_network_id
         for server in self.servers.keys():
             floating_ip = self._create_floating_ip(server, public_network_id)
             self.floating_ips[floating_ip] = server
@@ -253,7 +252,7 @@
     def _check_public_network_connectivity(self, should_connect=True):
         # The target login is assumed to have been configured for
         # key-based authentication by cloud-init.
-        ssh_login = self.config.compute.image_ssh_user
+        ssh_login = CONF.compute.image_ssh_user
         try:
             for floating_ip, server in self.floating_ips.iteritems():
                 ip_address = floating_ip.floating_ip_address
diff --git a/tempest/test.py b/tempest/test.py
index ceb2c80..56c0554 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -33,6 +33,8 @@
 
 LOG = logging.getLogger(__name__)
 
+CONF = config.CONF
+
 # All the successful HTTP status codes from RFC 2616
 HTTP_SUCCESS = (200, 201, 202, 203, 204, 205, 206)
 
@@ -146,7 +148,7 @@
     """A function that will check the list of enabled extensions from config
 
     """
-    configs = config.TempestConfig()
+    configs = CONF
     config_dict = {
         'compute': configs.compute_feature_enabled.api_extensions,
         'compute_v3': configs.compute_feature_enabled.api_v3_extensions,
@@ -214,7 +216,7 @@
                    testtools.testcase.WithAttributes,
                    testresources.ResourcedTestCase):
 
-    config = config.TempestConfig()
+    config = CONF
 
     setUpClassCalled = False
 
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index 5ae21c8..2f7a650 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -29,7 +29,7 @@
 
 import tempest.clients
 from tempest.common.utils.file_utils import have_effective_read_access
-import tempest.config
+from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
@@ -37,6 +37,7 @@
 from tempest.thirdparty.boto.utils.wait import state_wait
 from tempest.thirdparty.boto.utils.wait import wait_exception
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
@@ -50,11 +51,10 @@
     def all_read(*args):
         return all(map(have_effective_read_access, args))
 
-    config = tempest.config.TempestConfig()
-    materials_path = config.boto.s3_materials_path
-    ami_path = materials_path + os.sep + config.boto.ami_manifest
-    aki_path = materials_path + os.sep + config.boto.aki_manifest
-    ari_path = materials_path + os.sep + config.boto.ari_manifest
+    materials_path = CONF.boto.s3_materials_path
+    ami_path = materials_path + os.sep + CONF.boto.ami_manifest
+    aki_path = materials_path + os.sep + CONF.boto.aki_manifest
+    ari_path = materials_path + os.sep + CONF.boto.ari_manifest
 
     A_I_IMAGES_READY = all_read(ami_path, aki_path, ari_path)
     boto_logger = logging.getLogger('boto')
@@ -70,7 +70,7 @@
         raise Exception("Unknown (Authentication?) Error")
     openstack = tempest.clients.Manager()
     try:
-        if urlparse.urlparse(config.boto.ec2_url).hostname is None:
+        if urlparse.urlparse(CONF.boto.ec2_url).hostname is None:
             raise Exception("Failed to get hostname from the ec2_url")
         ec2client = openstack.ec2api_client
         try:
@@ -87,7 +87,7 @@
         EC2_CAN_CONNECT_ERROR = str(exc)
 
     try:
-        if urlparse.urlparse(config.boto.s3_url).hostname is None:
+        if urlparse.urlparse(CONF.boto.s3_url).hostname is None:
             raise Exception("Failed to get hostname from the s3_url")
         s3client = openstack.s3_client
         try:
diff --git a/tempest/thirdparty/boto/utils/wait.py b/tempest/thirdparty/boto/utils/wait.py
index 1cd847b..db2303a 100644
--- a/tempest/thirdparty/boto/utils/wait.py
+++ b/tempest/thirdparty/boto/utils/wait.py
@@ -21,17 +21,12 @@
 import boto.exception
 from testtools import TestCase
 
-import tempest.config
+from tempest import config
 from tempest.openstack.common import log as logging
 
+CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
-_boto_config = tempest.config.TempestConfig().boto
-
-default_timeout = _boto_config.build_timeout
-
-default_check_interval = _boto_config.build_interval
-
 
 def state_wait(lfunction, final_set=set(), valid_set=None):
     # TODO(afazekas): evaluate using ABC here
@@ -50,12 +45,12 @@
         if valid_set is not None and status not in valid_set:
             return status
         dtime = time.time() - start_time
-        if dtime > default_timeout:
+        if dtime > CONF.boto.build_timeout:
             raise TestCase.failureException("State change timeout exceeded!"
                                             '(%ds) While waiting'
                                             'for %s at "%s"' %
                                             (dtime, final_set, status))
-        time.sleep(default_check_interval)
+        time.sleep(CONF.boto.build_interval)
         old_status = status
         status = lfunction()
 
@@ -73,12 +68,12 @@
                      text)
             return result
         dtime = time.time() - start_time
-        if dtime > default_timeout:
+        if dtime > CONF.boto.build_timeout:
             raise TestCase.failureException('Pattern find timeout exceeded!'
                                             '(%ds) While waiting for'
                                             '"%s" pattern in "%s"' %
                                             (dtime, regexp, text))
-        time.sleep(default_check_interval)
+        time.sleep(CONF.boto.build_interval)
 
 
 def wait_no_exception(lfunction, exc_class=None, exc_matcher=None):
@@ -104,10 +99,10 @@
                     raise exc
         # Let the other exceptions propagate
         dtime = time.time() - start_time
-        if dtime > default_timeout:
+        if dtime > CONF.boto.build_timeout:
             raise TestCase.failureException("Wait timeout exceeded! (%ds)" %
                                             dtime)
-        time.sleep(default_check_interval)
+        time.sleep(CONF.boto.build_interval)
 
 
 # NOTE(afazekas): EC2/boto normally raise exception instead of empty list
@@ -122,9 +117,9 @@
                      time.time() - start_time)
             return exc
         dtime = time.time() - start_time
-        if dtime > default_timeout:
+        if dtime > CONF.boto.build_timeout:
             raise TestCase.failureException("Wait timeout exceeded! (%ds)" %
                                             dtime)
-        time.sleep(default_check_interval)
+        time.sleep(CONF.boto.build_interval)
 
 # TODO(afazekas): consider strategy design pattern..
diff --git a/tools/verify_tempest_config.py b/tools/verify_tempest_config.py
index 347659d..8850c2e 100755
--- a/tools/verify_tempest_config.py
+++ b/tools/verify_tempest_config.py
@@ -21,7 +21,7 @@
 from tempest import config
 
 
-CONF = config.TempestConfig()
+CONF = config.CONF
 
 #Dicts matching extension names to config options
 NOVA_EXTENSIONS = {