Changes the namespace from storm to tempest, as well as adding addition tests and improvements
* Changed namespace from storm to tempest
* Added absolute limits service and server personality file tests
* Optimized run time for image metadata tests
* Added additional assertions for create server and rebuild server tests
* Removed any SSH verification until further decisions are made

Change-Id: I5bebd29be382c9404914c7314302670ae09627fc
diff --git a/etc/STORM_README.txt b/etc/TEMPEST_README.txt
similarity index 69%
rename from etc/STORM_README.txt
rename to etc/TEMPEST_README.txt
index d445896..e46e195 100644
--- a/etc/STORM_README.txt
+++ b/etc/TEMPEST_README.txt
@@ -1,8 +1,8 @@
 To run:
--rename the /etc/storm.conf.sample file to storm.conf
+-rename the /etc/tempest.conf.sample file to tempest.conf
 -Set the fields in the file to values relevant to your system
 -Set the "authentication" value (basic or keystone_v2 currently supported)
--from the root directory of the project, run "nosetests storm/tests" to
+-from the root directory of the project, run "nosetests tempest/tests" to
  run all tests
 
 TODO:
diff --git a/etc/storm.conf.sample b/etc/tempest.conf.sample
similarity index 100%
rename from etc/storm.conf.sample
rename to etc/tempest.conf.sample
diff --git a/storm/tests/test_image_metadata.py b/storm/tests/test_image_metadata.py
deleted file mode 100644
index c8dff27..0000000
--- a/storm/tests/test_image_metadata.py
+++ /dev/null
@@ -1,158 +0,0 @@
-from nose.plugins.attrib import attr
-from storm import openstack
-from storm.common.utils.data_utils import rand_name
-import storm.config
-import unittest2 as unittest
-
-
-class ImagesMetadataTest(unittest.TestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.os = openstack.Manager()
-        cls.servers_client = cls.os.servers_client
-        cls.client = cls.os.images_client
-        cls.config = cls.os.config
-        cls.image_ref = cls.config.env.image_ref
-        cls.flavor_ref = cls.config.env.flavor_ref
-        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)
-        #Wait for the server to become active
-        cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
-
-        #Create an image from the server
-        name = rand_name('image')
-        cls.meta = {'key1': 'value1', 'key2': 'value2'}
-        resp, body = cls.client.create_image(cls.server['id'], name, cls.meta)
-        image_ref = resp['location']
-        temp = image_ref.rsplit('/')
-        image_id = temp[len(temp) - 1]
-
-        cls.client.wait_for_image_resp_code(image_id, 200)
-        cls.client.wait_for_image_status(image_id, 'ACTIVE')
-        resp, cls.image = cls.client.get_image(image_id)
-
-    @classmethod
-    def tearDownClass(cls):
-        cls.servers_client.delete_server(cls.server['id'])
-        cls.client.delete_image(cls.image['id'])
-
-    def _parse_image_id(self, image_ref):
-        temp = image_ref.rsplit('/')
-        return len(temp) - 1
-
-    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'])
-
-    def test_set_image_metadata(self):
-        """The metadata for the image should match the new values"""
-        meta = {'meta1': 'data1'}
-        name = rand_name('server')
-        resp, server = self.servers_client.create_server(name, self.image_ref,
-                                                self.flavor_ref)
-        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
-        name = rand_name('image')
-        resp, body = self.client.create_image(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)
-
-        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('meta1' not in metadata)
-
-        self.servers_client.delete_server(server['id'])
-        self.client.delete_image(image['id'])
-
-    def test_update_image_metadata(self):
-        """The metadata for the image should match the updated values"""
-        meta = {'key1': 'value1', 'key2': 'value2'}
-        name = rand_name('server')
-        resp, server = self.servers_client.create_server(name, self.image_ref,
-                                                self.flavor_ref)
-        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
-        name = rand_name('image')
-        resp, body = self.client.create_image(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)
-
-        meta = {'key1': 'alt1', 'key2': 'alt2'}
-        resp, metadata = self.client.update_image_metadata(image['id'], meta)
-
-        resp, metadata = self.client.list_image_metadata(image['id'])
-        self.assertEqual('alt1', metadata['key1'])
-        self.assertEqual('alt2', metadata['key2'])
-
-        self.servers_client.delete_server(server['id'])
-        self.client.delete_image(image['id'])
-
-    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'],
-                                                         'key2')
-        self.assertTrue('value2', meta['key2'])
-
-    def test_set_image_metadata_item(self):
-        """
-        The value provided for the given meta item should be set for the image
-        """
-        meta = {'nova': 'server'}
-        name = rand_name('server')
-        resp, server = self.servers_client.create_server(name, self.image_ref,
-                                                self.flavor_ref)
-        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
-        name = rand_name('image')
-        resp, body = self.client.create_image(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)
-
-        meta = {'nova': 'alt'}
-        resp, body = self.client.set_image_metadata_item(image['id'],
-                                                         'nova', meta)
-        resp, metadata = self.client.list_image_metadata(image['id'])
-        self.assertEqual('alt', metadata['nova'])
-
-        self.servers_client.delete_server(server['id'])
-        self.client.delete_image(image['id'])
-
-    def test_delete_image_metadata_item(self):
-        """The metadata value/key pair should be deleted from the image"""
-        meta = {'delkey': 'delvalue'}
-        name = rand_name('server')
-        resp, server = self.servers_client.create_server(name, self.image_ref,
-                                                self.flavor_ref)
-        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
-
-        name = rand_name('image')
-        resp, body = self.client.create_image(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)
-
-        resp, body = self.client.delete_image_metadata_item(image['id'],
-                                                            'delkey')
-        resp, metadata = self.client.list_image_metadata(image['id'])
-        self.assertTrue('delkey' not in metadata)
-
-        self.servers_client.delete_server(server['id'])
-        self.client.delete_image(image['id'])
diff --git a/storm/tests/test_server_actions.py b/storm/tests/test_server_actions.py
deleted file mode 100644
index d7c9db4..0000000
--- a/storm/tests/test_server_actions.py
+++ /dev/null
@@ -1,98 +0,0 @@
-from nose.plugins.attrib import attr
-from storm import openstack
-import unittest2 as unittest
-import storm.config
-from storm.common.utils.data_utils import rand_name
-
-# Some module-level skip conditions
-resize_available = False
-
-class ServerActionsTest(unittest.TestCase):
-
-    @classmethod
-    def setUpClass(cls):
-        cls.os = openstack.Manager()
-        cls.client = cls.os.servers_client
-        cls.config = cls.os.config
-        cls.image_ref = cls.config.env.image_ref
-        cls.image_ref_alt = cls.config.env.image_ref_alt
-        cls.flavor_ref = cls.config.env.flavor_ref
-        cls.flavor_ref_alt = cls.config.env.flavor_ref_alt
-        resize_available = cls.config.env.resize_available
-
-    def setUp(self):
-        self.name = rand_name('server')
-        resp, server = self.client.create_server(self.name, self.image_ref,
-                                                 self.flavor_ref)
-        self.id = server['id']
-        self.client.wait_for_server_status(self.id, 'ACTIVE')
-
-    def tearDown(self):
-        self.client.delete_server(self.id)
-
-    @attr(type='smoke')
-    def test_change_server_password(self):
-        """The server's password should be set to the provided password"""
-        resp, body = self.client.change_password(self.id, 'newpass')
-        self.client.wait_for_server_status(self.id, 'ACTIVE')
-        #TODO: SSH in to verify the new password works
-
-    @attr(type='smoke')
-    def test_reboot_server_hard(self):
-        """ The server should be power cycled """
-        #TODO: Add validation the server has been rebooted
-
-        resp, body = self.client.reboot(self.id, 'HARD')
-        self.client.wait_for_server_status(self.id, 'ACTIVE')
-
-    @attr(type='smoke')
-    def test_reboot_server_soft(self):
-        """The server should be signaled to reboot gracefully"""
-        #TODO: Add validation the server has been rebooted
-
-        resp, body = self.client.reboot(self.id, 'SOFT')
-        self.client.wait_for_server_status(self.id, 'ACTIVE')
-
-    @attr(type='smoke')
-    def test_rebuild_server(self):
-        """The server should be rebuilt using the provided image"""
-
-        self.client.rebuild(self.id, self.image_ref_alt, name='rebuiltserver')
-        self.client.wait_for_server_status(self.id, 'ACTIVE')
-        resp, server = self.client.get_server(self.id)
-        self.assertEqual(self.image_ref_alt, server['image']['id'])
-        self.assertEqual('rebuiltserver', server['name'])
-
-    @attr(type='smoke')
-    @unittest.skipIf(not resize_available, 'Resize not available.')
-    def test_resize_server_confirm(self):
-        """
-        The server's RAM and disk space should be modified to that of
-        the provided flavor
-        """
-
-        self.client.resize(self.id, self.flavor_ref_alt)
-        self.client.wait_for_server_status(self.id, 'VERIFY_RESIZE')
-
-        self.client.confirm_resize(self.id)
-        self.client.wait_for_server_status(self.id, 'ACTIVE')
-
-        resp, server = self.client.get_server(self.id)
-        self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
-
-    @attr(type='smoke')
-    @unittest.skipIf(not resize_available, 'Resize not available.')
-    def test_resize_server_revert(self):
-        """
-        The server's RAM and disk space should return to its original
-        values after a resize is reverted
-        """
-
-        self.client.resize(self.id, self.flavor_ref_alt)
-        self.client.wait_for_server_status(id, 'VERIFY_RESIZE')
-
-        self.client.revert_resize(self.id)
-        self.client.wait_for_server_status(id, 'ACTIVE')
-
-        resp, server = self.client.get_server(id)
-        self.assertEqual(self.flavor_ref, server['flavor']['id'])
diff --git a/storm/__init__.py b/tempest/__init__.py
similarity index 100%
rename from storm/__init__.py
rename to tempest/__init__.py
diff --git a/storm/common/__init__.py b/tempest/common/__init__.py
similarity index 100%
rename from storm/common/__init__.py
rename to tempest/common/__init__.py
diff --git a/storm/common/rest_client.py b/tempest/common/rest_client.py
similarity index 90%
rename from storm/common/rest_client.py
rename to tempest/common/rest_client.py
index 170e523..94e44e4 100644
--- a/storm/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -2,8 +2,8 @@
 
 import httplib2
 
-from storm import exceptions
-import storm.config
+from tempest import exceptions
+import tempest.config
 
 
 class RestClient(object):
@@ -102,4 +102,12 @@
             body = json.loads(body)
             raise exceptions.BadRequest(body['badRequest']['message'])
 
+        if resp.status == 413:
+            body = json.loads(body)
+            raise exceptions.OverLimit(body['overLimit']['message'])
+            
+        if resp.status in (500, 501):
+            body = json.loads(body)
+            raise exceptions.ComputeFault(body['computeFault']['message'])
+
         return resp, body
diff --git a/storm/common/ssh.py b/tempest/common/ssh.py
similarity index 100%
rename from storm/common/ssh.py
rename to tempest/common/ssh.py
diff --git a/storm/common/utils/__init__.py b/tempest/common/utils/__init__.py
similarity index 100%
rename from storm/common/utils/__init__.py
rename to tempest/common/utils/__init__.py
diff --git a/storm/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
similarity index 100%
rename from storm/common/utils/data_utils.py
rename to tempest/common/utils/data_utils.py
diff --git a/storm/config.py b/tempest/config.py
similarity index 98%
rename from storm/config.py
rename to tempest/config.py
index 42b9894..2bbadc7 100644
--- a/storm/config.py
+++ b/tempest/config.py
@@ -120,9 +120,10 @@
         return self.get("authentication", 'keystone')
 
 
-class StormConfig(object):
+class TempestConfig(object):
     """Provides OpenStack configuration information."""
 
+
     def __init__(self, conf_dir, conf_file):
         """
         Initialize a configuration from a conf directory and conf file.
diff --git a/storm/exceptions.py b/tempest/exceptions.py
similarity index 78%
rename from storm/exceptions.py
rename to tempest/exceptions.py
index 9290cf7..b4d056d 100644
--- a/storm/exceptions.py
+++ b/tempest/exceptions.py
@@ -16,10 +16,18 @@
 
     def __str__(self):
         return repr(self.message)
-
-
+        
+        
 class AuthenticationFailure(Exception):
     msg = ("Authentication with user %(user)s and password "
            "%(password)s failed.")
     def __init__(self, **kwargs):
         self.message = self.msg % kwargs
+
+
+class OverLimit(Exception):
+    def __init__(self, message):
+        self.message = message
+
+    def __str__(self):
+        return repr(self.message)
diff --git a/storm/openstack.py b/tempest/openstack.py
similarity index 74%
rename from storm/openstack.py
rename to tempest/openstack.py
index 78f8c03..15cfaf9 100644
--- a/storm/openstack.py
+++ b/tempest/openstack.py
@@ -1,10 +1,11 @@
 import os
 
-from storm.services.nova.json.images_client import ImagesClient
-from storm.services.nova.json.flavors_client import FlavorsClient
-from storm.services.nova.json.servers_client import ServersClient
-from storm.common.utils import data_utils
-import storm.config
+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):
@@ -48,6 +49,12 @@
                                               self.config.nova.api_key,
                                               self.auth_url,
                                               self.config.nova.tenant_name)
+            self.limits_client = LimitsClient(self.config,
+                                              self.config.nova.username,
+                                              self.config.nova.api_key,
+                                              self.auth_url,
+                                              self.config.nova.tenant_name)
+            
         else:
             #Assuming basic/native authentication
             self.servers_client = ServersClient(self.config,
@@ -63,3 +70,8 @@
                                               self.config.nova.auth_url,
                                               self.config.nova.api_key,
                                               self.auth_url)
+            self.limits_client = LimitsClient(self.config,
+                                              self.config.nova.username,
+                                              self.config.nova.auth_url,
+                                              self.config.nova.api_key,
+                                              self.auth_url)
diff --git a/storm/services/__init__.py b/tempest/services/__init__.py
similarity index 100%
rename from storm/services/__init__.py
rename to tempest/services/__init__.py
diff --git a/storm/services/nova/__init__.py b/tempest/services/nova/__init__.py
similarity index 100%
rename from storm/services/nova/__init__.py
rename to tempest/services/nova/__init__.py
diff --git a/storm/services/nova/json/__init__.py b/tempest/services/nova/json/__init__.py
similarity index 100%
rename from storm/services/nova/json/__init__.py
rename to tempest/services/nova/json/__init__.py
diff --git a/storm/services/nova/json/flavors_client.py b/tempest/services/nova/json/flavors_client.py
similarity index 96%
rename from storm/services/nova/json/flavors_client.py
rename to tempest/services/nova/json/flavors_client.py
index d6526c8..e3a030f 100644
--- a/storm/services/nova/json/flavors_client.py
+++ b/tempest/services/nova/json/flavors_client.py
@@ -1,4 +1,4 @@
-from storm.common import rest_client
+from tempest.common import rest_client
 import json
 import time
 
diff --git a/storm/services/nova/json/images_client.py b/tempest/services/nova/json/images_client.py
similarity index 97%
rename from storm/services/nova/json/images_client.py
rename to tempest/services/nova/json/images_client.py
index 59e9269..e5871cb 100644
--- a/storm/services/nova/json/images_client.py
+++ b/tempest/services/nova/json/images_client.py
@@ -1,6 +1,7 @@
-from storm.common import rest_client
+from tempest.common import rest_client
+from tempest import exceptions
 import json
-import storm.config
+import tempest.config
 import time
 
 
@@ -10,6 +11,7 @@
         self.config = config
         self.client = rest_client.RestClient(config, username, key,
                                              auth_url, tenant_name)
+
         self.build_interval = self.config.nova.build_interval
         self.build_timeout = self.config.nova.build_timeout
         self.headers = {'Content-Type': 'application/json',
diff --git a/tempest/services/nova/json/limits_client.py b/tempest/services/nova/json/limits_client.py
new file mode 100644
index 0000000..883bdf2
--- /dev/null
+++ b/tempest/services/nova/json/limits_client.py
@@ -0,0 +1,26 @@
+import json
+from tempest.common import rest_client
+
+
+class LimitsClient(object):
+
+    def __init__(self, username, key, auth_url, tenant_name=None):
+        self.client = rest_client.RestClient(config, username, key,
+                                             auth_url, tenant_name)
+
+    def get_limits(self):
+        resp, body = self.client.get("limits")
+        body = json.loads(body)
+        return resp, body['limits']
+
+    def get_max_server_meta(self):
+        resp, limits_dict = self.get_limits()
+        return resp, limits_dict['absolute']['maxServerMeta']
+
+    def get_personality_file_limit(self):
+        resp, limits_dict = self.get_limits()
+        return resp, limits_dict['absolute']['maxPersonality']
+
+    def get_personality_size_limit(self):
+        resp, limits_dict = self.get_limits()
+        return resp, limits_dict['absolute']['maxPersonalitySize']
diff --git a/storm/services/nova/json/servers_client.py b/tempest/services/nova/json/servers_client.py
similarity index 98%
rename from storm/services/nova/json/servers_client.py
rename to tempest/services/nova/json/servers_client.py
index b587ee0..502da72 100644
--- a/storm/services/nova/json/servers_client.py
+++ b/tempest/services/nova/json/servers_client.py
@@ -1,7 +1,7 @@
-from storm import exceptions
-from storm.common import rest_client
+from tempest import exceptions
+from tempest.common import rest_client
 import json
-import storm.config
+import tempest.config
 import time
 
 
@@ -11,6 +11,7 @@
         self.config = config
         self.client = rest_client.RestClient(config, username, key,
                                              auth_url, tenant_name)
+
         self.build_interval = self.config.nova.build_interval
         self.build_timeout = self.config.nova.build_timeout
         self.headers = {'Content-Type': 'application/json',
diff --git a/storm/services/nova/xml/__init__.py b/tempest/services/nova/xml/__init__.py
similarity index 100%
rename from storm/services/nova/xml/__init__.py
rename to tempest/services/nova/xml/__init__.py
diff --git a/storm/tests/__init__.py b/tempest/tests/__init__.py
similarity index 100%
rename from storm/tests/__init__.py
rename to tempest/tests/__init__.py
diff --git a/storm/tests/test_flavors.py b/tempest/tests/test_flavors.py
similarity index 96%
rename from storm/tests/test_flavors.py
rename to tempest/tests/test_flavors.py
index 5153693..b506795 100644
--- a/storm/tests/test_flavors.py
+++ b/tempest/tests/test_flavors.py
@@ -1,6 +1,6 @@
 from nose.plugins.attrib import attr
-from storm import openstack
-import storm.config
+from tempest import openstack
+import tempest.config
 import unittest2 as unittest
 
 
diff --git a/tempest/tests/test_image_metadata.py b/tempest/tests/test_image_metadata.py
new file mode 100644
index 0000000..7a15b32
--- /dev/null
+++ b/tempest/tests/test_image_metadata.py
@@ -0,0 +1,107 @@
+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
+
+
+class ImagesMetadataTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = openstack.Manager()
+        cls.servers_client = cls.os.servers_client
+        cls.client = cls.os.images_client
+        cls.config = cls.os.config
+        cls.image_ref = cls.config.env.image_ref
+        cls.flavor_ref = cls.config.env.flavor_ref
+        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)
+        #Wait for the server to become active
+        cls.servers_client.wait_for_server_status(cls.server['id'], 'ACTIVE')
+
+    @classmethod
+    def tearDownClass(cls):
+        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
+
+    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'])
+
+    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)
+
+        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'])
+
+    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)
+
+        resp, metadata = self.client.list_image_metadata(self.image['id'])
+        self.assertEqual('alt1', metadata['key1'])
+        self.assertEqual('alt2', metadata['key2'])
+
+    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'],
+                                                         'key2')
+        self.assertTrue('value2', meta['key2'])
+
+    def test_set_image_metadata_item(self):
+        """
+        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'],
+                                                         'key1', meta)
+        resp, metadata = self.client.list_image_metadata(self.image['id'])
+        self.assertEqual('alt', metadata['key1'])
+
+    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'],
+                                                            'key1')
+        resp, metadata = self.client.list_image_metadata(self.image['id'])
+        self.assertTrue('key1' not in metadata)
diff --git a/storm/tests/test_images.py b/tempest/tests/test_images.py
similarity index 65%
rename from storm/tests/test_images.py
rename to tempest/tests/test_images.py
index e1349b7..7f4c451 100644
--- a/storm/tests/test_images.py
+++ b/tempest/tests/test_images.py
@@ -1,8 +1,8 @@
 from nose.plugins.attrib import attr
-from storm import openstack
-from storm.common.utils.data_utils import rand_name
+from tempest import openstack
+from tempest.common.utils.data_utils import rand_name
 import unittest2 as unittest
-import storm.config
+import tempest.config
 
 # Some module-level skip conditions
 create_image_enabled = False
@@ -24,8 +24,9 @@
         temp = image_ref.rsplit('/')
         return temp[6]
 
-    @unittest.skipIf(not create_image_enabled,
+    @unittest.skipIf(not imaging_enabled,
                     'Environment unable to create images.')
+    @attr(type='smoke')
     def test_create_delete_image(self):
         """An image for the provided server should be created"""
         server_name = rand_name('server')
@@ -36,7 +37,8 @@
 
         #Create a new image
         name = rand_name('image')
-        resp, body = self.client.create_image(server['id'], name)
+        meta = {'image_type': 'test'}
+        resp, body = self.client.create_image(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')
@@ -44,27 +46,13 @@
         #Verify the image was created correctly
         resp, image = self.client.get_image(image_id)
         self.assertEqual(name, image['name'])
+        self.assertEqual('test', image['metadata']['image_type'])
+
+        #Verify minRAM and minDisk values are the same as the original image
+        resp, original_image = self.client.get_image(self.image_ref)
+        self.assertEqual(original_image['minRam'], image['minRam'])
+        self.assertEqual(original_image['minDisk'], image['minDisk'])
 
         #Teardown
         self.client.delete_image(image['id'])
         self.servers_client.delete_server(server['id'])
-
-    @attr(type='smoke')
-    def test_get_image(self):
-        """Returns the correct details for a single image"""
-        resp, image = self.client.get_image(self.image_ref)
-        self.assertEqual(self.image_ref, image['id'])
-
-    @attr(type='smoke')
-    def test_list_images(self):
-        """The list of all images should contain the image flavor"""
-        resp, images = self.client.list_images()
-        found = any([i for i in images if i['id'] == self.image_ref])
-        self.assertTrue(found)
-
-    @attr(type='smoke')
-    def test_list_images_with_detail(self):
-        """Detailed list of all images should contain the expected image"""
-        resp, images = self.client.list_images_with_detail()
-        found = any([i for i in images if i['id'] == self.image_ref])
-        self.assertTrue(found)
diff --git a/tempest/tests/test_list_images.py b/tempest/tests/test_list_images.py
new file mode 100644
index 0000000..a4cdac0
--- /dev/null
+++ b/tempest/tests/test_list_images.py
@@ -0,0 +1,37 @@
+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 ListImagesTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = openstack.Manager()
+        cls.client = cls.os.images_client
+        cls.servers_client = cls.os.servers_client
+        cls.config = cls.os.config
+        cls.image_ref = cls.config.env.image_ref
+        cls.flavor_ref = cls.config.env.flavor_ref
+
+    @attr(type='smoke')
+    def test_get_image(self):
+        """Returns the correct details for a single image"""
+        resp, image = self.client.get_image(self.image_ref)
+        self.assertEqual(self.image_ref, image['id'])
+
+    @attr(type='smoke')
+    def test_list_images(self):
+        """The list of all images should contain the image"""
+        resp, images = self.client.list_images()
+        found = any([i for i in images if i['id'] == self.image_ref])
+        self.assertTrue(found)
+
+    @attr(type='smoke')
+    def test_list_images_with_detail(self):
+        """Detailed list of all images should contain the expected image"""
+        resp, images = self.client.list_images_with_detail()
+        found = any([i for i in images if i['id'] == self.image_ref])
+        self.assertTrue(found)
diff --git a/storm/tests/test_server_details.py b/tempest/tests/test_list_servers.py
similarity index 96%
rename from storm/tests/test_server_details.py
rename to tempest/tests/test_list_servers.py
index b042ea2..76bf7aa 100644
--- a/storm/tests/test_server_details.py
+++ b/tempest/tests/test_list_servers.py
@@ -1,8 +1,8 @@
 from nose.plugins.attrib import attr
-from storm import openstack
-from storm.common.utils.data_utils import rand_name
+from tempest import openstack
+from tempest.common.utils.data_utils import rand_name
 import unittest2 as unittest
-import storm.config
+import tempest.config
 
 
 class ServerDetailsTest(unittest.TestCase):
diff --git a/tempest/tests/test_server_actions.py b/tempest/tests/test_server_actions.py
new file mode 100644
index 0000000..3ae9dd8
--- /dev/null
+++ b/tempest/tests/test_server_actions.py
@@ -0,0 +1,113 @@
+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
+
+
+class ServerActionsTest(unittest.TestCase):
+    resize_available = tempest.config.TempestConfig().env.resize_available
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = openstack.Manager()
+        cls.client = cls.os.servers_client
+        cls.config = cls.os.config
+        cls.image_ref = cls.config.env.image_ref
+        cls.image_ref_alt = cls.config.env.image_ref_alt
+        cls.flavor_ref = cls.config.env.flavor_ref
+        cls.flavor_ref_alt = cls.config.env.flavor_ref_alt
+
+    def setUp(self):
+        self.name = rand_name('server')
+        resp, self.server = self.client.create_server(self.name,
+                                                      self.image_ref,
+                                                      self.flavor_ref)
+        self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
+
+    def tearDown(self):
+        self.client.delete_server(self.id)
+
+    @attr(type='smoke')
+    def test_change_server_password(self):
+        """The server's password should be set to the provided password"""
+        resp, body = self.client.change_password(self.server['id'], 'newpass')
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
+
+    @attr(type='smoke')
+    def test_reboot_server_hard(self):
+        """ The server should be power cycled """
+        resp, body = self.client.reboot(self.server['id'], 'HARD')
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
+
+    @attr(type='smoke')
+    def test_reboot_server_soft(self):
+        """The server should be signaled to reboot gracefully"""
+        resp, body = self.client.reboot(self.server['id'], 'SOFT')
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(self.server['id'], 'ACTIVE')
+
+    @attr(type='smoke')
+    def test_rebuild_server(self):
+        """ The server should be rebuilt using the provided image and data """
+        meta = {'rebuild': 'server'}
+        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,
+                                                   personality=personality,
+                                                   adminPass='rebuild')
+
+        #Verify the properties in the initial response are correct
+        self.assertEqual(self.server['id'], rebuilt_server['id'])
+        self.assertEqual(self.image_ref_alt, rebuilt_server['image']['id'])
+        self.assertEqual(self.flavor_ref, rebuilt_server['flavor']['id'])
+
+        #Verify the server properties after the rebuild completes
+        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'])
+
+    @attr(type='smoke')
+    @unittest.skipIf(not resize_available, 'Resize not available.')
+    def test_resize_server_confirm(self):
+        """
+        The server's RAM and disk space should be modified to that of
+        the provided flavor
+        """
+
+        resp, server = self.client.resize(self.id, self.flavor_ref_alt)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(self.id, 'VERIFY_RESIZE')
+
+        self.client.confirm_resize(self.id)
+        self.client.wait_for_server_status(self.id, 'ACTIVE')
+
+        resp, server = self.client.get_server(self.id)
+        self.assertEqual(self.flavor_ref_alt, server['flavor']['id'])
+
+    @attr(type='smoke')
+    @unittest.skipIf(not resize_available, 'Resize not available.')
+    def test_resize_server_revert(self):
+        """
+        The server's RAM and disk space should return to its original
+        values after a resize is reverted
+        """
+
+        resp, server = self.client.resize(self.id, self.flavor_ref_alt)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(id, 'VERIFY_RESIZE')
+
+        self.client.revert_resize(self.id)
+        self.client.wait_for_server_status(id, 'ACTIVE')
+
+        resp, server = self.client.get_server(id)
+        self.assertEqual(self.flavor_ref, server['flavor']['id'])
diff --git a/storm/tests/test_server_metadata.py b/tempest/tests/test_server_metadata.py
similarity index 97%
rename from storm/tests/test_server_metadata.py
rename to tempest/tests/test_server_metadata.py
index 397599a..5ec826b 100644
--- a/storm/tests/test_server_metadata.py
+++ b/tempest/tests/test_server_metadata.py
@@ -1,8 +1,8 @@
 from nose.plugins.attrib import attr
-from storm import openstack
-from storm.common.utils.data_utils import rand_name
+from tempest import openstack
+from tempest.common.utils.data_utils import rand_name
 import unittest2 as unittest
-import storm.config
+import tempest.config
 
 
 class ServerMetadataTest(unittest.TestCase):
diff --git a/tempest/tests/test_server_personality.py b/tempest/tests/test_server_personality.py
new file mode 100644
index 0000000..ebf5e8f
--- /dev/null
+++ b/tempest/tests/test_server_personality.py
@@ -0,0 +1,67 @@
+from nose.plugins.attrib import attr
+from tempest import openstack
+from tempest import exceptions
+from tempest.common.utils.data_utils import rand_name
+import base64
+import tempest.config
+import unittest2 as unittest
+
+
+class ServerPersonalityTest(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = openstack.Manager()
+        cls.client = cls.os.servers_client
+        cls.config = cls.config = cls.os.config
+        cls.image_ref = cls.config.env.image_ref
+        cls.flavor_ref = cls.config.env.flavor_ref
+        cls.user_client = cls.os.limits_client
+
+    def test_personality_files_exceed_limit(self):
+        """
+        Server creation should fail if greater than the maximum allowed
+        number of files are injected into the server.
+        """
+        name = rand_name('server')
+        file_contents = 'This is a test file.'
+        personality = []
+        resp, max_file_limit = self.user_client.get_personality_file_limit()
+        for i in range(0, max_file_limit + 1):
+            path = 'etc/test' + str(i) + '.txt'
+            personality.append({'path': path,
+                                'contents': base64.b64encode(file_contents)})
+        try:
+            resp, resp_body = self.client.create_server(name, self.image_ref,
+                                                   self.flavor_ref,
+                                                   personality=personality)
+        except exceptions.OverLimit:
+            pass
+        else:
+            self.fail('This request did not fail as expected')
+
+    @attr(type='positive')
+    def test_can_create_server_with_max_number_personality_files(self):
+        """
+        Server should be created successfully if maximum allowed number of
+        files is injected into the server during creation.
+        """
+        name = rand_name('server')
+        file_contents = 'This is a test file.'
+
+        resp, max_file_limit = self.user_client.get_personality_file_limit()
+        self.assertEqual(200, resp.status)
+
+        personality = []
+        for i in range(0, max_file_limit):
+            path = 'etc/test' + str(i) + '.txt'
+            personality.append({'path': path,
+                                'contents': base64.b64encode(file_contents)})
+
+        resp, server = self.client.create_server(name, self.image_ref,
+                                               self.flavor_ref,
+                                               personality=personality)
+        self.assertEqual('202', resp['status'])
+
+        #Teardown
+        self.client.delete_server(server['id'])
diff --git a/storm/tests/test_servers.py b/tempest/tests/test_servers.py
similarity index 82%
rename from storm/tests/test_servers.py
rename to tempest/tests/test_servers.py
index fead6aa..8e332ed 100644
--- a/storm/tests/test_servers.py
+++ b/tempest/tests/test_servers.py
@@ -1,9 +1,9 @@
-from storm.common import ssh
+from tempest.common import ssh
 from nose.plugins.attrib import attr
-from storm import openstack
-from storm.common.utils.data_utils import rand_name
+from tempest import openstack
+from tempest.common.utils.data_utils import rand_name
 import base64
-import storm.config
+import tempest.config
 import unittest2 as unittest
 
 
@@ -16,7 +16,6 @@
         cls.config = cls.os.config
         cls.image_ref = cls.config.env.image_ref
         cls.flavor_ref = cls.config.env.flavor_ref
-        cls.ssh_timeout = cls.config.nova.ssh_timeout
 
     @attr(type='smoke')
     def test_create_delete_server(self):
@@ -34,6 +33,10 @@
                                                  accessIPv4=accessIPv4,
                                                  accessIPv6=accessIPv6,
                                                  personality=personality)
+        #Check the initial response
+        self.assertEqual(202, resp.status)
+        self.assertTrue(server['id'] is not None)
+        self.assertTrue(server['adminPass'] is not None)
 
         #Wait for the server to become active
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
@@ -46,8 +49,9 @@
         self.assertEqual(self.image_ref, server['image']['id'])
         self.assertEqual(str(self.flavor_ref), server['flavor']['id'])
 
-        #Teardown
-        self.client.delete_server(self.id)
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])
+        self.assertEqual(204, resp.status)
 
     @attr(type='smoke')
     def test_create_server_with_admin_password(self):
@@ -64,14 +68,6 @@
         #Verify the password is set correctly in the response
         self.assertEqual('testpassword', server['adminPass'])
 
-        #SSH into the server using the set password
-        self.client.wait_for_server_status(server['id'], 'ACTIVE')
-        resp, addresses = self.client.list_addresses(server['id'])
-        ip = addresses['public'][0]['addr']
-
-        client = ssh.Client(ip, 'root', 'testpassword', self.ssh_timeout)
-        self.assertTrue(client.test_connection_auth())
-
         #Teardown
         self.client.delete_server(server['id'])
 
@@ -84,7 +80,8 @@
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         #Update the server with a new name
-        self.client.update_server(server['id'], name='newname')
+        resp, server = self.client.update_server(server['id'], name='newname')
+        self.assertEquals(200, resp.status)
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         #Verify the name of the server has changed
@@ -105,8 +102,10 @@
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         #Update the IPv4 and IPv6 access addresses
-        self.client.update_server(server['id'], accessIPv4='1.1.1.1',
-                                  accessIPv6='::babe:2.2.2.2')
+        resp, body = self.client.update_server(server['id'],
+                                               accessIPv4='1.1.1.1',
+                                               accessIPv6='::babe:2.2.2.2')
+        self.assertEqual(200, resp.status)
         self.client.wait_for_server_status(server['id'], 'ACTIVE')
 
         #Verify the access addresses have been updated
diff --git a/storm/tests/test_servers_negative.py b/tempest/tests/test_servers_negative.py
similarity index 95%
rename from storm/tests/test_servers_negative.py
rename to tempest/tests/test_servers_negative.py
index 068ca5d..3355514 100644
--- a/storm/tests/test_servers_negative.py
+++ b/tempest/tests/test_servers_negative.py
@@ -1,11 +1,11 @@
 import unittest2 as unittest
-import storm.config
+import tempest.config
 import base64
 from nose.plugins.attrib import attr
-from storm import openstack
-from storm.common.utils.data_utils import rand_name
-from storm.common import ssh
-from storm import exceptions
+from tempest import openstack
+from tempest.common.utils.data_utils import rand_name
+from tempest.common import ssh
+from tempest import exceptions
 
 
 class ServersNegativeTest(unittest.TestCase):