Skip to content

Commit dcaad60

Browse files
Add sqs hook tests (#59586)
* Update test assertions and code formatting * Add assertions to verify queue and message attributes are actually set * Add assertion to verify message delay works correctly * Remove redundant 'is not None' checks * Fix setup fixture to use hook.create_queue instead of get_conn * Add periods to all docstrings * Add comprehensive async message tests * Use global constants instead of magic strings in tests * Combine message attribute assertions into single dict comparison * Fix SQS hook tests to handle dict response from create_queue The create_queue method returns a dict with 'QueueUrl' key, not a string. Updated tests to extract QueueUrl from the response dict. --------- Co-authored-by: Tyrell H <[email protected]>
1 parent 50e10d6 commit dcaad60

File tree

1 file changed

+131
-1
lines changed
  • providers/amazon/tests/unit/amazon/aws/hooks

1 file changed

+131
-1
lines changed

providers/amazon/tests/unit/amazon/aws/hooks/test_sqs.py

Lines changed: 131 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,17 +25,126 @@
2525
from airflow.providers.amazon.aws.hooks.sqs import SqsHook
2626

2727
QUEUE_URL = "https://sqs.region.amazonaws.com/123456789/test-queue"
28+
QUEUE_NAME = "test-queue"
2829
MESSAGE_BODY = "test message"
2930

31+
MAX_MESSAGE_SIZE = "262144"
32+
DELAY = 5
33+
DEDUPE = "banana"
34+
MSG_ATTRIBUTES = {
35+
"Author": {
36+
"StringValue": "test-user",
37+
"DataType": "String",
38+
},
39+
"Priority": {
40+
"StringValue": "1",
41+
"DataType": "Number",
42+
},
43+
}
44+
3045
MESSAGE_ID_KEY = "MessageId"
3146

47+
SEND_MESSAGE_DEFAULTS = {
48+
"DelaySeconds": 0,
49+
"MessageAttributes": {},
50+
}
51+
3252

3353
class TestSqsHook:
54+
@pytest.fixture(autouse=True)
55+
def setup_test_queue(self):
56+
"""Create a test queue before each test."""
57+
with mock_aws():
58+
hook = SqsHook(aws_conn_id="aws_default")
59+
response = hook.create_queue(queue_name=QUEUE_NAME)
60+
self.queue_url = response["QueueUrl"]
61+
yield
62+
63+
@pytest.fixture
64+
def hook(self):
65+
"""Fixture to provide a SqsHook instance."""
66+
with mock_aws():
67+
yield SqsHook(aws_conn_id="aws_default")
68+
3469
@mock_aws
3570
def test_get_conn(self):
3671
hook = SqsHook(aws_conn_id="aws_default")
3772
assert hook.get_conn() is not None
3873

74+
def test_create_queue(self, hook):
75+
"""Test that create_queue creates a queue and returns the queue URL."""
76+
queue_name = "test-create-queue"
77+
response = hook.create_queue(queue_name=queue_name)
78+
79+
assert isinstance(response, dict)
80+
assert "QueueUrl" in response
81+
assert queue_name in response["QueueUrl"]
82+
83+
def test_create_queue_with_attributes(self, hook):
84+
"""Test creating a queue with custom attributes."""
85+
queue_name = "test-queue-with-attributes"
86+
attributes = {
87+
"DelaySeconds": str(DELAY),
88+
"MaximumMessageSize": MAX_MESSAGE_SIZE,
89+
}
90+
91+
response = hook.create_queue(queue_name=queue_name, attributes=attributes)
92+
93+
assert isinstance(response, dict)
94+
assert "QueueUrl" in response
95+
assert queue_name in response["QueueUrl"]
96+
97+
# Verify attributes were actually set on the queue
98+
queue_attrs = hook.get_conn().get_queue_attributes(
99+
QueueUrl=response["QueueUrl"], AttributeNames=["DelaySeconds", "MaximumMessageSize"]
100+
)
101+
assert queue_attrs["Attributes"]["DelaySeconds"] == str(DELAY)
102+
assert queue_attrs["Attributes"]["MaximumMessageSize"] == MAX_MESSAGE_SIZE
103+
104+
def test_send_message(self, hook):
105+
"""Test sending a message to a queue."""
106+
response = hook.send_message(queue_url=self.queue_url, message_body=MESSAGE_BODY)
107+
108+
assert isinstance(response, dict)
109+
assert MESSAGE_ID_KEY in response
110+
assert "MD5OfMessageBody" in response
111+
112+
def test_send_message_with_attributes(self, hook):
113+
"""Test sending a message with message attributes."""
114+
115+
response = hook.send_message(
116+
queue_url=self.queue_url,
117+
message_body=MESSAGE_BODY,
118+
message_attributes=MSG_ATTRIBUTES,
119+
)
120+
121+
assert isinstance(response, dict)
122+
assert MESSAGE_ID_KEY in response
123+
124+
# Verify attributes were actually attached to the message
125+
received = hook.get_conn().receive_message(QueueUrl=self.queue_url, MessageAttributeNames=["All"])
126+
assert "Messages" in received
127+
message = received["Messages"][0]
128+
assert message["MessageAttributes"] == MSG_ATTRIBUTES
129+
130+
def test_send_message_with_delay(self, hook):
131+
"""Test sending a message with a delay."""
132+
delay_seconds = DELAY
133+
134+
response = hook.send_message(
135+
queue_url=self.queue_url,
136+
message_body=MESSAGE_BODY,
137+
delay_seconds=delay_seconds,
138+
)
139+
140+
assert isinstance(response, dict)
141+
assert MESSAGE_ID_KEY in response
142+
143+
# Verify the message is not immediately available (due to delay)
144+
# Immediate receive should return no messages
145+
immediate_receive = hook.get_conn().receive_message(QueueUrl=self.queue_url, WaitTimeSeconds=0)
146+
assert "Messages" not in immediate_receive or len(immediate_receive.get("Messages", [])) == 0
147+
39148

40149
@pytest.mark.asyncio
41150
class TestAsyncSqsHook:
@@ -67,7 +176,28 @@ async def test_get_async_conn(self, hook, mock_get_async_conn, mock_async_client
67176
async_conn = await hook.get_async_conn()
68177
assert async_conn is mock_async_client
69178

70-
async def test_asend_message(self, hook, mock_get_async_conn, mock_async_client):
179+
async def test_asend_message_minimal(self, hook, mock_get_async_conn, mock_async_client):
71180
response = await hook.asend_message(queue_url=QUEUE_URL, message_body=MESSAGE_BODY)
72181

73182
assert MESSAGE_ID_KEY in response
183+
mock_async_client.send_message.assert_called_once_with(
184+
MessageBody=MESSAGE_BODY, QueueUrl=QUEUE_URL, **SEND_MESSAGE_DEFAULTS
185+
)
186+
187+
async def test_asend_message_with_attributes(self, hook, mock_get_async_conn, mock_async_client):
188+
response = await hook.asend_message(
189+
queue_url=QUEUE_URL,
190+
message_body=MESSAGE_BODY,
191+
message_attributes=MSG_ATTRIBUTES,
192+
delay_seconds=DELAY,
193+
message_deduplication_id=DEDUPE,
194+
)
195+
196+
assert MESSAGE_ID_KEY in response
197+
mock_async_client.send_message.assert_called_once_with(
198+
DelaySeconds=DELAY,
199+
MessageBody=MESSAGE_BODY,
200+
MessageAttributes=MSG_ATTRIBUTES,
201+
QueueUrl=QUEUE_URL,
202+
MessageDeduplicationId=DEDUPE,
203+
)

0 commit comments

Comments
 (0)