diff --git a/moto/sqs/models.py b/moto/sqs/models.py index 188e25e9e..922da704f 100644 --- a/moto/sqs/models.py +++ b/moto/sqs/models.py @@ -415,7 +415,7 @@ class SQSBackend(BaseBackend): self.__dict__ = {} self.__init__(region_name) - def create_queue(self, name, **kwargs): + def create_queue(self, name, tags=None, **kwargs): queue = self.queues.get(name) if queue: try: @@ -454,6 +454,10 @@ class SQSBackend(BaseBackend): pass queue = Queue(name, region=self.region_name, **kwargs) self.queues[name] = queue + + if tags: + queue.tags = tags + return queue def list_queues(self, queue_name_prefix): @@ -654,6 +658,10 @@ class SQSBackend(BaseBackend): def untag_queue(self, queue_name, tag_keys): queue = self.get_queue(queue_name) + + if len(tag_keys) == 0: + raise RESTError('InvalidParameterValue', 'Tag keys must be between 1 and 128 characters in length.') + for key in tag_keys: try: del queue.tags[key] diff --git a/moto/sqs/responses.py b/moto/sqs/responses.py index 5ddaf8849..747fa2363 100644 --- a/moto/sqs/responses.py +++ b/moto/sqs/responses.py @@ -33,6 +33,12 @@ class SQSResponse(BaseResponse): self._attribute = self._get_map_prefix('Attribute', key_end='.Name', value_end='.Value') return self._attribute + @property + def tags(self): + if not hasattr(self, '_tags'): + self._tags = self._get_map_prefix('Tag', key_end='.Key', value_end='.Value') + return self._tags + def _get_queue_name(self): try: queue_name = self.querystring.get('QueueUrl')[0].split("/")[-1] @@ -73,12 +79,12 @@ class SQSResponse(BaseResponse): queue_name = self._get_param("QueueName") try: - queue = self.sqs_backend.create_queue(queue_name, **self.attribute) + queue = self.sqs_backend.create_queue(queue_name, self.tags, **self.attribute) except MessageAttributesInvalid as e: return self._error('InvalidParameterValue', e.description) template = self.response_template(CREATE_QUEUE_RESPONSE) - return template.render(queue=queue, request_url=request_url) + return template.render(queue_url=queue.url(request_url)) def get_queue_url(self): request_url = urlparse(self.uri) @@ -400,7 +406,11 @@ class SQSResponse(BaseResponse): queue_name = self._get_queue_name() tag_keys = self._get_multi_param('TagKey') - self.sqs_backend.untag_queue(queue_name, tag_keys) + try: + self.sqs_backend.untag_queue(queue_name, tag_keys) + except QueueDoesNotExist as e: + return self._error('AWS.SimpleQueueService.NonExistentQueue', + e.description) template = self.response_template(UNTAG_QUEUE_RESPONSE) return template.render() @@ -416,8 +426,7 @@ class SQSResponse(BaseResponse): CREATE_QUEUE_RESPONSE = """ - {{ queue.url(request_url) }} - {{ queue.visibility_timeout }} + {{ queue_url }} diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py index 56d82ea61..bc9fa8e4d 100644 --- a/tests/test_sqs/test_sqs.py +++ b/tests/test_sqs/test_sqs.py @@ -140,6 +140,22 @@ def test_create_queue_kms(): queue.attributes.get('KmsDataKeyReusePeriodSeconds').should.equal('600') +@mock_sqs +def test_create_queue_with_tags(): + client = boto3.client('sqs', region_name='us-east-1') + response = client.create_queue( + QueueName = 'test-queue-with-tags', + tags = { + 'tag_key_1': 'tag_value_1' + } + ) + queue_url = response['QueueUrl'] + + client.list_queue_tags(QueueUrl = queue_url)['Tags'].should.equal({ + 'tag_key_1': 'tag_value_1' + }) + + @mock_sqs def test_get_nonexistent_queue(): sqs = boto3.resource('sqs', region_name='us-east-1') @@ -959,6 +975,48 @@ def test_tags(): resp['Tags'].should.contain('test1') resp['Tags'].should_not.contain('test2') + # removing a non existing tag should not raise any error + client.untag_queue( + QueueUrl=queue_url, + TagKeys=[ + 'not-existing-tag' + ] + ) + client.list_queue_tags(QueueUrl=queue_url)['Tags'].should.equal({ + 'test1': 'value1' + }) + + +@mock_sqs +def test_untag_queue_errors(): + client = boto3.client('sqs', region_name='us-east-1') + + response = client.create_queue( + QueueName='test-queue-with-tags', + tags={ + 'tag_key_1': 'tag_value_1' + } + ) + queue_url = response['QueueUrl'] + + client.untag_queue.when.called_with( + QueueUrl=queue_url + '-not-existing', + TagKeys=[ + 'tag_key_1' + ] + ).should.throw( + ClientError, + "The specified queue does not exist for this wsdl version." + ) + + client.untag_queue.when.called_with( + QueueUrl=queue_url, + TagKeys=[] + ).should.throw( + ClientError, + 'Tag keys must be between 1 and 128 characters in length.' + ) + @mock_sqs def test_create_fifo_queue_with_dlq():