From 2b843d7189fa804d8d7b65050837f8a9234330ae Mon Sep 17 00:00:00 2001 From: wangxiyuan Date: Wed, 24 Feb 2016 09:27:43 +0800 Subject: [PATCH] Add tempest test for v1.1 This patch added the basic tempest test for v1.1. Change-Id: I0c79bc18333227d9cfe6509878c5a3f470afeb03 --- .../response/v1_1}/__init__.py | 0 .../api_schema/response/v1_1/queues.py | 250 ++++++++++++++++++ .../messaging/json/messaging_client.py | 188 ++++++++++++- .../tempest_plugin/tests/{api => }/base.py | 74 ++++-- .../tests/tempest_plugin/tests/v1/__init__.py | 0 .../tests/{api => v1}/test_claims.py | 8 +- .../tests/{api => v1}/test_messages.py | 4 +- .../tests/{api => v1}/test_queues.py | 6 +- .../tempest_plugin/tests/v1_1/__init__.py | 0 .../tempest_plugin/tests/v1_1/test_claims.py | 114 ++++++++ .../tests/v1_1/test_messages.py | 121 +++++++++ .../tempest_plugin/tests/v1_1/test_queues.py | 105 ++++++++ 12 files changed, 828 insertions(+), 42 deletions(-) rename zaqar/tests/tempest_plugin/{tests/api => api_schema/response/v1_1}/__init__.py (100%) create mode 100644 zaqar/tests/tempest_plugin/api_schema/response/v1_1/queues.py rename zaqar/tests/tempest_plugin/tests/{api => }/base.py (80%) create mode 100644 zaqar/tests/tempest_plugin/tests/v1/__init__.py rename zaqar/tests/tempest_plugin/tests/{api => v1}/test_claims.py (94%) rename zaqar/tests/tempest_plugin/tests/{api => v1}/test_messages.py (97%) rename zaqar/tests/tempest_plugin/tests/{api => v1}/test_queues.py (96%) create mode 100644 zaqar/tests/tempest_plugin/tests/v1_1/__init__.py create mode 100644 zaqar/tests/tempest_plugin/tests/v1_1/test_claims.py create mode 100644 zaqar/tests/tempest_plugin/tests/v1_1/test_messages.py create mode 100644 zaqar/tests/tempest_plugin/tests/v1_1/test_queues.py diff --git a/zaqar/tests/tempest_plugin/tests/api/__init__.py b/zaqar/tests/tempest_plugin/api_schema/response/v1_1/__init__.py similarity index 100% rename from zaqar/tests/tempest_plugin/tests/api/__init__.py rename to zaqar/tests/tempest_plugin/api_schema/response/v1_1/__init__.py diff --git a/zaqar/tests/tempest_plugin/api_schema/response/v1_1/queues.py b/zaqar/tests/tempest_plugin/api_schema/response/v1_1/queues.py new file mode 100644 index 000000000..92b5b6b89 --- /dev/null +++ b/zaqar/tests/tempest_plugin/api_schema/response/v1_1/queues.py @@ -0,0 +1,250 @@ +# Copyright (c) 2016 HuaWei, Inc. +# +# 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_link = { + 'type': 'object', + 'properties': { + 'rel': {'type': 'string'}, + 'href': { + 'type': 'string', + 'format': 'uri' + } + }, + 'required': ['href', 'rel'] +} + +list_queue = { + 'type': 'object', + 'properties': { + 'name': {'type': 'string'}, + 'href': { + 'type': 'string', + 'format': 'uri' + }, + 'metadata': {'type': 'object'} + }, + 'required': ['name', 'href'] +} + +list_queues = { + 'status_code': [200, 204], + 'response_body': { + 'type': 'object', + 'properties': { + 'links': { + 'type': 'array', + 'items': list_link, + 'maxItems': 1 + }, + 'queues': { + 'type': 'array', + 'items': list_queue + } + }, + 'required': ['links', 'queues'] + } +} + +age = { + 'type': 'number', + 'minimum': 0 +} + +message_link = { + 'type': 'object', + 'properties': { + 'href': { + 'type': 'string', + 'format': 'uri' + }, + 'age': age, + 'created': { + 'type': 'string', + 'format': 'date-time' + } + }, + 'required': ['href', 'age', 'created'] +} + +messages = { + 'type': 'object', + 'properties': { + 'free': {'type': 'number'}, + 'claimed': {'type': 'number'}, + 'total': {'type': 'number'}, + 'oldest': message_link, + 'newest': message_link + }, + 'required': ['free', 'claimed', 'total'] +} + +queue_stats = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'messages': messages + }, + 'required': ['messages'] + } +} + +resource_schema = { + 'type': 'array', + 'items': { + 'type': 'string' + }, + 'minItems': 1 +} + +post_messages = { + 'status_code': [201], + 'response_body': { + 'type': 'object', + 'properties': { + 'resources': resource_schema, + 'partial': {'type': 'boolean'} + } + }, + 'required': ['resources', 'partial'] +} + +message_ttl = { + 'type': 'number', + 'minimum': 1 +} + +list_messages_links = { + 'type': 'array', + 'maxItems': 1, + 'minItems': 1, + 'items': { + 'type': 'object', + 'properties': { + 'rel': {'type': 'string'}, + 'href': {'type': 'string'} + }, + 'required': ['rel', 'href'] + } +} + +list_messages_response = { + 'type': 'array', + 'minItems': 1, + 'items': { + 'type': 'object', + 'properties': { + 'href': {'type': 'string'}, + 'ttl': message_ttl, + 'age': age, + 'body': {'type': 'object'} + }, + 'required': ['href', 'ttl', 'age', 'body'] + } +} + +list_messages = { + 'status_code': [200, 204], + 'response_body': { + 'type': 'object', + 'properties': { + 'links': list_messages_links, + 'messages': list_messages_response + } + }, + 'required': ['links', 'messages'] +} + +single_message = { + 'type': 'object', + 'properties': { + 'href': {'type': 'string'}, + 'ttl': message_ttl, + 'age': age, + 'body': {'type': 'object'}, + 'id': {'type': 'string'} + }, + 'required': ['href', 'ttl', 'age', 'body', 'id'] +} + +get_single_message = { + 'status_code': [200], + 'response_body': single_message +} + +get_multiple_messages = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'messages': { + "type": "array", + "items": single_message, + "minItems": 1, + } + } + } +} + +messages_claimed = { + 'type': 'object', + 'properties': { + 'href': { + 'type': 'string', + 'format': 'uri' + }, + 'ttl': message_ttl, + 'age': {'type': 'number'}, + 'body': {'type': 'object'}, + 'id': {'type': 'string'} + }, + 'required': ['href', 'ttl', 'age', 'body', 'id'] +} + +claim_messages = { + 'status_code': [201, 204], + 'response_body': { + 'type': 'object', + 'properties': { + 'messages': { + "type": "array", + "items": single_message, + "minItems": 1, + } + } + } +} + +claim_ttl = { + 'type': 'number', + 'minimum': 1 +} + +query_claim = { + 'status_code': [200], + 'response_body': { + 'type': 'object', + 'properties': { + 'age': {'type': 'number'}, + 'ttl': claim_ttl, + 'messages': { + 'type': 'array', + 'minItems': 1 + } + }, + 'required': ['ttl', 'age', 'messages'] + } +} diff --git a/zaqar/tests/tempest_plugin/services/messaging/json/messaging_client.py b/zaqar/tests/tempest_plugin/services/messaging/json/messaging_client.py index 389ca1c5f..411839989 100644 --- a/zaqar/tests/tempest_plugin/services/messaging/json/messaging_client.py +++ b/zaqar/tests/tempest_plugin/services/messaging/json/messaging_client.py @@ -19,7 +19,10 @@ from oslo_serialization import jsonutils as json from six.moves.urllib import parse as urllib from tempest_lib.common import rest_client -from zaqar.tests.tempest_plugin.api_schema.response.v1 import queues as schema +from zaqar.tests.tempest_plugin.api_schema.response.v1 \ + import queues as v1schema +from zaqar.tests.tempest_plugin.api_schema.response.v1_1 \ + import queues as v11schema class MessagingClient(rest_client.RestClient): @@ -44,13 +47,31 @@ class MessagingClient(rest_client.RestClient): client_id = uuid.uuid4().hex self.headers = {'Client-ID': client_id} + +class V1MessagingClient(MessagingClient): + def __init__(self, auth_provider, service, region, + endpoint_type='publicURL', build_interval=1, build_timeout=60, + disable_ssl_certificate_validation=False, ca_certs=None, + trace_requests=''): + dscv = disable_ssl_certificate_validation + super(V1MessagingClient, self).__init__( + auth_provider, service, region, + endpoint_type=endpoint_type, + build_interval=build_interval, + build_timeout=build_timeout, + disable_ssl_certificate_validation=dscv, + ca_certs=ca_certs, + trace_requests=trace_requests) + + self.version = '1' + def list_queues(self): uri = '{0}/queues'.format(self.uri_prefix) resp, body = self.get(uri) if resp['status'] != '204': body = json.loads(body) - self.validate_response(schema.list_queues, resp, body) + self.validate_response(v1schema.list_queues, resp, body) return resp, body def create_queue(self, queue_name): @@ -81,7 +102,7 @@ class MessagingClient(rest_client.RestClient): uri = '{0}/queues/{1}/stats'.format(self.uri_prefix, queue_name) resp, body = self.get(uri) body = json.loads(body) - self.validate_response(schema.queue_stats, resp, body) + self.validate_response(v1schema.queue_stats, resp, body) return resp, body def show_queue_metadata(self, queue_name): @@ -104,7 +125,7 @@ class MessagingClient(rest_client.RestClient): headers=self.headers) body = json.loads(body) - self.validate_response(schema.post_messages, resp, body) + self.validate_response(v1schema.post_messages, resp, body) return resp, body def list_messages(self, queue_name): @@ -114,7 +135,7 @@ class MessagingClient(rest_client.RestClient): if resp['status'] != '204': body = json.loads(body) - self.validate_response(schema.list_messages, resp, body) + self.validate_response(v1schema.list_messages, resp, body) return resp, body @@ -123,7 +144,7 @@ class MessagingClient(rest_client.RestClient): headers=self.headers) if resp['status'] != '204': body = json.loads(body) - self.validate_response(schema.get_single_message, resp, + self.validate_response(v1schema.get_single_message, resp, body) return resp, body @@ -133,7 +154,7 @@ class MessagingClient(rest_client.RestClient): if resp['status'] != '204': body = json.loads(body) - self.validate_response(schema.get_multiple_messages, + self.validate_response(v1schema.get_multiple_messages, resp, body) @@ -154,7 +175,7 @@ class MessagingClient(rest_client.RestClient): headers=self.headers) body = json.loads(body) - self.validate_response(schema.claim_messages, resp, body) + self.validate_response(v1schema.claim_messages, resp, body) return resp, body def query_claim(self, claim_uri): @@ -162,7 +183,7 @@ class MessagingClient(rest_client.RestClient): if resp['status'] != '204': body = json.loads(body) - self.validate_response(schema.query_claim, resp, body) + self.validate_response(v1schema.query_claim, resp, body) return resp, body def update_claim(self, claim_uri, rbody): @@ -174,3 +195,152 @@ class MessagingClient(rest_client.RestClient): resp, body = self.delete(claim_uri) self.expected_success(204, resp.status) return resp, body + + +class V11MessagingClient(MessagingClient): + def __init__(self, auth_provider, service, region, + endpoint_type='publicURL', build_interval=1, build_timeout=60, + disable_ssl_certificate_validation=False, ca_certs=None, + trace_requests=''): + dscv = disable_ssl_certificate_validation + super(V11MessagingClient, self).__init__( + auth_provider, service, region, + endpoint_type=endpoint_type, + build_interval=build_interval, + build_timeout=build_timeout, + disable_ssl_certificate_validation=dscv, + ca_certs=ca_certs, + trace_requests=trace_requests) + + self.version = '1.1' + self.uri_prefix = 'v{0}'.format(self.version) + + client_id = uuid.uuid4().hex + self.headers = {'Client-ID': client_id} + + def list_queues(self): + uri = '{0}/queues'.format(self.uri_prefix) + resp, body = self.get(uri, headers=self.headers) + + if resp['status'] != '204': + body = json.loads(body) + self.validate_response(v11schema.list_queues, resp, body) + return resp, body + + def create_queue(self, queue_name): + uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name) + resp, body = self.put(uri, body=None, headers=self.headers) + self.expected_success(201, resp.status) + return resp, body + + def show_queue(self, queue_name): + uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name) + resp, body = self.get(uri, headers=self.headers) + self.expected_success(200, resp.status) + return resp, body + + def delete_queue(self, queue_name): + uri = '{0}/queues/{1}'.format(self.uri_prefix, queue_name) + resp, body = self.delete(uri, headers=self.headers) + self.expected_success(204, resp.status) + return resp, body + + def show_queue_stats(self, queue_name): + uri = '{0}/queues/{1}/stats'.format(self.uri_prefix, queue_name) + resp, body = self.get(uri, headers=self.headers) + body = json.loads(body) + self.validate_response(v11schema.queue_stats, resp, body) + return resp, body + + def show_queue_metadata(self, queue_name): + uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name) + resp, body = self.get(uri, headers=self.headers) + self.expected_success(200, resp.status) + body = json.loads(body) + return resp, body + + def set_queue_metadata(self, queue_name, rbody): + uri = '{0}/queues/{1}/metadata'.format(self.uri_prefix, queue_name) + resp, body = self.put(uri, body=json.dumps(rbody), + headers=self.headers) + self.expected_success(204, resp.status) + return resp, body + + def post_messages(self, queue_name, rbody): + uri = '{0}/queues/{1}/messages'.format(self.uri_prefix, queue_name) + resp, body = self.post(uri, body=json.dumps(rbody), + extra_headers=True, + headers=self.headers) + + body = json.loads(body) + self.validate_response(v11schema.post_messages, resp, body) + return resp, body + + def list_messages(self, queue_name): + uri = '{0}/queues/{1}/messages?echo=True'.format(self.uri_prefix, + queue_name) + resp, body = self.get(uri, extra_headers=True, headers=self.headers) + + if resp['status'] != '204': + body = json.loads(body) + self.validate_response(v11schema.list_messages, resp, body) + + return resp, body + + def show_single_message(self, message_uri): + resp, body = self.get(message_uri, extra_headers=True, + headers=self.headers) + if resp['status'] != '204': + body = json.loads(body) + self.validate_response(v11schema.get_single_message, resp, + body) + return resp, body + + def show_multiple_messages(self, message_uri): + resp, body = self.get(message_uri, extra_headers=True, + headers=self.headers) + + if resp['status'] != '404': + body = json.loads(body) + self.validate_response(v11schema.get_multiple_messages, + resp, + body) + + return resp, body + + def delete_messages(self, message_uri): + resp, body = self.delete(message_uri, headers=self.headers) + self.expected_success(204, resp.status) + return resp, body + + def post_claims(self, queue_name, rbody, url_params=False): + uri = '{0}/queues/{1}/claims'.format(self.uri_prefix, queue_name) + if url_params: + uri += '?%s' % urllib.urlencode(url_params) + + resp, body = self.post(uri, body=json.dumps(rbody), + extra_headers=True, + headers=self.headers) + + body = json.loads(body) + self.validate_response(v11schema.claim_messages, resp, body) + return resp, body + + def query_claim(self, claim_uri): + resp, body = self.get(claim_uri, headers=self.headers) + + if resp['status'] != '204': + body = json.loads(body) + self.validate_response(v11schema.query_claim, resp, body) + return resp, body + + def update_claim(self, claim_uri, rbody): + resp, body = self.patch(claim_uri, body=json.dumps(rbody), + headers=self.headers) + self.expected_success(204, resp.status) + return resp, body + + def delete_claim(self, claim_uri): + resp, body = self.delete(claim_uri, headers=self.headers) + self.expected_success(204, resp.status) + return resp, body diff --git a/zaqar/tests/tempest_plugin/tests/api/base.py b/zaqar/tests/tempest_plugin/tests/base.py similarity index 80% rename from zaqar/tests/tempest_plugin/tests/api/base.py rename to zaqar/tests/tempest_plugin/tests/base.py index 9a6cbfe47..40ed765f6 100644 --- a/zaqar/tests/tempest_plugin/tests/api/base.py +++ b/zaqar/tests/tempest_plugin/tests/base.py @@ -1,4 +1,4 @@ -# Copyright (c) 2014 Rackspace, Inc. +# Copyright (c) 2016 HuaWei, Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -40,15 +40,6 @@ class BaseMessagingTest(test.BaseTestCase): if not CONF.service_available.zaqar: raise cls.skipException("Zaqar support is required") - @classmethod - def setup_clients(cls): - super(BaseMessagingTest, cls).setup_clients() - cls.client = messaging_client.MessagingClient( - cls.os.auth_provider, - CONF.messaging.catalog_type, - CONF.identity.region, - **cls.os.default_params_with_timeout_values) - @classmethod def resource_setup(cls): super(BaseMessagingTest, cls).resource_setup() @@ -66,18 +57,6 @@ class BaseMessagingTest(test.BaseTestCase): resp, body = cls.client.delete_queue(queue_name) return resp, body - @classmethod - def check_queue_exists(cls, queue_name): - """Wrapper utility that checks the existence of a test queue.""" - resp, body = cls.client.show_queue(queue_name) - return resp, body - - @classmethod - def check_queue_exists_head(cls, queue_name): - """Wrapper utility checks the head of a queue via http HEAD.""" - resp, body = cls.client.head_queue(queue_name) - return resp, body - @classmethod def list_queues(cls): """Wrapper utility that lists queues.""" @@ -165,3 +144,54 @@ class BaseMessagingTest(test.BaseTestCase): rbody = ([{'body': message_body, 'ttl': message_ttl}] * repeat) return rbody + + +class BaseV1MessagingTest(BaseMessagingTest): + """Base class for the Messaging (Zaqar) v1.0 tests.""" + @classmethod + def setup_clients(cls): + super(BaseV1MessagingTest, cls).setup_clients() + cls.client = messaging_client.V1MessagingClient( + cls.os.auth_provider, + CONF.messaging.catalog_type, + CONF.identity.region, + **cls.os.default_params_with_timeout_values) + + @classmethod + def check_queue_exists(cls, queue_name): + """Wrapper utility that checks the existence of a test queue.""" + resp, body = cls.client.show_queue(queue_name) + return resp, body + + @classmethod + def check_queue_exists_head(cls, queue_name): + """Wrapper utility checks the head of a queue via http HEAD.""" + resp, body = cls.client.head_queue(queue_name) + return resp, body + + +class BaseV11MessagingTest(BaseMessagingTest): + """Base class for the Messaging (Zaqar) v1.1 tests.""" + @classmethod + def setup_clients(cls): + super(BaseV11MessagingTest, cls).setup_clients() + cls.client = messaging_client.V11MessagingClient( + cls.os.auth_provider, + CONF.messaging.catalog_type, + CONF.identity.region, + **cls.os.default_params_with_timeout_values) + + @classmethod + def generate_message_body(cls, repeat=1): + """Wrapper utility that sets the metadata of a queue.""" + message_ttl = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_message_ttl) + + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_body = {key: value} + + body = ([{'body': message_body, 'ttl': message_ttl}] * repeat) + rbody = {'messages': body} + return rbody diff --git a/zaqar/tests/tempest_plugin/tests/v1/__init__.py b/zaqar/tests/tempest_plugin/tests/v1/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/zaqar/tests/tempest_plugin/tests/api/test_claims.py b/zaqar/tests/tempest_plugin/tests/v1/test_claims.py similarity index 94% rename from zaqar/tests/tempest_plugin/tests/api/test_claims.py rename to zaqar/tests/tempest_plugin/tests/v1/test_claims.py index 8267c8c92..b204d40f6 100644 --- a/zaqar/tests/tempest_plugin/tests/api/test_claims.py +++ b/zaqar/tests/tempest_plugin/tests/v1/test_claims.py @@ -18,13 +18,13 @@ from tempest import config from tempest_lib.common.utils import data_utils from tempest_lib import decorators -from zaqar.tests.tempest_plugin.tests.api import base +from zaqar.tests.tempest_plugin.tests import base CONF = config.CONF -class TestClaims(base.BaseMessagingTest): +class TestClaims(base.BaseV1MessagingTest): @classmethod def resource_setup(cls): @@ -55,10 +55,6 @@ class TestClaims(base.BaseMessagingTest): _, body = self._post_and_claim_messages(queue_name=self.queue_name) claimed_message_uri = body[0]['href'] - # Skipping this step till bug-1331517 is fixed - # Get posted claim - # self.client.query_claim(claimed_message_uri) - # Delete Claimed message self.client.delete_messages(claimed_message_uri) diff --git a/zaqar/tests/tempest_plugin/tests/api/test_messages.py b/zaqar/tests/tempest_plugin/tests/v1/test_messages.py similarity index 97% rename from zaqar/tests/tempest_plugin/tests/api/test_messages.py rename to zaqar/tests/tempest_plugin/tests/v1/test_messages.py index db5789c91..401b877f4 100644 --- a/zaqar/tests/tempest_plugin/tests/api/test_messages.py +++ b/zaqar/tests/tempest_plugin/tests/v1/test_messages.py @@ -17,12 +17,12 @@ from tempest import config from tempest_lib.common.utils import data_utils from tempest_lib import decorators -from zaqar.tests.tempest_plugin.tests.api import base +from zaqar.tests.tempest_plugin.tests import base CONF = config.CONF -class TestMessages(base.BaseMessagingTest): +class TestMessages(base.BaseV1MessagingTest): @classmethod def resource_setup(cls): diff --git a/zaqar/tests/tempest_plugin/tests/api/test_queues.py b/zaqar/tests/tempest_plugin/tests/v1/test_queues.py similarity index 96% rename from zaqar/tests/tempest_plugin/tests/api/test_queues.py rename to zaqar/tests/tempest_plugin/tests/v1/test_queues.py index 809cd717d..e873a7456 100644 --- a/zaqar/tests/tempest_plugin/tests/api/test_queues.py +++ b/zaqar/tests/tempest_plugin/tests/v1/test_queues.py @@ -20,10 +20,10 @@ from tempest_lib import decorators from tempest_lib import exceptions as lib_exc from testtools import matchers -from zaqar.tests.tempest_plugin.tests.api import base +from zaqar.tests.tempest_plugin.tests import base -class TestQueues(base.BaseMessagingTest): +class TestQueues(base.BaseV1MessagingTest): @decorators.idempotent_id('9f1c4c72-80c5-4dac-acf3-188cef42e36c') def test_create_delete_queue(self): @@ -43,7 +43,7 @@ class TestQueues(base.BaseMessagingTest): queue_name) -class TestManageQueue(base.BaseMessagingTest): +class TestManageQueue(base.BaseV1MessagingTest): @classmethod def resource_setup(cls): diff --git a/zaqar/tests/tempest_plugin/tests/v1_1/__init__.py b/zaqar/tests/tempest_plugin/tests/v1_1/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/zaqar/tests/tempest_plugin/tests/v1_1/test_claims.py b/zaqar/tests/tempest_plugin/tests/v1_1/test_claims.py new file mode 100644 index 000000000..8369a299b --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v1_1/test_claims.py @@ -0,0 +1,114 @@ +# Copyright (c) 2016 HuaWei, Inc. +# +# 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 six.moves.urllib import parse as urlparse +from tempest import config +from tempest_lib.common.utils import data_utils +from tempest_lib import decorators + +from zaqar.tests.tempest_plugin.tests import base + + +CONF = config.CONF + + +class TestClaims(base.BaseV11MessagingTest): + + @classmethod + def resource_setup(cls): + super(TestClaims, cls).resource_setup() + cls.queue_name = data_utils.rand_name('Queues-Test') + # Create Queue + cls.create_queue(cls.queue_name) + + def _post_and_claim_messages(self, queue_name, repeat=1): + # Post Messages + message_body = self.generate_message_body(repeat=repeat) + self.client.post_messages(queue_name=self.queue_name, + rbody=message_body) + + # Post Claim + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + claim_grace = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_claim_grace) + claim_body = {"ttl": claim_ttl, "grace": claim_grace} + resp, body = self.client.post_claims(queue_name=self.queue_name, + rbody=claim_body) + + return resp, body + + @decorators.idempotent_id('6fc4b79d-2366-4911-b0be-6446a1f02aea') + def test_post_claim(self): + _, body = self._post_and_claim_messages(queue_name=self.queue_name) + claimed_message_uri = body['messages'][0]['href'] + + # Delete Claimed message + self.client.delete_messages(claimed_message_uri) + + @decorators.idempotent_id('c61829f9-104a-4860-a136-6af2a89f3eef') + def test_query_claim(self): + # Post a Claim + resp, body = self._post_and_claim_messages(queue_name=self.queue_name) + + # Query Claim + claim_uri = resp['location'][resp['location'].find('/v1.1'):] + self.client.query_claim(claim_uri) + + # Delete Claimed message + claimed_message_uri = body['messages'][0]['href'] + self.delete_messages(claimed_message_uri) + + @decorators.idempotent_id('57b9d065-1995-420f-9173-4d716339e3b9') + def test_update_claim(self): + # Post a Claim + resp, body = self._post_and_claim_messages(queue_name=self.queue_name) + + claim_uri = resp['location'][resp['location'].find('/v1.1'):] + claimed_message_uri = body['messages'][0]['href'] + + # Update Claim + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + update_rbody = {"ttl": claim_ttl} + + self.client.update_claim(claim_uri, rbody=update_rbody) + + # Verify claim ttl >= updated ttl value + _, body = self.client.query_claim(claim_uri) + updated_claim_ttl = body["ttl"] + self.assertTrue(updated_claim_ttl >= claim_ttl) + + # Delete Claimed message + self.client.delete_messages(claimed_message_uri) + + @decorators.idempotent_id('71081c25-3eb4-427a-b2f3-891d0c5f7d32') + def test_release_claim(self): + # Post a Claim + resp, body = self._post_and_claim_messages(queue_name=self.queue_name) + claim_uri = resp['location'][resp['location'].find('/v1.1'):] + + # Release Claim + self.client.delete_claim(claim_uri) + + # Delete Claimed message + # This will implicitly verify that the claim is deleted. + message_uri = urlparse.urlparse(claim_uri).path + self.client.delete_messages(message_uri) + + @classmethod + def resource_cleanup(cls): + cls.delete_queue(cls.queue_name) + super(TestClaims, cls).resource_cleanup() diff --git a/zaqar/tests/tempest_plugin/tests/v1_1/test_messages.py b/zaqar/tests/tempest_plugin/tests/v1_1/test_messages.py new file mode 100644 index 000000000..f78febac3 --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v1_1/test_messages.py @@ -0,0 +1,121 @@ +# Copyright (c) 2016 HuaWei, Inc. +# +# 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 import config +from tempest_lib.common.utils import data_utils +from tempest_lib import decorators +from tempest_lib import exceptions as lib_exc + +from zaqar.tests.tempest_plugin.tests import base + +CONF = config.CONF + + +class TestMessages(base.BaseV11MessagingTest): + + @classmethod + def resource_setup(cls): + super(TestMessages, cls).resource_setup() + cls.queue_name = data_utils.rand_name('Queues-Test') + # Create Queue + cls.client.create_queue(cls.queue_name) + + def _post_messages(self, repeat=CONF.messaging.max_messages_per_page): + message_body = self.generate_message_body(repeat=repeat) + resp, body = self.post_messages(queue_name=self.queue_name, + rbody=message_body) + return resp, body + + @decorators.idempotent_id('7e506151-6870-404b-b746-801a72599418') + def test_post_messages(self): + # Post Messages + resp, _ = self._post_messages() + + # Get on the posted messages + message_uri = resp['location'][resp['location'].find('/v1.1'):] + resp, _ = self.client.show_multiple_messages(message_uri) + # The test has an assertion here, because the response cannot be 204 + # in this case (the client allows 200 or 204 for this API call). + self.assertEqual('200', resp['status']) + + @decorators.idempotent_id('d50ae94e-5f84-4e2d-bda4-48d8ab3ee3af') + def test_list_messages(self): + # Post Messages + self._post_messages() + + # List Messages + resp, _ = self.list_messages(queue_name=self.queue_name) + # The test has an assertion here, because the response cannot be 204 + # in this case (the client allows 200 or 204 for this API call). + self.assertEqual('200', resp['status']) + + @decorators.idempotent_id('a679d6be-f2ef-4649-b03c-710c72126b2f') + def test_get_message(self): + # Post Messages + _, body = self._post_messages() + message_uri = body['resources'][0] + + # Get posted message + resp, _ = self.client.show_single_message(message_uri) + # The test has an assertion here, because the response cannot be 204 + # in this case (the client allows 200 or 204 for this API call). + self.assertEqual('200', resp['status']) + + @decorators.idempotent_id('889e7263-2d0c-4de1-aebd-d192157e347d') + def test_get_multiple_messages(self): + # Post Messages + resp, _ = self._post_messages() + message_uri = resp['location'][resp['location'].find('/v1.1'):] + + # Get posted messages + resp, _ = self.client.show_multiple_messages(message_uri) + # The test has an assertion here, because the response cannot be 204 + # in this case (the client allows 200 or 204 for this API call). + self.assertEqual('200', resp['status']) + + @decorators.idempotent_id('9a932955-933e-4283-86d0-85dd121c2edf') + def test_delete_single_message(self): + # Post Messages + _, body = self._post_messages() + message_uri = body['resources'][0] + + # Delete posted message & verify the delete operration + self.client.delete_messages(message_uri) + + message_uri = message_uri.replace('/messages/', '/messages?ids=') + # The test has an assertion here, because the response has to be 404 + # in this case(different from v1). + self.assertRaises(lib_exc.NotFound, + self.client.show_multiple_messages, + message_uri) + + @decorators.idempotent_id('ad1949a7-36c0-45be-8020-df91467d0bbb') + def test_delete_multiple_messages(self): + # Post Messages + resp, _ = self._post_messages() + message_uri = resp['location'][resp['location'].find('/v1.1'):] + + # Delete multiple messages + self.client.delete_messages(message_uri) + # The test has an assertion here, because the response has to be 404 + # in this case(different from v1). + self.assertRaises(lib_exc.NotFound, + self.client.show_multiple_messages, + message_uri) + + @classmethod + def resource_cleanup(cls): + cls.delete_queue(cls.queue_name) + super(TestMessages, cls).resource_cleanup() diff --git a/zaqar/tests/tempest_plugin/tests/v1_1/test_queues.py b/zaqar/tests/tempest_plugin/tests/v1_1/test_queues.py new file mode 100644 index 000000000..c07966a3e --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v1_1/test_queues.py @@ -0,0 +1,105 @@ +# Copyright (c) 2016 HuaWei, Inc. +# +# 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 six import moves +from tempest.common.utils import data_utils +from tempest_lib import decorators +from testtools import matchers + +from zaqar.tests.tempest_plugin.tests import base + + +class TestQueues(base.BaseV11MessagingTest): + + @decorators.idempotent_id('16a8a53e-e9f0-4c84-bc74-4e4e89abae75') + def test_create_delete_queue(self): + # Create & Delete Queue + queue_name = data_utils.rand_name('test') + _, body = self.create_queue(queue_name) + + self.addCleanup(self.client.delete_queue, queue_name) + # NOTE(gmann): create_queue returns response status code as 201 + # so specifically checking the expected empty response body as + # this is not going to be checked in response_checker(). + self.assertEqual('', body) + + self.delete_queue(queue_name) + # lazy queue + self.client.show_queue(queue_name) + + +class TestManageQueue(base.BaseV11MessagingTest): + + @classmethod + def resource_setup(cls): + super(TestManageQueue, cls).resource_setup() + cls.queues = list() + for _ in moves.xrange(5): + queue_name = data_utils.rand_name('Queues-Test') + cls.queues.append(queue_name) + # Create Queue + cls.client.create_queue(queue_name) + + @decorators.idempotent_id('a27e9c2f-66ba-400e-b175-7b2e3f0f2ef9') + def test_list_queues(self): + # Listing queues + _, body = self.list_queues() + self.assertEqual(len(body['queues']), len(self.queues)) + for item in body['queues']: + self.assertIn(item['name'], self.queues) + + @decorators.idempotent_id('fe1a0655-08f9-4366-b1c6-b4bc4d30396b') + def test_get_queue_stats(self): + # Retrieve random queue + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + # Get Queue Stats for a newly created Queue + _, body = self.get_queue_stats(queue_name) + msgs = body['messages'] + for element in ('free', 'claimed', 'total'): + self.assertEqual(0, msgs[element]) + for element in ('oldest', 'newest'): + self.assertNotIn(element, msgs) + + @decorators.skip_because(bug='1543900') + @decorators.idempotent_id('883a5fba-fb87-4663-b941-cf4a25e64607') + def test_set_and_get_queue_metadata(self): + # Retrieve random queue + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + # Check the Queue has no metadata + _, body = self.get_queue_metadata(queue_name) + self.assertThat(body, matchers.HasLength(0)) + # Create metadata + key3 = [0, 1, 2, 3, 4] + key2 = data_utils.rand_name('value') + req_body1 = dict() + req_body1[data_utils.rand_name('key3')] = key3 + req_body1[data_utils.rand_name('key2')] = key2 + req_body = dict() + req_body[data_utils.rand_name('key1')] = req_body1 + # Set Queue Metadata + self.set_queue_metadata(queue_name, req_body) + + # Get Queue Metadata + _, body = self.get_queue_metadata(queue_name) + self.assertThat(body, matchers.Equals(req_body)) + + @classmethod + def resource_cleanup(cls): + for queue_name in cls.queues: + cls.client.delete_queue(queue_name) + super(TestManageQueue, cls).resource_cleanup()