From 88d23bd810896c38bff17723946b37dfcd1fb4c4 Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Wed, 14 Oct 2015 06:22:23 +0000 Subject: [PATCH] Migrated services_client.py from tempest This migrates the above files from tempest. This includes tempest commits: * services_client.py : Ib5617c3957cf60b2c1f11b78b7c3a136adf7ef9d * test_services_client.py: I3ad6761651cec5e66012d08e6b63322f53286a5c * services.py : Icd49783f19be4c30df9532e85b0cccf3410ad8fb to see the commit history for these files refer to the above Change-Ids in the tempest repository. Partially implements blueprint migrate-service-clients-to-tempest-lib Change-Id: I29684ec61023650bd2bb3a76b708bac24608f6c0 --- .../response/compute/v2_1/services.py | 65 +++++++++++++ .../services/compute/services_client.py | 58 ++++++++++++ .../services/compute/test_services_client.py | 94 +++++++++++++++++++ 3 files changed, 217 insertions(+) create mode 100644 tempest_lib/api_schema/response/compute/v2_1/services.py create mode 100644 tempest_lib/services/compute/services_client.py create mode 100644 tempest_lib/tests/services/compute/test_services_client.py diff --git a/tempest_lib/api_schema/response/compute/v2_1/services.py b/tempest_lib/api_schema/response/compute/v2_1/services.py new file mode 100644 index 0000000..ddef7b2 --- /dev/null +++ b/tempest_lib/api_schema/response/compute/v2_1/services.py @@ -0,0 +1,65 @@ +# Copyright 2014 NEC Corporation. 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. + +list_services = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'services': { + 'type': 'array', + 'items': { + 'type': 'object', + 'properties': { + 'id': {'type': ['integer', 'string'], + 'pattern': '^[a-zA-Z!]*@[0-9]+$'}, + 'zone': {'type': 'string'}, + 'host': {'type': 'string'}, + 'state': {'type': 'string'}, + 'binary': {'type': 'string'}, + 'status': {'type': 'string'}, + 'updated_at': {'type': ['string', 'null']}, + 'disabled_reason': {'type': ['string', 'null']} + }, + 'additionalProperties': False, + 'required': ['id', 'zone', 'host', 'state', 'binary', + 'status', 'updated_at', 'disabled_reason'] + } + } + }, + 'additionalProperties': False, + 'required': ['services'] + } +} + +enable_disable_service = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'service': { + 'type': 'object', + 'properties': { + 'status': {'type': 'string'}, + 'binary': {'type': 'string'}, + 'host': {'type': 'string'} + }, + 'additionalProperties': False, + 'required': ['status', 'binary', 'host'] + } + }, + 'additionalProperties': False, + 'required': ['service'] + } +} diff --git a/tempest_lib/services/compute/services_client.py b/tempest_lib/services/compute/services_client.py new file mode 100644 index 0000000..5cdfea3 --- /dev/null +++ b/tempest_lib/services/compute/services_client.py @@ -0,0 +1,58 @@ +# Copyright 2013 NEC Corporation +# 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 oslo_serialization import jsonutils as json +from six.moves.urllib import parse as urllib + +from tempest_lib.api_schema.response.compute.v2_1 import services as schema +from tempest_lib.common import rest_client + + +class ServicesClient(rest_client.RestClient): + + def list_services(self, **params): + url = 'os-services' + if params: + url += '?%s' % urllib.urlencode(params) + + resp, body = self.get(url) + body = json.loads(body) + self.validate_response(schema.list_services, resp, body) + return rest_client.ResponseBody(resp, body) + + def enable_service(self, **kwargs): + """Enable service on a host + + host_name: Name of host + binary: Service binary + """ + post_body = json.dumps(kwargs) + resp, body = self.put('os-services/enable', post_body) + body = json.loads(body) + self.validate_response(schema.enable_disable_service, resp, body) + return rest_client.ResponseBody(resp, body) + + def disable_service(self, **kwargs): + """Disable service on a host + + host_name: Name of host + binary: Service binary + """ + post_body = json.dumps(kwargs) + resp, body = self.put('os-services/disable', post_body) + body = json.loads(body) + self.validate_response(schema.enable_disable_service, resp, body) + return rest_client.ResponseBody(resp, body) diff --git a/tempest_lib/tests/services/compute/test_services_client.py b/tempest_lib/tests/services/compute/test_services_client.py new file mode 100644 index 0000000..67d717a --- /dev/null +++ b/tempest_lib/tests/services/compute/test_services_client.py @@ -0,0 +1,94 @@ +# Copyright 2015 NEC Corporation. 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 copy + +from tempest_lib.services.compute import services_client +from tempest_lib.tests import fake_auth_provider +from tempest_lib.tests.services.compute import base + + +class TestServicesClient(base.BaseComputeServiceTest): + + FAKE_SERVICES = { + "services": + [{ + "status": "enabled", + "binary": "nova-conductor", + "zone": "internal", + "state": "up", + "updated_at": "2015-08-19T06:50:55.000000", + "host": "controller", + "disabled_reason": None, + "id": 1 + }] + } + + FAKE_SERVICE = { + "service": + { + "status": "enabled", + "binary": "nova-conductor", + "host": "controller" + } + } + + def setUp(self): + super(TestServicesClient, self).setUp() + fake_auth = fake_auth_provider.FakeAuthProvider() + self.client = services_client.ServicesClient( + fake_auth, 'compute', 'regionOne') + + def test_list_services_with_str_body(self): + self.check_service_client_function( + self.client.list_services, + 'tempest_lib.common.rest_client.RestClient.get', + self.FAKE_SERVICES) + + def test_list_services_with_bytes_body(self): + self.check_service_client_function( + self.client.list_services, + 'tempest_lib.common.rest_client.RestClient.get', + self.FAKE_SERVICES, to_utf=True) + + def _test_enable_service(self, bytes_body=False): + self.check_service_client_function( + self.client.enable_service, + 'tempest_lib.common.rest_client.RestClient.put', + self.FAKE_SERVICE, + bytes_body, + host_name="nova-conductor", binary="controller") + + def test_enable_service_with_str_body(self): + self._test_enable_service() + + def test_enable_service_with_bytes_body(self): + self._test_enable_service(bytes_body=True) + + def _test_disable_service(self, bytes_body=False): + fake_service = copy.deepcopy(self.FAKE_SERVICE) + fake_service["service"]["status"] = "disable" + + self.check_service_client_function( + self.client.disable_service, + 'tempest_lib.common.rest_client.RestClient.put', + fake_service, + bytes_body, + host_name="nova-conductor", binary="controller") + + def test_disable_service_with_str_body(self): + self._test_disable_service() + + def test_disable_service_with_bytes_body(self): + self._test_disable_service(bytes_body=True)