Skip to content

Commit

Permalink
feat(consumerdsl): initial shell for Pact Go
Browse files Browse the repository at this point in the history
  • Loading branch information
mefellows committed Jun 4, 2016
1 parent da45ddc commit 2b5b06e
Show file tree
Hide file tree
Showing 25 changed files with 363 additions and 2 deletions.
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,17 @@ _testmain.go
*.exe
*.test
*.prof

pkg
bin
dist
build
output
pact-mock-service
pact-provider-verifier

*.out
*.cov
*.iml
*.idea
*.bak
23 changes: 23 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
TEST?=./...

default: test

package:
@sh -c "$(CURDIR)/scripts/package.sh"

bin:
@sh -c "$(CURDIR)/scripts/build.sh"

dev:
@TF_DEV=1 sh -c "$(CURDIR)/scripts/dev.sh"

test:
"$(CURDIR)/scripts/test.sh"

testrace:
go test -race $(TEST) $(TESTARGS)

updatedeps:
go get -d -v -p 2 ./...

.PHONY: bin default dev test updatedeps
56 changes: 54 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,54 @@
# pact-go
Golang Pact implementation
# Pact Go

Golang version of [Pact](http://pact.io). Enables consumer driven contract testing, providing a mock service and
DSL for the consumer project, and interaction playback and verification for the service Provider project.

Implements [Pact Specification v2](https://github.com/pact-foundation/pact-specification/tree/version-2),
including [flexible matching](http://docs.pact.io/documentation/matching.html).

From the [Ruby Pact website](https://github.com/realestate-com-au/pact):

> Define a pact between service consumers and providers, enabling "consumer driven contract" testing.
>
>Pact provides an RSpec DSL for service consumers to define the HTTP requests they will make to a service provider and the HTTP responses they expect back.
>These expectations are used in the consumers specs to provide a mock service provider. The interactions are recorded, and played back in the service provider
>specs to ensure the service provider actually does provide the response the consumer expects.
>
>This allows testing of both sides of an integration point using fast unit tests.
>
>This gem is inspired by the concept of "Consumer driven contracts". See http://martinfowler.com/articles/consumerDrivenContracts.html for more information.

Read [Getting started with Pact](http://dius.com.au/2016/02/03/microservices-pact/) for more information on
how to get going.


[![wercker status](https://app.wercker.com/status/273436f3ec1ec8e6ea348b81e93aeea1/s/master "wercker status")](https://app.wercker.com/project/bykey/273436f3ec1ec8e6ea348b81e93aeea1)


## Installation

* Download a [release](https://github.com/mefellows/pact-go/releases) for your OS.
* Unzip the package into a known location, and add to the `PATH`.
* Run `pact-go`

## Contact

* Twitter: [@pact_up](https://twitter.com/pact_up)
* Google users group: https://groups.google.com/forum/#!forum/pact-support

## Documentation

Additional documentation can be found in the [Pact Wiki](https://github.com/realestate-com-au/pact/wiki),
and in the [Pact-JVM wiki](https://github.com/DiUS/pact-jvm/wiki).

## Developing

For full integration testing locally, Ruby 2.1.5 must be installed. Under the hood, Pact Go bundles the [Pact Mock Service]() and [Pact Provider Verifier]() projects to implement up to v2.0 of the Pact Specification. This is only temporary, until [Pact Reference](https://github.com/pact-foundation/pact-reference/) work is completed.

* Git clone https://github.com/mefellows/pact-go.git
* Run `make dev` to build the package and setup the Ruby 'binaries' locally

### Docker

The current Wercker build uses this custom [Docker image](https://github.com/mefellows/pact-go-docker-build).
1 change: 1 addition & 0 deletions dsl/interceptor.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/interceptor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/matcher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/matcher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/mock_service.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/mock_service_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
31 changes: 31 additions & 0 deletions dsl/pact.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package dsl

import "fmt"

type Pact struct {
}

func (p *Pact) Given(state string) *Pact {
fmt.Println("Pact()")
return p
}

func (p *Pact) UponReceiving(test string) *Pact {
fmt.Println("UponReceiving()")
return p
}

func (p *Pact) WithRequest(request Request) *Pact {
fmt.Println("WithRequest()")
return p
}

func (p *Pact) WillRespondWith(response Response) *Pact {
fmt.Println("RespondWith()")
return p
}

func (p *Pact) Verify() *Pact {
fmt.Println("Verify()")
return p
}
1 change: 1 addition & 0 deletions dsl/pact_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/publisher.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/publisher_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
3 changes: 3 additions & 0 deletions dsl/request.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dsl

type Request struct{}
3 changes: 3 additions & 0 deletions dsl/response.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dsl

type Response struct{}
1 change: 1 addition & 0 deletions dsl/verifier.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
1 change: 1 addition & 0 deletions dsl/verifier_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
package dsl
14 changes: 14 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package main

import "fmt"
import "github.com/mefellows/pact-go/dsl"

func main() {
fmt.Printf("Testing")
pact := dsl.Pact{}
pact.
Given("Some state").
UponReceiving("Some name for the test").
WithRequest(dsl.Request{}).
WillRespondWith(dsl.Response{})
}
30 changes: 30 additions & 0 deletions scripts/build_standalone_packages.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#!/bin/bash

set -e

mkdir -p build
cd build

# Provider Verifier
if [ ! -d "pact-provider-verifier-${PACT_PROVIDER_VERIFIER_VERSION}" ]; then
wget https://github.com/pact-foundation/pact-provider-verifier/archive/v${PACT_PROVIDER_VERIFIER_VERSION}.zip -O temp.zip
unzip temp.zip
rm temp.zip
cd pact-provider-verifier-${PACT_PROVIDER_VERIFIER_VERSION}
bundle
bundle exec rake package
else
echo "pact provider verifier already generated, run './scripts/clean.sh' to generate a new package"
fi

# Mock Service
if [ ! -d "pact-mock_service-${PACT_MOCK_SERVICE_VERSION}" ]; then
wget https://github.com/bethesque/pact-mock_service/archive/v${PACT_MOCK_SERVICE_VERSION}.zip -O temp.zip
unzip temp.zip
rm temp.zip
cd pact-mock_service-${PACT_MOCK_SERVICE_VERSION}
bundle
bundle exec rake package
else
echo "pact mock service already generated, run './scripts/clean.sh' to generate a new package"
fi
5 changes: 5 additions & 0 deletions scripts/clean.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash -e

rm -rf build
rm -rf output
rm -rf dist
90 changes: 90 additions & 0 deletions scripts/compile.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/bin/bash

set -ex

# Create go binary and package verifier + mock service into distribution
rm -rf output/*
rm -rf dist/*
go get github.com/mitchellh/gox
go get -d ./...

# if [ -n "$(type -t rvm)" ]; then
# rvm use 2.1.5
# fi

###
### Darwin/OSX
###

rm -rf output/*
# gox -os="darwin" -arch="amd64" -output="output/{{.Dir}}_{{.OS}}_{{.Arch}}"

cd output
cp ../build/pact-provider-verifier-*/pkg/pact-provider-verifier-*osx* .
cp ../build/pact-mock_service-*/pkg/pact-mock-service-*osx*.tar.gz .

tar -xzf pact-provider-verifier-*osx*.tar.gz && rm pact-provider*.tar.gz && mv pact-provider-verifier* pact-provider-verifier
tar -xzf pact-mock-service-*osx*.tar.gz && rm pact-mock-service-*.tar.gz && mv pact-mock-service* pact-mock-service

rm -rf pact-provider*.tar.gz
rm -rf pact-mock*.tar.gz
tar -czf darwin-amd64.tar.gz * && mv darwin-amd64.tar.gz ../dist
cd ..


####
#### Windows 32bit
####

rm -rf output/*
gox -os="windows" -arch="386" -output="output/{{.Dir}}_{{.OS}}_{{.Arch}}"

cd output
cp ../build/pact-provider-verifier-*/pkg/pact-provider-verifier-*win32*.zip .
cp ../build/pact-mock_service-*/pkg/pact-mock-service-*win32*.zip .

unzip pact-provider-verifier-*win32*.zip && rm pact-provider*.zip && mv pact-provider-verifier* pact-provider-verifier
unzip pact-mock-service-*win32*.zip && rm pact-mock-service-*.zip && mv pact-mock-service* pact-mock-service

rm -rf pact-provider*.zip
rm -rf pact-mock*.zip
tar -czf windows-386.tar.gz * && mv windows-386.tar.gz ../dist
cd ..

####
#### Linux 32bit
####

rm -rf output/*
gox -os="linux" -arch="386" -output="output/{{.Dir}}_{{.OS}}_{{.Arch}}"

cd output
cp ../build/pact-provider-verifier-*/pkg/pact-provider-verifier-*linux-x86.tar.gz .
cp ../build/pact-mock_service-*/pkg/pact-mock-service-*linux-x86.tar.gz .

tar -xzf pact-provider-verifier-*linux-x86.tar.gz && rm pact-provider*.tar.gz && mv pact-provider-verifier* pact-provider-verifier
tar -xzf pact-mock-service-*linux-x86.tar.gz && rm pact-mock-service-*.tar.gz && mv pact-mock-service* pact-mock-service

rm -rf pact-provider*.tar.gz
rm -rf pact-mock*.tar.gz
tar -czf linux-386.tar.gz * && mv linux-386.tar.gz ../dist
cd ..

####
#### Linux 64bit
####

rm -rf output/*
gox -os="linux" -arch="amd64" -output="output/{{.Dir}}_{{.OS}}_{{.Arch}}"

cd output
cp ../build/pact-provider-verifier-*/pkg/pact-provider-verifier-*linux-x86_64* .
cp ../build/pact-mock_service-*/pkg/pact-mock-service-*linux-x86_64*.tar.gz .

tar -xzf pact-provider-verifier-*linux-x86_64*.tar.gz && rm pact-provider*.tar.gz && mv pact-provider-verifier* pact-provider-verifier
tar -xzf pact-mock-service-*linux-x86_64*.tar.gz && rm pact-mock-service-*.tar.gz && mv pact-mock-service* pact-mock-service

rm -rf pact-provider*.tar.gz
rm -rf pact-mock*.tar.gz
tar -czf linux-amd64.tar.gz * && mv linux-amd64.tar.gz ../dist
cd ..
9 changes: 9 additions & 0 deletions scripts/dev.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/bin/bash -e

set -e

./scripts/package.sh

# Setup dev
echo "==> Creating OS distributions..."
tar -xzf dist/darwin-amd64.tar.gz -C ..
24 changes: 24 additions & 0 deletions scripts/package.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/bash -e

set -e

export PACT_MOCK_SERVICE_VERSION=0.8.2
export PACT_PROVIDER_VERIFIER_VERSION=0.0.4

VERSION=$(go version)
echo "==> Go version ${VERSION}"

echo "==> Getting dependencies..."
export GO15VENDOREXPERIMENT=1

# Create the OS specific versions of the mock service and verifier
echo "==> Building Ruby Binaries..."
scripts/build_standalone_packages.sh

# Build each go package for specific OS, bundling the mock service and verifier
echo "==> Creating OS distributions..."
scripts/compile.sh

echo
echo "==> Results:"
ls -hl dist/
25 changes: 25 additions & 0 deletions scripts/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh
go test -race -v $(go list ./... | grep -v vendor | grep -v output | grep -v dist | grep -v build)

# Get Test dependencies
go get github.com/axw/gocov/gocov
go get github.com/mattn/goveralls
go get golang.org/x/tools/cmd/cover
go get github.com/modocache/gover

# Run test coverage on each subdirectories and merge the coverage profile.

echo "mode: count" > profile.cov

# Standard go tooling behavior is to ignore dirs with leading underscors
for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d); do
if ls $dir/*.go &> /dev/null; then
go test -covermode=count -coverprofile=$dir/profile.tmp $dir
if [ -f $dir/profile.tmp ]; then
cat $dir/profile.tmp | tail -n +2 >> profile.cov
rm $dir/profile.tmp
fi
fi
done

go tool cover -func profile.cov
27 changes: 27 additions & 0 deletions wercker.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
box: tcnksm/gox:1.5.3
build:
steps:
- setup-go-workspace
- script:
name: go test
code: |
make test
- script:
name: Publish Coveralls
code: goveralls -service="wercker.com" -coverprofile=profile.cov -repotoken $COVERALLS_TOKEN
- script:
name: gox build
code: |
XC_OS="linux darwin windows" XC_ARCH="386 amd64" make bin
- tcnksm/zip:
input: pkg
output: $WERCKER_OUTPUT_DIR/dist

deploy:
steps:
- tcnksm/ghr:
token: $GITHUB_TOKEN
version: $RELEASE_VERSION
input: dist
replace: $RELEASE_IS_DRAFT
pre-release: $RELEASE_IS_DRAFT

0 comments on commit 2b5b06e

Please sign in to comment.