Contract testing for AWS Microservices with PACT and localstack



Table of Contents
  1. About The Project
  2. Prerequisites
  3. Installation
  4. Consumer Testing
  5. Provider Testing
  6. Pact package installation issues
  7. Links

About The Project

This project is a demo that will allow you to understand and learn how to do contract testing in an AWS Serverless microservice (AWS API Gateway and AWS Lambda) without needing to deploy any service to a real AWS environment.

This demo use the next components:

  • PACT For running the tests
  • PACT Broker For sharing the contracts
  • Localstack to run a local AWS enviroment
  • Terraform for deploying the provider

The demo is composed by two microservices Account API (Consumer) and User API (Provider).

image

Prerequisites

To run this demo you are going to need the next installed in your machine:

Docker: https://docs.docker.com/get-docker/

Terraform: https://learn.hashicorp.com/tutorials/terraform/install-cli

Node JS: https://nodejs.org/en/download/

Pact broker

Postgre db

docker run --name pactbroker-db -e POSTGRES_PASSWORD=ThePostgresPassword -e POSTGRES_USER=admin -e PGDATA=/var/lib/postgresql/data/pgdata -v /var/lib/postgresql/data:/var/lib/postgresql/data -d postgres
docker run -it --link pactbroker-db:postgres --rmGRES_PORT_5432_TCP_ADDR" -p "$POSTGRES_PORT_5432_TCP_PORT" -U admin'

Login with you password and run the next commands individually:

CREATE USER pactbrokeruser WITH PASSWORD 'TheUserPassword';
CREATE DATABASE pactbroker WITH OWNER pactbrokeruser;
GRANT ALL PRIVILEGES ON DATABASE pactbroker TO pactbrokeruser;
exit

Pact Brocker

docker run --name pactbroker --link pactbroker-db:postgres -e PACT_BROKER_DATABASE_USERNAME=pactbrokeruser -e PACT_BROKER_DATABASE_PASSWORD=TheUserPassword -e PACT_BROKER_DATABASE_HOST=postgres -e PACT_BROKER_DATABASE_NAME=pactbroker -d  -p 9292:9292 pactfoundation/pact-broker

Installation

  1. Clone the repo
https://github.com/JavierRodPi/pact-testing-demo.git
  1. Navigate to the root folder of the proyect and run localstack from the docker compose file.
docker-compose -f docker-localstack.yml up -d

Consumer (Account API)

You will find the consumer test under

~/AccountApi/contract-testing/get-user.spec.ts

In order tu run this test first you will need to install all the dependencies.

  1. From the project root folder cd AccountApi/contract-testing

  2. yarn install If you are facing issues with the installation of PACT, please review this Section

  3. Once all the dependencies are installed you will need to configure your PACT Broker path. Inside the "get-user.spec.ts" file modify

pactBroker:  "YOUR_BROKER_URL",
  1. Run the test jest

The test will generate the pact file and it will upload the pact to the broker.

Provider Testing (User API)

You will find the provider under

~/UserApi/components/get-account

In order tu run this test first you will need to build and updaload get-user to localstack:

  1. From the project root folder cd UserApi/components/get-user
  2. yarn install / npm install
  3. tsc
  4. Copy node_modules folder into dist
  5. Zip all the content inside dist and name the file "get-user.zip"
  6. cd dist
  7. aws --endpoint-url=http://localhost:4566 s3 mb s3://artifacts
  8. aws --endpoint-url=http://localhost:4566 s3 cp ./get-user.zip s3://artifacts

After building and uploading the get-user artifact into S3 you will need to create the enviroment inde localstack.

  1. From the project root folder cd UserApi/iac/env/local
  2. terraform init
  3. terraform plan
  4. terraform apply -auto-approve

Now that the local enviroment is live you will be able to continue with the provider test

Install test dependencies and run the provider test

  1. From the project root folder cd UserApi/contract-testing

  2. yarn install If you are facing issues with the installation of PACT, please review this Section

  3. Once all the dependencies are installed you will need to configure your PACT Broker path. Inside the "get-user.spec.ts" file modify: pactUrls: "YOUR_BROKER_URL",

  4. Run the test jest

Pact package installation issues

Installation work around: Source: https://github.com/pact-foundation/pact-js-core

Pact Download Location

For those that are behind a corporate firewall or are seeing issues where our package downloads binaries during installation, you can download the binaries directly from our github releases, and specify the location where you want Pact to get the binaries from using the 'config' section in your package.json file:

{
	"name": "some-project",
	...
	"config": {
		"pact_binary_location": "/home/some-user/Downloads"
	},
	...
}

It will accept both a local path or an http(s) url. It must point to the directory containing the binary needed as the binary name is appended to the end of the location. For the example given above, Pact will look for the binary at /home/some-user/Downloads/pact-1.44.0-win32.zip for a Windows system. However, by using this method, you must use the correct Pact version binary associated with this version of Pact-Core. For extra security measurements, checksum validation has been added to prevent tampering with the binaries.

If your environment uses self-signed certificates from an internal Certificate Authority (CA), you can configure this using the standard options in an npmrc file as per below:

_~/.npmrc_:

cafile=/etc/ssl/certs/ca-certificates.crt
strict-ssl=true

Skip Pact binary downloading

You can also force Pact to skip the installation of the binary during npm install by setting PACT_SKIP_BINARY_INSTALL=true. This feature is useful if you want to speed up builds that don't need Pact and don't want to modify your projects dependencies.

Note that pact-core will not be functional without the binary.

PACT_SKIP_BINARY_INSTALL=true npm install

Links

Tools

Contracts testing