New API test - test_list_service_statuses

Test scenario:
  Initiate "Service Statuses" API request and make sure that:
  1) All mandatory services are listed in API responce
  2) Each listed service is in "UP" status

Change-Id: Ib11297d5e17df8caf9e8b533c3dccdbe97899dec
diff --git a/designate_tempest_plugin/clients.py b/designate_tempest_plugin/clients.py
index 87b43c4..43ec5a7 100644
--- a/designate_tempest_plugin/clients.py
+++ b/designate_tempest_plugin/clients.py
@@ -47,6 +47,8 @@
     import TransferAcceptClient
 from designate_tempest_plugin.services.dns.v2.json.tsigkey_client \
     import TsigkeyClient
+from designate_tempest_plugin.services.dns.v2.json.service_client \
+    import SevriceClient
 
 CONF = config.CONF
 
@@ -93,6 +95,7 @@
         self.transfer_request_client = TransferRequestClient(**params)
         self.transfer_accept_client = TransferAcceptClient(**params)
         self.tsigkey_client = TsigkeyClient(**params)
+        self.service_client = SevriceClient(**params)
 
         self.query_client = QueryClient(
             nameservers=CONF.dns.nameservers,
diff --git a/designate_tempest_plugin/common/constants.py b/designate_tempest_plugin/common/constants.py
new file mode 100644
index 0000000..7ebcc87
--- /dev/null
+++ b/designate_tempest_plugin/common/constants.py
@@ -0,0 +1,16 @@
+# Copyright 2021 Red Hat.
+#
+# 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.
+
+# API statuses
+UP = 'UP'
diff --git a/designate_tempest_plugin/services/dns/json/base.py b/designate_tempest_plugin/services/dns/json/base.py
index d7bf614..c478654 100644
--- a/designate_tempest_plugin/services/dns/json/base.py
+++ b/designate_tempest_plugin/services/dns/json/base.py
@@ -152,16 +152,17 @@
 
         return resp, self.deserialize(resp, body)
 
-    def _list_request(self, resource, params=None):
+    def _list_request(self, resource, params=None, headers=None):
         """Gets a list of objects.
         :param resource: The name of the REST resource, e.g., 'zones'.
         :param params: A Python dict that represents the query paramaters to
                        include in the request URI.
+        :param headers (dict): The headers to use for the request.
         :returns: Serialized object as a dictionary.
         """
         uri = self.get_uri(resource, params=params)
 
-        resp, body = self.get(uri)
+        resp, body = self.get(uri, headers=headers)
 
         self.expected_success(self.LIST_STATUS_CODES, resp.status)
 
diff --git a/designate_tempest_plugin/services/dns/v2/json/service_client.py b/designate_tempest_plugin/services/dns/v2/json/service_client.py
new file mode 100644
index 0000000..fd24047
--- /dev/null
+++ b/designate_tempest_plugin/services/dns/v2/json/service_client.py
@@ -0,0 +1,27 @@
+# Copyright 2021 Red Hat.
+#
+# 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 designate_tempest_plugin.services.dns.v2.json import base
+
+
+class SevriceClient(base.DnsClientV2Base):
+
+    @base.handle_errors
+    def list_statuses(self, headers=None):
+        """List all Services and statuses
+
+        :param headers: (dict): The headers to use for the request.
+        :return: Serialized service statuses as a list.
+        """
+        return self._list_request(
+            'service_statuses', headers=headers)[1]['service_statuses']
diff --git a/designate_tempest_plugin/tests/api/v2/test_service_statuses.py b/designate_tempest_plugin/tests/api/v2/test_service_statuses.py
new file mode 100644
index 0000000..68396c5
--- /dev/null
+++ b/designate_tempest_plugin/tests/api/v2/test_service_statuses.py
@@ -0,0 +1,66 @@
+# Copyright 2021 Red Hat.
+#
+# 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 oslo_log import log as logging
+from designate_tempest_plugin.common import constants as const
+from tempest import config
+from tempest.lib import decorators
+
+from designate_tempest_plugin.tests import base
+
+LOG = logging.getLogger(__name__)
+
+
+CONF = config.CONF
+
+
+class ServiceStatus(base.BaseDnsV2Test):
+
+    credentials = ['primary', 'admin']
+
+    @classmethod
+    def setup_credentials(cls):
+        # Do not create network resources for these test.
+        cls.set_network_resources()
+        super(ServiceStatus, cls).setup_credentials()
+
+    @classmethod
+    def setup_clients(cls):
+        super(ServiceStatus, cls).setup_clients()
+
+        cls.client = cls.os_primary.service_client
+        cls.admin_client = cls.os_admin.service_client
+
+    @decorators.idempotent_id('bf277a76-8583-11eb-a557-74e5f9e2a801')
+    def test_list_service_statuses(self):
+
+        services_statuses_tup = [
+            (item['service_name'],
+             item['status']) for item in self.admin_client.list_statuses()]
+        LOG.info("Listed service tuples: (name,status)' are:{} ".format(
+            services_statuses_tup))
+
+        LOG.info('Make sure that all expected/mandatory services are '
+                 'listed in API response.')
+        expected_services = ['central', 'mdns', 'worker', 'producer']
+        for service in expected_services:
+            self.assertIn(
+                service, [item[0] for item in services_statuses_tup],
+                "Failed, expected service: {} wasn't detected in API "
+                "response".format(service))
+
+        LOG.info('Make sure that all listed services are in UP status.')
+        self.assertEqual(
+            {const.UP}, set([item[1] for item in services_statuses_tup]),
+            "Failed, not all listed services are in UP status, "
+            "services: {}".format(services_statuses_tup))