Skip to content

Commit

Permalink
fix: allow empty responses in sync messages (#386)
Browse files Browse the repository at this point in the history
  • Loading branch information
stan-is-hate committed Feb 13, 2024
1 parent f04022c commit 59a586d
Show file tree
Hide file tree
Showing 14 changed files with 522 additions and 142 deletions.
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

0 comments on commit 59a586d

Please sign in to comment.