Skip to content

javajon/pact-with-kubernetes

Repository files navigation

Pact Testing with Kubernetes

This project is a collection of a few Gradle based projects and Docker containers that demonstrate consumer-driven contract testing using Pact and Kubernetes.

Highly cohesive and loosely coupled business functions can have a significant impact on your agility to continuously deliver features. Microservices in containers is an effective mechanism for continuous delivery. However, before you bite into that big sandwich, consider how provisioning a variety of data flavors as containerized endpoints could greatly improve your testing coverage.

How many times have you heard a colleague say, “Well that feature does not have integration tests because it requires a database with some specialized data”? Balderdash - put your data flavors in containers!

This project explores a solution to create a pipeline of data flavors. We use Docker images, Kubernetes Pods and Minikube to provision these endpoints. See how a Gradle project drives integration tests against these Pod endpoints, all ready for your continuous integration pipeline. In the end, you can see the power of Consumer Driven Contracts against your dataset flavors.

Pact is a testing framework that guarantees the Consumer Driven Contracts are satisfied by the Provider. A consumer is a client who defines a set of tests that define the contracts, the pacts. Those pacts are documents what is stored in a pact repository. At any time, the writers and tests of the API, the providers, can pull those contracts and run them as tests against their changing API.

Empower your team to create their own dataset flavors in containers for developing Consumer Driven Contracts. See a wall to integration testing come down.

In this project, you will build and deploy two containers with a Gradle based project, deploy several containers to a Kubernetes cluster and interact with the Pact tools using Gradle based project.

Kubernetes containers Gradle based projects
Private container registry H2 Database seeded with some world statistics
H2 Database Microservice to model the world data
REST/JSON Microservice Testing with mocks producing Pacts
Pact Broker Pact verification

The steps below are also captured in a collection of screen shot videos in the file readme-video-examples.zip

Where Do I Start?

The consumer tests are a good place to start, but first get the technology stack up and running. The consumer will need to publish the pact and the service provider will need to run the pacts.

How do I set up the live service provider?

The cluster runs on Kubernetes. Here we use the Minikube solution to set up a simple Kubernetes cluster. You may run this project on Windows, OS X or Linux based on your preferences.

Installs

Ensure you have a command prompt that can run shell scripts, on Windows Git Bash, ConEmu or Cmder can work well.

VirtualBox

Install VirtualBox, as this is an ideal cross platform virtual machine manager tested with Minikube. For any virtualization solution you may need to enable the virtualization BIOS setting. Here is an article on enabling Intel VT and AMD-V virtualization hardware extensions in the BIOS.

The chart below offers one-liner shell command that will download the current version of two executables needed to initialize and interact with Minikube and Kubernetes from the command line.

Minikube and KubeCtl

For Linux or OS X

curl -Lo minikube https://github.com/kubernetes/minikube/releases/latest && chmod +x minikube && sudo mv minikube /usr/local/bin/

For Windows with Git Bash (or equivalent Linux shell)

curl -Lo minikube.exe https://storage.googleapis.com/minikube/releases/latest/minikube-windows-amd64.exe

Start Kubernetes

Normally Minikube is installed into the virtual machine with just a simple command 'minikube start', however for this project there are a few other things needed so all those details are encompassed in this script. Before starting view the script to see what it does.

Start Kubernetes

./start.sh

In a few minutes Minikube will be running with a complete Kubernetes cluster and the script will complete. Next, set the environment parameters to allow Minikube and KubeCtl to interact with the new running cluster:

Initialize environment settings

. ./env.sh && minikube status

For each command prompt that interacts with Minikube be sure to always first source this env.sh script (you can add this sourcing to your .bash_profile). Kubernetes will now be running several support services including a dashboard, a private Docker registry and Heapster as a resource monitor. You can run the Kubernetes dashboard and see these services running in the kube-system namespace.

Explore Kubernetes

minikube dashboard

Select pacts from the namespace dropdown and notice the Workload lists are empty. Kubernetes is now ready to start accepting some declarations so it can standup the ms-cities and h2 database we require for the Pact verification.

Deploy the Containers

Deploy h2-world-a Container

Build and deploy the database container

cd h2-world-a && ./gradlew pushImage && cd ..

The database container image is now listed in the private registry running on the cluster.

Deploy ms-cities Container

Build and deploy the ms-cities microservice container

cd ms-cities && ./gradlew pushImage && cd ..

The ms-cities container image is now listed in the private registry running on the cluster.

View Container Registry Contents

While you just deployed two containers to the registry, it's difficult to see them without a view that lists the contents of the registry. Run this command to add a service that enables a browser based viewer for the registry:

Start a registry viewer service

kubectl create -f cluster/registry-ui

Shortly, based on your machine and network speed the registry will be browsable.

View the registry 

minikube service --namespace kube-system registry-ui

This command will point your browser to the registry listing page and there the h2-world-a and ms-cities repositories are listed.

Start Pact Broker

The Pact files will need to be deployed to a Pack Broker, so the broker needs to be started.

Start the Pact Broker Service

kubectl create -f cluster/pact-broker

Shortly, the broker will be browsable.

View the Pact broker contents

minikube service --namespace pact pact-broker

The broker listing indicates the broker is responding, but will be empty since the Pacts have not been pushed yet.

Start h2-world-a Service

While the database container image has been pushed into the registry the database service is not running.

Start the database

kubectl create -f cluster/h2-world-a

Shortly the database will be available. The database comes with a browser based SQL viewer.

Explore the database

minikube service --namespace pact h2-world-a

This will open two tabs in your browser, close the second tab as it's the JDBC URL and in the first tab you will see a JDBC web form. In the web form connect to the database with this JDBC URL:

jdbc:h2:/usr/h2-data/world

Leave the User Name and Password fields blank and click the Connect button. At the subsequent browser page the world database can be explored with standard SQL commands.

Start ms-cities Service

While the ms-cities microservice image has been pushed into the registry the microservice is not running.

Start the ms-cities service

kubectl create -f cluster/ms-cities

Shortly the ms-cities service will be available.

Request information from the service

minikube service --namespace pact ms-cities

This will open a browser tab with the error message Whitelabel Error Page. This is expected as the service requires a specific REST call. Add any of these to the end of the browser URL

Relative REST calls for ms-cities

/city/random, /city/denver, /city/list or /city/largest

How Do I Generate and Verify Pacts?

Publish Pact Tests

The Pact broker listing is currently empty. The Pacts need to be pushed to this broker.

Push Pacts to Broker

cd pact-consumer-cities && ./gradlew pactPublish && cd ..

Verify the Pacts have been deployed to the broker by viewing the listing.

View the Pact broker listings

minikube service --namespace pact pact-broker

Verify Pact Tests

Services are running and the Pacts are deployed so now it's time to Run the provider tests and verify them against the producer running in Kubernetes.

Verify the Pacts

cd pact-provider-world && ./gradlew pactVerify && cd ..

The tests will run and generate the results. But wait, the test failed!. You should see the error message "Expected 'Denver' but received 'This is wrong'". The pack verification for the /city/denver failed. To fix the problem modify the ms-world's CityController class's getDenver() method to correct the error.

Rebuild and push the corrected ms-cities microservice

cd ms-cities && ./gradlew pushImage && cd ..

Force the update of the existing ms-cities pod with

kubectl delete pod --namespace pact $(kubectl get pod --namespace pact -o=custom-columns=NAME:.metadata.name | grep ms-cities)

Wait a few seconds, then again run the pactVerify and notice both tests now pass.

RE-verify the Pacts

cd pact-provider-world && ./gradlew pactVerify && cd ..

You should see the output of the verifications ending with "BUILD SUCCESSFUL".

That's It !

You now have performed Pact based tests using Pact, Kubernetes, Microservices and Containers. Notice how you could create more databases with different seeds, more client tests that generate more contacts and more services with a variety of Pacts.

How can I customize it?

There is more data in the database in other tables. You can use the ms-cities as an example microservice and use it to access different data. First look at the database contents and envision a new service to get more data. First write a Pact test that describes, from a customer point of view, what should be delivered. Verify the Pact tests run with the mocked service and publish the Pacts. Clone the ms-cities microservice and write your own model that provides the service you have envisioned. Deploy the new service.

Credits and References

If you have further interest about this project and related topics you can meet me on tour with the []No Fluff Just Stuff](www.nofluffjuststuff.com) events. Through any channel, I would appreciate your feedback.

This project was tested using Minikube v0.20.0 with Kubernetes V1.7.0 and VirtualBox 5.1.22

How do I shut down?

Suspend Minikube and the entire cluster

minikube stop

or

Delete the Kubernetes pact namespaces

kubectl delete namespace pact

The easiest way to start fresh is to remove the Minikube virtual machine from VirtualBox

This will remove the whole Minikube installation

minikube delete

The Minikube installation can always be recreate with the start.sh script.

About

Demonstrates Pact testing using Kubernetes.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published