1
+ from random import randint
1
2
from typing import Callable
2
3
from unittest .mock import patch
3
4
8
9
from aws_lambda_powertools .utilities .batch import PartialSQSProcessor , batch_processor , sqs_batch_processor
9
10
from aws_lambda_powertools .utilities .batch .base import BatchProcessor , EventType
10
11
from aws_lambda_powertools .utilities .batch .exceptions import SQSBatchProcessingError
12
+ from tests .functional .utils import decode_kinesis_data , str_to_b64
11
13
12
14
13
15
@pytest .fixture (scope = "module" )
@@ -28,6 +30,31 @@ def factory(body: str):
28
30
return factory
29
31
30
32
33
+ @pytest .fixture (scope = "module" )
34
+ def kinesis_event_factory () -> Callable :
35
+ def factory (body : str ):
36
+ seq = "" .join (str (randint (0 , 9 )) for _ in range (52 ))
37
+ partition_key = str (randint (1 , 9 ))
38
+ return {
39
+ "kinesis" : {
40
+ "kinesisSchemaVersion" : "1.0" ,
41
+ "partitionKey" : partition_key ,
42
+ "sequenceNumber" : seq ,
43
+ "data" : str_to_b64 (body ),
44
+ "approximateArrivalTimestamp" : 1545084650.987 ,
45
+ },
46
+ "eventSource" : "aws:kinesis" ,
47
+ "eventVersion" : "1.0" ,
48
+ "eventID" : f"shardId-000000000006:{ seq } " ,
49
+ "eventName" : "aws:kinesis:record" ,
50
+ "invokeIdentityArn" : "arn:aws:iam::123456789012:role/lambda-role" ,
51
+ "awsRegion" : "us-east-2" ,
52
+ "eventSourceARN" : "arn:aws:kinesis:us-east-2:123456789012:stream/lambda-stream" ,
53
+ }
54
+
55
+ return factory
56
+
57
+
31
58
@pytest .fixture (scope = "module" )
32
59
def record_handler () -> Callable :
33
60
def handler (record ):
@@ -39,6 +66,17 @@ def handler(record):
39
66
return handler
40
67
41
68
69
+ @pytest .fixture (scope = "module" )
70
+ def kinesis_record_handler () -> Callable :
71
+ def handler (record ):
72
+ body = decode_kinesis_data (record )
73
+ if "fail" in body :
74
+ raise Exception ("Failed to process record." )
75
+ return body
76
+
77
+ return handler
78
+
79
+
42
80
@pytest .fixture (scope = "module" )
43
81
def config () -> Config :
44
82
return Config (region_name = "us-east-1" )
@@ -366,3 +404,61 @@ def test_batch_processor_context_with_failure(sqs_event_factory, record_handler)
366
404
assert processed_messages [1 ] == ("success" , second_record ["body" ], second_record )
367
405
assert len (batch .fail_messages ) == 1
368
406
assert batch .response () == {"batchItemFailures" : [{first_record ["receiptHandle" ]: first_record ["messageId" ]}]}
407
+
408
+
409
+ def test_batch_processor_kinesis_context_success_only (kinesis_event_factory , kinesis_record_handler ):
410
+ # GIVEN
411
+ first_record = kinesis_event_factory ("success" )
412
+ second_record = kinesis_event_factory ("success" )
413
+ records = [first_record , second_record ]
414
+ processor = BatchProcessor (event_type = EventType .KinesisDataStreams )
415
+
416
+ # WHEN
417
+ with processor (records , kinesis_record_handler ) as batch :
418
+ processed_messages = batch .process ()
419
+
420
+ # THEN
421
+ assert processed_messages == [
422
+ ("success" , decode_kinesis_data (first_record ), first_record ),
423
+ ("success" , decode_kinesis_data (second_record ), second_record ),
424
+ ]
425
+
426
+ assert batch .response () == {"batchItemFailures" : []}
427
+
428
+
429
+ def test_batch_processor_kinesis_context_with_failure (kinesis_event_factory , kinesis_record_handler ):
430
+ # GIVEN
431
+ first_record = kinesis_event_factory ("failure" )
432
+ second_record = kinesis_event_factory ("success" )
433
+ records = [first_record , second_record ]
434
+ processor = BatchProcessor (event_type = EventType .KinesisDataStreams )
435
+
436
+ # WHEN
437
+ with processor (records , kinesis_record_handler ) as batch :
438
+ processed_messages = batch .process ()
439
+
440
+ # THEN
441
+ assert processed_messages [1 ] == ("success" , decode_kinesis_data (second_record ), second_record )
442
+ assert len (batch .fail_messages ) == 1
443
+ assert batch .response () == {
444
+ "batchItemFailures" : [{first_record ["eventID" ]: first_record ["kinesis" ]["sequenceNumber" ]}]
445
+ }
446
+
447
+
448
+ def test_batch_processor_kinesis_middleware_with_failure (kinesis_event_factory , kinesis_record_handler ):
449
+ # GIVEN
450
+ first_record = kinesis_event_factory ("failure" )
451
+ second_record = kinesis_event_factory ("success" )
452
+ event = {"Records" : [first_record , second_record ]}
453
+
454
+ processor = BatchProcessor (event_type = EventType .KinesisDataStreams )
455
+
456
+ @batch_processor (record_handler = kinesis_record_handler , processor = processor )
457
+ def lambda_handler (event , context ):
458
+ return processor .response ()
459
+
460
+ # WHEN
461
+ result = lambda_handler (event , {})
462
+
463
+ # THEN
464
+ assert len (result ["batchItemFailures" ]) == 1
0 commit comments