Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: allow empty responses #386

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/vendor/
# Compiled Object files, Static and Dynamic libs (Shared Objects)
*.o
*.a
Expand Down
16 changes: 15 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ deps: download_plugins
download_plugins:
@echo "--- 🐿 Installing plugins"; \
./scripts/install-cli.sh
~/.pact/bin/pact-plugin-cli -y install https://github.com/pactflow/pact-protobuf-plugin/releases/tag/v-0.3.8
~/.pact/bin/pact-plugin-cli -y install https://github.com/pactflow/pact-protobuf-plugin/releases/tag/v-0.3.13
~/.pact/bin/pact-plugin-cli -y install https://github.com/pact-foundation/pact-plugins/releases/tag/csv-plugin-0.0.1
~/.pact/bin/pact-plugin-cli -y install https://github.com/mefellows/pact-matt-plugin/releases/tag/v0.0.9
~/.pact/bin/pact-plugin-cli -y install https://github.com/austek/pact-avro-plugin/releases/tag/v0.0.3
Expand Down Expand Up @@ -97,3 +97,17 @@ updatedeps:
go get -d -v -p 2 ./...

.PHONY: install bin default dev test pact updatedeps clean release

PROTOC ?= $(shell which protoc)

.PHONY: protos
protos:
@echo "--- 🛠 Compiling Protobufs"
cd ./examples/grpc/routeguide && $(PROTOC) --go_out=paths=source_relative:. \
--go-grpc_out=paths=source_relative:. ./route_guide.proto

.PHONY: grpc-test
grpc-test:
rm -rf ./examples/pacts
go test -v -tags=consumer -count=1 github.com/pact-foundation/pact-go/v2/examples/grpc
go test -v -timeout=30s -tags=provider -count=1 github.com/pact-foundation/pact-go/v2/examples/grpc
2 changes: 1 addition & 1 deletion consumer/http_v4_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ func TestHttpV4TypeSystem(t *testing.T) {
UponReceiving("some scenario").
UsingPlugin(PluginConfig{
Plugin: "protobuf",
Version: "0.3.8",
Version: "0.3.13",
}).
WithRequest("GET", "/").
// WithRequest("GET", "/", func(b *V4InteractionWithPluginRequestBuilder) {
Expand Down
7 changes: 7 additions & 0 deletions examples/grpc/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//go:build consumer || provider

package grpc

import "os"

var dir, _ = os.Getwd()
151 changes: 146 additions & 5 deletions examples/grpc/grpc_consumer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,18 @@ import (
"github.com/pact-foundation/pact-go/v2/log"
message "github.com/pact-foundation/pact-go/v2/message/v4"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
)

var dir, _ = os.Getwd()

func TestGrpcInteraction(t *testing.T) {
func TestGetFeatureSuccess(t *testing.T) {
p, _ := message.NewSynchronousPact(message.Config{
Consumer: "grpcconsumer",
Provider: "grpcprovider",
PactDir: filepath.ToSlash(fmt.Sprintf("%s/../pacts", dir)),
})
log.SetLogLevel("INFO")
log.SetLogLevel("DEBUG")

dir, _ := os.Getwd()
path := fmt.Sprintf("%s/routeguide/route_guide.proto", dir)
Expand All @@ -53,7 +52,7 @@ func TestGrpcInteraction(t *testing.T) {
Given("feature 'Big Tree' exists").
UsingPlugin(message.PluginConfig{
Plugin: "protobuf",
Version: "0.3.8",
Version: "0.3.13",
}).
WithContents(grpcInteraction, "application/protobuf").
StartTransport("grpc", "127.0.0.1", nil). // For plugin tests, we can't assume if a transport is needed, so this is optional
Expand Down Expand Up @@ -93,3 +92,145 @@ func TestGrpcInteraction(t *testing.T) {

assert.NoError(t, err)
}

func TestGetFeatureError(t *testing.T) {
log.SetLogLevel("DEBUG")
p, _ := message.NewSynchronousPact(message.Config{
Consumer: "grpcconsumer",
Provider: "grpcprovider",
PactDir: filepath.ToSlash(fmt.Sprintf("%s/../pacts", dir)),
})

dir, _ := os.Getwd()
path := fmt.Sprintf("%s/routeguide/route_guide.proto", dir)

grpcInteraction := `{
"pact:proto": "` + path + `",
"pact:proto-service": "RouteGuide/GetFeature",
"pact:content-type": "application/protobuf",
"request": {
"latitude": "matching(number, -1)",
"longitude": "matching(number, -1)"
},
"responseMetadata": {
"grpc-status": "NOT_FOUND",
"grpc-message": "matching(type, 'no feature was found at latitude:-1 longitude:-1')"
}
}`

err := p.AddSynchronousMessage("Route guide - GetFeature - error response").
Given("feature does not exist at -1, -1").
UsingPlugin(message.PluginConfig{
Plugin: "protobuf",
Version: "0.3.13",
}).
WithContents(grpcInteraction, "application/protobuf").
StartTransport("grpc", "127.0.0.1", nil). // For plugin tests, we can't assume if a transport is needed, so this is optional
ExecuteTest(t, func(transport message.TransportConfig, m message.SynchronousMessage) error {
fmt.Println("gRPC transport running on", transport)

// Establish the gRPC connection
conn, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%d", transport.Port), grpc.WithTransportCredentials(insecure.NewCredentials()))
require.NoError(t, err)
defer conn.Close()

// Create the gRPC client
c := routeguide.NewRouteGuideClient(conn)

point := &routeguide.Point{
Latitude: -1,
Longitude: -1,
}

// Now we can make a normal gRPC request
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
_, err = c.GetFeature(ctx, point)

require.Error(t, err)
// TODO: uncomment once new FFI and new pact-protobuf plugin are released with a fix
// https://github.com/pact-foundation/pact-reference/commit/29b326e59b48a6a78a019b37e378b7742c728da5
// require.ErrorContains(t, err, "no feature was found at latitude:-1 longitude:-1")

return nil
})

assert.NoError(t, err)
}

func TestSaveFeature(t *testing.T) {
p, _ := message.NewSynchronousPact(message.Config{
Consumer: "grpcconsumer",
Provider: "grpcprovider",
PactDir: filepath.ToSlash(fmt.Sprintf("%s/../pacts", dir)),
})
log.SetLogLevel("INFO")

dir, _ := os.Getwd()
path := fmt.Sprintf("%s/routeguide/route_guide.proto", dir)

grpcInteraction := `{
"pact:proto": "` + path + `",
"pact:proto-service": "RouteGuide/SaveFeature",
"pact:content-type": "application/protobuf",
"request": {
"name": "notEmpty('A shed')",
"location": {
"latitude": "matching(number, 99)",
"longitude": "matching(number, 99)"
}
},
"response": {
"name": "notEmpty('A shed')",
"location": {
"latitude": "matching(number, 99)",
"longitude": "matching(number, 99)"
}
}
}`

err := p.AddSynchronousMessage("Route guide - SaveFeature").
Given("feature does not exist at -1, -1").
UsingPlugin(message.PluginConfig{
Plugin: "protobuf",
Version: "0.3.13",
}).
WithContents(grpcInteraction, "application/protobuf").
StartTransport("grpc", "127.0.0.1", nil). // For plugin tests, we can't assume if a transport is needed, so this is optional
ExecuteTest(t, func(transport message.TransportConfig, m message.SynchronousMessage) error {
fmt.Println("gRPC transport running on", transport)

// Establish the gRPC connection
conn, err := grpc.Dial(fmt.Sprintf("127.0.0.1:%d", transport.Port), grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
t.Fatal("unable to communicate to grpc server", err)
}
defer conn.Close()

// Create the gRPC client
c := routeguide.NewRouteGuideClient(conn)
feature := &routeguide.Feature{
Name: "A shed",
Location: &routeguide.Point{
Latitude: 99,
Longitude: 99,
},
}

// Now we can make a normal gRPC request
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
response, err := c.SaveFeature(ctx, feature)

if err != nil {
t.Fatal(err.Error())
}

assert.Equal(t, feature.GetName(), response.GetName())
assert.Equal(t, feature.GetLocation().GetLatitude(), feature.GetLocation().GetLatitude())

return nil
})

assert.NoError(t, err)
}
5 changes: 1 addition & 4 deletions examples/grpc/grpc_provider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"log"

"net"
"os"
"path/filepath"
"testing"

Expand All @@ -20,8 +19,6 @@ import (
"google.golang.org/grpc"
)

var dir, _ = os.Getwd()

func TestGrpcProvider(t *testing.T) {
go startProvider()
l.SetLogLevel("TRACE")
Expand All @@ -31,7 +28,7 @@ func TestGrpcProvider(t *testing.T) {
err := verifier.VerifyProvider(t, provider.VerifyRequest{
ProviderBaseURL: "http://localhost:8222",
Transports: []provider.Transport{
provider.Transport{
{
Protocol: "grpc",
Port: 8222,
},
Expand Down
Loading
Loading