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!!
