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 dfd27e903..128fefeaa 100644 --- a/zaqar/tests/tempest_plugin/services/messaging/json/messaging_client.py +++ b/zaqar/tests/tempest_plugin/services/messaging/json/messaging_client.py @@ -329,10 +329,12 @@ class V2MessagingClient(MessagingClient): client_id = uuid.uuid4().hex self.headers = {'Client-ID': client_id} - def list_queues(self): + def list_queues(self, url_params=False): uri = '{0}/queues'.format(self.uri_prefix) - resp, body = self.get(uri, headers=self.headers) + if url_params: + uri += '?%s' % urllib.urlencode(url_params) + resp, body = self.get(uri, headers=self.headers) if resp['status'] != '204': body = json.loads(body) self.validate_response(v2schema.list_queues, resp, body) diff --git a/zaqar/tests/tempest_plugin/tests/v2/test_claims_negative.py b/zaqar/tests/tempest_plugin/tests/v2/test_claims_negative.py new file mode 100644 index 000000000..39462b6c7 --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v2/test_claims_negative.py @@ -0,0 +1,417 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 LARSEN & TOUBRO LIMITED. 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 uuid + +from tempest import config +from tempest.lib.common.utils import data_utils +from tempest.lib import exceptions as lib_exc +from tempest import test + +from zaqar.tests.tempest_plugin.tests import base + +CONF = config.CONF + + +class TestClaimsNegative(base.BaseV2MessagingTest): + + @classmethod + def resource_setup(cls): + super(TestClaimsNegative, 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 + + # Claim Messages + + @test.attr(type=['negative']) + @test.idempotent_id('bd524990-7dff-4950-a82b-554ef1d644b6') + def test_request_claim_message_with_no_request_body(self): + # Claim a message with no request body + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + + claim_body = {} + resp, _ = self.client.post_claims(self.queue_name, + claim_body) + self.assertEqual('201', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('21de9b01-00a7-406a-a2e7-86ecfea2f21a') + def test_request_claim_message_with_invalid_character_request_body(self): + # Claim a message with invalid characters as request body + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + + claim_body = '[' + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, + claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('5149cf66-0273-438c-b9de-f8c4af56f382') + def test_request_claim_message_with_invalid_request_body(self): + # Claim a message with invalid request body + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + + claim_body = '"Try"' + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, + claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('9537b022-659e-4220-a05d-eabc10661772') + def test_request_claim_message_with_greater_value_for_limit(self): + # Claim messages with a greater limit value + message_body = self.generate_message_body(repeat=1) + self.client.post_messages(queue_name=self.queue_name, + rbody=message_body) + 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} + params = {'limit': 200} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, + claim_body, url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('b9160f04-31f0-4246-b879-329b806a0d8a') + def test_request_claim_message_with_lesser_value_for_limit(self): + # Claim messages with an invalid lesser value + message_body = self.generate_message_body(repeat=1) + _, body = self.client.post_messages(queue_name=self.queue_name, + rbody=message_body) + 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} + params = {'limit': 0} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, + claim_body, url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('5dfa2fa4-ca17-46f3-9a28-8e70fbbd7f9e') + def test_request_claim_message_with_negative_value_for_limit(self): + # Claim messages with a negative value of limit + message_body = self.generate_message_body(repeat=1) + _, body = self.client.post_messages(queue_name=self.queue_name, + rbody=message_body) + 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} + + params = {'limit': -1} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, + claim_body, url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('eb8025bb-0f42-42fd-9905-6376bdc74cf4') + def test_request_claim_message_with_no_TTL_field(self): + # Claim a message with no TTL field + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + + claim_grace = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_claim_grace) + claim_body = {"grace": claim_grace} + resp, _ = self.client.post_claims(self.queue_name, + claim_body) + self.assertEqual('201', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('6b99cab8-17f0-4ec5-bb6a-9ad490a0eb7a') + def test_request_claim_message_with_greater_invalid_TTL_value(self): + # TTL for a claim may not exceed 1209600 seconds, + # and must be at least 60 seconds long , configurable + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + claim_ttl = data_utils.rand_int_id(start=43201, + end=43500) + claim_grace = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_claim_grace) + claim_body = {"ttl": claim_ttl, "grace": claim_grace} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('3d65af6e-b104-40a6-a15c-1cf65358e687') + def test_request_claim_message_with_lesser_invalid_TTL_value(self): + # TTL for a claim may not exceed 1209600 seconds, + # and must be at least 60 seconds long , configurable + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + claim_ttl = data_utils.rand_int_id(start=-43500, + end=0) + claim_grace = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_claim_grace) + claim_body = {"ttl": claim_ttl, "grace": claim_grace} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('86978d35-65be-44bb-aba4-0610728b5399') + def test_request_claim_message_with_no_grace_field(self): + # Grace for a claim may not exceed 1209600 seconds, + # and must be at least 60 seconds long , configurable + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + claim_body = {"ttl": claim_ttl} + resp, _ = self.client.post_claims(self.queue_name, + claim_body) + self.assertEqual('201', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('812d9092-2d59-4dae-b67d-ce00da3f74f9') + def test_request_claim_message_with_invalid_greater_grace_value(self): + # Grace for a claim may not exceed 1209600 seconds, + # and must be at least 60 seconds long , configurable + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + claim_grace = data_utils.\ + rand_int_id(start=43201, end=43501) + claim_body = {"ttl": claim_ttl, "grace": claim_grace} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('bf10b08c-e254-49e4-a751-a0e128dce618') + def test_request_claim_message_with_invalid_lesser_grace_value(self): + # Grace for a claim may not exceed 1209600 seconds, + # and must be at least 60 seconds long , configurable + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + claim_grace = data_utils.\ + rand_int_id(start=-43201, end=0) + claim_body = {"ttl": claim_ttl, "grace": claim_grace} + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('69b0d11a-40f5-4f35-847f-05f92ffadeb3') + def test_request_claim_message_with_non_JSON_request_body(self): + # Claim a messsage with an invalid JSON + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + claim_body = "123" + self.assertRaises(lib_exc.BadRequest, + self.client.post_claims, self.queue_name, claim_body) + + @test.attr(type=['negative']) + @test.idempotent_id('d145ea04-203d-41f9-a893-f6e5716005b6') + def test_request_claim_message_with_invalid_url_params(self): + # Post Messages + message_body = self.generate_message_body(repeat=1) + _, body = self.client.post_messages(queue_name=self.queue_name, + rbody=message_body) + 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} + params = {'Invalid': 'ImAnInvalidParam'} + resp, _ = self.client.post_claims(self.queue_name, + claim_body, url_params=params) + self.assertEqual('201', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('dbdf17ce-879f-4688-b71c-260cb9e4c4ab') + def test_claim_message_with_invalid_token(self): + # Claim a message without a valid token + body = self.generate_message_body() + self.client.post_messages(self.queue_name, body) + + 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} + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.post_claims, self.queue_name, claim_body) + + # Query Claim + + @test.attr(type=['negative']) + @test.idempotent_id('a1844a12-62d6-435e-906b-6b6ae538834f') + def test_query_from_a_nonexistent_queue(self): + # Query claim a non existent queue + non_existent_queue = data_utils.rand_name('rand_queuename') + non_existent_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/claims/{1}".format(non_existent_queue, + non_existent_id) + self.assertRaises(lib_exc.NotFound, + self.client.query_claim, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('a2af8e9b-08fb-4079-a77a-28c0390a614a') + def test_query_claim_with_non_existing_claim_id(self): + # Query claim using a non existing claim id + non_existent_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/claims/{1}".format(self.queue_name, + non_existent_id) + self.assertRaises(lib_exc.NotFound, + self.client.query_claim, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('a58c5214-68b9-47d6-a036-de73e7b2cdad') + def test_query_claim_with_invalid_token(self): + # Query claim with an invalid token + resp, body = self._post_and_claim_messages(queue_name=self.queue_name) + claim_uri = resp['location'][resp['location'].find('/v2'):] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.query_claim, claim_uri) + + # Update Claim + + @test.attr(type=['negative']) + @test.idempotent_id('28915079-8b20-487d-ab01-64218572c543') + def test_update_claim_on_non_existing_queue(self): + # Update claim on a non existing queue + resp, body = self._post_and_claim_messages(queue_name=self.queue_name) + self.client.delete_queue(self.queue_name) + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + update_rbody = {"ttl": claim_ttl} + claim_uri = resp['location'][resp['location'].find('/v2'):] + self.assertRaises(lib_exc.NotFound, + self.client.update_claim, claim_uri, update_rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('732e9ca6-6e4f-4d66-9e78-200c3d6aca88') + def test_update_a_non_existing_claim(self): + # Update a non existing claim + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + update_rbody = {"ttl": claim_ttl} + claim_id = str(uuid.uuid4()) + claim_uri = "/v2/queues/{0}/claims/{1}".format(self.queue_name, + claim_id) + self.assertRaises(lib_exc.NotFound, + self.client.update_claim, claim_uri, update_rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('925514e9-57f0-4209-a64e-8b0a72bb8f0f') + def test_update_claim_with_no_request_body(self): + # Update claim with no request body + resp, body = self._post_and_claim_messages(self.queue_name) + update_rbody = {} + claim_uri = resp['location'][resp['location'].find('/v2'):] + resp, body = self.client.update_claim(claim_uri, update_rbody) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('c17793da-112a-4e90-b2fd-a5acbfdcddc5') + def test_update_claim_with_invalid_json_in_request_body(self): + # Update claim with an invalid JSON + resp, body = self._post_and_claim_messages(self.queue_name) + update_rbody = {"123"} + claim_uri = resp['location'][resp['location'].find('/v2'):] + self.assertRaises(lib_exc.BadRequest, + self.client.update_claim, claim_uri, update_rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('1cd2fed7-6840-49cd-9b7a-1d80c01300fb') + def test_update_claim_with_invalid_token(self): + # Update claim without a valid token + resp, body = self._post_and_claim_messages(self.queue_name) + claim_uri = resp['location'][resp['location'].find('/v2'):] + claim_ttl = data_utils.rand_int_id(start=60, + end=CONF.messaging.max_claim_ttl) + update_rbody = {"ttl": claim_ttl} + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.update_claim, claim_uri, update_rbody) + + # Release Claim + + @test.attr(type=['negative']) + @test.idempotent_id('b61a0d09-bc47-4b33-aa6d-7f20cbbe9bd2') + def test_release_claim_from_a_non_existing_queue(self): + # Release claim from a non existing queue + non_existent_queue = data_utils.rand_name('rand_queuename') + non_existent_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/claims/{1}".format(non_existent_queue, + non_existent_id) + resp, body = self.client.delete_claim(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('20a6e6ed-0f53-484d-aa78-717cdaa25e50') + def test_release_a_nonexisting_claim_id(self): + # Release a non existing claim + non_existent_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/claims/{1}".format(self.queue_name, + non_existent_id) + resp, body = self.client.delete_claim(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('082d50ca-bd3e-4d66-a92b-6ff917ab3b21') + def test_release_claim_with_invalid_token(self): + # Release claim without a valid token + resp, body = self._post_and_claim_messages(queue_name=self.queue_name) + claim_uri = resp['location'][resp['location'].find('/v2'):] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.delete_claim, claim_uri) + + @classmethod + def resource_cleanup(cls): + cls.delete_queue(cls.queue_name) + super(TestClaimsNegative, cls).resource_cleanup() diff --git a/zaqar/tests/tempest_plugin/tests/v2/test_messages_negative.py b/zaqar/tests/tempest_plugin/tests/v2/test_messages_negative.py new file mode 100644 index 000000000..79add63a9 --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v2/test_messages_negative.py @@ -0,0 +1,646 @@ +# Copyright (c) 2016 LARSEN & TOUBRO LIMITED. 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 random +import uuid + +from six import moves +from tempest import config +from tempest.lib.common.utils import data_utils +from tempest.lib import exceptions as lib_exc +from tempest import test + +from zaqar.tests.tempest_plugin.tests import base + +CONF = config.CONF + + +class TestMessagesNegative(base.BaseV2MessagingTest): + + @classmethod + def resource_setup(cls): + super(TestMessagesNegative, cls).resource_setup() + cls.queues = list() + for _ in moves.xrange(1): + queue_name = data_utils.rand_name('Queues-Test') + cls.queues.append(queue_name) + # Create Queue + cls.client.create_queue(queue_name) + + # Get specific Message + + @test.attr(type=['negative']) + @test.idempotent_id('8246ee51-651c-4e2a-9a07-91848ca5e1e4') + def test_request_single_message_from_a_nonexistent_queue(self): + # List a message from a nonexistent queue + id = str(uuid.uuid4()) + non_existent_queue = data_utils.rand_name('rand_queuename') + uri = "/v2/queues/{0}/messages/{1}".format(non_existent_queue, id) + self.assertRaises(lib_exc.NotFound, + self.client.show_single_message, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('767fdad1-37df-485a-8063-5036e8d16a12') + def test_request_a_non_existing_message(self): + # List a message with an invalid id + invalid_id = str(uuid.uuid4()) + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages/{1}".format(queue_name, invalid_id) + self.assertRaises(lib_exc.NotFound, + self.client.show_single_message, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('ac2d1a88-5721-4bef-8dfa-53d936630e84') + def test_request_a_message_with_negative_message_id(self): + # List a message with an invalid id, negative + negative_id = '-1' + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages?ids={1}".format(queue_name, + negative_id) + self.assertRaises(lib_exc.NotFound, + self.client.show_single_message, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('ac083d78-67bb-4515-b553-2fc76499e2bd') + def test_request_a_message_without_a_token(self): + # List a message without a valid token + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages/{1}".format(queue_name, id) + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.show_single_message, uri) + + # Get a Set of Messages by ID + + @test.attr(type=['negative']) + @test.idempotent_id('f544e745-f3da-451d-8621-c3711cd37453') + def test_request_multiple_messages_from_a_nonexistent_queue(self): + # List multiple messages from a non existent queue + id1 = str(uuid.uuid4()) + id2 = str(uuid.uuid4()) + queue = data_utils.rand_name('nonexistent_queue') + uri = "/v2/queues/{0}/messages?ids={1},{2}".format(queue, + id1, id2) + self.assertRaises(lib_exc.NotFound, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('654e64f8-01df-40a0-a09e-d5ec17a3e187') + def test_request_multiple_messages_with_invalid_message_id(self): + # List multiple messages by passing invalid id + invalid_id = str(uuid.uuid4()) + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages?ids={1},{2}".format(queue_name, + invalid_id, + invalid_id) + self.assertRaises(lib_exc.NotFound, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('295a37a6-5c93-43e3-a316-3f3dffd4b242') + def test_request_multiple_messages_by_exceeding_the_default_limit(self): + # Default limit value is 20 , configurable + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + ids = str.join(',', (str(uuid.uuid4())) * 21) + uri = "/v2/queues/{0}/messages?ids={1}".format(queue_name, ids) + self.assertRaises(lib_exc.BadRequest, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('f96eb4a0-8930-4d5e-b8bf-11080628c761') + def test_request_message_by_passing_invalid_echo_param(self): + # Value of the echo parameter must be either true or false + echo = None + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages?echo={1}".format(queue_name, echo) + self.assertRaises(lib_exc.BadRequest, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('6f668242-6a45-48bc-8ef2-fb581e57d471') + def test_request_messages_by_passing_invalid_include_claimed_param(self): + # Value of include_claimed param must be either true or false + value = None + queue = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages?include_claimed={1}".format(queue, + value) + self.assertRaises(lib_exc.BadRequest, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('dd267387-76f6-47bd-849b-b1640051aff4') + def test_request_messages_limit_greater_than_configured_value(self): + # Default limit value is 20 , configurable + invalid_limit = data_utils.rand_int_id(21, 10000) + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages?limit={1}".format(queue_name, + invalid_limit) + self.assertRaises(lib_exc.BadRequest, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('d199f64e-0f22-4129-9bc4-ff709c01592b') + def test_request_messages_with_limit_less_than_configured_value(self): + # Default limit value is 20 , configurable + invalid_limit = data_utils.rand_int_id(-1000, 0) + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + uri = "/v2/queues/{0}/messages?limit={1}".format(queue_name, + invalid_limit) + self.assertRaises(lib_exc.BadRequest, + self.client.show_multiple_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('0b2e803c-7cb9-4c11-bed6-f976f5247b27') + def test_request_multiple_messages_request_without_a_token(self): + # List messages without a valid token + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + id1 = str(uuid.uuid4()) + id2 = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages/{1},{2}".format(queue_name, id1, id2) + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.show_multiple_messages, uri) + + # Get Messages + + @test.idempotent_id('125632c4-c7ce-47fb-93fe-c446d14396f9') + def test_list_messages_with_invalid_token(self): + # List messages without a valid token + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.list_messages, queue_name) + + # Post Messages + + @test.attr(type=['negative']) + @test.idempotent_id('5a0ba3e6-e6ca-4952-be50-fb6be7834ab7') + def test_post_messages_with_no_request_body(self): + # Post message with empty body + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + body = {} + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, body) + + @test.attr(type=['negative']) + @test.idempotent_id('af5ffb4d-c0b4-41db-aea3-bcfc8a232bd6') + def test_post_messages_with_a_bad_message(self): + # Post message with invalid message format + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + body = {'[]', '.'} + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, body) + + @test.attr(type=['negative']) + @test.idempotent_id('10bc153c-97d2-4a19-9795-e0f6993bad4f') + def test_post_messages_to_a_nonexistent_queue(self): + # Post message to a non existent queue + non_existent_queue = data_utils.rand_name('rand_queuename') + body = self.generate_message_body() + resp, _ = self.client.post_messages(non_existent_queue, body) + self.assertEqual('201', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('263d6361-4759-4f2c-be9c-12559f064135') + def test_post_messages_to_a_non_ascii_queue(self): + # Post message to a queue with non ascii queue name + queue_name = data_utils.rand_name('\u6c49\u5b57\u6f22\u5b57') + body = self.generate_message_body() + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, body) + + @test.attr(type=['negative']) + @test.idempotent_id('04c1b220-1e22-4e38-9db2-a76e8b5e2f3f') + def test_post_messages_to_a_queue_with_invalid_name(self): + # Post messages to a queue with invalid characters for queue name + queue_name = '@$@^qw@' + body = self.generate_message_body() + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, body) + + @test.attr(type=['negative']) + @test.idempotent_id('72290766-cb01-425e-856b-a57877015336') + def test_post_messages_to_a_queue_with_invalid_length_for_queue_name(self): + # Post messages to a queue with a long queue name + queue_name = 'q' * 65 + body = self.generate_message_body() + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, body) + + @test.attr(type=['negative']) + @test.idempotent_id('774e8bc8-9b20-40fb-9eed-c5368de368c5') + def test_post_messages_with_invalid_json_request_body(self): + # Post messages to a queue with non-JSON request body + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + body = "123" + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, body) + + @test.attr(type=['negative']) + @test.idempotent_id('ebbe257a-9f1e-498a-bba8-f5c71230365a') + def test_post_messages_with_TTL_less_than_60(self): + # TTL for a message may not exceed 1209600 seconds, + # and must be at least 60 seconds long. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_ttl = data_utils.\ + rand_int_id(start=0, end=60) + + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_body = {key: value} + + rbody = ([{'body': message_body, 'ttl': message_ttl}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('6d64de03-fd57-4f07-b6f1-8563200a4b4d') + def test_post_messages_with_TTL_greater_than_1209600(self): + # TTL for a message may not exceed 1209600 seconds, and + # must be at least 60 seconds long. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_ttl = data_utils.\ + rand_int_id(start=1209601, end=1309600) + + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_body = {key: value} + + rbody = ([{'body': message_body, 'ttl': message_ttl}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('c48802d7-7e91-4d5f-9c23-32cd4edc41ff') + def test_post_messages_with_non_int_value_of_TTL(self): + # TTL for a message may not exceed 1209600 seconds, and + # must be at least 60 seconds long. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_ttl = random.uniform(0.0, 0.120960) + + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_body = {key: value} + + rbody = ([{'body': message_body, 'ttl': message_ttl}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('203fed96-0df3-43c0-9956-723b34b8a23b') + def test_post_messages_with_negative_value_of_TTL(self): + # TTL for a message may not exceed 1209600 seconds, and + # must be at least 60 seconds long. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_ttl = data_utils.\ + rand_int_id(start=-9999, end=-1) + + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_body = {key: value} + + rbody = ([{'body': message_body, 'ttl': message_ttl}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('d3ad28e7-0c84-43cf-bb87-1574da28a10d') + def test_post_messages_without_TTL(self): + # TTL for a message may not exceed 1209600 seconds, and + # must be at least 60 seconds long. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_body = {key: value} + + rbody = ([{'body': message_body}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('662428d4-302f-4000-8ac6-1a53fb8818b8') + def test_post_messages_exceeding_message_post_size(self): + # Post messages with greater message size + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = 'a' * 1024 + message_ttl = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_message_ttl) + + message_body = {key: value} + + rbody = ([{'body': message_body, 'ttl': message_ttl}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('ba4f7334-1a4d-4bc8-acd3-040a1310fe62') + def test_post_messages_with_invalid_body_size(self): + # Maximum number of queue message per page + # while posting messages is 20 + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + message_ttl = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_message_ttl) + + message_body = {key: value} + rbody = ([{'body': message_body, 'ttl': message_ttl}] * 21) + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('855d36a2-e583-4355-af33-fcec0f71842c') + def test_post_messages_without_body_in_request_body(self): + # TTL for a message may not exceed 1209600 seconds, and + # must be at least 60 seconds long. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_ttl = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_message_ttl) + + rbody = ([{'ttl': message_ttl}] * 1) + + self.assertRaises(lib_exc.BadRequest, + self.client.post_messages, queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('074fe312-0077-41ba-8aa9-e6d6a586a685') + def test_post_messages_with_invalid_auth_token(self): + # X-Auth-Token is not provided + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + body = self.generate_message_body() + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None) + self.assertRaises(lib_exc.Unauthorized, + self.client.post_messages, + queue_name, body) + + # Delete Messages + + @test.attr(type=['negative']) + @test.idempotent_id('8552d5b3-7c16-4eaf-a8de-a7b178823458') + def test_delete_message_from_a_nonexistent_queue(self): + # Delete is an idempotent operation + non_existent_queue = data_utils.rand_name('rand_queuename') + message_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages?ids={1}".format(non_existent_queue, + message_id) + resp, _ = self.client.delete_messages(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('a5d581f0-0403-4c2d-9ea4-048cc6cc85f0') + def test_delete_a_non_existing_message(self): + # Delete is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages?ids={1}".format(queue_name, + message_id) + resp, _ = self.client.delete_messages(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('f792f462-0ad9-41b1-9bae-636957364ca0') + def test_delete_message_with_non_existent_message_id(self): + # Delete is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages/{1}".format(queue_name, + message_id) + resp, _ = self.client.delete_messages(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('6b8f14b3-2307-49e2-aa53-75d4d4b82754') + def test_delete_multiple_non_existing_messages(self): + # Delete is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + id1 = str(uuid.uuid4()) + id2 = str(uuid.uuid4()) + id3 = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages?ids={1}{2}{3}".format(queue_name, + id1, id2, id3) + resp, _ = self.client.delete_messages(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('805f75fd-6447-4c8a-860c-2659d8a5b0b5') + def test_delete_message_without_id(self): + # Delete all the message from a queue + # without passing any id + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_body = self.generate_message_body(repeat=1) + self.post_messages(queue_name, message_body) + uri = "/v2/queues/{0}/messages".format(queue_name) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('85eed2fb-fa72-4886-8cfc-44c7fb58ffea') + def test_delete_message_with_invalid_message_id(self): + # Delete is an idempotent operation + # Delete a message with negative id + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages?ids=-{1}".format(queue_name, + message_id) + resp, _ = self.client.delete_messages(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('374265e7-1146-4da4-a265-38c8698e4144') + def test_delete_the_deleted_message(self): + # Delete is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_id = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages?ids={1}".format(queue_name, + message_id) + resp, _ = self.client.delete_messages(uri) + # Delete the message again + resp, _ = self.client.delete_messages(uri) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('a130d499-cd41-42dd-b1f0-e859f73b00e0') + def test_delete_multiple_messages_by_exceeding_the_default_limit(self): + # Default limit value is 20 + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + ids = str.join(',', (str(uuid.uuid4())) * 21) + uri = "/v2/queues/{0}/messages?ids={1}".format(queue_name, ids) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('51a2f5ca-e358-4ef6-9f33-73d3e01f07b9') + def test_delete_message_without_providing_claim_id(self): + # When message is claimed; + # it cannot be deleted without a valid claim ID. + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + # Post Messages + message_body = self.generate_message_body(repeat=1) + self.client.post_messages(queue_name=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=queue_name, + rbody=claim_body) + message_uri = body['messages'][0]['href'] + sep = "?claim_id" + uri = message_uri.split(sep, 1)[0] + self.assertRaises(lib_exc.Forbidden, + self.client.delete_messages, + uri) + + @test.attr(type=['negative']) + @test.idempotent_id('18fa5f43-20e6-47bd-a751-ef33e62a4315') + def test_delete_message_with_invalid_claim_id(self): + # Delete with a non existent claim id + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_body = self.generate_message_body(repeat=1) + resp, body = self.post_messages(queue_name, message_body) + message_uri = body['resources'][0] + claim_id = "?claim_id=123" + uri = message_uri + str(claim_id) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('b82e5dee-5470-4408-9dca-d4a7536ff25f') + def test_delete_message_with_no_pop_value(self): + # Pop value must be at least 1 and may not be greater than 20 + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + value = ' ' + uri = "/v2/queues/{0}/messages?pop={1}".format(queue_name, value) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('6454103d-9cfd-48da-bd8c-061e61a7e634') + def test_delete_message_with_invalid_pop_value(self): + # Pop value must be at least 1 and may not be greater than 20 + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + value = 1000000000 + uri = "/v2/queues/{0}/messages?pop={1}".format(queue_name, value) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('9874b696-352b-47d7-a338-d149d4096c28') + def test_delete_message_with_negative_pop_value(self): + # Pop value must be at least 1 and may not be greater than 20 + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + value = '-1' + uri = "/v2/queues/{0}/messages?pop={1}".format(queue_name, value) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('4044f38a-0a70-4c86-ab1b-ca369e5b443a') + def test_delete_message_with_invalid_params_with_pop(self): + # Pop & ids parameters are mutually exclusive + # Anyone of which needs to be used with delete + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + pop_value = 5 + ids_value = str(uuid.uuid4()) + uri = "/v2/queues/{0}/messages?pop={1}&ids={2}".format(queue_name, + pop_value, + ids_value) + self.assertRaises(lib_exc.BadRequest, + self.client.delete_messages, uri) + + @test.attr(type=['negative']) + @test.idempotent_id('ea609ee5-a7a2-41a0-a9fb-73e8c7ed8c59') + def test_delete_messages_with_invalid_auth_token(self): + # Delete message with an invalid token + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + message_body = self.generate_message_body(repeat=1) + resp, body = self.post_messages(queue_name, message_body) + message_uri = body['resources'][0] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None) + self.assertRaises(lib_exc.Unauthorized, + self.client.delete_messages, + message_uri) + + @classmethod + def resource_cleanup(cls): + for queue_name in cls.queues: + cls.client.delete_queue(queue_name) + super(TestMessagesNegative, cls).resource_cleanup() diff --git a/zaqar/tests/tempest_plugin/tests/v2/test_queues_negative.py b/zaqar/tests/tempest_plugin/tests/v2/test_queues_negative.py new file mode 100644 index 000000000..b34e61574 --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v2/test_queues_negative.py @@ -0,0 +1,240 @@ +# -*- coding: utf-8 -*- +# Copyright (c) 2016 LARSEN & TOUBRO LIMITED. 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 six import moves +from tempest.lib.common.utils import data_utils +from tempest.lib import exceptions as lib_exc +from tempest import test + +from zaqar.tests.tempest_plugin.tests import base + + +class QueueNegativeTestJSON(base.BaseV2MessagingTest): + + @classmethod + def resource_setup(cls): + super(QueueNegativeTestJSON, cls).resource_setup() + cls.queues = list() + for _ in moves.xrange(1): + queue_name = data_utils.rand_name('Queues-Test') + cls.queues.append(queue_name) + cls.client.create_queue(queue_name) + + # Create Queues + + @test.attr(type=['negative']) + @test.idempotent_id('77634fd0-0a25-4cc7-a01c-b6d16304f907') + def test_queue_has_a_long_name(self): + # Length of queue name should >= 1 and <=64 bytes + queue_name = 'q' * 65 + self.assertRaises(lib_exc.BadRequest, + self.client.create_queue, + queue_name) + + @test.attr(type=['negative']) + @test.idempotent_id('639206ad-d74c-4f51-895d-76e2c7dff60b') + def test_queue_name_is_not_specified(self): + # Length of queue name should >= 1 and <=64 bytes + queue_name = ' ' + self.assertRaises(lib_exc.UnexpectedResponseCode, + self.client.create_queue, + queue_name) + + @test.attr(type=['negative']) + @test.idempotent_id('3ca0e180-c770-4922-8a48-9563c484aaed') + def test_queue_name_has_a_invalid_character_set(self): + # Invalid name with characters + queue_name = '@$@^qw@' + self.assertRaises(lib_exc.BadRequest, + self.client.create_queue, + queue_name) + + @test.attr(type=['negative']) + @test.idempotent_id('533c5a65-fcc9-4e07-84bc-82ac0c007dbc') + def test_queue_name_with_non_ASCII_characters(self): + # Invalid name with non-ASCII characters + queue_name = data_utils.rand_name('\u6c49\u5b57\u6f22\u5b57') + self.assertRaises(lib_exc.BadRequest, + self.client.create_queue, + queue_name) + + @test.attr(type=['negative']) + @test.idempotent_id('44775212-2b79-40c7-8604-fcf01eddba79') + def test_queue_name_with_numeric_values(self): + # Numeric values for queue name + queue_name = data_utils.rand_int_id() + resp, _ = self.client.create_queue(queue_name) + self.assertEqual('201', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('2ce4f4c1-cbaa-4c2d-b28a-f562aec037aa') + def test_create_queue_with_invalid_auth_token(self): + # Create queue with empty headers + # X-Auth-Token is not provided + queue_name = data_utils.rand_name(name='queue') + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.create_queue, + queue_name) + + # List Queues + + @test.attr(type=['negative']) + @test.idempotent_id('d4d33596-0f06-4911-aecc-17512c00a301') + def test_request_a_nonexistent_queue(self): + # List a non-existent queue + nonexistent_queuename = data_utils.rand_name('rand_queuename') + resp, _ = self.client.show_queue(nonexistent_queuename) + self.assertEqual('200', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('0c8122a8-e28b-4320-8f1f-af97a0bfa26b') + def test_request_after_deleting_queue(self): + # Request queue after deleting the queue + # DELETE is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + self.client.delete_queue(queue_name) + resp, _ = self.client.show_queue(queue_name) + self.assertEqual('200', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('b7c4521a-d0f1-4fc6-b99d-ece2131ac082') + def test_request_with_a_greater_limit_value(self): + # Limit for listing queues is 20 , configurable + params = {'limit': '200'} + self.assertRaises(lib_exc.BadRequest, + self.client.list_queues, + url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('121e5171-e189-4be5-8ccf-d0b2009b3bbe') + def test_request_with_zero_limit_value(self): + # Limit for listing queues is 20 , configurable + params = {'limit': '0'} + self.assertRaises(lib_exc.BadRequest, + self.client.list_queues, + url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('6c710fa6-9447-4c2c-b8c0-7581a56b4ab5') + def test_request_with_negative_limit_value(self): + # Limit for listing queues is 20 , configurable + params = {'limit': '-1'} + self.assertRaises(lib_exc.BadRequest, + self.client.list_queues, + url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('4a54b60c-0a6a-4662-9ba1-fe0b9dd4f399') + def test_with_non_boolean_value_for_detailed(self): + # Value for detailed parameter should be true or false + params = {'detailed': 'None'} + self.assertRaises(lib_exc.BadRequest, + self.client.list_queues, url_params=params) + + @test.attr(type=['negative']) + @test.idempotent_id('f66f1225-bfe8-4fe0-b8c9-35e4342e0f0e') + def test_list_queues_with_invalid_auth_token(self): + # List queue with empty headers + # X-Auth-Token is not provided + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.list_queues) + + # Get Queue Stats + + @test.attr(type=['negative']) + @test.idempotent_id('16cec0df-b58a-44e8-9132-f99f0c1da29a') + def test_request_stats_for_a_non_existing_queue(self): + # Show stats for a non-existent queue + nonexistent_queuename = data_utils.rand_name('rand_queuename') + resp, _ = self.client.show_queue_stats(nonexistent_queuename) + self.assertEqual('200', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('1cad4984-3f66-48f6-82c9-9a544be78ca6') + def test_request_queue_stats_after_deleting_queue(self): + # List queue stats after deleting the queue + # DELETE is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + self.client.delete_queue(queue_name) + resp, _ = self.client.show_queue_stats(queue_name) + self.assertEqual('200', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('2b1aeba8-a314-495b-8d45-84692354a013') + def test_request_queue_stats_with_invalid_auth_token(self): + # Get queue stats with empty headers + # X-Auth-Token is not provided + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.show_queue_stats, + queue_name) + + # Delete Queues + + @test.attr(type=['negative']) + @test.idempotent_id('cf7d5cff-0e4f-4d2c-82eb-59f450ca1b7d') + def test_delete_a_non_existing_queue(self): + # Delete is an idempotent operation + non_existent_queue = data_utils.rand_name('Queue_name') + resp, _ = self.client.delete_queue(non_existent_queue) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('c5973d87-5b59-446c-8e81-a8e28de9e61d') + def test_delete_the_deleted_queue(self): + # Delete is an idempotent operation + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + self.client.delete_queue(queue_name) + # Delete again + resp, _ = self.client.delete_queue(queue_name) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('a54e2715-478a-4701-9080-a06b9364dc74') + def test_delete_queue_with_invalid_auth_token(self): + # Delete queue with empty headers + # X-Auth-Token is not provided + queue_name = self.queues[data_utils.rand_int_id(0, + len(self.queues) - 1)] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.delete_queue, + queue_name) + + @classmethod + def resource_cleanup(cls): + for queue_name in cls.queues: + cls.client.delete_queue(queue_name) + super(QueueNegativeTestJSON, cls).resource_cleanup() diff --git a/zaqar/tests/tempest_plugin/tests/v2/test_subscriptions_negative.py b/zaqar/tests/tempest_plugin/tests/v2/test_subscriptions_negative.py new file mode 100644 index 000000000..2e623a667 --- /dev/null +++ b/zaqar/tests/tempest_plugin/tests/v2/test_subscriptions_negative.py @@ -0,0 +1,391 @@ +# Copyright (c) 2016 LARSEN & TOUBRO LIMITED. 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 uuid + +from tempest import config +from tempest.lib.common.utils import data_utils +from tempest.lib import exceptions as lib_exc +from tempest import test + +from zaqar.tests.tempest_plugin.tests import base + +CONF = config.CONF + + +class TestSubscriptionsNegative(base.BaseV2MessagingTest): + + @classmethod + def resource_setup(cls): + super(TestSubscriptionsNegative, cls).resource_setup() + cls.queue_name = data_utils.rand_name('Queues-Test') + # Create Queue + cls.client.create_queue(cls.queue_name) + + def _create_subscriptions(self): + bodys = self.generate_subscription_body() + results = [] + for body in bodys: + resp, body = self.create_subscription(queue_name=self.queue_name, + rbody=body) + results.append((resp, body)) + return results + + # Create Subscriptions + + @test.attr(type=['negative']) + @test.idempotent_id('fe0d8ec1-1a64-4490-8869-e821b2252e74') + def test_create_subscriptions_with_duplicate_subscriber(self): + # Adding a subscription to the queue + results = self._create_subscriptions() + # Adding a duplicate subscriber + rbody = {'subscriber': 'http://fake:8080', + 'options': {'MessagingKeyMsg': 'MessagingValueMsg'}, + 'ttl': 293305} + self.assertRaises(lib_exc.Conflict, + self.create_subscription, self.queue_name, rbody) + # Delete the subscriptions created + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('0bda2907-a783-4614-af16-23d7a7d53b72') + def test_create_subscriptions_with_invalid_body(self): + # Missing subscriber parameter in body + 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') + option_body = {key: value} + rbody = {'options': option_body, 'ttl': message_ttl} + self.assertRaises(lib_exc.BadRequest, + self.create_subscription, self.queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('36601d23-77d5-42b1-b234-6789acdda7ba') + def test_create_subscriptions_with_no_body(self): + # Missing parameters in body + rbody = {} + self.assertRaises(lib_exc.BadRequest, + self.create_subscription, self.queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('1d510d93-635f-4161-b071-91f838d6907e') + def test_create_subscriptions_with_invalid_subscriber(self): + # The subscriber type of subscription must be supported in the list + # ['http', 'https', 'mailto'] + 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') + option_body = {key: value} + subscriber = 'fake' + rbody = {'options': option_body, 'ttl': message_ttl, + 'subscriber': subscriber} + self.assertRaises(lib_exc.BadRequest, + self.create_subscription, self.queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('65be33a4-a063-47e1-b56b-9d7aa979bbcb') + def test_create_subscriptions_with_unsupported_subscriber(self): + # The subscriber type of subscription must be supported in the list + # ['http', 'https', 'mailto'] + 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') + option_body = {key: value} + subscriber = 'email://fake' + rbody = {'options': option_body, 'ttl': message_ttl, + 'subscriber': subscriber} + self.assertRaises(lib_exc.BadRequest, + self.create_subscription, self.queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('cada6c25-0f59-4021-a4c3-961945913998') + def test_create_subscriptions_with_invalid_options(self): + # Options must be a dict + message_ttl = data_utils.\ + rand_int_id(start=60, end=CONF.messaging.max_message_ttl) + option_body = '123' + subscriber = 'http://fake:8080' + rbody = {'options': option_body, 'ttl': message_ttl, + 'subscriber': subscriber} + self.assertRaises(lib_exc.BadRequest, + self.create_subscription, self.queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('84c1e298-c632-4ccb-859f-afe9a390081c') + def test_create_subscriptions_with_non_integer_value_for_ttl(self): + # The subscriber type of subscription must be supported in the list + # ['http', 'https', 'mailto'] + message_ttl = "123" + key = data_utils.arbitrary_string(size=20, base_text='MessagingKey') + value = data_utils.arbitrary_string(size=20, + base_text='MessagingValue') + option_body = {key: value} + subscriber = 'http://fake:8080' + rbody = {'options': option_body, 'ttl': message_ttl, + 'subscriber': subscriber} + self.assertRaises(lib_exc.BadRequest, + self.create_subscription, self.queue_name, rbody) + + @test.attr(type=['negative']) + @test.idempotent_id('1302e137-4db6-48ad-b779-ef2095198bc2') + def test_create_a_subscription_without_a_token(self): + # X-Auth-Token is not provided + 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') + option_body = {key: value} + subscriber = 'http://fake:8080' + rbody = {'options': option_body, 'ttl': message_ttl, + 'subscriber': subscriber} + + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.create_subscription, self.queue_name, rbody) + + # List Subscriptions + + @test.attr(type=['negative']) + @test.idempotent_id('e2109835-34ad-4f0a-8bbb-43d475d1315d') + def test_list_subscriptions_from_non_existing_queue(self): + # Request for listing subscriptions from a non existent queue + non_existent_queue = data_utils.rand_name('rand_queuename') + resp, _ = self.client.list_subscription(non_existent_queue) + self.assertEqual('200', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('95d7c77f-4912-49ce-9f38-cfcc6d5cd65b') + def test_list_subscriptions_from_queue_with_no_subsciptions(self): + # Request to list subscription + resp, _ = self.client.list_subscription(self.queue_name) + self.assertEqual('200', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('72f8c0b7-23d8-40ef-ae7c-212cc0751946') + def test_list_subscription_without_a_token(self): + # X-Auth-Token is not provided + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.list_subscription, self.queue_name) + + # Show Subscriptions + + @test.attr(type=['negative']) + @test.idempotent_id('7ecc2cb9-a0f4-4d03-b903-ecf2917fda13') + def test_show_subscriptions_from_non_existing_queue(self): + # Show subscription details from a non existent queue + non_existent_queue = data_utils.rand_name('rand_queuename') + invalid_id = '123' + self.assertRaises(lib_exc.NotFound, + self.show_subscription, non_existent_queue, + invalid_id) + + @test.attr(type=['negative']) + @test.idempotent_id('bb46d838-e9f9-4851-a788-c30bff41c484') + def test_show_subscriptions_with_invalid_id(self): + # Show subscription details with invaild id + invalid_id = '123' + self.assertRaises(lib_exc.NotFound, + self.show_subscription, self.queue_name, invalid_id) + + @test.attr(type=['negative']) + @test.idempotent_id('1120f006-397a-4e8b-9e79-e2dc96b37d46') + def test_show_subscriptions_after_deleting_subscription(self): + # Create subscription + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + # Delete subscription + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + # Show the details of the subscription + self.assertRaises(lib_exc.NotFound, + self.show_subscription, self.queue_name, + subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('47a3f29f-6ddb-4cf2-87ed-a2b97733f386') + def test_show_subscription_without_a_token(self): + # X-Auth-Token is not provided + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.show_subscription, self.queue_name, + subscription_id) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + # Update Subscriptions + + @test.attr(type=['negative']) + @test.idempotent_id('5c93b468-cb84-424f-af35-d4f5febc7c56') + def test_update_subscription_on_non_existing_queue(self): + # Update subscription on a non existing queue + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + non_existent_queue = data_utils.rand_name('rand_queuename') + update_rbody = {'ttl': 1000} + resp, _ = self.client.update_subscription(non_existent_queue, + subscription_id, + update_rbody) + self.assertEqual('204', resp['status']) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('b383a29a-08f1-418f-8adb-c29ef080358c') + def test_update_subscription_with_invalid_id(self): + # Update subscription using invalid id + results = self._create_subscriptions() + subscription_id = str(uuid.uuid4()) + update_rbody = {'ttl': 100} + self.assertRaises(lib_exc.NotFound, + self.client.update_subscription, self.queue_name, + subscription_id, update_rbody) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('4e446118-fa90-4f67-9a91-e157fbaa5a4c') + def test_update_subscription_with_empty_body(self): + # Update subscription with no body + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + update_rbody = {' '} + self.assertRaises(lib_exc.BadRequest, + self.client.update_subscription, self.queue_name, + subscription_id, update_rbody) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('966f5356-9d0b-46c6-9d57-26bcd9d8e699') + def test_update_subscription_with_invalid_TTL(self): + # Update subscription using invalid TTL + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + update_rbody = {'ttl': 50} + self.assertRaises(lib_exc.BadRequest, + self.client.update_subscription, self.queue_name, + subscription_id, update_rbody) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('8838f3b2-d4c3-42e2-840c-4314e334a2f0') + def test_update_subscription_with_invalid_json_in_request_body(self): + # Update subscription with invalid json + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + update_rbody = {"123"} + self.assertRaises(lib_exc.BadRequest, + self.client.update_subscription, self.queue_name, + subscription_id, update_rbody) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('8bfe5638-0126-483e-b88a-2767fa6564e6') + def test_update_subscription_with_invalid_token(self): + # X-Auth-Token is not provided + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + update_rbody = {"ttl": "1000"} + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.update_subscription, self.queue_name, + subscription_id, update_rbody) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + # Delete Subscriptions + + @test.attr(type=['negative']) + @test.idempotent_id('bb885255-ccac-47e1-a491-2630f205df58') + def test_delete_subscription_from_a_non_existing_queue(self): + # Delete subscription from a non existing queue + rbody = {'subscriber': 'http://fake123:8080', + 'options': {'MessagingKey': 'MessagingValue'}, + 'ttl': 2935} + results = self.create_subscription(self.queue_name, rbody) + subscription_id = results[1]["subscription_id"] + non_existent_queue = data_utils.rand_name('rand_queuename') + resp, _ = self.client.delete_subscription(non_existent_queue, + subscription_id) + self.assertEqual('204', resp['status']) + + @test.attr(type=['negative']) + @test.idempotent_id('a7007b4b-1ab1-4121-9d59-afe5eb82d31c') + def test_delete_subscription_using_a_nonexisting_id(self): + # Delete subscription with non existent id + results = self._create_subscriptions() + subscription_id = str(uuid.uuid4()) + resp, _ = self.client.delete_subscription(self.queue_name, + subscription_id) + self.assertEqual('204', resp['status']) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @test.attr(type=['negative']) + @test.idempotent_id('8faf37ee-4abe-4586-9e4b-ed896129a3e8') + def test_delete_subscription_with_invalid_token(self): + # X-Auth-Token is not provided + results = self._create_subscriptions() + subscription_id = results[0][1]["subscription_id"] + self.client.auth_provider.set_alt_auth_data( + request_part='headers', + auth_data=None + ) + self.assertRaises(lib_exc.Unauthorized, + self.client.delete_subscription, self.queue_name, + subscription_id) + for result in results: + subscription_id = result[1]["subscription_id"] + self.delete_subscription(self.queue_name, subscription_id) + + @classmethod + def resource_cleanup(cls): + cls.delete_queue(cls.queue_name) + super(TestSubscriptionsNegative, cls).resource_cleanup()