Skip to content
This repository has been archived by the owner on Mar 11, 2021. It is now read-only.

Commit

Permalink
test: Create contract tests for interaction with Auth service.
Browse files Browse the repository at this point in the history
  • Loading branch information
pmacik committed Oct 12, 2018
1 parent df67bff commit 0ce4f49
Show file tree
Hide file tree
Showing 11 changed files with 335 additions and 0 deletions.
46 changes: 46 additions & 0 deletions .make/test.mk
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,14 @@ ALL_PKGS_EXCLUDE_PATTERN = 'vendor\|app\|tool\/cli\|design\|client\|test'
GOANALYSIS_PKGS_EXCLUDE_PATTERN="vendor|app|client|tool/cli"
GOANALYSIS_DIRS=$(shell go list -f {{.Dir}} ./... | grep -v -E $(GOANALYSIS_PKGS_EXCLUDE_PATTERN))

# Folder with contract tests
CONTRACT_TESTS=$(CUR_DIR)/test/contracts

# Configuration of contract tests
PACT_VERSION ?= 1.0.0
PACT_BROKER_URL ?= http://pact-broker-pact-broker.193b.starter-ca-central-1.openshiftapps.com
PACT_PROVIDER_BASE_URL ?= https://auth.openshift.io

#-------------------------------------------------------------------------------
# Normal test targets
#
Expand Down Expand Up @@ -159,6 +167,7 @@ test-templates-flags:
test-unit: test-templates-flags prebuild-check clean-coverage-unit $(COV_PATH_UNIT)

.PHONY: test-unit-no-coverage

## Runs the unit tests and WITHOUT producing coverage files for each package.
test-unit-no-coverage: test-templates-flags prebuild-check $(SOURCES)
$(call log-info,"Running test: $@")
Expand All @@ -183,6 +192,43 @@ test-integration-no-coverage: prebuild-check migrate-database $(SOURCES)
$(eval TEST_PACKAGES:=$(shell go list ./... | grep -v $(ALL_PKGS_EXCLUDE_PATTERN)))
F8_DEVELOPER_MODE_ENABLED=1 F8_RESOURCE_DATABASE=1 F8_RESOURCE_UNIT_TEST=0 F8_POSTGRES_DATABASE=postgres go test -v $(TEST_PACKAGES)

.PHONY: test-contract-auth-consumer
## Runs the consumer side contract tests of the Auth service and produces pact files.
test-contract-auth-consumers:
cd $(CONTRACT_TESTS)/auth && \
PACT_DIR=$(CONTRACT_TESTS)/pacts \
./consumer-contracts.sh

.PHONY: test-contract-auth-publish
## Publishes the generated files to a Pact broker.
test-contract-auth-publish:
cd $(CONTRACT_TESTS)/auth && \
PACT_VERSION=$(PACT_VERSION) \
PACT_BROKER_URL=$(PACT_BROKER_URL) \
./publish-contracts.sh

.PHONY: test-contract-auth-verify
## Verifies the contracts against the living provider. The pact files are taken from pact directory.
test-contract-auth-verify:
cd $(CONTRACT_TESTS)/auth && \
PACT_PROVIDER_BASE_URL=$(PACT_PROVIDER_BASE_URL) \
./verify-contracts.sh

.PHONY: test-contract-auth-verify-broker
## Verifies the contracts against the living provider. The pact files are taken from the Pact broker.
test-contract-auth-verify-broker:
cd $(CONTRACT_TESTS)/auth && \
PACT_VERSION=$(PACT_VERSION) \
PACT_BROKER_URL=$(PACT_BROKER_URL) \
PACT_PROVIDER_BASE_URL=$(PACT_PROVIDER_BASE_URL) \
./verify-contracts-broker.sh

.PHONY: clean-test-contract-auth
## Runs the consumer side contract tests and produces pact files.
clean-test-contract-auth:
cd $(CONTRACT_TESTS)/auth && \
rm -rvf pacts log logs

.PHONY: test-remote
## Runs the remote tests and produces coverage files for each package.
test-remote: prebuild-check clean-coverage-remote $(COV_PATH_REMOTE)
Expand Down
3 changes: 3 additions & 0 deletions test/contracts/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**/*log
**/*logs
**/*pacts
1 change: 1 addition & 0 deletions test/contracts/auth/.#setenv.sh
59 changes: 59 additions & 0 deletions test/contracts/auth/auth_api_status.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
// Package contracts contains a runnable Consumer Pact test example.
package contracts

import (
"fmt"
"log"
"net/http"
"testing"

"github.com/pact-foundation/pact-go/dsl"
)

// AuthAPIStatus defines contract of /api/status endpoint
func AuthAPIStatus(t *testing.T, pact *dsl.Pact) {
// Pass in test case
var test = func() error {
u := fmt.Sprintf("http://localhost:%d/api/status", pact.Server.Port)
req, err := http.NewRequest("GET", u, nil)

req.Header.Set("Content-Type", "application/json")
if err != nil {
return err
}

_, err = http.DefaultClient.Do(req)
if err != nil {
return err
}
return err
}

type STATUS struct {
buildTime string `json:"buildTime" pact:"example=2018-10-05T10:03:04Z"`
commit string `json:"commit" pact:"example=0f9921980549b2baeb43f6f16cbe794f430f498c"`
configurationStatus string `json:"configurationStatus" pact:"example=OK"`
databaseStatus string `json:"databaseStatus" pact:"example=OK"`
startTime string `json:"startTime" pact:"example=2018-10-09T15:04:50Z"`
}

// Set up our expected interactions.
pact.
AddInteraction().
UponReceiving("A request to get status").
WithRequest(dsl.Request{
Method: "GET",
Path: dsl.String("/api/status"),
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/json")},
}).
WillRespondWith(dsl.Response{
Status: 200,
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/vnd.status+json")},
Body: dsl.Match(STATUS{}),
})

// Verify
if err := pact.Verify(test); err != nil {
log.Fatalf("Error on Verify: %v", err)
}
}
147 changes: 147 additions & 0 deletions test/contracts/auth/auth_api_user.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,147 @@
// Package contracts contains a runnable Consumer Pact test example.
package contracts

import (
"fmt"
"log"
"net/http"
"os"
"testing"

"github.com/pact-foundation/pact-go/dsl"
)

type Data struct {
Attributes struct {
Bio string `json:"bio" pact:"example=n/a"`
Cluster string `json:"cluster" pact:"example=https://api.starter-us-east-2a.openshift.com/"`
Company string `json:"company" pact:"example=n/a"`
ContextInformation struct {
RecentContexts []struct {
User string `json:"user" pact:"example=c46445eb-2448-4c91-916a-2c1de3e6f63e"`
} `json:"recentContexts"`
RecentSpaces []string `json:"recentSpaces"`
} `json:"contextInformation"`
CreatedAt string `json:"created-at" pact:"example=2018-03-16T14:34:31.615511Z"`
Email string `json:"email" pact:"[email protected]"`
EmailPrivate bool `json:"emailPrivate" pact:"example=false"`
EmailVerified bool `json:"emailVerified" pact:"example=true"`
FeatureLevel string `json:"featureLevel" pact:"example=internal"`
FullName string `json:"fullName" pact:"example=Osio10 Automated Tests"`
IdentityID string `json:"identityID" pact:"example=c46445eb-2448-4c91-916a-2c1de3e6f63e"`
ImageURL string `json:"imageURL" pact:"example=n/a"`
ProviderType string `json:"providerType" pact:"example=kc"`
RegistrationCompleted bool `json:"registrationCompleted" pact:"example=true"`
UpdatedAt string `json:"updated-at" pact:"example=2018-05-30T11:05:23.513612Z"`
URL string `json:"url" pact:"example=n/a"`
UserID string `json:"userID" pact:"example=5f41b66e-6f84-42b3-ab5f-8d9ef21149b1"`
Username string `json:"username" pact:"example=osio-ci-ee10"`
} `json:"attributes"`
ID string `json:"id" pact:"example=c46445eb-2448-4c91-916a-2c1de3e6f63e"`
Links struct {
Related string `json:"related" pact:"example=https://auth.openshift.io/api/users/c46445eb-2448-4c91-916a-2c1de3e6f63e"`
Self string `json:"self" pact:"example=https://auth.openshift.io/api/users/c46445eb-2448-4c91-916a-2c1de3e6f63e"`
} `json:"links"`
Type string `json:"type" pact:"example=identities"`
}

type USER struct {
data Data `json:"data"`
}

type USERS struct {
data []Data `json:"data"`
}

// APIUserByNameConsumer defines contract of /api/users?filter[username]=<user_name> endpoint
func AuthAPIUserByNameConsumer(t *testing.T, pact *dsl.Pact) {
userName := os.Getenv("OSIO_USERNAME")

// Pass in test case
var test = func() error {
url := fmt.Sprintf("http://localhost:%d/api/users?filter[username]=%s", pact.Server.Port, userName)
req, err := http.NewRequest("GET", url, nil)

req.Header.Set("Content-Type", "application/json")
if err != nil {
return err
}

_, err = http.DefaultClient.Do(req)
if err != nil {
return err
}
return err
}

// Set up our expected interactions.
pact.
AddInteraction().
UponReceiving("A request to get user's information by name").
WithRequest(dsl.Request{
Method: "GET",
Path: dsl.String("/api/users"),
Query: dsl.MapMatcher{
"filter[username]": dsl.Term(
userName,
".*",
),
},
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/json")},
}).
WillRespondWith(dsl.Response{
Status: 200,
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/vnd.api+json")},
Body: dsl.Match(USERS{}),
})

// Verify
if err := pact.Verify(test); err != nil {
log.Fatalf("Error on Verify: %v", err)
}
}

// APIUserByIDConsumer defines contract of /api/users/<user_id> endpoint
func AuthAPIUserByIDConsumer(t *testing.T, pact *dsl.Pact) {
userID := os.Getenv("OSIO_USER_ID")

// Pass in test case
var test = func() error {
url := fmt.Sprintf("http://localhost:%d/api/users/%s", pact.Server.Port, userID)
req, err := http.NewRequest("GET", url, nil)

req.Header.Set("Content-Type", "application/json")
if err != nil {
return err
}

_, err = http.DefaultClient.Do(req)
if err != nil {
return err
}
return err
}

// Set up our expected interactions.
pact.
AddInteraction().
UponReceiving("A request to get user's information by ID").
WithRequest(dsl.Request{
Method: "GET",
Path: dsl.Term(
fmt.Sprintf("/api/users/%s", userID),
"/api/users/.*",
),
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/json")},
}).
WillRespondWith(dsl.Response{
Status: 200,
Headers: dsl.MapMatcher{"Content-Type": dsl.String("application/vnd.api+json")},
Body: dsl.Match(USER{}),
})

// Verify
if err := pact.Verify(test); err != nil {
log.Fatalf("Error on Verify: %v", err)
}
}
6 changes: 6 additions & 0 deletions test/contracts/auth/consumer-contracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#!/bin/bash

. ./setenv.sh

# run test
go test -v -run 'Test*'
26 changes: 26 additions & 0 deletions test/contracts/auth/contract_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Package contracts contains a runnable Consumer Pact test example.
package contracts

import (
"os"
"testing"

"github.com/pact-foundation/pact-go/dsl"
)

// TestAuthAPI runs all user related tests
func TestAuthAPI(t *testing.T) {
// Create Pact connecting to local Daemon
pact := &dsl.Pact{
Consumer: os.Getenv("PACT_CONSUMER"),
Provider: os.Getenv("PACT_PROVIDER"),
Host: "localhost",
PactFileWriteMode: "merge",
}
defer pact.Teardown()

// Test interactions
AuthAPIStatus(t, pact)
AuthAPIUserByNameConsumer(t, pact)
AuthAPIUserByIDConsumer(t, pact)
}
19 changes: 19 additions & 0 deletions test/contracts/auth/publish-contracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

. ./setenv.sh

for PACT_FILE in $(find "$PACT_DIR" -name "*.json"); do
echo "Publishing $PACT_FILE to a Pact broker at $PACT_BROKER_URL"

PACT_CONSUMER=$(jq '.["consumer"]["name"]' "$PACT_FILE" | tr -d '"')
PACT_PROVIDER=$(jq '.["provider"]["name"]' "$PACT_FILE" | tr -d '"')

result=$(curl -L --silent -XPUT -H "Content-Type: application/json" -d@$PACT_FILE "$PACT_BROKER_URL/pacts/provider/$PACT_PROVIDER/consumer/$PACT_CONSUMER/version/$PACT_VERSION")

if [[ $result = *'"consumer":{"name":"'$PACT_CONSUMER'"},"provider":{"name":"'$PACT_PROVIDER'"}'* ]]; then
echo "Pact successfully published."
else
echo "Unable to publish pact:"
echo "$result"
fi
done
11 changes: 11 additions & 0 deletions test/contracts/auth/setenv.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/bash

set -a

# Add the current directory to Go path.
GOPATH="$GOPATH:$(pwd)"

# A directory to save pact files
PACT_DIR="${PACT_DIR:-pacts}"
PACT_CONSUMER="${PACT_CONSUMER:-Fabric8TenantService}"
PACT_PROVIDER="${PACT_PROVIDER:-Fabric8AuthService}"
10 changes: 10 additions & 0 deletions test/contracts/auth/verify-contracts-broker.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

. ./setenv.sh

for PACT_FILE in $(find "$PACT_DIR" -name "*.json"); do
PACT_CONSUMER=$(jq '.["consumer"]["name"]' "$PACT_FILE" | tr -d '"')
PACT_PROVIDER=$(jq '.["provider"]["name"]' "$PACT_FILE" | tr -d '"')

pact-provider-verifier "$PACT_BROKER_URL/pacts/provider/$PACT_PROVIDER/consumer/$PACT_CONSUMER/versions/$PACT_VERSION" --provider-base-url "$PACT_PROVIDER_BASE_URL"
done
7 changes: 7 additions & 0 deletions test/contracts/auth/verify-contracts.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash

. ./setenv.sh

for PACT_FILE in $(find "$PACT_DIR" -name "*.json"); do
pact-provider-verifier "$PACT_FILE" --provider-base-url "$PACT_PROVIDER_BASE_URL"
done

0 comments on commit 0ce4f49

Please sign in to comment.