Best Python code snippet using localstack_python
test_lambda.py
Source:test_lambda.py
...200 retry(receive_message, retries=10, sleep=3)201 # clean up202 sqs_client.delete_queue(QueueUrl=queue_url)203 lambda_client.delete_function(FunctionName=lambda_name)204def _check_lambda_logs(func_name, expected_lines=None):205 if not expected_lines:206 expected_lines = []207 log_events = LambdaTestBase.get_lambda_logs(func_name)208 log_messages = [e["message"] for e in log_events]209 for line in expected_lines:210 if ".*" in line:211 found = [re.match(line, m) for m in log_messages]212 if any(found):213 continue214 assert line in log_messages215def test_create_lambda_function():216 """Basic test that creates and deletes a Lambda function"""217 func_name = "lambda_func-{}".format(short_uid())218 kms_key_arn = f"arn:aws:kms:{aws_stack.get_region()}:{TEST_AWS_ACCOUNT_ID}:key11"219 vpc_config = {220 "SubnetIds": ["subnet-123456789"],221 "SecurityGroupIds": ["sg-123456789"],222 }223 tags = {"env": "testing"}224 kwargs = {225 "FunctionName": func_name,226 "Runtime": LAMBDA_RUNTIME_PYTHON37,227 "Handler": LAMBDA_DEFAULT_HANDLER,228 "Role": LAMBDA_TEST_ROLE,229 "KMSKeyArn": kms_key_arn,230 "Code": {231 "ZipFile": create_lambda_archive(load_file(TEST_LAMBDA_PYTHON_ECHO), get_content=True)232 },233 "Timeout": 3,234 "VpcConfig": vpc_config,235 "Tags": tags,236 "Environment": {"Variables": {"foo": "bar"}},237 }238 client = aws_stack.connect_to_service("lambda")239 client.create_function(**kwargs)240 function_arn = lambda_function_arn(func_name)241 partial_function_arn = ":".join(function_arn.split(":")[3:])242 # Get function by Name, ARN and partial ARN243 for func_ref in [func_name, function_arn, partial_function_arn]:244 rs = client.get_function(FunctionName=func_ref)245 assert rs["Configuration"].get("KMSKeyArn", "") == kms_key_arn246 assert rs["Configuration"].get("VpcConfig", {}) == vpc_config247 assert rs["Tags"] == tags248 # clean up249 client.delete_function(FunctionName=func_name)250 with pytest.raises(Exception) as exc:251 client.delete_function(FunctionName=func_name)252 assert "ResourceNotFoundException" in str(exc)253class LambdaTestBase(unittest.TestCase):254 # TODO remove once refactoring to pytest is complete255 def check_lambda_logs(self, func_name, expected_lines=[]):256 log_events = LambdaTestBase.get_lambda_logs(func_name)257 log_messages = [e["message"] for e in log_events]258 for line in expected_lines:259 if ".*" in line:260 found = [re.match(line, m) for m in log_messages]261 if any(found):262 continue263 self.assertIn(line, log_messages)264 @staticmethod265 def get_lambda_logs(func_name):266 logs_client = aws_stack.connect_to_service("logs")267 log_group_name = "/aws/lambda/%s" % func_name268 streams = logs_client.describe_log_streams(logGroupName=log_group_name)["logStreams"]269 streams = sorted(streams, key=lambda x: x["creationTime"], reverse=True)270 log_events = logs_client.get_log_events(271 logGroupName=log_group_name, logStreamName=streams[0]["logStreamName"]272 )["events"]273 return log_events274class TestLambdaBaseFeatures(unittest.TestCase):275 def test_forward_to_fallback_url_dynamodb(self):276 db_table = "lambda-records"277 ddb_client = aws_stack.connect_to_service("dynamodb")278 def num_items():279 return len((run_safe(ddb_client.scan, TableName=db_table) or {"Items": []})["Items"])280 items_before = num_items()281 _run_forward_to_fallback_url("dynamodb://%s" % db_table)282 items_after = num_items()283 self.assertEqual(items_before + 3, items_after)284 def test_forward_to_fallback_url_http(self):285 class MyUpdateListener(ProxyListener):286 def forward_request(self, method, path, data, headers):287 records.append({"data": data, "headers": headers, "method": method, "path": path})288 return lambda_result289 lambda_result = {"result": "test123"}290 local_port = get_free_tcp_port()291 proxy = start_proxy(local_port, backend_url=None, update_listener=MyUpdateListener())292 local_url = "%s://localhost:%s" % (get_service_protocol(), local_port)293 # test 1: forward to LAMBDA_FALLBACK_URL294 records = []295 _run_forward_to_fallback_url(local_url)296 items_after = len(records)297 for record in records:298 self.assertIn("non-existing-lambda", record["headers"]["lambda-function-name"])299 self.assertEqual(3, items_after)300 # create test Lambda301 lambda_name = "test-%s" % short_uid()302 testutil.create_lambda_function(303 handler_file=TEST_LAMBDA_PYTHON,304 func_name=lambda_name,305 libs=TEST_LAMBDA_LIBS,306 )307 # test 2: forward to LAMBDA_FORWARD_URL308 records = []309 inv_results = _run_forward_to_fallback_url(310 local_url, lambda_name=lambda_name, fallback=False311 )312 items_after = len(records)313 for record in records:314 headers = record["headers"]315 self.assertIn("/lambda/", headers["Authorization"])316 self.assertEqual("POST", record["method"])317 self.assertIn("/functions/%s/invocations" % lambda_name, record["path"])318 self.assertTrue(headers.get("X-Amz-Client-Context"))319 self.assertEqual("RequestResponse", headers.get("X-Amz-Invocation-Type"))320 self.assertEqual({"foo": "bar"}, json.loads(to_str(record["data"])))321 self.assertEqual(3, items_after)322 # assert result payload matches323 response_payload = inv_results[0]["Payload"].read()324 self.assertEqual(lambda_result, json.loads(response_payload))325 # clean up / shutdown326 lambda_client = aws_stack.connect_to_service("lambda")327 lambda_client.delete_function(FunctionName=lambda_name)328 proxy.stop()329 def test_adding_fallback_function_name_in_headers(self):330 lambda_client = aws_stack.connect_to_service("lambda")331 ddb_client = aws_stack.connect_to_service("dynamodb")332 db_table = "lambda-records"333 config.LAMBDA_FALLBACK_URL = "dynamodb://%s" % db_table334 lambda_client.invoke(335 FunctionName="non-existing-lambda",336 Payload=b"{}",337 InvocationType="RequestResponse",338 )339 result = run_safe(ddb_client.scan, TableName=db_table)340 self.assertEqual("non-existing-lambda", result["Items"][0]["function_name"]["S"])341 def test_dead_letter_queue(self):342 sqs_client = aws_stack.connect_to_service("sqs")343 lambda_client = aws_stack.connect_to_service("lambda")344 # create DLQ and Lambda function345 queue_name = "test-%s" % short_uid()346 lambda_name = "test-%s" % short_uid()347 queue_url = sqs_client.create_queue(QueueName=queue_name)["QueueUrl"]348 queue_arn = aws_stack.sqs_queue_arn(queue_name)349 testutil.create_lambda_function(350 handler_file=TEST_LAMBDA_PYTHON,351 func_name=lambda_name,352 libs=TEST_LAMBDA_LIBS,353 runtime=LAMBDA_RUNTIME_PYTHON36,354 DeadLetterConfig={"TargetArn": queue_arn},355 )356 # invoke Lambda, triggering an error357 payload = {lambda_integration.MSG_BODY_RAISE_ERROR_FLAG: 1}358 lambda_client.invoke(359 FunctionName=lambda_name,360 Payload=json.dumps(payload),361 InvocationType="Event",362 )363 # assert that message has been received on the DLQ364 def receive_dlq():365 result = sqs_client.receive_message(QueueUrl=queue_url, MessageAttributeNames=["All"])366 self.assertGreater(len(result["Messages"]), 0)367 msg_attrs = result["Messages"][0]["MessageAttributes"]368 self.assertIn("RequestID", msg_attrs)369 self.assertIn("ErrorCode", msg_attrs)370 self.assertIn("ErrorMessage", msg_attrs)371 retry(receive_dlq, retries=8, sleep=2)372 # update DLQ config373 lambda_client.update_function_configuration(FunctionName=lambda_name, DeadLetterConfig={})374 # invoke Lambda again, assert that status code is 200 and error details contained in the payload375 result = lambda_client.invoke(376 FunctionName=lambda_name, Payload=json.dumps(payload), LogType="Tail"377 )378 payload = json.loads(to_str(result["Payload"].read()))379 self.assertEqual(200, result["StatusCode"])380 self.assertEqual("Unhandled", result["FunctionError"])381 self.assertEqual("$LATEST", result["ExecutedVersion"])382 self.assertIn("Test exception", payload["errorMessage"])383 self.assertIn("Exception", payload["errorType"])384 self.assertEqual(list, type(payload["stackTrace"]))385 log_result = result.get("LogResult")386 self.assertTrue(log_result)387 logs = to_str(base64.b64decode(to_str(log_result)))388 self.assertIn("START", logs)389 self.assertIn("Test exception", logs)390 self.assertIn("END", logs)391 self.assertIn("REPORT", logs)392 # clean up393 sqs_client.delete_queue(QueueUrl=queue_url)394 lambda_client.delete_function(FunctionName=lambda_name)395 def test_success_destination(self):396 payload = {}397 _assess_lambda_destination_invocation("Success", payload, self)398 def test_failure_destination(self):399 payload = {lambda_integration.MSG_BODY_RAISE_ERROR_FLAG: 1}400 _assess_lambda_destination_invocation("RetriesExhausted", payload, self)401 def test_add_lambda_permission(self):402 function_name = "lambda_func-{}".format(short_uid())403 testutil.create_lambda_function(404 handler_file=TEST_LAMBDA_ECHO_FILE,405 func_name=function_name,406 runtime=LAMBDA_RUNTIME_PYTHON36,407 )408 iam_client = aws_stack.connect_to_service("iam")409 lambda_client = aws_stack.connect_to_service("lambda")410 # create lambda permission411 action = "lambda:InvokeFunction"412 sid = "s3"413 principal = "s3.amazonaws.com"414 resp = lambda_client.add_permission(415 FunctionName=function_name,416 Action=action,417 StatementId=sid,418 Principal=principal,419 SourceArn=aws_stack.s3_bucket_arn("test-bucket"),420 )421 self.assertIn("Statement", resp)422 # fetch lambda policy423 policy = lambda_client.get_policy(FunctionName=function_name)["Policy"]424 self.assertIsInstance(policy, str)425 policy = json.loads(to_str(policy))426 self.assertEqual(action, policy["Statement"][0]["Action"])427 self.assertEqual(sid, policy["Statement"][0]["Sid"])428 self.assertEqual(lambda_api.func_arn(function_name), policy["Statement"][0]["Resource"])429 self.assertEqual(principal, policy["Statement"][0]["Principal"]["Service"])430 self.assertEqual(431 aws_stack.s3_bucket_arn("test-bucket"),432 policy["Statement"][0]["Condition"]["ArnLike"]["AWS:SourceArn"],433 )434 # fetch IAM policy435 policies = iam_client.list_policies(Scope="Local", MaxItems=500)["Policies"]436 policy_name = get_lambda_policy_name(function_name)437 matching = [p for p in policies if p["PolicyName"] == policy_name]438 self.assertEqual(len(matching), 1)439 self.assertIn(":policy/", matching[0]["Arn"])440 # remove permission that we just added441 resp = lambda_client.remove_permission(442 FunctionName=function_name,443 StatementId=sid,444 Qualifier="qual1",445 RevisionId="r1",446 )447 self.assertEqual(200, resp["ResponseMetadata"]["HTTPStatusCode"])448 lambda_client.delete_function(FunctionName=function_name)449 def test_large_payloads(self):450 function_name = "large_payload-{}".format(short_uid())451 testutil.create_lambda_function(452 handler_file=TEST_LAMBDA_ECHO_FILE,453 func_name=function_name,454 runtime=LAMBDA_RUNTIME_PYTHON36,455 )456 lambda_client = aws_stack.connect_to_service("lambda")457 payload = {"test": "test123456" * 100 * 1000 * 5} # 5MB payload458 payload_bytes = to_bytes(json.dumps(payload))459 result = lambda_client.invoke(FunctionName=function_name, Payload=payload_bytes)460 self.assertEqual(200, result["ResponseMetadata"]["HTTPStatusCode"])461 result_data = result["Payload"].read()462 result_data = json.loads(to_str(result_data))463 self.assertEqual(payload, result_data)464 # clean up465 lambda_client.delete_function(FunctionName=function_name)466 def test_additional_docker_flags(self):467 if not use_docker():468 pytest.skip("not using docker executor")469 flags_before = config.LAMBDA_DOCKER_FLAGS470 env_value = short_uid()471 config.LAMBDA_DOCKER_FLAGS = f"-e Hello={env_value}"472 function_name = "flags-{}".format(short_uid())473 try:474 testutil.create_lambda_function(475 handler_file=TEST_LAMBDA_ENV,476 libs=TEST_LAMBDA_LIBS,477 func_name=function_name,478 )479 lambda_client = aws_stack.connect_to_service("lambda")480 result = lambda_client.invoke(FunctionName=function_name, Payload="{}")481 self.assertEqual(200, result["ResponseMetadata"]["HTTPStatusCode"])482 result_data = result["Payload"].read()483 result_data = json.loads(to_str(result_data))484 self.assertEqual({"Hello": env_value}, result_data)485 finally:486 config.LAMBDA_DOCKER_FLAGS = flags_before487 # clean up488 lambda_client.delete_function(FunctionName=function_name)489 def test_add_lambda_multiple_permission(self):490 function_name = "lambda_func-{}".format(short_uid())491 testutil.create_lambda_function(492 handler_file=TEST_LAMBDA_ECHO_FILE,493 func_name=function_name,494 runtime=LAMBDA_RUNTIME_PYTHON36,495 )496 iam_client = aws_stack.connect_to_service("iam")497 lambda_client = aws_stack.connect_to_service("lambda")498 # create lambda permissions499 action = "lambda:InvokeFunction"500 principal = "s3.amazonaws.com"501 statement_ids = ["s4", "s5"]502 for sid in statement_ids:503 resp = lambda_client.add_permission(504 FunctionName=function_name,505 Action=action,506 StatementId=sid,507 Principal=principal,508 SourceArn=aws_stack.s3_bucket_arn("test-bucket"),509 )510 self.assertIn("Statement", resp)511 # fetch IAM policy512 policies = iam_client.list_policies(Scope="Local", MaxItems=500)["Policies"]513 policy_name = get_lambda_policy_name(function_name)514 matching = [p for p in policies if p["PolicyName"] == policy_name]515 self.assertEqual(1, len(matching))516 self.assertIn(":policy/", matching[0]["Arn"])517 # validate both statements518 policy = matching[0]519 versions = iam_client.list_policy_versions(PolicyArn=policy["Arn"])["Versions"]520 self.assertEqual(1, len(versions))521 statements = versions[0]["Document"]["Statement"]522 for i in range(len(statement_ids)):523 self.assertEqual(action, statements[i]["Action"])524 self.assertEqual(lambda_api.func_arn(function_name), statements[i]["Resource"])525 self.assertEqual(principal, statements[i]["Principal"]["Service"])526 self.assertEqual(527 aws_stack.s3_bucket_arn("test-bucket"),528 statements[i]["Condition"]["ArnLike"]["AWS:SourceArn"],529 )530 # check statement_ids in reverse order531 self.assertEqual(statement_ids[abs(i - 1)], statements[i]["Sid"])532 # remove permission that we just added533 resp = lambda_client.remove_permission(534 FunctionName=function_name,535 StatementId=sid,536 Qualifier="qual1",537 RevisionId="r1",538 )539 self.assertEqual(200, resp["ResponseMetadata"]["HTTPStatusCode"])540 lambda_client.delete_function(FunctionName=function_name)541 def test_lambda_asynchronous_invocations(self):542 function_name = "lambda_func-{}".format(short_uid())543 testutil.create_lambda_function(544 handler_file=TEST_LAMBDA_ECHO_FILE,545 func_name=function_name,546 runtime=LAMBDA_RUNTIME_PYTHON36,547 )548 lambda_client = aws_stack.connect_to_service("lambda")549 # adding event invoke config550 response = lambda_client.put_function_event_invoke_config(551 FunctionName=function_name,552 MaximumRetryAttempts=123,553 MaximumEventAgeInSeconds=123,554 DestinationConfig={555 "OnSuccess": {"Destination": function_name},556 "OnFailure": {"Destination": function_name},557 },558 )559 destination_config = {560 "OnSuccess": {"Destination": function_name},561 "OnFailure": {"Destination": function_name},562 }563 # checking for parameter configuration564 self.assertEqual(123, response["MaximumRetryAttempts"])565 self.assertEqual(123, response["MaximumEventAgeInSeconds"])566 self.assertEqual(destination_config, response["DestinationConfig"])567 # over writing event invoke config568 response = lambda_client.put_function_event_invoke_config(569 FunctionName=function_name,570 MaximumRetryAttempts=123,571 DestinationConfig={572 "OnSuccess": {"Destination": function_name},573 "OnFailure": {"Destination": function_name},574 },575 )576 # checking if 'MaximumEventAgeInSeconds' is removed577 self.assertNotIn("MaximumEventAgeInSeconds", response)578 self.assertIsInstance(response["LastModified"], datetime)579 # updating event invoke config580 response = lambda_client.update_function_event_invoke_config(581 FunctionName=function_name,582 MaximumRetryAttempts=111,583 )584 # checking for updated and existing configuration585 self.assertEqual(111, response["MaximumRetryAttempts"])586 self.assertEqual(destination_config, response["DestinationConfig"])587 # clean up588 _ = lambda_client.delete_function_event_invoke_config(FunctionName=function_name)589 lambda_client.delete_function(FunctionName=function_name)590 def test_event_source_mapping_default_batch_size(self):591 function_name = "lambda_func-{}".format(short_uid())592 queue_name_1 = "queue-{}-1".format(short_uid())593 queue_name_2 = "queue-{}-2".format(short_uid())594 ddb_table = "ddb_table-{}".format(short_uid())595 testutil.create_lambda_function(596 handler_file=TEST_LAMBDA_ECHO_FILE,597 func_name=function_name,598 runtime=LAMBDA_RUNTIME_PYTHON36,599 )600 lambda_client = aws_stack.connect_to_service("lambda")601 sqs_client = aws_stack.connect_to_service("sqs")602 queue_url_1 = sqs_client.create_queue(QueueName=queue_name_1)["QueueUrl"]603 queue_arn_1 = aws_stack.sqs_queue_arn(queue_name_1)604 rs = lambda_client.create_event_source_mapping(605 EventSourceArn=queue_arn_1, FunctionName=function_name606 )607 self.assertEqual(BATCH_SIZE_RANGES["sqs"][0], rs["BatchSize"])608 uuid = rs["UUID"]609 try:610 # Update batch size with invalid value611 lambda_client.update_event_source_mapping(612 UUID=uuid,613 FunctionName=function_name,614 BatchSize=BATCH_SIZE_RANGES["sqs"][1] + 1,615 )616 self.fail("This call should not be successful as the batch size > MAX_BATCH_SIZE")617 except ClientError as e:618 self.assertEqual(INVALID_PARAMETER_VALUE_EXCEPTION, e.response["Error"]["Code"])619 queue_url_2 = sqs_client.create_queue(QueueName=queue_name_2)["QueueUrl"]620 queue_arn_2 = aws_stack.sqs_queue_arn(queue_name_2)621 try:622 # Create event source mapping with invalid batch size value623 lambda_client.create_event_source_mapping(624 EventSourceArn=queue_arn_2,625 FunctionName=function_name,626 BatchSize=BATCH_SIZE_RANGES["sqs"][1] + 1,627 )628 self.fail("This call should not be successful as the batch size > MAX_BATCH_SIZE")629 except ClientError as e:630 self.assertEqual(INVALID_PARAMETER_VALUE_EXCEPTION, e.response["Error"]["Code"])631 table_arn = aws_stack.create_dynamodb_table(ddb_table, partition_key="id")[632 "TableDescription"633 ]["TableArn"]634 rs = lambda_client.create_event_source_mapping(635 EventSourceArn=table_arn, FunctionName=function_name636 )637 self.assertEqual(BATCH_SIZE_RANGES["dynamodb"][0], rs["BatchSize"])638 # clean up639 dynamodb_client = aws_stack.connect_to_service("dynamodb")640 dynamodb_client.delete_table(TableName=ddb_table)641 sqs_client.delete_queue(QueueUrl=queue_url_1)642 sqs_client.delete_queue(QueueUrl=queue_url_2)643 lambda_client.delete_function(FunctionName=function_name)644 def test_disabled_event_source_mapping_with_dynamodb(self):645 function_name = "lambda_func-{}".format(short_uid())646 ddb_table = "ddb_table-{}".format(short_uid())647 testutil.create_lambda_function(648 handler_file=TEST_LAMBDA_ECHO_FILE,649 func_name=function_name,650 runtime=LAMBDA_RUNTIME_PYTHON36,651 )652 table_arn = aws_stack.create_dynamodb_table(ddb_table, partition_key="id")[653 "TableDescription"654 ]["TableArn"]655 lambda_client = aws_stack.connect_to_service("lambda")656 rs = lambda_client.create_event_source_mapping(657 FunctionName=function_name, EventSourceArn=table_arn658 )659 uuid = rs["UUID"]660 dynamodb = aws_stack.connect_to_resource("dynamodb")661 table = dynamodb.Table(ddb_table)662 items = [663 {"id": short_uid(), "data": "data1"},664 {"id": short_uid(), "data": "data2"},665 ]666 table.put_item(Item=items[0])667 events = get_lambda_log_events(function_name)668 # lambda was invoked 1 time669 self.assertEqual(1, len(events[0]["Records"]))670 # disable event source mapping671 lambda_client.update_event_source_mapping(UUID=uuid, Enabled=False)672 table.put_item(Item=items[1])673 events = get_lambda_log_events(function_name)674 # lambda no longer invoked, still have 1 event675 self.assertEqual(1, len(events[0]["Records"]))676 # clean up677 dynamodb_client = aws_stack.connect_to_service("dynamodb")678 dynamodb_client.delete_table(TableName=ddb_table)679 lambda_client.delete_function(FunctionName=function_name)680 def test_deletion_event_source_mapping_with_dynamodb(self):681 function_name = "lambda_func-{}".format(short_uid())682 ddb_table = "ddb_table-{}".format(short_uid())683 testutil.create_lambda_function(684 handler_file=TEST_LAMBDA_ECHO_FILE,685 func_name=function_name,686 runtime=LAMBDA_RUNTIME_PYTHON36,687 )688 table_arn = aws_stack.create_dynamodb_table(ddb_table, partition_key="id")[689 "TableDescription"690 ]["TableArn"]691 lambda_client = aws_stack.connect_to_service("lambda")692 lambda_client.create_event_source_mapping(693 FunctionName=function_name, EventSourceArn=table_arn694 )695 dynamodb_client = aws_stack.connect_to_service("dynamodb")696 dynamodb_client.delete_table(TableName=ddb_table)697 result = lambda_client.list_event_source_mappings(EventSourceArn=table_arn)698 self.assertEqual(0, len(result["EventSourceMappings"]))699 # clean up700 lambda_client.delete_function(FunctionName=function_name)701 def test_event_source_mapping_with_sqs(self):702 lambda_client = aws_stack.connect_to_service("lambda")703 sqs_client = aws_stack.connect_to_service("sqs")704 function_name = "lambda_func-{}".format(short_uid())705 queue_name_1 = "queue-{}-1".format(short_uid())706 testutil.create_lambda_function(707 handler_file=TEST_LAMBDA_ECHO_FILE,708 func_name=function_name,709 runtime=LAMBDA_RUNTIME_PYTHON36,710 )711 queue_url_1 = sqs_client.create_queue(QueueName=queue_name_1)["QueueUrl"]712 queue_arn_1 = aws_stack.sqs_queue_arn(queue_name_1)713 lambda_client.create_event_source_mapping(714 EventSourceArn=queue_arn_1, FunctionName=function_name715 )716 sqs_client.send_message(QueueUrl=queue_url_1, MessageBody=json.dumps({"foo": "bar"}))717 events = retry(get_lambda_log_events, sleep_before=3, function_name=function_name)718 # lambda was invoked 1 time719 self.assertEqual(1, len(events[0]["Records"]))720 rs = sqs_client.receive_message(QueueUrl=queue_url_1)721 self.assertIsNone(rs.get("Messages"))722 # clean up723 sqs_client.delete_queue(QueueUrl=queue_url_1)724 lambda_client.delete_function(FunctionName=function_name)725 def test_create_kinesis_event_source_mapping(self):726 function_name = "lambda_func-{}".format(short_uid())727 stream_name = "test-foobar"728 testutil.create_lambda_function(729 handler_file=TEST_LAMBDA_ECHO_FILE,730 func_name=function_name,731 runtime=LAMBDA_RUNTIME_PYTHON36,732 )733 arn = aws_stack.kinesis_stream_arn(stream_name, account_id="000000000000")734 lambda_client = aws_stack.connect_to_service("lambda")735 lambda_client.create_event_source_mapping(EventSourceArn=arn, FunctionName=function_name)736 def process_records(record):737 print("Processing {}".format(record))738 stream_name = "test-foobar"739 aws_stack.create_kinesis_stream(stream_name, delete=True)740 kinesis_connector.listen_to_kinesis(741 stream_name=stream_name,742 listener_func=process_records,743 wait_until_started=True,744 )745 kinesis = aws_stack.connect_to_service("kinesis")746 stream_summary = kinesis.describe_stream_summary(StreamName=stream_name)747 self.assertEqual(1, stream_summary["StreamDescriptionSummary"]["OpenShardCount"])748 num_events_kinesis = 10749 kinesis.put_records(750 Records=[751 {"Data": "{}", "PartitionKey": "test_%s" % i} for i in range(0, num_events_kinesis)752 ],753 StreamName=stream_name,754 )755 events = get_lambda_log_events(function_name)756 self.assertEqual(10, len(events[0]["Records"]))757 self.assertIn("eventID", events[0]["Records"][0])758 self.assertIn("eventSourceARN", events[0]["Records"][0])759 self.assertIn("eventSource", events[0]["Records"][0])760 self.assertIn("eventVersion", events[0]["Records"][0])761 self.assertIn("eventName", events[0]["Records"][0])762 self.assertIn("invokeIdentityArn", events[0]["Records"][0])763 self.assertIn("awsRegion", events[0]["Records"][0])764 self.assertIn("kinesis", events[0]["Records"][0])765 def test_function_concurrency(self):766 lambda_client = aws_stack.connect_to_service("lambda")767 function_name = "lambda_func-{}".format(short_uid())768 testutil.create_lambda_function(769 handler_file=TEST_LAMBDA_ECHO_FILE,770 func_name=function_name,771 runtime=LAMBDA_RUNTIME_PYTHON36,772 )773 response = lambda_client.put_function_concurrency(774 FunctionName=function_name, ReservedConcurrentExecutions=123775 )776 self.assertIn("ReservedConcurrentExecutions", response)777 response = lambda_client.get_function_concurrency(FunctionName=function_name)778 self.assertIn("ReservedConcurrentExecutions", response)779 response = lambda_client.delete_function_concurrency(FunctionName=function_name)780 self.assertNotIn("ReservedConcurrentExecutions", response)781 testutil.delete_lambda_function(name=function_name)782 def test_function_code_signing_config(self):783 lambda_client = aws_stack.connect_to_service("lambda")784 function_name = "lambda_func-{}".format(short_uid())785 testutil.create_lambda_function(786 handler_file=TEST_LAMBDA_ECHO_FILE,787 func_name=function_name,788 runtime=LAMBDA_RUNTIME_PYTHON36,789 )790 response = lambda_client.create_code_signing_config(791 Description="Testing CodeSigning Config",792 AllowedPublishers={793 "SigningProfileVersionArns": [794 "arn:aws:signer:%s:000000000000:/signing-profiles/test"795 % aws_stack.get_region(),796 ]797 },798 CodeSigningPolicies={"UntrustedArtifactOnDeployment": "Enforce"},799 )800 self.assertIn("Description", response["CodeSigningConfig"])801 self.assertIn(802 "SigningProfileVersionArns",803 response["CodeSigningConfig"]["AllowedPublishers"],804 )805 self.assertIn(806 "UntrustedArtifactOnDeployment",807 response["CodeSigningConfig"]["CodeSigningPolicies"],808 )809 code_signing_arn = response["CodeSigningConfig"]["CodeSigningConfigArn"]810 response = lambda_client.update_code_signing_config(811 CodeSigningConfigArn=code_signing_arn,812 CodeSigningPolicies={"UntrustedArtifactOnDeployment": "Warn"},813 )814 self.assertEqual(815 "Warn",816 response["CodeSigningConfig"]["CodeSigningPolicies"]["UntrustedArtifactOnDeployment"],817 )818 response = lambda_client.get_code_signing_config(CodeSigningConfigArn=code_signing_arn)819 self.assertEqual(200, response["ResponseMetadata"]["HTTPStatusCode"])820 response = lambda_client.put_function_code_signing_config(821 CodeSigningConfigArn=code_signing_arn, FunctionName=function_name822 )823 self.assertEqual(200, response["ResponseMetadata"]["HTTPStatusCode"])824 response = lambda_client.get_function_code_signing_config(FunctionName=function_name)825 self.assertEqual(200, response["ResponseMetadata"]["HTTPStatusCode"])826 self.assertEqual(code_signing_arn, response["CodeSigningConfigArn"])827 self.assertEqual(function_name, response["FunctionName"])828 response = lambda_client.delete_function_code_signing_config(FunctionName=function_name)829 self.assertEqual(204, response["ResponseMetadata"]["HTTPStatusCode"])830 response = lambda_client.delete_code_signing_config(CodeSigningConfigArn=code_signing_arn)831 self.assertEqual(204, response["ResponseMetadata"]["HTTPStatusCode"])832 testutil.delete_lambda_function(name=function_name)833class TestPythonRuntimes(LambdaTestBase):834 @classmethod835 def setUpClass(cls):836 cls.lambda_client = aws_stack.connect_to_service("lambda")837 cls.s3_client = aws_stack.connect_to_service("s3")838 cls.sns_client = aws_stack.connect_to_service("sns")839 Util.create_function(TEST_LAMBDA_PYTHON, TEST_LAMBDA_NAME_PY, libs=TEST_LAMBDA_LIBS)840 @classmethod841 def tearDownClass(cls):842 testutil.delete_lambda_function(TEST_LAMBDA_NAME_PY)843 def test_invocation_type_not_set(self):844 result = self.lambda_client.invoke(845 FunctionName=TEST_LAMBDA_NAME_PY, Payload=b"{}", LogType="Tail"846 )847 result_data = json.loads(result["Payload"].read())848 # assert response details849 self.assertEqual(200, result["StatusCode"])850 self.assertEqual({}, result_data["event"])851 # assert that logs are contained in response852 logs = result.get("LogResult", "")853 logs = to_str(base64.b64decode(to_str(logs)))854 self.assertIn("START", logs)855 self.assertIn("Lambda log message", logs)856 self.assertIn("END", logs)857 self.assertIn("REPORT", logs)858 def test_invocation_type_request_response(self):859 result = self.lambda_client.invoke(860 FunctionName=TEST_LAMBDA_NAME_PY,861 Payload=b"{}",862 InvocationType="RequestResponse",863 )864 result_data = result["Payload"].read()865 result_data = json.loads(to_str(result_data))866 self.assertEqual(867 "application/json",868 result["ResponseMetadata"]["HTTPHeaders"]["content-type"],869 )870 self.assertEqual(200, result["StatusCode"])871 self.assertIsInstance(result_data, dict)872 def test_invocation_type_event(self):873 result = self.lambda_client.invoke(874 FunctionName=TEST_LAMBDA_NAME_PY, Payload=b"{}", InvocationType="Event"875 )876 self.assertEqual(202, result["StatusCode"])877 def test_invocation_type_dry_run(self):878 result = self.lambda_client.invoke(879 FunctionName=TEST_LAMBDA_NAME_PY, Payload=b"{}", InvocationType="DryRun"880 )881 self.assertEqual(204, result["StatusCode"])882 def test_lambda_environment(self):883 vars = {"Hello": "World"}884 testutil.create_lambda_function(885 handler_file=TEST_LAMBDA_ENV,886 libs=TEST_LAMBDA_LIBS,887 func_name=TEST_LAMBDA_NAME_ENV,888 envvars=vars,889 )890 # invoke function and assert result contains env vars891 result = self.lambda_client.invoke(FunctionName=TEST_LAMBDA_NAME_ENV, Payload=b"{}")892 result_data = result["Payload"]893 self.assertEqual(200, result["StatusCode"])894 self.assertDictEqual(json.load(result_data), vars)895 # get function config and assert result contains env vars896 result = self.lambda_client.get_function_configuration(FunctionName=TEST_LAMBDA_NAME_ENV)897 self.assertEqual(result["Environment"], {"Variables": vars})898 # clean up899 testutil.delete_lambda_function(TEST_LAMBDA_NAME_ENV)900 def test_invocation_with_qualifier(self):901 lambda_name = "test_lambda_%s" % short_uid()902 bucket_name = "test-bucket-lambda2"903 bucket_key = "test_lambda.zip"904 # upload zip file to S3905 zip_file = testutil.create_lambda_archive(906 load_file(TEST_LAMBDA_PYTHON), get_content=True, libs=TEST_LAMBDA_LIBS907 )908 self.s3_client.create_bucket(Bucket=bucket_name)909 self.s3_client.upload_fileobj(BytesIO(zip_file), bucket_name, bucket_key)910 # create lambda function911 response = self.lambda_client.create_function(912 FunctionName=lambda_name,913 Runtime=LAMBDA_RUNTIME_PYTHON37,914 Role="r1",915 Publish=True,916 Handler="handler.handler",917 Code={"S3Bucket": bucket_name, "S3Key": bucket_key},918 Timeout=10,919 )920 self.assertIn("Version", response)921 # invoke lambda function922 data_before = b'{"foo": "bar with \'quotes\\""}'923 result = self.lambda_client.invoke(924 FunctionName=lambda_name, Payload=data_before, Qualifier=response["Version"]925 )926 data_after = json.loads(result["Payload"].read())927 self.assertEqual(json.loads(to_str(data_before)), data_after["event"])928 context = data_after["context"]929 self.assertEqual(response["Version"], context["function_version"])930 self.assertTrue(context.get("aws_request_id"))931 self.assertEqual(lambda_name, context["function_name"])932 self.assertEqual("/aws/lambda/%s" % lambda_name, context["log_group_name"])933 self.assertTrue(context.get("log_stream_name"))934 self.assertTrue(context.get("memory_limit_in_mb"))935 # assert that logs are present936 expected = ["Lambda log message - print function"]937 if use_docker():938 # Note that during regular test execution, nosetests captures the output from939 # the logging module - hence we can only expect this when running in Docker940 expected.append(".*Lambda log message - logging module")941 self.check_lambda_logs(lambda_name, expected_lines=expected)942 # clean up943 testutil.delete_lambda_function(lambda_name)944 def test_http_invocation_with_apigw_proxy(self):945 lambda_name = "test_lambda_%s" % short_uid()946 lambda_resource = "/api/v1/{proxy+}"947 lambda_path = "/api/v1/hello/world"948 lambda_request_context_path = "/" + TEST_STAGE_NAME + lambda_path949 lambda_request_context_resource_path = lambda_resource950 # create lambda function951 testutil.create_lambda_function(952 handler_file=TEST_LAMBDA_PYTHON,953 libs=TEST_LAMBDA_LIBS,954 func_name=lambda_name,955 )956 # create API Gateway and connect it to the Lambda proxy backend957 lambda_uri = aws_stack.lambda_function_arn(lambda_name)958 invocation_uri = "arn:aws:apigateway:%s:lambda:path/2015-03-31/functions/%s/invocations"959 target_uri = invocation_uri % (aws_stack.get_region(), lambda_uri)960 result = testutil.connect_api_gateway_to_http_with_lambda_proxy(961 "test_gateway2",962 target_uri,963 path=lambda_resource,964 stage_name=TEST_STAGE_NAME,965 )966 api_id = result["id"]967 url = gateway_request_url(api_id=api_id, stage_name=TEST_STAGE_NAME, path=lambda_path)968 result = safe_requests.post(969 url, data=b"{}", headers={"User-Agent": "python-requests/testing"}970 )971 content = json.loads(result.content)972 self.assertEqual(lambda_path, content["path"])973 self.assertEqual(lambda_resource, content["resource"])974 self.assertEqual(lambda_request_context_path, content["requestContext"]["path"])975 self.assertEqual(976 lambda_request_context_resource_path,977 content["requestContext"]["resourcePath"],978 )979 # clean up980 testutil.delete_lambda_function(lambda_name)981 def test_upload_lambda_from_s3(self):982 lambda_name = "test_lambda_%s" % short_uid()983 bucket_name = "test-bucket-lambda"984 bucket_key = "test_lambda.zip"985 # upload zip file to S3986 zip_file = testutil.create_lambda_archive(987 load_file(TEST_LAMBDA_PYTHON), get_content=True, libs=TEST_LAMBDA_LIBS988 )989 self.s3_client.create_bucket(Bucket=bucket_name)990 self.s3_client.upload_fileobj(BytesIO(zip_file), bucket_name, bucket_key)991 # create lambda function992 self.lambda_client.create_function(993 FunctionName=lambda_name,994 Runtime=LAMBDA_RUNTIME_PYTHON37,995 Handler="handler.handler",996 Role="r1",997 Code={"S3Bucket": bucket_name, "S3Key": bucket_key},998 Timeout=10,999 )1000 # invoke lambda function1001 data_before = b'{"foo": "bar with \'quotes\\""}'1002 result = self.lambda_client.invoke(FunctionName=lambda_name, Payload=data_before)1003 data_after = json.loads(result["Payload"].read())1004 self.assertEqual(json.loads(to_str(data_before)), data_after["event"])1005 context = data_after["context"]1006 self.assertEqual("$LATEST", context["function_version"])1007 self.assertEqual(lambda_name, context["function_name"])1008 # clean up1009 testutil.delete_lambda_function(lambda_name)1010 def test_python_lambda_running_in_docker(self):1011 if not use_docker():1012 pytest.skip("not using docker executor")1013 testutil.create_lambda_function(1014 handler_file=TEST_LAMBDA_PYTHON3,1015 libs=TEST_LAMBDA_LIBS,1016 func_name=TEST_LAMBDA_NAME_PY3,1017 runtime=LAMBDA_RUNTIME_PYTHON36,1018 )1019 result = self.lambda_client.invoke(FunctionName=TEST_LAMBDA_NAME_PY3, Payload=b"{}")1020 result_data = result["Payload"].read()1021 self.assertEqual(200, result["StatusCode"])1022 self.assertEqual("{}", to_str(result_data).strip())1023 # clean up1024 testutil.delete_lambda_function(TEST_LAMBDA_NAME_PY3)1025 def test_handler_in_submodule(self):1026 func_name = "lambda-%s" % short_uid()1027 zip_file = testutil.create_lambda_archive(1028 load_file(TEST_LAMBDA_PYTHON),1029 get_content=True,1030 libs=TEST_LAMBDA_LIBS,1031 runtime=LAMBDA_RUNTIME_PYTHON36,1032 file_name="localstack_package/def/main.py",1033 )1034 testutil.create_lambda_function(1035 func_name=func_name,1036 zip_file=zip_file,1037 handler="localstack_package.def.main.handler",1038 runtime=LAMBDA_RUNTIME_PYTHON36,1039 )1040 # invoke function and assert result1041 result = self.lambda_client.invoke(FunctionName=func_name, Payload=b"{}")1042 result_data = json.loads(result["Payload"].read())1043 self.assertEqual(200, result["StatusCode"])1044 self.assertEqual(json.loads("{}"), result_data["event"])1045 def test_python3_runtime_multiple_create_with_conflicting_module(self):1046 original_do_use_docker = lambda_api.DO_USE_DOCKER1047 try:1048 # always use the local runner1049 lambda_api.DO_USE_DOCKER = False1050 python3_with_settings1 = load_file(TEST_LAMBDA_PYTHON3_MULTIPLE_CREATE1, mode="rb")1051 python3_with_settings2 = load_file(TEST_LAMBDA_PYTHON3_MULTIPLE_CREATE2, mode="rb")1052 lambda_name1 = "test1-%s" % short_uid()1053 testutil.create_lambda_function(1054 func_name=lambda_name1,1055 zip_file=python3_with_settings1,1056 runtime=LAMBDA_RUNTIME_PYTHON36,1057 handler="handler1.handler",1058 )1059 lambda_name2 = "test2-%s" % short_uid()1060 testutil.create_lambda_function(1061 func_name=lambda_name2,1062 zip_file=python3_with_settings2,1063 runtime=LAMBDA_RUNTIME_PYTHON36,1064 handler="handler2.handler",1065 )1066 result1 = self.lambda_client.invoke(FunctionName=lambda_name1, Payload=b"{}")1067 result_data1 = result1["Payload"].read()1068 result2 = self.lambda_client.invoke(FunctionName=lambda_name2, Payload=b"{}")1069 result_data2 = result2["Payload"].read()1070 self.assertEqual(200, result1["StatusCode"])1071 self.assertIn("setting1", to_str(result_data1))1072 self.assertEqual(200, result2["StatusCode"])1073 self.assertIn("setting2", to_str(result_data2))1074 # clean up1075 testutil.delete_lambda_function(lambda_name1)1076 testutil.delete_lambda_function(lambda_name2)1077 finally:1078 lambda_api.DO_USE_DOCKER = original_do_use_docker1079 def test_lambda_subscribe_sns_topic(self):1080 function_name = "{}-{}".format(TEST_LAMBDA_FUNCTION_PREFIX, short_uid())1081 testutil.create_lambda_function(1082 handler_file=TEST_LAMBDA_ECHO_FILE,1083 func_name=function_name,1084 runtime=LAMBDA_RUNTIME_PYTHON36,1085 )1086 topic = self.sns_client.create_topic(Name=TEST_SNS_TOPIC_NAME)1087 topic_arn = topic["TopicArn"]1088 self.sns_client.subscribe(1089 TopicArn=topic_arn,1090 Protocol="lambda",1091 Endpoint=lambda_api.func_arn(function_name),1092 )1093 subject = "[Subject] Test subject"1094 message = "Hello world."1095 self.sns_client.publish(TopicArn=topic_arn, Subject=subject, Message=message)1096 events = retry(1097 check_expected_lambda_log_events_length,1098 retries=3,1099 sleep=1,1100 function_name=function_name,1101 expected_length=1,1102 regex_filter="Records.*Sns",1103 )1104 notification = events[0]["Records"][0]["Sns"]1105 self.assertIn("Subject", notification)1106 self.assertEqual(subject, notification["Subject"])1107 def test_lambda_send_message_to_sqs(self):1108 function_name = "{}-{}".format(TEST_LAMBDA_FUNCTION_PREFIX, short_uid())1109 queue_name = "lambda-queue-{}".format(short_uid())1110 sqs_client = aws_stack.connect_to_service("sqs")1111 testutil.create_lambda_function(1112 handler_file=TEST_LAMBDA_SEND_MESSAGE_FILE,1113 func_name=function_name,1114 runtime=LAMBDA_RUNTIME_PYTHON36,1115 )1116 queue_url = sqs_client.create_queue(QueueName=queue_name)["QueueUrl"]1117 event = {1118 "message": "message-from-test-lambda-{}".format(short_uid()),1119 "queue_name": queue_name,1120 "region_name": config.DEFAULT_REGION,1121 }1122 self.lambda_client.invoke(FunctionName=function_name, Payload=json.dumps(event))1123 # assert that message has been received on the Queue1124 def receive_message():1125 rs = sqs_client.receive_message(QueueUrl=queue_url, MessageAttributeNames=["All"])1126 self.assertGreater(len(rs["Messages"]), 0)1127 return rs["Messages"][0]1128 message = retry(receive_message, retries=3, sleep=2)1129 self.assertEqual(event["message"], message["Body"])1130 # clean up1131 testutil.delete_lambda_function(function_name)1132 sqs_client.delete_queue(QueueUrl=queue_url)1133 def test_lambda_put_item_to_dynamodb(self):1134 table_name = "ddb-table-{}".format(short_uid())1135 function_name = "{}-{}".format(TEST_LAMBDA_FUNCTION_PREFIX, short_uid())1136 aws_stack.create_dynamodb_table(table_name, partition_key="id")1137 testutil.create_lambda_function(1138 handler_file=TEST_LAMBDA_PUT_ITEM_FILE,1139 func_name=function_name,1140 runtime=LAMBDA_RUNTIME_PYTHON36,1141 )1142 data = {short_uid(): "data-{}".format(i) for i in range(3)}1143 event = {1144 "table_name": table_name,1145 "region_name": config.DEFAULT_REGION,1146 "items": [{"id": k, "data": v} for k, v in data.items()],1147 }1148 self.lambda_client.invoke(FunctionName=function_name, Payload=json.dumps(event))1149 dynamodb = aws_stack.connect_to_resource("dynamodb")1150 rs = dynamodb.Table(table_name).scan()1151 items = rs["Items"]1152 self.assertEqual(len(items), len(data.keys()))1153 for item in items:1154 self.assertEqual(data[item["id"]], item["data"])1155 # clean up1156 testutil.delete_lambda_function(function_name)1157 dynamodb_client = aws_stack.connect_to_service("dynamodb")1158 dynamodb_client.delete_table(TableName=table_name)1159 def test_lambda_start_stepfunctions_execution(self):1160 function_name = "{}-{}".format(TEST_LAMBDA_FUNCTION_PREFIX, short_uid())1161 resource_lambda_name = "{}-{}".format(TEST_LAMBDA_FUNCTION_PREFIX, short_uid())1162 state_machine_name = "state-machine-{}".format(short_uid())1163 testutil.create_lambda_function(1164 handler_file=TEST_LAMBDA_START_EXECUTION_FILE,1165 func_name=function_name,1166 runtime=LAMBDA_RUNTIME_PYTHON36,1167 )1168 testutil.create_lambda_function(1169 handler_file=TEST_LAMBDA_ECHO_FILE,1170 func_name=resource_lambda_name,1171 runtime=LAMBDA_RUNTIME_PYTHON36,1172 )1173 state_machine_def = {1174 "StartAt": "step1",1175 "States": {1176 "step1": {1177 "Type": "Task",1178 "Resource": aws_stack.lambda_function_arn(resource_lambda_name),1179 "ResultPath": "$.result_value",1180 "End": True,1181 }1182 },1183 }1184 sfn_client = aws_stack.connect_to_service("stepfunctions")1185 rs = sfn_client.create_state_machine(1186 name=state_machine_name,1187 definition=json.dumps(state_machine_def),1188 roleArn=aws_stack.role_arn("sfn_role"),1189 )1190 sm_arn = rs["stateMachineArn"]1191 self.lambda_client.invoke(1192 FunctionName=function_name,1193 Payload=json.dumps(1194 {1195 "state_machine_arn": sm_arn,1196 "region_name": config.DEFAULT_REGION,1197 "input": {},1198 }1199 ),1200 )1201 time.sleep(1)1202 rs = sfn_client.list_executions(stateMachineArn=sm_arn)1203 # assert that state machine get executed 1 time1204 self.assertEqual(1, len([ex for ex in rs["executions"] if ex["stateMachineArn"] == sm_arn]))1205 # clean up1206 testutil.delete_lambda_function(function_name)1207 testutil.delete_lambda_function(resource_lambda_name)1208 # clean up1209 sfn_client.delete_state_machine(stateMachineArn=sm_arn)1210 def create_multiple_lambda_permissions(self):1211 iam_client = aws_stack.connect_to_service("iam")1212 lambda_client = aws_stack.connect_to_service("lambda")1213 role_name = "role-{}".format(short_uid())1214 assume_policy_document = {1215 "Version": "2012-10-17",1216 "Statement": [1217 {1218 "Action": "sts:AssumeRole",1219 "Principal": {"Service": "lambda.amazonaws.com"},1220 }1221 ],1222 }1223 iam_client.create_role(1224 RoleName=role_name,1225 AssumeRolePolicyDocument=json.dumps(assume_policy_document),1226 )1227 Util.create_function(1228 "testLambda",1229 TEST_LAMBDA_NAME_PY,1230 runtime=LAMBDA_RUNTIME_PYTHON37,1231 libs=TEST_LAMBDA_LIBS,1232 )1233 action = "lambda:InvokeFunction"1234 sid = "logs"1235 resp = lambda_client.add_permission(1236 FunctionName="testLambda",1237 Action=action,1238 StatementId=sid,1239 Principal="logs.amazonaws.com",1240 )1241 self.assertIn("Statement", resp)1242 sid = "kinesis"1243 resp = lambda_client.add_permission(1244 FunctionName="testLambda",1245 Action=action,1246 StatementId=sid,1247 Principal="kinesis.amazonaws.com",1248 )1249 self.assertIn("Statement", resp)1250 # delete lambda1251 testutil.delete_lambda_function(TEST_LAMBDA_PYTHON)1252class TestNodeJSRuntimes:1253 def test_nodejs_lambda_running_in_docker(self, lambda_client, create_lambda_function):1254 if not use_docker():1255 pytest.skip("not using docker executor")1256 create_lambda_function(1257 func_name=TEST_LAMBDA_NAME_JS,1258 handler_file=TEST_LAMBDA_NODEJS,1259 handler="lambda_integration.handler",1260 runtime=LAMBDA_RUNTIME_NODEJS810,1261 )1262 ctx = {1263 "custom": {"foo": "bar"},1264 "client": {"snap": ["crackle", "pop"]},1265 "env": {"fizz": "buzz"},1266 }1267 result = lambda_client.invoke(1268 FunctionName=TEST_LAMBDA_NAME_JS,1269 Payload=b"{}",1270 ClientContext=to_str(base64.b64encode(to_bytes(json.dumps(ctx)))),1271 )1272 result_data = result["Payload"].read()1273 assert 200 == result["StatusCode"]1274 assert "bar" == json.loads(json.loads(result_data)["context"]["clientContext"]).get(1275 "custom"1276 ).get("foo")1277 # assert that logs are present1278 expected = [".*Node.js Lambda handler executing."]1279 _check_lambda_logs(TEST_LAMBDA_NAME_JS, expected_lines=expected)1280 def test_invoke_nodejs_lambda(self, lambda_client, create_lambda_function):1281 handler_file = os.path.join(THIS_FOLDER, "lambdas", "lambda_handler.js")1282 create_lambda_function(1283 func_name=TEST_LAMBDA_NAME_JS,1284 zip_file=testutil.create_zip_file(handler_file, get_content=True),1285 runtime=LAMBDA_RUNTIME_NODEJS14X,1286 handler="lambda_handler.handler",1287 )1288 rs = lambda_client.invoke(1289 FunctionName=TEST_LAMBDA_NAME_JS,1290 Payload=json.dumps({"event_type": "test_lambda"}),1291 )1292 assert 200 == rs["ResponseMetadata"]["HTTPStatusCode"]1293 payload = rs["Payload"].read()1294 response = json.loads(to_str(payload))1295 assert "response from localstack lambda" in response["body"]1296 events = get_lambda_log_events(TEST_LAMBDA_NAME_JS)1297 assert len(events) > 01298 def test_invoke_nodejs_lambda_with_payload_containing_quotes(1299 self, lambda_client, create_lambda_function1300 ):1301 handler_file = os.path.join(THIS_FOLDER, "lambdas", "lambda_handler.js")1302 function_name = "test_lambda_%s" % short_uid()1303 create_lambda_function(1304 func_name=function_name,1305 zip_file=testutil.create_zip_file(handler_file, get_content=True),1306 runtime=LAMBDA_RUNTIME_NODEJS14X,1307 handler="lambda_handler.handler",1308 )1309 test_string = "test_string' with some quotes"1310 body = '{"test_var": "%s"}' % test_string1311 rs = lambda_client.invoke(1312 FunctionName=function_name,1313 Payload=body,1314 )1315 assert 200 == rs["ResponseMetadata"]["HTTPStatusCode"]1316 payload = rs["Payload"].read()1317 response = json.loads(to_str(payload))1318 assert "response from localstack lambda" in response["body"]1319 events = get_lambda_log_events(function_name)1320 assert len(events) > 01321 assert test_string in str(events[0])1322class TestCustomRuntimes(LambdaTestBase):1323 @classmethod1324 def setUpClass(cls):1325 cls.lambda_client = aws_stack.connect_to_service("lambda")1326 def test_provided_runtime_running_in_docker(self):1327 if not use_docker():1328 pytest.skip("not using docker executor")1329 testutil.create_lambda_function(1330 func_name=TEST_LAMBDA_NAME_CUSTOM_RUNTIME,1331 handler_file=TEST_LAMBDA_CUSTOM_RUNTIME,1332 handler="function.handler",1333 runtime=LAMBDA_RUNTIME_PROVIDED,1334 )1335 result = self.lambda_client.invoke(1336 FunctionName=TEST_LAMBDA_NAME_CUSTOM_RUNTIME,1337 Payload=b'{"text": "bar with \'quotes\\""}',1338 )1339 result_data = result["Payload"].read()1340 self.assertEqual(200, result["StatusCode"])1341 result_data = to_str(result_data).strip()1342 # jsonify in pro (re-)formats the event json so we allow both versions here1343 self.assertIn(1344 result_data,1345 (1346 """Echoing request: '{"text": "bar with \'quotes\\""}'""",1347 """Echoing request: '{"text":"bar with \'quotes\\""}'""",1348 ),1349 )1350 # assert that logs are present1351 expected = [".*Custom Runtime Lambda handler executing."]1352 self.check_lambda_logs(TEST_LAMBDA_NAME_CUSTOM_RUNTIME, expected_lines=expected)1353 # clean up1354 testutil.delete_lambda_function(TEST_LAMBDA_NAME_CUSTOM_RUNTIME)1355class TestDotNetCoreRuntimes(LambdaTestBase):1356 @classmethod1357 def setUpClass(cls):1358 cls.lambda_client = aws_stack.connect_to_service("lambda")1359 cls.zip_file_content2 = load_file(TEST_LAMBDA_DOTNETCORE2, mode="rb")1360 cls.zip_file_content31 = load_file(TEST_LAMBDA_DOTNETCORE31, mode="rb")1361 def __run_test(self, func_name, zip_file, handler, runtime, expected_lines):1362 if not use_docker():1363 pytest.skip("not using docker executor")1364 testutil.create_lambda_function(1365 func_name=func_name, zip_file=zip_file, handler=handler, runtime=runtime1366 )1367 result = self.lambda_client.invoke(FunctionName=func_name, Payload=b"{}")1368 result_data = result["Payload"].read()1369 self.assertEqual(200, result["StatusCode"])1370 self.assertEqual("{}", to_str(result_data).strip())1371 # TODO make lambda log checks more resilient to various formats1372 # self.check_lambda_logs(func_name, expected_lines=expected_lines)1373 testutil.delete_lambda_function(func_name)1374 def test_dotnetcore2_lambda_running_in_docker(self):1375 self.__run_test(1376 func_name=TEST_LAMBDA_NAME_DOTNETCORE2,1377 zip_file=self.zip_file_content2,1378 handler="DotNetCore2::DotNetCore2.Lambda.Function::SimpleFunctionHandler",1379 runtime=LAMBDA_RUNTIME_DOTNETCORE2,1380 expected_lines=["Running .NET Core 2.0 Lambda"],1381 )1382 def test_dotnetcore31_lambda_running_in_docker(self):1383 self.__run_test(1384 func_name=TEST_LAMBDA_NAME_DOTNETCORE31,1385 zip_file=self.zip_file_content31,1386 handler="dotnetcore31::dotnetcore31.Function::FunctionHandler",1387 runtime=LAMBDA_RUNTIME_DOTNETCORE31,1388 expected_lines=["Running .NET Core 3.1 Lambda"],1389 )1390class TestRubyRuntimes(LambdaTestBase):1391 @classmethod1392 def setUpClass(cls):1393 cls.lambda_client = aws_stack.connect_to_service("lambda")1394 def test_ruby_lambda_running_in_docker(self):1395 if not use_docker():1396 pytest.skip("not using docker executor")1397 testutil.create_lambda_function(1398 func_name=TEST_LAMBDA_NAME_RUBY,1399 handler_file=TEST_LAMBDA_RUBY,1400 handler="lambda_integration.handler",1401 runtime=LAMBDA_RUNTIME_RUBY27,1402 )1403 result = self.lambda_client.invoke(FunctionName=TEST_LAMBDA_NAME_RUBY, Payload=b"{}")1404 result_data = result["Payload"].read()1405 self.assertEqual(200, result["StatusCode"])1406 self.assertEqual("{}", to_str(result_data).strip())1407 # clean up1408 testutil.delete_lambda_function(TEST_LAMBDA_NAME_RUBY)1409class TestGolangRuntimes(LambdaTestBase):1410 @classmethod1411 def setUpClass(cls):1412 cls.lambda_client = aws_stack.connect_to_service("lambda")1413 @only_in_alpine1414 def test_golang_lambda_running_locally(self):1415 if use_docker():1416 return1417 # TODO: bundle in repo1418 response = requests.get(TEST_GOLANG_LAMBDA_URL, allow_redirects=True)1419 if not response.ok:1420 response.raise_for_status()1421 open(TEST_LAMBDA_GOLANG_ZIP, "wb").write(response.content)1422 testutil.create_lambda_function(1423 func_name=TEST_LAMBDA_NAME_GOLANG,1424 zip_file=load_file(TEST_LAMBDA_GOLANG_ZIP, mode="rb"),1425 handler="handler",1426 runtime=LAMBDA_RUNTIME_GOLANG,1427 )1428 result = self.lambda_client.invoke(1429 FunctionName=TEST_LAMBDA_NAME_GOLANG, Payload=json.dumps({"name": "Test"})1430 )1431 result_data = result["Payload"].read()1432 self.maxDiff = None1433 self.assertEqual(200, result["StatusCode"])1434 self.assertEqual('"Hello Test!"', to_str(result_data).strip())1435 # clean up1436 testutil.delete_lambda_function(TEST_LAMBDA_NAME_GOLANG)1437 os.remove(TEST_LAMBDA_GOLANG_ZIP)1438class TestJavaRuntimes(LambdaTestBase):1439 @classmethod1440 def setUpClass(cls):1441 cls.lambda_client = aws_stack.connect_to_service("lambda")1442 # deploy lambda - Java1443 if not os.path.exists(TEST_LAMBDA_JAVA):1444 mkdir(os.path.dirname(TEST_LAMBDA_JAVA))1445 download(TEST_LAMBDA_JAR_URL, TEST_LAMBDA_JAVA)1446 # deploy Lambda - default handler1447 cls.test_java_jar = load_file(TEST_LAMBDA_JAVA, mode="rb")1448 zip_dir = new_tmp_dir()1449 zip_lib_dir = os.path.join(zip_dir, "lib")1450 zip_jar_path = os.path.join(zip_lib_dir, "test.lambda.jar")1451 mkdir(zip_lib_dir)1452 cp_r(1453 INSTALL_PATH_LOCALSTACK_FAT_JAR,1454 os.path.join(zip_lib_dir, "executor.lambda.jar"),1455 )1456 save_file(zip_jar_path, cls.test_java_jar)1457 cls.test_java_zip = testutil.create_zip_file(zip_dir, get_content=True)1458 testutil.create_lambda_function(1459 func_name=TEST_LAMBDA_NAME_JAVA,1460 zip_file=cls.test_java_zip,1461 runtime=LAMBDA_RUNTIME_JAVA8,1462 handler="cloud.localstack.sample.LambdaHandler",1463 )1464 # Deploy lambda - Java with stream handler.1465 # Lambda supports single JAR deployments without the zip, so we upload the JAR directly.1466 testutil.create_lambda_function(1467 func_name=TEST_LAMBDA_NAME_JAVA_STREAM,1468 zip_file=cls.test_java_jar,1469 runtime=LAMBDA_RUNTIME_JAVA8,1470 handler="cloud.localstack.awssdkv1.sample.LambdaStreamHandler",1471 )1472 # deploy lambda - Java with serializable input object1473 testutil.create_lambda_function(1474 func_name=TEST_LAMBDA_NAME_JAVA_SERIALIZABLE,1475 zip_file=cls.test_java_zip,1476 runtime=LAMBDA_RUNTIME_JAVA8,1477 handler="cloud.localstack.awssdkv1.sample.SerializedInputLambdaHandler",1478 )1479 # deploy lambda - Java with Kinesis input object1480 testutil.create_lambda_function(1481 func_name=TEST_LAMBDA_NAME_JAVA_KINESIS,1482 zip_file=cls.test_java_zip,1483 runtime=LAMBDA_RUNTIME_JAVA8,1484 handler="cloud.localstack.awssdkv1.sample.KinesisLambdaHandler",1485 )1486 @classmethod1487 def tearDownClass(cls):1488 # clean up1489 testutil.delete_lambda_function(TEST_LAMBDA_NAME_JAVA)1490 testutil.delete_lambda_function(TEST_LAMBDA_NAME_JAVA_STREAM)1491 testutil.delete_lambda_function(TEST_LAMBDA_NAME_JAVA_SERIALIZABLE)1492 testutil.delete_lambda_function(TEST_LAMBDA_NAME_JAVA_KINESIS)1493 def test_java_runtime(self):1494 self.assertIsNotNone(self.test_java_jar)1495 result = self.lambda_client.invoke(1496 FunctionName=TEST_LAMBDA_NAME_JAVA,1497 Payload=b'{"echo":"echo"}',1498 )1499 result_data = result["Payload"].read()1500 self.assertEqual(200, result["StatusCode"])1501 # TODO: find out why the assertion below does not work in Travis-CI! (seems to work locally)1502 self.assertIn("LinkedHashMap", to_str(result_data))1503 self.assertIsNotNone(result_data)1504 def test_java_runtime_with_large_payload(self):1505 self.assertIsNotNone(self.test_java_jar)1506 payload = {"test": "test123456" * 100 * 1000 * 5} # 5MB payload1507 payload = to_bytes(json.dumps(payload))1508 result = self.lambda_client.invoke(FunctionName=TEST_LAMBDA_NAME_JAVA, Payload=payload)1509 result_data = result["Payload"].read()1510 self.assertEqual(200, result["StatusCode"])1511 self.assertIn("LinkedHashMap", to_str(result_data))1512 self.assertIsNotNone(result_data)1513 def test_java_runtime_with_lib(self):1514 java_jar_with_lib = load_file(TEST_LAMBDA_JAVA_WITH_LIB, mode="rb")1515 # create ZIP file from JAR file1516 jar_dir = new_tmp_dir()1517 zip_dir = new_tmp_dir()1518 unzip(TEST_LAMBDA_JAVA_WITH_LIB, jar_dir)1519 zip_lib_dir = os.path.join(zip_dir, "lib")1520 shutil.move(os.path.join(jar_dir, "lib"), zip_lib_dir)1521 jar_without_libs_file = testutil.create_zip_file(jar_dir)1522 shutil.copy(jar_without_libs_file, os.path.join(zip_lib_dir, "lambda.jar"))1523 java_zip_with_lib = testutil.create_zip_file(zip_dir, get_content=True)1524 java_zip_with_lib_gradle = load_file(1525 os.path.join(1526 THIS_FOLDER,1527 "lambdas",1528 "java",1529 "lambda_echo",1530 "build",1531 "distributions",1532 "lambda-function-built-by-gradle.zip",1533 ),1534 mode="rb",1535 )1536 for archive in [java_jar_with_lib, java_zip_with_lib, java_zip_with_lib_gradle]:1537 lambda_name = "test-%s" % short_uid()1538 testutil.create_lambda_function(1539 func_name=lambda_name,1540 zip_file=archive,1541 runtime=LAMBDA_RUNTIME_JAVA11,1542 handler="cloud.localstack.sample.LambdaHandlerWithLib",1543 )1544 result = self.lambda_client.invoke(FunctionName=lambda_name, Payload=b'{"echo":"echo"}')1545 result_data = result["Payload"].read()1546 self.assertEqual(200, result["StatusCode"])1547 self.assertIn("echo", to_str(result_data))1548 # clean up1549 testutil.delete_lambda_function(lambda_name)1550 def test_sns_event(self):1551 result = self.lambda_client.invoke(1552 FunctionName=TEST_LAMBDA_NAME_JAVA,1553 InvocationType="Event",1554 Payload=b'{"Records": [{"Sns": {"Message": "{}"}}]}',1555 )1556 self.assertEqual(202, result["StatusCode"])1557 def test_ddb_event(self):1558 result = self.lambda_client.invoke(1559 FunctionName=TEST_LAMBDA_NAME_JAVA,1560 InvocationType="Event",1561 Payload=b'{"Records": [{"dynamodb": {"Message": "{}"}}]}',1562 )1563 self.assertEqual(202, result["StatusCode"])1564 def test_kinesis_invocation(self):1565 payload = (1566 b'{"Records": [{'1567 b'"kinesis": {"data": "dGVzdA==", "partitionKey": "partition"},'1568 b'"eventID": "shardId-000000000001:12345678901234567890123456789012345678901234567890",'1569 b'"eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test"}]}'1570 )1571 result = self.lambda_client.invoke(1572 FunctionName=TEST_LAMBDA_NAME_JAVA_KINESIS, Payload=payload1573 )1574 result_data = result["Payload"].read()1575 self.assertEqual(200, result["StatusCode"])1576 self.assertEqual('"test "', to_str(result_data).strip())1577 def test_kinesis_event(self):1578 payload = (1579 b'{"Records": [{'1580 b'"kinesis": {"data": "dGVzdA==", "partitionKey": "partition"},'1581 b'"eventID": "shardId-000000000001:12345678901234567890123456789012345678901234567890",'1582 b'"eventSourceARN": "arn:aws:kinesis:us-east-1:123456789012:stream/test"}]}'1583 )1584 result = self.lambda_client.invoke(1585 FunctionName=TEST_LAMBDA_NAME_JAVA,1586 InvocationType="Event",1587 Payload=payload,1588 )1589 result_data = result["Payload"].read()1590 self.assertEqual(202, result["StatusCode"])1591 self.assertEqual("", to_str(result_data).strip())1592 def test_stream_handler(self):1593 result = self.lambda_client.invoke(1594 FunctionName=TEST_LAMBDA_NAME_JAVA_STREAM,1595 Payload=b'{"echo":"echo"}',1596 )1597 result_data = result["Payload"].read()1598 self.assertEqual(200, result["StatusCode"])1599 self.assertEqual("{}", to_str(result_data).strip())1600 def test_serializable_input_object(self):1601 result = self.lambda_client.invoke(1602 FunctionName=TEST_LAMBDA_NAME_JAVA_SERIALIZABLE,1603 Payload=b'{"bucket": "test_bucket", "key": "test_key"}',1604 )1605 result_data = result["Payload"].read()1606 self.assertEqual(200, result["StatusCode"])1607 self.assertDictEqual(1608 json.loads(to_str(result_data)),1609 {"validated": True, "bucket": "test_bucket", "key": "test_key"},1610 )1611 def test_trigger_java_lambda_through_sns(self):1612 topic_name = "topic-%s" % short_uid()1613 bucket_name = "bucket-%s" % short_uid()1614 key = "key-%s" % short_uid()1615 function_name = TEST_LAMBDA_NAME_JAVA1616 sns_client = aws_stack.connect_to_service("sns")1617 topic_arn = sns_client.create_topic(Name=topic_name)["TopicArn"]1618 s3_client = aws_stack.connect_to_service("s3")1619 s3_client.create_bucket(Bucket=bucket_name)1620 s3_client.put_bucket_notification_configuration(1621 Bucket=bucket_name,1622 NotificationConfiguration={1623 "TopicConfigurations": [{"TopicArn": topic_arn, "Events": ["s3:ObjectCreated:*"]}]1624 },1625 )1626 sns_client.subscribe(1627 TopicArn=topic_arn,1628 Protocol="lambda",1629 Endpoint=aws_stack.lambda_function_arn(function_name),1630 )1631 events_before = run_safe(get_lambda_log_events, function_name, regex_filter="Records") or []1632 s3_client.put_object(Bucket=bucket_name, Key=key, Body="something")1633 time.sleep(2)1634 # We got an event that confirm lambda invoked1635 retry(1636 function=check_expected_lambda_log_events_length,1637 retries=3,1638 sleep=1,1639 expected_length=len(events_before) + 1,1640 function_name=function_name,1641 regex_filter="Records",1642 )1643 # clean up1644 sns_client.delete_topic(TopicArn=topic_arn)1645 s3_client.delete_objects(Bucket=bucket_name, Delete={"Objects": [{"Key": key}]})1646 s3_client.delete_bucket(Bucket=bucket_name)1647@pytest.mark.parametrize(1648 "handler,expected_result",1649 [1650 (1651 "cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom::handleRequestCustom",1652 "CUSTOM",1653 ),1654 ("cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom", "INTERFACE"),1655 ("cloud.localstack.sample.LambdaHandlerWithInterfaceAndCustom::handleRequest", "INTERFACE"),1656 ],1657)1658def test_java_custom_handler_method_specification(1659 lambda_client, create_lambda_function, handler, expected_result1660):1661 java_handler_multiple_handlers = load_file(TEST_LAMBDA_JAVA_MULTIPLE_HANDLERS, mode="rb")1662 expected = ['.*"echo": "echo".*']1663 function_name = "lambda_handler_test_%s" % short_uid()1664 create_lambda_function(1665 func_name=function_name,1666 zip_file=java_handler_multiple_handlers,1667 runtime=LAMBDA_RUNTIME_JAVA11,1668 handler=handler,1669 )1670 result = lambda_client.invoke(FunctionName=function_name, Payload=b'{"echo":"echo"}')1671 result_data = result["Payload"].read()1672 assert 200 == result["StatusCode"]1673 assert expected_result == to_str(result_data).strip('"\n ')1674 _check_lambda_logs(function_name, expected_lines=expected)1675class TestDockerBehaviour(LambdaTestBase):1676 @classmethod1677 def setUpClass(cls):1678 cls.lambda_client = aws_stack.connect_to_service("lambda")1679 cls.s3_client = aws_stack.connect_to_service("s3")1680 def test_code_updated_on_redeployment(self):1681 lambda_api.LAMBDA_EXECUTOR.cleanup()1682 func_name = "test_code_updated_on_redeployment"1683 # deploy function for the first time1684 testutil.create_lambda_function(1685 func_name=func_name,1686 handler_file=TEST_LAMBDA_ENV,1687 libs=TEST_LAMBDA_LIBS,1688 envvars={"Hello": "World"},...
test_lambda_integration_sqs.py
Source:test_lambda_integration_sqs.py
...910 mapping_uuid = create_event_source_mapping_response["UUID"]911 cleanups.append(lambda: lambda_client.delete_event_source_mapping(UUID=mapping_uuid))912 snapshot.match("create_event_source_mapping_response", create_event_source_mapping_response)913 _await_event_source_mapping_enabled(lambda_client, mapping_uuid)914 def _check_lambda_logs():915 events = get_lambda_log_events(function_name, logs_client=logs_client)916 # once invoked917 assert len(events) == 1918 records = events[0]["Records"]919 # one record processed920 assert len(records) == 1921 # check for correct record presence922 if "body" in json.dumps(filter):923 item_matching_str = json.dumps(item_matching)924 assert records[0]["body"] == item_matching_str925 return events926 invocation_events = retry(_check_lambda_logs, retries=10)927 snapshot.match("invocation_events", invocation_events)928 rs = sqs_client.receive_message(QueueUrl=queue_url_1)...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!