Adds basic tests for disk config extension

* Adds non-intrusive tests for disk config
* Added method to extensions class to check
  if extensions are enabled

Change-Id: I7dcb3a4b1fafb1f7b7179d231af5751faca98018
diff --git a/tempest/services/nova/json/extensions_client.py b/tempest/services/nova/json/extensions_client.py
index 284a655..f216f3c 100644
--- a/tempest/services/nova/json/extensions_client.py
+++ b/tempest/services/nova/json/extensions_client.py
@@ -16,3 +16,8 @@
         resp, body = self.client.get(url)
         body = json.loads(body)
         return resp, body
+
+    def is_enabled(self, extension):
+        _, extensions = self.list_extensions()
+        exts = extensions['extensions']
+        return any([e for e in exts if e['name'] == extension])
diff --git a/tempest/services/nova/json/servers_client.py b/tempest/services/nova/json/servers_client.py
index 35e5782..7d2a1cb 100644
--- a/tempest/services/nova/json/servers_client.py
+++ b/tempest/services/nova/json/servers_client.py
@@ -37,6 +37,7 @@
         accessIPv6: The IPv6 access address for the server.
         min_count: Count of minimum number of instances to launch.
         max_count: Count of maximum number of instances to launch.
+        disk_config: Determines if user or admin controls disk configuration.
         """
         post_body = {
             'name': name,
@@ -53,6 +54,7 @@
             'accessIPv6': kwargs.get('accessIPv6'),
             'min_count': kwargs.get('min_count'),
             'max_count': kwargs.get('max_count'),
+            'OS-DCF:diskConfig': kwargs.get('disk_config')
         }
 
         post_body = json.dumps({'server': post_body})
@@ -193,7 +195,7 @@
                                 post_body, self.headers)
 
     def rebuild(self, server_id, image_ref, name=None, meta=None,
-                personality=None, adminPass=None):
+                personality=None, adminPass=None, disk_config=None):
         """Rebuilds a server with a new image"""
         post_body = {
                 'imageRef': image_ref,
@@ -211,6 +213,9 @@
         if personality != None:
             post_body['personality'] = personality
 
+        if disk_config != None:
+            post_body['OS-DCF:diskConfig'] = disk_config
+
         post_body = json.dumps({'rebuild': post_body})
         resp, body = self.client.post('servers/%s/action' %
                                       str(server_id), post_body,
@@ -218,7 +223,7 @@
         body = json.loads(body)
         return resp, body['server']
 
-    def resize(self, server_id, flavor_ref):
+    def resize(self, server_id, flavor_ref, disk_config=None):
         """Changes the flavor of a server."""
         post_body = {
             'resize': {
@@ -226,6 +231,9 @@
             }
         }
 
+        if disk_config != None:
+            post_body['resize']['OS-DCF:diskConfig'] = disk_config
+
         post_body = json.dumps(post_body)
         resp, body = self.client.post('servers/%s/action' %
                                       str(server_id), post_body, self.headers)
diff --git a/tempest/tests/compute/test_disk_config.py b/tempest/tests/compute/test_disk_config.py
new file mode 100644
index 0000000..6352f2d
--- /dev/null
+++ b/tempest/tests/compute/test_disk_config.py
@@ -0,0 +1,176 @@
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest import openstack
+import tempest.config
+from tempest.tests import utils
+import unittest2 as unittest
+from nose.plugins.attrib import attr
+
+
+class TestServerDiskConfig(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        cls.os = openstack.Manager()
+        cls.client = cls.os.servers_client
+        extensions_client = cls.os.extensions_client
+        cls.config = cls.os.config
+        cls.image_ref = cls.config.compute.image_ref
+        cls.image_ref_alt = cls.config.compute.image_ref_alt
+        cls.flavor_ref = cls.config.compute.flavor_ref
+        cls.flavor_ref_alt = cls.config.compute.flavor_ref_alt
+        cls.disk_config = extensions_client.is_enabled('DiskConfig')
+
+    @attr(type='positive')
+    @utils.skip_unless_attr('disk_config', 'Disk config extension not enabled')
+    def test_create_server_with_manual_disk_config(self):
+        """A server should be created with manual disk config"""
+        name = rand_name('server')
+        resp, server = self.client.create_server(name,
+                                                 self.image_ref,
+                                                 self.flavor_ref,
+                                                 disk_config='MANUAL')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Verify the specified attributes are set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
+
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])
+
+    @attr(type='positive')
+    @utils.skip_unless_attr('disk_config', 'Disk config extension not enabled')
+    def test_create_server_with_auto_disk_config(self):
+        """A server should be created with auto disk config"""
+        name = rand_name('server')
+        resp, server = self.client.create_server(name,
+                                                 self.image_ref,
+                                                 self.flavor_ref,
+                                                 disk_config='AUTO')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Verify the specified attributes are set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
+
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])
+
+    @attr(type='positive')
+    @utils.skip_unless_attr('disk_config', 'Disk config extension not enabled')
+    def test_rebuild_server_with_manual_disk_config(self):
+        """A server should be rebuilt using the manual disk config option"""
+        name = rand_name('server')
+        resp, server = self.client.create_server(name,
+                                                 self.image_ref,
+                                                 self.flavor_ref,
+                                                 disk_config='AUTO')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Verify the specified attributes are set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
+
+        resp, server = self.client.rebuild(server['id'],
+                                           self.image_ref_alt,
+                                           disk_config='MANUAL')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Verify the specified attributes are set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
+
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])
+
+    @attr(type='positive')
+    @utils.skip_unless_attr('disk_config', 'Disk config extension not enabled')
+    def test_rebuild_server_with_auto_disk_config(self):
+        """A server should be rebuilt using the auto disk config option"""
+        name = rand_name('server')
+        resp, server = self.client.create_server(name,
+                                                 self.image_ref,
+                                                 self.flavor_ref,
+                                                 disk_config='MANUAL')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Verify the specified attributes are set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
+
+        resp, server = self.client.rebuild(server['id'],
+                                           self.image_ref_alt,
+                                           disk_config='AUTO')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Verify the specified attributes are set correctly
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
+
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])
+
+    @attr(type='positive')
+    @utils.skip_unless_attr('disk_config', 'Disk config extension not enabled')
+    def test_resize_server_from_manual_to_auto(self):
+        """A server should be resized from manual to auto disk config"""
+        name = rand_name('server')
+        resp, server = self.client.create_server(name,
+                                                 self.image_ref,
+                                                 self.flavor_ref,
+                                                 disk_config='MANUAL')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Resize with auto option
+        self.client.resize(server['id'], self.flavor_ref_alt,
+                           disk_config='AUTO')
+        self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
+        self.client.confirm_resize(server['id'])
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('AUTO', server['OS-DCF:diskConfig'])
+
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])
+
+    @attr(type='positive')
+    @utils.skip_unless_attr('disk_config', 'Disk config extension not enabled')
+    def test_resize_server_from_auto_to_manual(self):
+        """A server should be resized from auto to manual disk config"""
+        name = rand_name('server')
+        resp, server = self.client.create_server(name,
+                                                 self.image_ref,
+                                                 self.flavor_ref,
+                                                 disk_config='AUTO')
+
+        #Wait for the server to become active
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        #Resize with manual option
+        self.client.resize(server['id'], self.flavor_ref_alt,
+                           disk_config='MANUAL')
+        self.client.wait_for_server_status(server['id'], 'VERIFY_RESIZE')
+        self.client.confirm_resize(server['id'])
+        self.client.wait_for_server_status(server['id'], 'ACTIVE')
+
+        resp, server = self.client.get_server(server['id'])
+        self.assertEqual('MANUAL', server['OS-DCF:diskConfig'])
+
+        #Delete the server
+        resp, body = self.client.delete_server(server['id'])