Skip to content

Commit bd76812

Browse files
committed
Add failing unit and integration tests
1 parent 3ba304a commit bd76812

File tree

2 files changed

+66
-42
lines changed

2 files changed

+66
-42
lines changed
Lines changed: 53 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,73 +1,86 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING
3+
from typing import Iterator, Sequence
44

5-
if TYPE_CHECKING:
6-
from mypy_boto3_lambda import LambdaClient
7-
from mypy_boto3_s3 import S3ServiceResource
8-
from mypy_boto3_sqs import SQSServiceResource
9-
from mypy_boto3_ssm import SSMClient
5+
from mypy_boto3_s3 import S3ServiceResource
6+
from mypy_boto3_s3.service_resource import Bucket, Object
7+
from mypy_boto3_sqs import SQSServiceResource
8+
from mypy_boto3_sqs.service_resource import Message, Queue
9+
from mypy_boto3_ssm import SSMClient
1010

1111

1212
def test_notification(
13-
lambda_: LambdaClient,
1413
s3: S3ServiceResource,
1514
sqs: SQSServiceResource,
1615
ssm: SSMClient,
1716
) -> None:
1817
# Get source bucket
1918
bucket_name = ssm_param_value(ssm, "/hls/tests/forward-bucket-name")
2019
bucket = s3.Bucket(bucket_name)
21-
22-
# Get forward notification queue
2320
forward_queue_name = ssm_param_value(ssm, "/hls/tests/forward-queue-name")
2421
forward_queue = sqs.get_queue_by_name(QueueName=forward_queue_name)
25-
26-
# Get tiler queue
2722
tiler_queue_name = ssm_param_value(ssm, "/hls/tests/tiler-queue-name")
2823
tiler_queue = sqs.get_queue_by_name(QueueName=tiler_queue_name)
2924

30-
# Write S3 Object with .v2.0.json suffix to source bucket to trigger notification.
3125
body = '{ "greeting": "hello world!" }'
32-
json_key = "greeting.v2.0.json"
33-
obj = bucket.Object(json_key)
34-
obj.put(Body=body)
35-
obj.wait_until_exists()
26+
objects = write_objects(bucket, body)
3627

3728
try:
38-
# Wait for lambda function to succeed, which should be triggered by S3
39-
# notification of object created in bucket above.
40-
name = ssm_param_value(ssm, "/hls/tests/forward-function-name")
41-
waiter = lambda_.get_waiter("function_active_v2")
42-
waiter.wait(FunctionName=name, WaiterConfig={"Delay": 5, "MaxAttempts": 20})
43-
44-
# Receive message from destination queue, which should be sent by Lambda
45-
# function above.
46-
forward_messages = forward_queue.receive_messages(
47-
MaxNumberOfMessages=10, WaitTimeSeconds=20
48-
)
49-
tiler_messages = tiler_queue.receive_messages(
50-
MaxNumberOfMessages=10, WaitTimeSeconds=20
51-
)
29+
forward_messages = list(fetch_messages(forward_queue))
30+
tiler_messages = list(fetch_messages(tiler_queue))
5231
finally:
5332
# Cleanup S3 Object with .v2.0.json suffix from source bucket.
54-
obj.delete()
55-
obj.wait_until_not_exists()
33+
for obj in objects:
34+
obj.delete()
35+
obj.wait_until_not_exists()
5636

57-
# Assert message contents == S3 Object contents (written above)
58-
assert len(forward_messages) == 1
37+
# We expect 4 messages, 2 for regular and 2 for VI
38+
assert len(forward_messages) == 4
5939
assert forward_messages[0].body == body
6040

61-
# Assert message contents == S3 Object contents (written above)
62-
assert len(tiler_messages) == 1
63-
assert (
64-
tiler_messages[0].body
65-
== f"s3://{bucket_name}/{json_key.replace('.json', '_stac.json')}"
66-
)
41+
# We expect only 2 messages for the 2 non-VI objects written
42+
assert len(tiler_messages) == 2
43+
expected_bodies = [
44+
f"s3://{bucket_name}/{obj.key.replace('.json', '_stac.json')}"
45+
for obj in objects
46+
if "_VI" in obj.key
47+
]
48+
assert all(message.body in expected_bodies for message in tiler_messages)
6749

6850

6951
def ssm_param_value(ssm: SSMClient, name: str) -> str:
7052
value = ssm.get_parameter(Name=name)["Parameter"].get("Value")
7153
assert value is not None # make type checker happy
7254

7355
return value
56+
57+
58+
def write_objects(bucket: Bucket, body: str) -> Sequence[Object]:
59+
# Write S3 Objects with .v2.0.json suffix to source bucket to trigger notification.
60+
# We expect 4 messages in the forward queue and 2 in the tiler queue because the
61+
# tiler queue should not send messages for VI.
62+
63+
objects = [
64+
bucket.Object(f"{prefix}/greeting.v2.0.json")
65+
for prefix in ("L30", "S30", "L30_VI", "S30_VI")
66+
]
67+
68+
for obj in objects:
69+
obj.put(Body=body)
70+
obj.wait_until_exists()
71+
72+
return objects
73+
74+
75+
def fetch_messages(queue: Queue) -> Iterator[Message]:
76+
while messages := queue.receive_messages(
77+
MaxNumberOfMessages=10, WaitTimeSeconds=20
78+
):
79+
queue.delete_messages(
80+
Entries=[
81+
{"Id": message.message_id, "ReceiptHandle": message.receipt_handle}
82+
for message in messages
83+
]
84+
)
85+
86+
yield from messages

tests/unit/test_forward_handler.py

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,28 @@
22

33
from typing import Callable
44

5+
import pytest
56
from mypy_boto3_s3.service_resource import Object
67
from mypy_boto3_sqs.service_resource import Queue
78

89
from . import make_s3_event
910

1011

12+
@pytest.mark.parametrize(
13+
("prefix", "expect_tiler_message"),
14+
(("L30", True), ("S30", True), ("L30_VI", False), ("S30_VI", False)),
15+
)
1116
def test_lpdaac_forward_handler(
17+
prefix: str,
18+
expect_tiler_message: bool,
1219
make_s3_object_with_prefix: Callable[[str], Object],
1320
sqs_queue: Queue,
1421
) -> None:
1522
# Import here (rather than at top level) to ensure AWS mocks are established.
1623
# See http://docs.getmoto.org/en/latest/docs/getting_started.html#what-about-those-pesky-imports
1724
from hls_lpdaac.forward import _handler
1825

19-
s3_object = make_s3_object_with_prefix("L30/")
26+
s3_object = make_s3_object_with_prefix(prefix)
2027
s3_event = make_s3_event(s3_object)
2128
_handler(s3_event, lpdaac_queue_url=sqs_queue.url, tiler_queue_url=sqs_queue.url)
2229

@@ -27,7 +34,11 @@ def test_lpdaac_forward_handler(
2734
]
2835
expected_messages = [
2936
s3_object.get()["Body"].read().decode("utf-8"),
30-
f"s3://{bucket}/{key.replace('.json', '_stac.json')}",
37+
*(
38+
[f"s3://{bucket}/{key.replace('.json', '_stac.json')}"]
39+
if expect_tiler_message
40+
else []
41+
),
3142
]
3243

3344
assert messages == expected_messages

0 commit comments

Comments
 (0)