General test cleanup

- removal of unnecessary code
- update usage of create_image_enabled in image test
- rewriting image metadata tests
- fixing test_images skip
- add exceptions.ComputeFault
- fix server actions teardown
- fixing rebuild name verification
- rewriting server metadata tests

Change-Id: I03f29d864c456cbc78ca6d6dae25cacbcdf2b0d9
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 17f1e42..bcdc758 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -3,7 +3,6 @@
 import httplib2
 
 from tempest import exceptions
-import tempest.config
 
 
 class RestClient(object):
diff --git a/tempest/config.py b/tempest/config.py
index 8fa3ee5..4b90932 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -133,13 +133,23 @@
 class TempestConfig(object):
     """Provides OpenStack configuration information."""
 
-    def __init__(self, conf_dir, conf_file):
-        """
-        Initialize a configuration from a conf directory and conf file.
+    DEFAULT_CONFIG_DIR = os.path.join(
+        os.path.abspath(
+          os.path.dirname(
+            os.path.dirname(__file__))),
+        "etc")
 
-        :param conf_dir: Directory to look for config files
-        :param conf_file: Name of config file to use
-        """
+    DEFAULT_CONFIG_FILE = "tempest.conf"
+
+    def __init__(self):
+        """Initialize a configuration from a conf directory and conf file."""
+
+        # Environment variables override defaults...
+        conf_dir = os.environ.get('TEMPEST_CONFIG_DIR',
+            self.DEFAULT_CONFIG_DIR)
+        conf_file = os.environ.get('TEMPEST_CONFIG',
+            self.DEFAULT_CONFIG_FILE)
+
         path = os.path.join(conf_dir, conf_file)
 
         if not os.path.exists(path):
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index d9babb2..180f13a 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -32,3 +32,11 @@
 
     def __str__(self):
         return repr(self.message)
+
+
+class ComputeFault(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return repr(self.message)
diff --git a/tempest/openstack.py b/tempest/openstack.py
index b1e22ad..1d46f00 100644
--- a/tempest/openstack.py
+++ b/tempest/openstack.py
@@ -1,33 +1,17 @@
-import os
-
 from tempest.services.nova.json.images_client import ImagesClient
 from tempest.services.nova.json.flavors_client import FlavorsClient
 from tempest.services.nova.json.servers_client import ServersClient
 from tempest.services.nova.json.limits_client import LimitsClient
-from tempest.common.utils import data_utils
 import tempest.config
 
 
 class Manager(object):
 
-    DEFAULT_CONFIG_DIR = os.path.join(
-        os.path.abspath(
-          os.path.dirname(
-            os.path.dirname(__file__))),
-        "etc")
-
-    DEFAULT_CONFIG_FILE = "tempest.conf"
-
     def __init__(self):
         """
         Top level manager for all Openstack APIs
         """
-        # Environment variables override defaults...
-        config_dir = os.environ.get('TEMPEST_CONFIG_DIR',
-            self.DEFAULT_CONFIG_DIR)
-        config_file = os.environ.get('TEMPEST_CONFIG',
-            self.DEFAULT_CONFIG_FILE)
-        self.config = tempest.config.TempestConfig(config_dir, config_file)
+        self.config = tempest.config.TempestConfig()
 
         if self.config.env.authentication == 'keystone_v2':
             self.servers_client = ServersClient(self.config,
diff --git a/tempest/services/nova/json/servers_client.py b/tempest/services/nova/json/servers_client.py
index 502da72..9baa280 100644
--- a/tempest/services/nova/json/servers_client.py
+++ b/tempest/services/nova/json/servers_client.py
@@ -208,7 +208,7 @@
                                       str(server_id), post_body,
                                       self.headers)
         body = json.loads(body)
-        return resp, body
+        return resp, body['server']
 
     def resize(self, server_id, flavor_ref):
         """Changes the flavor of a server."""
diff --git a/tempest/tests/test_image_metadata.py b/tempest/tests/test_image_metadata.py
index b533a1b..23f0689 100644
--- a/tempest/tests/test_image_metadata.py
+++ b/tempest/tests/test_image_metadata.py
@@ -1,7 +1,5 @@
-from nose.plugins.attrib import attr
 from tempest import openstack
 from tempest.common.utils.data_utils import rand_name
-import tempest.config
 import unittest2 as unittest
 
 
@@ -18,75 +16,59 @@
         cls.ssh_timeout = cls.config.nova.ssh_timeout
 
         name = rand_name('server')
-        resp, cls.server = cls.servers_client.create_server(name,
-                                                            cls.image_ref,
-                                                            cls.flavor_ref)
+        resp, server = cls.servers_client.create_server(name, cls.image_ref,
+                                                        cls.flavor_ref)
+        cls.server_id = server['id']
+
         #Wait for the server to become active
-        cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
+        cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
+
+        # Snapshot the server once to save time
+        name = rand_name('image')
+        resp, _ = cls.client.create_image(cls.server_id, name, {})
+        cls.image_id = resp['location'].rsplit('/', 1)[1]
+
+        cls.client.wait_for_image_resp_code(cls.image_id, 200)
+        cls.client.wait_for_image_status(cls.image_id, 'ACTIVE')
 
     @classmethod
     def tearDownClass(cls):
-        cls.servers_client.delete_server(cls.server['id'])
+        cls.client.delete_image(cls.image_id)
+        cls.servers_client.delete_server(cls.server_id)
 
     def setUp(self):
         meta = {'key1': 'value1', 'key2': 'value2'}
-        name = rand_name('image')
-        resp, body = self.client.create_image(self.server['id'], name, meta)
-        image_ref = resp['location']
-        temp = image_ref.rsplit('/')
-        image_id = temp[6]
-
-        self.client.wait_for_image_resp_code(image_id, 200)
-        self.client.wait_for_image_status(image_id, 'ACTIVE')
-        resp, self.image = self.client.get_image(image_id)
-
-    def tearDown(self):
-        self.client.delete_image(self.image['id'])
-
-    def _parse_image_id(self, image_ref):
-        temp = image_ref.rsplit('/')
-        return len(temp) - 1
+        resp, _ = self.client.set_image_metadata(self.image_id, meta)
+        self.assertEqual(resp.status, 200)
 
     def test_list_image_metadata(self):
         """All metadata key/value pairs for an image should be returned"""
-        resp, metadata = self.client.list_image_metadata(self.image['id'])
-        self.assertEqual('value1', metadata['key1'])
-        self.assertEqual('value2', metadata['key2'])
+        resp, resp_metadata = self.client.list_image_metadata(self.image_id)
+        expected = {'key1': 'value1', 'key2': 'value2'}
+        self.assertEqual(expected, resp_metadata)
 
     def test_set_image_metadata(self):
         """The metadata for the image should match the new values"""
-        meta = {'meta1': 'data1'}
-        name = rand_name('image')
-        resp, body = self.client.create_image(self.server['id'], name, meta)
-        image_id = self._parse_image_id(resp['location'])
-        self.client.wait_for_image_resp_code(image_id, 200)
-        self.client.wait_for_image_status(image_id, 'ACTIVE')
-        resp, image = self.client.get_image(image_id)
+        req_metadata = {'meta2': 'value2', 'meta3': 'value3'}
+        resp, body = self.client.set_image_metadata(self.image_id,
+                                                    req_metadata)
 
-        meta = {'meta2': 'data2', 'meta3': 'data3'}
-        resp, body = self.client.set_image_metadata(image['id'], meta)
-
-        resp, metadata = self.client.list_image_metadata(image['id'])
-        self.assertEqual('data2', metadata['meta2'])
-        self.assertEqual('data3', metadata['meta3'])
-        self.assertTrue('key1' not in metadata)
-
-        self.servers_client.delete_server(server['id'])
-        self.client.delete_image(image['id'])
+        resp, resp_metadata = self.client.list_image_metadata(self.image_id)
+        self.assertEqual(req_metadata, resp_metadata)
 
     def test_update_image_metadata(self):
         """The metadata for the image should match the updated values"""
-        meta = {'key1': 'alt1', 'key2': 'alt2'}
-        resp, metadata = self.client.update_image_metadata(self.image['id'],
-                                                           meta)
+        req_metadata = {'key1': 'alt1', 'key3': 'value3'}
+        resp, metadata = self.client.update_image_metadata(self.image_id,
+                                                           req_metadata)
 
-        resp, metadata = self.client.list_image_metadata(self.image['id'])
-        self.assertEqual('alt1', metadata['key1'])
-        self.assertEqual('alt2', metadata['key2'])
+        resp, resp_metadata = self.client.list_image_metadata(self.image_id)
+        expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
+        self.assertEqual(expected, resp_metadata)
 
     def test_get_image_metadata_item(self):
-        """The value for a specic metadata key should be returned"""
-        resp, meta = self.client.get_image_metadata_item(self.image['id'],
+        """The value for a specific metadata key should be returned"""
+        resp, meta = self.client.get_image_metadata_item(self.image_id,
                                                          'key2')
         self.assertTrue('value2', meta['key2'])
 
@@ -95,14 +77,16 @@
         The value provided for the given meta item should be set for the image
         """
         meta = {'key1': 'alt'}
-        resp, body = self.client.set_image_metadata_item(self.image['id'],
+        resp, body = self.client.set_image_metadata_item(self.image_id,
                                                          'key1', meta)
-        resp, metadata = self.client.list_image_metadata(self.image['id'])
-        self.assertEqual('alt', metadata['key1'])
+        resp, resp_metadata = self.client.list_image_metadata(self.image_id)
+        expected = {'key1': 'alt', 'key2': 'value2'}
+        self.assertEqual(expected, resp_metadata)
 
     def test_delete_image_metadata_item(self):
         """The metadata value/key pair should be deleted from the image"""
-        resp, body = self.client.delete_image_metadata_item(self.image['id'],
+        resp, body = self.client.delete_image_metadata_item(self.image_id,
                                                             'key1')
-        resp, metadata = self.client.list_image_metadata(self.image['id'])
-        self.assertTrue('key1' not in metadata)
+        resp, resp_metadata = self.client.list_image_metadata(self.image_id)
+        expected = {'key2': 'value2'}
+        self.assertEqual(expected, resp_metadata)
diff --git a/tempest/tests/test_images.py b/tempest/tests/test_images.py
index 7f4c451..bb8dc68 100644
--- a/tempest/tests/test_images.py
+++ b/tempest/tests/test_images.py
@@ -1,15 +1,21 @@
 from nose.plugins.attrib import attr
-from tempest import openstack
-from tempest.common.utils.data_utils import rand_name
 import unittest2 as unittest
-import tempest.config
 
-# Some module-level skip conditions
-create_image_enabled = False
+from tempest.common.utils.data_utils import rand_name
+import tempest.config
+from tempest import openstack
+
+
+def _parse_image_id(image_ref):
+    temp = image_ref.rsplit('/')
+    return temp[6]
 
 
 class ImagesTest(unittest.TestCase):
 
+    create_image_enabled = tempest.config.TempestConfig().\
+            env.create_image_enabled
+
     @classmethod
     def setUpClass(cls):
         cls.os = openstack.Manager()
@@ -18,15 +24,11 @@
         cls.config = cls.os.config
         cls.image_ref = cls.config.env.image_ref
         cls.flavor_ref = cls.config.env.flavor_ref
-        create_image_enabled = cls.config.env.create_image_enabled
+        cls.create_image_enabled = cls.config.env.create_image_enabled
 
-    def _parse_image_id(self, image_ref):
-        temp = image_ref.rsplit('/')
-        return temp[6]
-
-    @unittest.skipIf(not imaging_enabled,
-                    'Environment unable to create images.')
     @attr(type='smoke')
+    @unittest.skipUnless(create_image_enabled,
+                         'Environment unable to create images.')
     def test_create_delete_image(self):
         """An image for the provided server should be created"""
         server_name = rand_name('server')
@@ -39,7 +41,7 @@
         name = rand_name('image')
         meta = {'image_type': 'test'}
         resp, body = self.client.create_image(server['id'], name, meta)
-        image_id = self._parse_image_id(resp['location'])
+        image_id = _parse_image_id(resp['location'])
         self.client.wait_for_image_resp_code(image_id, 200)
         self.client.wait_for_image_status(image_id, 'ACTIVE')
 
diff --git a/tempest/tests/test_server_actions.py b/tempest/tests/test_server_actions.py
index 3ae9dd8..0d58fb0 100644
--- a/tempest/tests/test_server_actions.py
+++ b/tempest/tests/test_server_actions.py
@@ -1,12 +1,15 @@
-from nose.plugins.attrib import attr
-from tempest import openstack
-from tempest.common.utils.data_utils import rand_name
-import unittest2 as unittest
-import tempest.config
 import base64
 
+from nose.plugins.attrib import attr
+import unittest2 as unittest
+
+from tempest.common.utils.data_utils import rand_name
+import tempest.config
+from tempest import openstack
+
 
 class ServerActionsTest(unittest.TestCase):
+
     resize_available = tempest.config.TempestConfig().env.resize_available
 
     @classmethod
@@ -27,7 +30,7 @@
         self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
 
     def tearDown(self):
-        self.client.delete_server(self.id)
+        self.client.delete_server(self.server['id'])
 
     @attr(type='smoke')
     def test_change_server_password(self):
@@ -54,14 +57,14 @@
     def test_rebuild_server(self):
         """ The server should be rebuilt using the provided image and data """
         meta = {'rebuild': 'server'}
-        name = rand_name('server')
+        new_name = rand_name('server')
         file_contents = 'Test server rebuild.'
         personality = [{'path': '/etc/rebuild.txt',
                        'contents': base64.b64encode(file_contents)}]
 
         resp, rebuilt_server = self.client.rebuild(self.server['id'],
                                                    self.image_ref_alt,
-                                                   name=name, meta=meta,
+                                                   name=new_name, meta=meta,
                                                    personality=personality,
                                                    adminPass='rebuild')
 
@@ -74,7 +77,7 @@
         self.client.wait_for_server_status(rebuilt_server['id'], 'ACTIVE')
         resp, server = self.client.get_server(rebuilt_server['id'])
         self.assertEqual(self.image_ref_alt, rebuilt_server['image']['id'])
-        self.assertEqual('rebuiltserver', rebuilt_server['name'])
+        self.assertEqual(new_name, rebuilt_server['name'])
 
     @attr(type='smoke')
     @unittest.skipIf(not resize_available, 'Resize not available.')
diff --git a/tempest/tests/test_server_metadata.py b/tempest/tests/test_server_metadata.py
index 5ec826b..64bedb9 100644
--- a/tempest/tests/test_server_metadata.py
+++ b/tempest/tests/test_server_metadata.py
@@ -1,8 +1,6 @@
-from nose.plugins.attrib import attr
 from tempest import openstack
 from tempest.common.utils.data_utils import rand_name
 import unittest2 as unittest
-import tempest.config
 
 
 class ServerMetadataTest(unittest.TestCase):
@@ -16,117 +14,86 @@
         cls.flavor_ref = cls.config.env.flavor_ref
 
         #Create a server to be used for all read only tests
-        cls.meta = {'test1': 'value1', 'test2': 'value2'}
         name = rand_name('server')
-        resp, cls.server = cls.client.create_server(name, cls.image_ref,
-                                                cls.flavor_ref, meta=cls.meta)
+        resp, server = cls.client.create_server(name, cls.image_ref,
+                                                cls.flavor_ref, meta={})
+        cls.server_id = server['id']
 
         #Wait for the server to become active
-        cls.client.wait_for_server_status(cls.server['id'], 'ACTIVE')
+        cls.client.wait_for_server_status(cls.server_id, 'ACTIVE')
 
     @classmethod
     def tearDownClass(cls):
-        cls.client.delete_server(cls.server['id'])
+        cls.client.delete_server(cls.server_id)
+
+    def setUp(self):
+        meta = {'key1': 'value1', 'key2': 'value2'}
+        resp, _ = self.client.set_server_metadata(self.server_id, meta)
+        self.assertEqual(resp.status, 200)
 
     def test_list_server_metadata(self):
         """All metadata key/value pairs for a server should be returned"""
-        resp, metadata = self.client.list_server_metadata(self.server['id'])
+        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
 
         #Verify the expected metadata items are in the list
         self.assertEqual(200, resp.status)
-        self.assertEqual('value1', metadata['test1'])
-        self.assertEqual('value2', metadata['test2'])
+        expected = {'key1': 'value1', 'key2': 'value2'}
+        self.assertEqual(expected, resp_metadata)
 
     def test_set_server_metadata(self):
         """The server's metadata should be replaced with the provided values"""
-        meta = {'meta1': 'data1'}
-        name = rand_name('server')
-        resp, server = self.client.create_server(name, self.image_ref,
-                                                self.flavor_ref, meta=meta)
-        self.client.wait_for_server_status(server['id'], 'ACTIVE')
-
         #Create a new set of metadata for the server
-        meta = {'meta2': 'data2', 'meta3': 'data3'}
-        resp, metadata = self.client.set_server_metadata(server['id'], meta)
+        req_metadata = {'meta2': 'data2', 'meta3': 'data3'}
+        resp, metadata = self.client.set_server_metadata(self.server_id,
+                                                         req_metadata)
         self.assertEqual(200, resp.status)
 
         #Verify the expected values are correct, and that the
         #previous values have been removed
-        resp, body = self.client.list_server_metadata(server['id'])
-        self.assertEqual('data2', metadata['meta2'])
-        self.assertEqual('data3', metadata['meta3'])
-        self.assertTrue('meta1' not in metadata)
-
-        #Teardown
-        self.client.delete_server(server['id'])
+        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        self.assertEqual(resp_metadata, req_metadata)
 
     def test_update_server_metadata(self):
         """
         The server's metadata values should be updated to the
         provided values
         """
-        meta = {'key1': 'value1', 'key2': 'value2'}
-        name = rand_name('server')
-        resp, server = self.client.create_server(name, self.image_ref,
-                                                self.flavor_ref, meta=meta)
-        self.client.wait_for_server_status(server['id'], 'ACTIVE')
-
-        #Update all metadata items for the server
-        meta = {'key1': 'alt1', 'key2': 'alt2'}
-        resp, metadata = self.client.update_server_metadata(server['id'], meta)
+        meta = {'key1': 'alt1', 'key3': 'value3'}
+        resp, metadata = self.client.update_server_metadata(self.server_id,
+                                                            meta)
         self.assertEqual(200, resp.status)
 
         #Verify the values have been updated to the proper values
-        resp, body = self.client.list_server_metadata(server['id'])
-        self.assertEqual('alt1', metadata['key1'])
-        self.assertEqual('alt2', metadata['key2'])
-
-        #Teardown
-        self.client.delete_server(server['id'])
+        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        expected = {'key1': 'alt1', 'key2': 'value2', 'key3': 'value3'}
+        self.assertEqual(expected, resp_metadata)
 
     def test_get_server_metadata_item(self):
         """ The value for a specic metadata key should be returned """
-        resp, meta = self.client.get_server_metadata_item(self.server['id'],
-                                                          'test2')
-        self.assertTrue('value2', meta['test2'])
+        resp, meta = self.client.get_server_metadata_item(self.server_id,
+                                                          'key2')
+        self.assertTrue('value2', meta['key2'])
 
     def test_set_server_metadata_item(self):
         """The item's value should be updated to the provided value"""
-        meta = {'nova': 'server'}
-        name = rand_name('server')
-        resp, server = self.client.create_server(name, self.image_ref,
-                                                self.flavor_ref, meta=meta)
-        self.client.wait_for_server_status(server['id'], 'ACTIVE')
-
         #Update the metadata value
         meta = {'nova': 'alt'}
-        resp, body = self.client.set_server_metadata_item(server['id'],
+        resp, body = self.client.set_server_metadata_item(self.server_id,
                                                           'nova', meta)
         self.assertEqual(200, resp.status)
 
         #Verify the meta item's value has been updated
-        resp, body = self.client.list_server_metadata(server['id'])
-        self.assertEqual('alt', metadata['nova'])
-
-        #Teardown
-        self.client.delete_server(server.id)
+        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        expected = {'key1': 'value1', 'key2': 'value2', 'nova': 'alt'}
+        self.assertEqual(expected, resp_metadata)
 
     def test_delete_server_metadata_item(self):
         """The metadata value/key pair should be deleted from the server"""
-        meta = {'delkey': 'delvalue'}
-        name = rand_name('server')
-        resp, server = self.client.create_server(name, self.image_ref,
-                                                self.flavor_ref, meta=meta)
-        self.client.wait_for_server_status(server['id'], 'ACTIVE')
-
-        #Delete the metadata item
-        resp, metadata = self.client.delete_server_metadata_item(server['id'],
-                                                                 'delkey')
+        resp, meta = self.client.delete_server_metadata_item(self.server_id,
+                                                             'key1')
         self.assertEqual(204, resp.status)
 
         #Verify the metadata item has been removed
-        resp, metadata = self.client.list_server_metadata(server['id'])
-        self.assertTrue('delkey' not in metadata)
-
-        #Teardown
-        self.client.delete_server(server['id'])
+        resp, resp_metadata = self.client.list_server_metadata(self.server_id)
+        expected = {'key2': 'value2'}
+        self.assertEqual(expected, resp_metadata)