Add volume extensions tests

This commit adds clients for the cinder extensions api and adds
tests to list the extensions, which parallels the existing tests we
have for the nova equivalent api.

Change-Id: Ie24609ade3a4884b42f75ba6f3d3d969aca37505
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 465f570..ba99309 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -42,6 +42,7 @@
         cls.volumes_client = os.volumes_client
         cls.snapshots_client = os.snapshots_client
         cls.servers_client = os.servers_client
+        cls.volumes_extension_client = os.volumes_extension_client
         cls.image_ref = cls.config.compute.image_ref
         cls.flavor_ref = cls.config.compute.flavor_ref
         cls.build_interval = cls.config.volume.build_interval
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
new file mode 100644
index 0000000..90988a2
--- /dev/null
+++ b/tempest/api/volume/test_extensions.py
@@ -0,0 +1,43 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from tempest.api.volume import base
+from tempest.test import attr
+
+
+class ExtensionsTestJSON(base.BaseVolumeTest):
+    _interface = 'json'
+
+    @attr(type='gate')
+    def test_list_extensions(self):
+        # List of all extensions
+        resp, extensions = self.volumes_extension_client.list_extensions()
+        self.assertEqual(200, resp.status)
+        if len(self.config.volume_feature_enabled.api_extensions) == 0:
+            raise self.skipException('There are not any extensions configured')
+        ext = self.config.volume_feature_enabled.api_extensions[0]
+        if ext == 'all':
+            self.assertIn('Hosts', map(lambda x: x['name'], extensions))
+        elif ext:
+            self.assertIn(ext, map(lambda x: x['name'], extensions))
+        else:
+            raise self.skipException('There are not any extensions configured')
+
+
+class ExtensionsTestXML(ExtensionsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/clients.py b/tempest/clients.py
index ac79ce0..5e7d136 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -144,12 +144,16 @@
     VolumeHostsClientJSON
 from tempest.services.volume.json.admin.volume_types_client import \
     VolumeTypesClientJSON
+from tempest.services.volume.json.extensions_client import \
+    ExtensionsClientJSON as VolumeExtensionClientJSON
 from tempest.services.volume.json.snapshots_client import SnapshotsClientJSON
 from tempest.services.volume.json.volumes_client import VolumesClientJSON
 from tempest.services.volume.xml.admin.volume_hosts_client import \
     VolumeHostsClientXML
 from tempest.services.volume.xml.admin.volume_types_client import \
     VolumeTypesClientXML
+from tempest.services.volume.xml.extensions_client import \
+    ExtensionsClientXML as VolumeExtensionClientXML
 from tempest.services.volume.xml.snapshots_client import SnapshotsClientXML
 from tempest.services.volume.xml.volumes_client import VolumesClientXML
 
@@ -250,6 +254,8 @@
             self.instance_usages_audit_log_client = \
                 InstanceUsagesAuditLogClientXML(*client_args)
             self.volume_hosts_client = VolumeHostsClientXML(*client_args)
+            self.volumes_extension_client = VolumeExtensionClientXML(
+                *client_args)
 
             if client_args_v3_auth:
                 self.servers_client_v3_auth = ServersClientXML(
@@ -301,6 +307,8 @@
             self.instance_usages_audit_log_client = \
                 InstanceUsagesAuditLogClientJSON(*client_args)
             self.volume_hosts_client = VolumeHostsClientJSON(*client_args)
+            self.volumes_extension_client = VolumeExtensionClientJSON(
+                *client_args)
 
             if client_args_v3_auth:
                 self.servers_client_v3_auth = ServersClientJSON(
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/json/extensions_client.py
new file mode 100644
index 0000000..01dd3e9
--- /dev/null
+++ b/tempest/services/volume/json/extensions_client.py
@@ -0,0 +1,34 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+
+from tempest.common.rest_client import RestClient
+
+
+class ExtensionsClientJSON(RestClient):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(ExtensionsClientJSON, self).__init__(config, username, password,
+                                                   auth_url, tenant_name)
+        self.service = self.config.volume.catalog_type
+
+    def list_extensions(self):
+        url = 'extensions'
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['extensions']
diff --git a/tempest/services/volume/xml/extensions_client.py b/tempest/services/volume/xml/extensions_client.py
new file mode 100644
index 0000000..b4e6536
--- /dev/null
+++ b/tempest/services/volume/xml/extensions_client.py
@@ -0,0 +1,40 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from lxml import etree
+from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import xml_to_json
+
+
+class ExtensionsClientXML(RestClientXML):
+
+    def __init__(self, config, username, password, auth_url, tenant_name=None):
+        super(ExtensionsClientXML, self).__init__(config, username, password,
+                                                  auth_url, tenant_name)
+        self.service = self.config.volume.catalog_type
+
+    def _parse_array(self, node):
+        array = []
+        for child in node:
+            array.append(xml_to_json(child))
+        return array
+
+    def list_extensions(self):
+        url = 'extensions'
+        resp, body = self.get(url, self.headers)
+        body = self._parse_array(etree.fromstring(body))
+        return resp, body