Merge "Adds "list-groups" testcase to v3/test_groups"
diff --git a/tempest/api/database/base.py b/tempest/api/database/base.py
index c9f16ca..dd4c684 100644
--- a/tempest/api/database/base.py
+++ b/tempest/api/database/base.py
@@ -41,4 +41,5 @@
         cls.os = os
         cls.database_flavors_client = cls.os.database_flavors_client
         cls.os_flavors_client = cls.os.flavors_client
+        cls.database_limits_client = cls.os.database_limits_client
         cls.database_versions_client = cls.os.database_versions_client
diff --git a/tempest/api/database/limits/__init__.py b/tempest/api/database/limits/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api/database/limits/__init__.py
diff --git a/tempest/api/database/limits/test_limits.py b/tempest/api/database/limits/test_limits.py
new file mode 100644
index 0000000..30d0a77
--- /dev/null
+++ b/tempest/api/database/limits/test_limits.py
@@ -0,0 +1,45 @@
+# Copyright 2014 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 tempest.api.database import base
+from tempest import test
+
+
+class DatabaseLimitsTest(base.BaseDatabaseTest):
+    _interface = 'json'
+
+    @classmethod
+    def resource_setup(cls):
+        super(DatabaseLimitsTest, cls).resource_setup()
+        cls.client = cls.database_limits_client
+
+    @test.attr(type='smoke')
+    def test_absolute_limits(self):
+        # Test to verify if all absolute limit paramaters are
+        # present when verb is ABSOLUTE
+        _, limits = self.client.list_db_limits()
+        expected_abs_limits = ['max_backups', 'max_volumes',
+                               'max_instances', 'verb']
+        absolute_limit = [l for l in limits
+                          if l['verb'] == 'ABSOLUTE']
+        self.assertEqual(1, len(absolute_limit), "One ABSOLUTE limit "
+                         "verb is allowed. Fetched %s"
+                         % len(absolute_limit))
+        actual_abs_limits = absolute_limit[0].keys()
+        missing_abs_limit = set(expected_abs_limits) - set(actual_abs_limits)
+        self.assertEmpty(missing_abs_limit,
+                         "Failed to find the following absolute limit(s)"
+                         " in a fetched list: %s" %
+                         ', '.join(str(a) for a in missing_abs_limit))
diff --git a/tempest/clients.py b/tempest/clients.py
index 03cffcb..723e7b5 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -65,6 +65,8 @@
 from tempest.services.data_processing.v1_1.client import DataProcessingClient
 from tempest.services.database.json.flavors_client import \
     DatabaseFlavorsClientJSON
+from tempest.services.database.json.limits_client import \
+    DatabaseLimitsClientJSON
 from tempest.services.database.json.versions_client import \
     DatabaseVersionsClientJSON
 from tempest.services.identity.json.identity_client import IdentityClientJSON
@@ -158,6 +160,7 @@
         super(Manager, self).__init__(credentials=credentials)
 
         self._set_compute_clients()
+        self._set_database_clients()
         self._set_identity_clients()
         self._set_volume_clients()
         self._set_object_storage_clients()
@@ -176,16 +179,6 @@
             build_interval=CONF.network.build_interval,
             build_timeout=CONF.network.build_timeout,
             **self.default_params)
-        self.database_flavors_client = DatabaseFlavorsClientJSON(
-            self.auth_provider,
-            CONF.database.catalog_type,
-            CONF.identity.region,
-            **self.default_params_with_timeout_values)
-        self.database_versions_client = DatabaseVersionsClientJSON(
-            self.auth_provider,
-            CONF.database.catalog_type,
-            CONF.identity.region,
-            **self.default_params_with_timeout_values)
         self.messaging_client = MessagingClientJSON(
             self.auth_provider,
             CONF.messaging.catalog_type,
@@ -281,6 +274,23 @@
         self.volumes_extensions_client = VolumesExtensionsClientJSON(
             self.auth_provider, **params_volume)
 
+    def _set_database_clients(self):
+        self.database_flavors_client = DatabaseFlavorsClientJSON(
+            self.auth_provider,
+            CONF.database.catalog_type,
+            CONF.identity.region,
+            **self.default_params_with_timeout_values)
+        self.database_limits_client = DatabaseLimitsClientJSON(
+            self.auth_provider,
+            CONF.database.catalog_type,
+            CONF.identity.region,
+            **self.default_params_with_timeout_values)
+        self.database_versions_client = DatabaseVersionsClientJSON(
+            self.auth_provider,
+            CONF.database.catalog_type,
+            CONF.identity.region,
+            **self.default_params_with_timeout_values)
+
     def _set_identity_clients(self):
         self.identity_client = IdentityClientJSON(self.auth_provider)
         self.identity_v3_client = IdentityV3ClientJSON(self.auth_provider)
diff --git a/tempest/common/service_client.py b/tempest/common/service_client.py
index d2f67e3..c0a7133 100644
--- a/tempest/common/service_client.py
+++ b/tempest/common/service_client.py
@@ -81,8 +81,6 @@
             raise exceptions.NotImplemented(ex)
         except lib_exceptions.ServerFault as ex:
             raise exceptions.ServerFault(ex)
-        except lib_exceptions.UnexpectedResponseCode as ex:
-            raise exceptions.UnexpectedResponseCode(ex)
         # TODO(oomichi): This is just a workaround for failing gate tests
         # when separating Forbidden from Unauthorized in tempest-lib.
         # We will need to remove this translation and replace negative tests
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 86f488a..f265186 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -209,10 +209,6 @@
     message = "Invalid content type provided"
 
 
-class UnexpectedResponseCode(RestClientException):
-    message = "Unexpected response code received"
-
-
 class InvalidStructure(TempestException):
     message = "Invalid structure of table with details"
 
diff --git a/tempest/services/database/json/limits_client.py b/tempest/services/database/json/limits_client.py
new file mode 100644
index 0000000..4daf028
--- /dev/null
+++ b/tempest/services/database/json/limits_client.py
@@ -0,0 +1,33 @@
+# Copyright 2014 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 urllib
+
+from tempest import config
+from tempest_lib.common import rest_client
+
+CONF = config.CONF
+
+
+class DatabaseLimitsClientJSON(rest_client.RestClient):
+
+    def list_db_limits(self, params=None):
+        """List all limits."""
+        url = 'limits'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        return resp, self._parse_resp(body)