pythonaws-lambdawiremocklocalstack

How to mock response for request.get object in AWS Lambda deployed through localstack for local testing purpose


As per requirement I am doing the lambda testing locally using the LocalStack. I could able to deploy and invoke the lambda using localstack. But I get an error in the lambda handler code, as my code is accessing some external link through requests.get() module.

I have mocked those external link locally using wiremock, So If I try to access those link on terminal, I can get the response, but I gets below error when its getting called from Lambda which was invoked by Localstack.

Error:

INFO:root:error MyHTTPConnectionPool(host='localhost', port=8082): Max retries exceeded with url: /api/v1/health (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x7fff8314cee0>: Failed to establish a new connection: [Errno 111] Connection refused'))

Below is my localstack and wiremock configuration. I am creating both docker container with docker-compose.yml file

version: "3.3"

services:
  localstack:
    container_name: "${LOCALSTACK_DOCKER_NAME-localstack_main}"
    image: localstack/localstack:3.0.0
    platform: linux/amd64
    ports:
      - "4566:4566"
    expose:
      - "4566"
    environment:
      - SERVICES=lambda,s3,iam,logs
      - AWS_DEFAULT_REGION=eu-west-1
      - SKIP_SSL_CERT_DOWNLOAD=true
    networks:
      - shared-network

  wiremock:
    container_name: wiremock-container
    platform: linux/amd64
    image: wiremock/wiremock:2.31.0
    volumes:
      - $PWD/resources/wiremock:/home/wiremock
    ports:
      - "8082:8080"
    networks:
      - shared-network

networks:
  shared-network:
    name: local_network

Below is the Lambda handler code

def lambda_handler(event, context):
    print("Lambda invoked")
    # Some code
    my_external_url = "http://localhost:8082/api/v1/health" # I am setting this link to get the mocked response through localstack
    requests.get(my_external_url).json() # I get the error here
    # Some code
    return {
        'status': 'OK',
    }

I am mocking the links through wiremock, I can use any other way also for mocking the link if suggested. But I need to use localstack to invoke the lambda. Obviously there should be some use cases where lambda is trying to access some link, and local testing can be done through localstack by mocking those links.


Solution

  • I found there are 2 issues in the code. 1: When it's in Network and when one docker wants to communicate to the another docker, we need to call api like http://host.docker.internal:8080/api/v1/health instead of http://localhost:8080/api/v1/health

    1. This has solved the issue locally running the test cases locally but when I tried it though Jenkins I ended up having the same error mentioned in my question. As a solution I have updated my localstack configuration in docker compose file, I have passed below configuration.

      extra_hosts:

      • "host.docker.internal:host-gateway"