Skip to content

Commit

Permalink
fix(test): fix flakey tests due to race conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
bmarini authored and mefellows committed Nov 7, 2017
1 parent 7117b21 commit 9f66925
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 37 deletions.
56 changes: 32 additions & 24 deletions dsl/broker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,18 @@ import (
"fmt"
"log"
"net/http"
"net/http/httptest"
"testing"

"github.com/pact-foundation/pact-go/types"
"github.com/pact-foundation/pact-go/utils"
)

func TestPact_findConsumersNoTags(t *testing.T) {
port := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
request := types.VerifyRequest{
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
}
err := findConsumers("bobby", &request)
if err != nil {
Expand All @@ -24,17 +26,18 @@ func TestPact_findConsumersNoTags(t *testing.T) {
t.Fatalf("Expected 2 PactURLs but got: %d", len(request.PactURLs))
}

pactURL := fmt.Sprintf("http://localhost:%d/pacts/provider/bobby/consumer/jessica/version/2.0.0", port)
pactURL := fmt.Sprintf("%s/pacts/provider/bobby/consumer/jessica/version/2.0.0", s.URL)
if request.PactURLs[0] != pactURL && request.PactURLs[1] != pactURL {
t.Fatalf("Expected '%s', but got '%s'", pactURL, request.PactURLs[0])
}
}

func TestPact_findConsumersWithTags(t *testing.T) {
port := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
request := types.VerifyRequest{
Tags: []string{"dev", "prod"},
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
}
err := findConsumers("bobby", &request)
if err != nil {
Expand All @@ -45,7 +48,7 @@ func TestPact_findConsumersWithTags(t *testing.T) {
t.Fatalf("Expected 2 PactURLs but got: %d", len(request.PactURLs))
}

pactURL := fmt.Sprintf("http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.1", port)
pactURL := fmt.Sprintf("%s/pacts/provider/bobby/consumer/billy/version/1.0.1", s.URL)
if request.PactURLs[0] != pactURL && request.PactURLs[1] != pactURL {
t.Fatalf("Expected '%s', but got '%s'", pactURL, request.PactURLs[0])
}
Expand All @@ -65,10 +68,11 @@ func TestPact_findConsumersBrokerDown(t *testing.T) {
}

func TestPact_findConsumersInvalidResponse(t *testing.T) {
port := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
request := types.VerifyRequest{
Tags: []string{"broken"},
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
}
err := findConsumers("bobby", &request)

Expand All @@ -89,10 +93,11 @@ func TestPact_findConsumersInvalidURL(t *testing.T) {
}

func TestPact_findConsumersErrorResponse(t *testing.T) {
port := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
request := types.VerifyRequest{
Tags: []string{"dev"},
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
}
err := findConsumers("broken", &request)

Expand All @@ -102,10 +107,11 @@ func TestPact_findConsumersErrorResponse(t *testing.T) {
}

func TestPact_findConsumersNoConsumers(t *testing.T) {
port := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
request := types.VerifyRequest{
Tags: []string{"dev", "prod"},
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
}
err := findConsumers("idontexist", &request)
if err == nil {
Expand All @@ -114,10 +120,11 @@ func TestPact_findConsumersNoConsumers(t *testing.T) {
}

func TestPact_findConsumersAuthenticated(t *testing.T) {
port := setupMockBroker(true)
s := setupMockBroker(true)
defer s.Close()
request := types.VerifyRequest{
Tags: []string{"dev", "prod"},
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
BrokerUsername: "foo",
BrokerPassword: "bar",
}
Expand All @@ -128,10 +135,11 @@ func TestPact_findConsumersAuthenticated(t *testing.T) {
}

func TestPact_findConsumersAuthenticatedFail(t *testing.T) {
port := setupMockBroker(true)
s := setupMockBroker(true)
defer s.Close()
request := types.VerifyRequest{
Tags: []string{"dev", "prod"},
BrokerURL: fmt.Sprintf("http://localhost:%d", port),
BrokerURL: s.URL,
}
err := findConsumers("bobby", &request)

Expand All @@ -143,8 +151,7 @@ func TestPact_findConsumersAuthenticatedFail(t *testing.T) {
}

// Pretend to be a Broker for fetching Pacts
func setupMockBroker(auth bool) int {
port, _ := utils.GetFreePort()
func setupMockBroker(auth bool) *httptest.Server {
mux := http.NewServeMux()
var authFunc func(inner http.HandlerFunc) http.HandlerFunc

Expand Down Expand Up @@ -173,19 +180,21 @@ func setupMockBroker(auth bool) int {
}
}

server := httptest.NewServer(mux)

// Find latest 'bobby' consumers (no tag)
// curl --user pactuser:pact -H "accept: application/hal+json" "http://pact.onegeek.com.au/pacts/provider/bobby/latest"
mux.HandleFunc("/pacts/provider/bobby/latest", authFunc(func(w http.ResponseWriter, req *http.Request) {
log.Println("[DEBUG] get pacts for provider 'bobby'")
fmt.Fprintf(w, `{"_links":{"self":{"href":"http://localhost:%d/pacts/provider/bobby/latest","title":"Latest pact versions for the provider bobby"},"provider":{"href":"http://localhost:%d/pacticipants/bobby","title":"bobby"},"pacts":[{"href":"http://localhost:%d/pacts/provider/bobby/consumer/jessica/version/2.0.0","title":"Pact between jessica (v2.0.0) and bobby","name":"jessica"},{"href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.0","title":"Pact between billy (v1.0.0) and bobby","name":"billy"}]}}`, port, port, port, port)
fmt.Fprintf(w, `{"_links":{"self":{"href":"%s/pacts/provider/bobby/latest","title":"Latest pact versions for the provider bobby"},"provider":{"href":"%s/pacticipants/bobby","title":"bobby"},"pacts":[{"href":"%s/pacts/provider/bobby/consumer/jessica/version/2.0.0","title":"Pact between jessica (v2.0.0) and bobby","name":"jessica"},{"href":"%s/pacts/provider/bobby/consumer/billy/version/1.0.0","title":"Pact between billy (v1.0.0) and bobby","name":"billy"}]}}`, server.URL, server.URL, server.URL, server.URL)
w.Header().Add("Content-Type", "application/hal+json")
}))

// Find 'bobby' consumers for tag 'prod'
// curl --user pactuser:pact -H "accept: application/hal+json" "http://pact.onegeek.com.au/pacts/provider/bobby/latest/sit4"
mux.Handle("/pacts/provider/bobby/latest/prod", authFunc(func(w http.ResponseWriter, req *http.Request) {
log.Println("[DEBUG] get all pacts for provider 'bobby' where the tag 'prod' exists")
fmt.Fprintf(w, `{"_links":{"self":{"href":"http://localhost:%d/pacts/provider/bobby/latest/dev","title":"Latest pact versions for the provider bobby with tag 'dev'"},"provider":{"href":"http://localhost:%d/pacticipants/bobby","title":"bobby"},"pacts":[{"href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.0","title":"Pact between billy (v1.0.0) and bobby","name":"billy"}]}}`, port, port, port)
fmt.Fprintf(w, `{"_links":{"self":{"href":"%s/pacts/provider/bobby/latest/dev","title":"Latest pact versions for the provider bobby with tag 'dev'"},"provider":{"href":"%s/pacticipants/bobby","title":"bobby"},"pacts":[{"href":"%s/pacts/provider/bobby/consumer/billy/version/1.0.0","title":"Pact between billy (v1.0.0) and bobby","name":"billy"}]}}`, server.URL, server.URL, server.URL)
w.Header().Add("Content-Type", "application/hal+json")
}))

Expand All @@ -208,18 +217,17 @@ func setupMockBroker(auth bool) int {
// curl --user pactuser:pact -H "accept: application/hal+json" "http://pact.onegeek.com.au/pacts/provider/bobby/latest/sit4"
mux.Handle("/pacts/provider/bobby/latest/dev", authFunc(func(w http.ResponseWriter, req *http.Request) {
log.Println("[DEBUG] get all pacts for provider 'bobby' where the tag 'dev' exists")
fmt.Fprintf(w, `{"_links":{"self":{"href":"http://localhost:%d/pacts/provider/bobby/latest/dev","title":"Latest pact versions for the provider bobby with tag 'dev'"},"provider":{"href":"http://localhost:%d/pacticipants/bobby","title":"bobby"},"pacts":[{"href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.1","title":"Pact between billy (v1.0.1) and bobby","name":"billy"}]}}`, port, port, port)
fmt.Fprintf(w, `{"_links":{"self":{"href":"%s/pacts/provider/bobby/latest/dev","title":"Latest pact versions for the provider bobby with tag 'dev'"},"provider":{"href":"%s/pacticipants/bobby","title":"bobby"},"pacts":[{"href":"%s/pacts/provider/bobby/consumer/billy/version/1.0.1","title":"Pact between billy (v1.0.1) and bobby","name":"billy"}]}}`, server.URL, server.URL, server.URL)
w.Header().Add("Content-Type", "application/hal+json")
}))

// Actual Consumer Pact
// curl -v --user pactuser:pact -H "accept: application/json" http://pact.onegeek.com.au/pacts/provider/bobby/consumer/billy/version/1.0.0
mux.Handle("/pacts/provider/bobby/consumer/billy/version/", authFunc(func(w http.ResponseWriter, req *http.Request) {
log.Println("[DEBUG] get all pacts for provider 'bobby' where any tag exists")
fmt.Fprintf(w, `{"consumer":{"name":"billy"},"provider":{"name":"bobby"},"interactions":[{"description":"Some name for the test","provider_state":"Some state","request":{"method":"GET","path":"/foobar"},"response":{"status":200,"headers":{"Content-Type":"application/json"}}},{"description":"Some name for the test","provider_state":"Some state2","request":{"method":"GET","path":"/bazbat"},"response":{"status":200,"headers":{},"body":[[{"colour":"red","size":10,"tag":[["jumper","shirt"],["jumper","shirt"]]}]],"matchingRules":{"$.body":{"min":1},"$.body[*].*":{"match":"type"},"$.body[*]":{"min":1},"$.body[*][*].*":{"match":"type"},"$.body[*][*].colour":{"match":"regex","regex":"red|green|blue"},"$.body[*][*].size":{"match":"type"},"$.body[*][*].tag":{"min":2},"$.body[*][*].tag[*].*":{"match":"type"},"$.body[*][*].tag[*][0]":{"match":"type"},"$.body[*][*].tag[*][1]":{"match":"type"}}}}],"metadata":{"pactSpecificationVersion":"2.0.0"},"updatedAt":"2016-06-11T13:11:33+00:00","createdAt":"2016-06-09T12:46:42+00:00","_links":{"self":{"title":"Pact","name":"Pact between billy (v1.0.0) and bobby","href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.0"},"pb:consumer":{"title":"Consumer","name":"billy","href":"http://localhost:%d/pacticipants/billy"},"pb:provider":{"title":"Provider","name":"bobby","href":"http://localhost:%d/pacticipants/bobby"},"pb:latest-pact-version":{"title":"Pact","name":"Latest version of this pact","href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/latest"},"pb:previous-distinct":{"title":"Pact","name":"Previous distinct version of this pact","href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.0/previous-distinct"},"pb:diff-previous-distinct":{"title":"Diff","name":"Diff with previous distinct version of this pact","href":"http://localhost:%d/pacts/provider/bobby/consumer/billy/version/1.0.0/diff/previous-distinct"},"pb:pact-webhooks":{"title":"Webhooks for the pact between billy and bobby","href":"http://localhost:%d/webhooks/provider/bobby/consumer/billy"},"pb:tag-prod-version":{"title":"Tag this version as 'production'","href":"http://localhost:%d/pacticipants/billy/versions/1.0.0/tags/prod"},"pb:tag-version":{"title":"Tag version","href":"http://localhost:%d/pacticipants/billy/versions/1.0.0/tags/{tag}"},"curies":[{"name":"pb","href":"http://localhost:%d/doc/{rel}","templated":true}]}}`, port, port, port, port, port, port, port, port, port, port)
fmt.Fprintf(w, `{"consumer":{"name":"billy"},"provider":{"name":"bobby"},"interactions":[{"description":"Some name for the test","provider_state":"Some state","request":{"method":"GET","path":"/foobar"},"response":{"status":200,"headers":{"Content-Type":"application/json"}}},{"description":"Some name for the test","provider_state":"Some state2","request":{"method":"GET","path":"/bazbat"},"response":{"status":200,"headers":{},"body":[[{"colour":"red","size":10,"tag":[["jumper","shirt"],["jumper","shirt"]]}]],"matchingRules":{"$.body":{"min":1},"$.body[*].*":{"match":"type"},"$.body[*]":{"min":1},"$.body[*][*].*":{"match":"type"},"$.body[*][*].colour":{"match":"regex","regex":"red|green|blue"},"$.body[*][*].size":{"match":"type"},"$.body[*][*].tag":{"min":2},"$.body[*][*].tag[*].*":{"match":"type"},"$.body[*][*].tag[*][0]":{"match":"type"},"$.body[*][*].tag[*][1]":{"match":"type"}}}}],"metadata":{"pactSpecificationVersion":"2.0.0"},"updatedAt":"2016-06-11T13:11:33+00:00","createdAt":"2016-06-09T12:46:42+00:00","_links":{"self":{"title":"Pact","name":"Pact between billy (v1.0.0) and bobby","href":"%s/pacts/provider/bobby/consumer/billy/version/1.0.0"},"pb:consumer":{"title":"Consumer","name":"billy","href":"%s/pacticipants/billy"},"pb:provider":{"title":"Provider","name":"bobby","href":"%s/pacticipants/bobby"},"pb:latest-pact-version":{"title":"Pact","name":"Latest version of this pact","href":"%s/pacts/provider/bobby/consumer/billy/latest"},"pb:previous-distinct":{"title":"Pact","name":"Previous distinct version of this pact","href":"%s/pacts/provider/bobby/consumer/billy/version/1.0.0/previous-distinct"},"pb:diff-previous-distinct":{"title":"Diff","name":"Diff with previous distinct version of this pact","href":"%s/pacts/provider/bobby/consumer/billy/version/1.0.0/diff/previous-distinct"},"pb:pact-webhooks":{"title":"Webhooks for the pact between billy and bobby","href":"%s/webhooks/provider/bobby/consumer/billy"},"pb:tag-prod-version":{"title":"Tag this version as 'production'","href":"%s/pacticipants/billy/versions/1.0.0/tags/prod"},"pb:tag-version":{"title":"Tag version","href":"%s/pacticipants/billy/versions/1.0.0/tags/{tag}"},"curies":[{"name":"pb","href":"%s/doc/{rel}","templated":true}]}}`, server.URL, server.URL, server.URL, server.URL, server.URL, server.URL, server.URL, server.URL, server.URL, server.URL)
w.Header().Add("Content-Type", "application/hal+json")
}))

go http.ListenAndServe(fmt.Sprintf(":%d", port), mux)
return port
return server
}
11 changes: 6 additions & 5 deletions dsl/pact_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package dsl

import (
"fmt"
"io/ioutil"
"log"
"os"
Expand Down Expand Up @@ -283,7 +282,8 @@ func TestPact_VerifyProvider(t *testing.T) {
}

func TestPact_VerifyProviderBroker(t *testing.T) {
brokerPort := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
old := waitForPort
defer func() { waitForPort = old }()
waitForPort = func(int, string, string, string) error {
Expand All @@ -296,7 +296,7 @@ func TestPact_VerifyProviderBroker(t *testing.T) {
pact := &Pact{Port: port, LogLevel: "DEBUG", pactClient: &PactClient{Port: port}, Provider: "bobby"}
err := pact.VerifyProvider(types.VerifyRequest{
ProviderBaseURL: "http://www.foo.com",
BrokerURL: fmt.Sprintf("http://localhost:%d", brokerPort),
BrokerURL: s.URL,
PublishVerificationResults: true,
ProviderVersion: "1.0.0",
})
Expand All @@ -307,7 +307,8 @@ func TestPact_VerifyProviderBroker(t *testing.T) {
}

func TestPact_VerifyProviderBrokerNoConsumers(t *testing.T) {
brokerPort := setupMockBroker(false)
s := setupMockBroker(false)
defer s.Close()
old := waitForPort
defer func() { waitForPort = old }()
waitForPort = func(int, string, string, string) error {
Expand All @@ -320,7 +321,7 @@ func TestPact_VerifyProviderBrokerNoConsumers(t *testing.T) {
pact := &Pact{Port: port, LogLevel: "DEBUG", pactClient: &PactClient{Port: port}, Provider: "providernotexist"}
err := pact.VerifyProvider(types.VerifyRequest{
ProviderBaseURL: "http://www.foo.com",
BrokerURL: fmt.Sprintf("http://localhost:%d", brokerPort),
BrokerURL: s.URL,
})

if err == nil {
Expand Down
19 changes: 11 additions & 8 deletions dsl/publish_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ import (
"github.com/pact-foundation/pact-go/utils"
)

func createMockRemoteServer(valid bool) string {
func createMockRemoteServer(valid bool) (*httptest.Server, string) {
file := createSimplePact(valid)
dir := filepath.Dir(file.Name())
path := filepath.Base(file.Name())
port, _ := utils.GetFreePort()
go http.ListenAndServe(fmt.Sprintf(":%d", port), http.FileServer(http.Dir(dir)))
server := httptest.NewServer(http.FileServer(http.Dir(dir)))

return fmt.Sprintf("http://localhost:%d/%s", port, path)
return server, fmt.Sprintf("%s/%s", server.URL, path)
}

func createSimplePact(valid bool) *os.File {
Expand Down Expand Up @@ -250,7 +249,8 @@ func TestPublish_readLocalPactFileFail(t *testing.T) {

func TestPublish_readRemotePactFile(t *testing.T) {
p := &Publisher{request: types.PublishRequest{}}
url := createMockRemoteServer(true)
s, url := createMockRemoteServer(true)
defer s.Close()

f, _, err := p.readRemotePactFile(url)

Expand All @@ -269,7 +269,8 @@ func TestPublish_readRemotePactFile(t *testing.T) {

func TestPublish_readRemotePactFileFail(t *testing.T) {
p := &Publisher{request: types.PublishRequest{}}
url := createMockRemoteServer(false)
s, url := createMockRemoteServer(false)
defer s.Close()

_, _, err := p.readRemotePactFile(url)

Expand All @@ -285,7 +286,8 @@ func TestPublish_readRemotePactFileFail(t *testing.T) {

func TestPublish_readPactFile(t *testing.T) {
p := &Publisher{request: types.PublishRequest{}}
url := createMockRemoteServer(true)
s, url := createMockRemoteServer(true)
defer s.Close()

f, _, err := p.readPactFile(url)

Expand Down Expand Up @@ -319,7 +321,8 @@ func TestPublish_readPactFile(t *testing.T) {

func TestPublish_readPactFileFail(t *testing.T) {
p := &Publisher{request: types.PublishRequest{}}
url := createMockRemoteServer(false)
s, url := createMockRemoteServer(false)
defer s.Close()

_, _, err := p.readPactFile(url)

Expand Down

0 comments on commit 9f66925

Please sign in to comment.