Repository: getmoto/moto

Issue:
SQS:GetQueueAttributes failing when Optional AttributeNames param not passed
In updating to `moto 2.2.5`, I surfaced an issue with moto's [`sqs.get_queue_attributes`](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sqs.html#SQS.Client.get_queue_attributes) where the mock was failing when the optional `AttributeNames` parameter was not passed.

Here's a brief test that passes with `2.2.4`, but fails with `2.2.5` -- testing in a `pyenv` managed Python 3.9.5 virtualenv on macOS.

`$ cat test_sqs.py`
```
"""Illustrate breakage of sqs:GetQueueAttributes()."""

import json
import os

import boto3
import pytest
from moto import mock_sqs


@pytest.fixture(scope="function")
def aws_credentials():
    """Mock AWS Credentials for moto."""
    os.environ["AWS_ACCESS_KEY_ID"] = "testing"
    os.environ["AWS_SECRET_ACCESS_KEY"] = "testing"
    os.environ["AWS_SECURITY_TOKEN"] = "testing"
    os.environ["AWS_SESSION_TOKEN"] = "testing"


@pytest.fixture(scope="function")
def sqs(aws_credentials):
    """Mock SQS CLient."""
    with mock_sqs():
        yield boto3.client("sqs", region_name="us-east-1")


@pytest.fixture(scope="function")
def sqs_queue(sqs):
    """Mock SQS Queue."""
    queue_url = sqs.create_queue(QueueName="test-queue")["QueueUrl"]

    yield {"QueueUrl": queue_url}

    # cleanup
    sqs.delete_queue(QueueUrl=queue_url)


def batch_send_sqs_events(queue_url, events):
    """Batch send a bunch of events on SQS."""
    sqs_resource = boto3.resource("sqs", region_name="us-east-1")
    sqs_queue = sqs_resource.Queue(queue_url)
    for event in events:
        sqs_queue.send_message(MessageBody=json.dumps(event))
    return len(events)


def test_get_queue_attributes_no_param(sqs, sqs_queue):
    """
    Illustrate breakage where Optional `AttributeNames` is NOT passed.
    
    Function: SQS:GetQueueAttributes
    """
    queue_url = sqs.get_queue_url(QueueName="test-queue")["QueueUrl"]
    input_event_count = 43
    events = [{"something": "test"} for x in range(input_event_count)]

    batch_send_sqs_events(queue_url, events)

    queue_attrs = sqs.get_queue_attributes(QueueUrl=queue_url)
    assert (
        int(queue_attrs["Attributes"]["ApproximateNumberOfMessages"])
        == input_event_count
    )


def test_get_queue_attributes_passed_param(sqs, sqs_queue):
    """
    Illustrate functioning where optional `AttributeNames` param is passed.

    Function: SQS:GetQueueAttributes
    """
    queue_url = sqs.get_queue_url(QueueName="test-queue")["QueueUrl"]
    input_event_count = 43
    events = [{"something": "test"} for x in range(input_event_count)]

    batch_send_sqs_events(queue_url, events)

    queue_attrs = sqs.get_queue_attributes(QueueUrl=queue_url, AttributeNames=["All"])
    assert (
        int(queue_attrs["Attributes"]["ApproximateNumberOfMessages"])
        == input_event_count
    )
```

Problem with commit e865362 where code appending the `"All"` string to `attribute_names` was removed.  Parent commit that appends `"All"` to `attribute_names` as default when param is empty appears to function properly:
https://github.com/spulec/moto/blob/21021a6a039dcd7430b45d91c3437ebd814fa845/moto/sqs/models.py#L638-L640

Both tests pass with `moto==2.2.4`. `test_get_queue_attributes_no_param` does not pass with `moto==2.2.5`.

Steps to repro:
```
$ ls
test_sqs.py
$ pip install pytest moto==2.2.4
$ pytest
# ... observe tests passing ...
$ pip install --upgrade moto==2.2.5
$ pytest
# ... observe tests failing ...
 ```


Discussion:
Hi @tkalus, thanks for raising this, and welcome to Moto!
The `test_get_queue_attributes_no_param` does not pass against AWS either, I've just tested this - AWS does not return any attributes when omitting the AttributeNames-parameter.

Moto should not fail as it does, though, it should just return an empty response - so I'll mark it as a bug to fix this.

Resolving patch:
diff --git a/moto/sqs/models.py b/moto/sqs/models.py
--- a/moto/sqs/models.py
+++ b/moto/sqs/models.py
@@ -642,6 +642,8 @@ def delete_queue(self, queue_name):
 
     def get_queue_attributes(self, queue_name, attribute_names):
         queue = self.get_queue(queue_name)
+        if not attribute_names:
+            return {}
 
         valid_names = (
             ["All"]


Test patch:
diff --git a/tests/test_sqs/test_sqs.py b/tests/test_sqs/test_sqs.py
--- a/tests/test_sqs/test_sqs.py
+++ b/tests/test_sqs/test_sqs.py
@@ -1254,6 +1254,21 @@ def test_fifo_send_receive_message_with_attribute_name(attribute_name, expected)
     expected["SequenceNumber"](message["Attributes"].get("SequenceNumber"))
 
 
+@mock_sqs
+def test_get_queue_attributes_no_param():
+    """
+    AWS does not return the Attributes-key when omitting the AttributeNames-parameter
+    """
+    sqs = boto3.client("sqs", region_name="ap-northeast-3")
+    queue_url = sqs.create_queue(QueueName="test-queue")["QueueUrl"]
+
+    queue_attrs = sqs.get_queue_attributes(QueueUrl=queue_url)
+    queue_attrs.shouldnt.have.key("Attributes")
+
+    queue_attrs = sqs.get_queue_attributes(QueueUrl=queue_url, AttributeNames=["All"])
+    queue_attrs.should.have.key("Attributes")
+
+
 @mock_sqs
 def test_max_number_of_messages_invalid_param():
     sqs = boto3.resource("sqs", region_name="us-east-1")