9
9
import requests
10
10
import json
11
11
import boto3
12
+ import random
12
13
import __init__
13
14
from localstack .utils .aws import aws_stack
14
15
from localstack .utils import common
35
36
INSTALL_DIR_ES = '%s/elasticsearch' % INSTALL_DIR_INFRA
36
37
TMP_ARCHIVE_ES = '/tmp/localstack.es.zip'
37
38
39
+ ERROR_PROBABILITY = 0.05
40
+
38
41
# set up logger
39
42
LOGGER = logging .getLogger (__name__ )
40
43
@@ -365,7 +368,12 @@ def update_apigateway(method, path, data, headers, response=None, return_forward
365
368
return True
366
369
367
370
368
- def update_kinesis (method , path , data , headers , response = None , return_forward_info = False ):
371
+ def update_kinesis (method , path , data , headers , response = None , return_forward_info = False , return_errors = 0 ):
372
+ # return_errors tells this method whether to include errors in its response
373
+ # 0: no errors
374
+ # 1: sometimes error response (governed by ERROR_PROBABILITY)
375
+ # 2: always error response
376
+ return_errors = 1
369
377
if return_forward_info :
370
378
return True
371
379
@@ -388,6 +396,7 @@ def update_kinesis(method, path, data, headers, response=None, return_forward_in
388
396
records .append (record )
389
397
stream_name = data ['StreamName' ]
390
398
lambda_api .process_kinesis_records (records , stream_name )
399
+ return put_records_response (records , return_errors )
391
400
392
401
393
402
def update_dynamodb (method , path , data , headers , response = None , return_forward_info = False ):
@@ -470,6 +479,49 @@ def dynamodb_extract_keys(item, table_name):
470
479
return result
471
480
472
481
482
+ # helper methods for response object
483
+ def put_records_response (records , return_errors ):
484
+ response = {
485
+ 'FailedRecordCount' : 0 ,
486
+ 'Records' : [
487
+ ]
488
+ }
489
+ for rec in records :
490
+ response = mock_record (response , return_errors )
491
+ return response
492
+
493
+
494
+ def mock_record (response , return_errors ):
495
+ if return_errors == 0 :
496
+ record = good_record ()
497
+ elif return_errors == 1 :
498
+ record = unreliable_record ()
499
+ else :
500
+ record = error_record ()
501
+ if 'ErrorCode' in record :
502
+ response ['FailedRecordCount' ] += 1
503
+ response ['Records' ].append (record )
504
+ return response
505
+
506
+
507
+ def good_record ():
508
+ return {"SequenceNumber" : 1 , "ShardId" : 1 }
509
+
510
+
511
+ def error_record ():
512
+ return {
513
+ "ErrorCode" : "ProvisionedThroughputExceededException" ,
514
+ "ErrorMessage" : "Rate exceeded for shard shardId-1 in stream X under account 1."
515
+ }
516
+
517
+
518
+ def unreliable_record ():
519
+ if (random .random () < ERROR_PROBABILITY ):
520
+ return bad_record ()
521
+ else :
522
+ return good_record ()
523
+
524
+
473
525
if __name__ == '__main__' :
474
526
print ('Starting local dev environment. CTRL-C to quit.' )
475
527
logging .basicConfig (level = logging .WARNING )
0 commit comments