From 5f293ae787a89522cd2f4d56b08c374999c97c71 Mon Sep 17 00:00:00 2001 From: Ronald Holshausen Date: Thu, 8 Jun 2023 12:04:56 +1000 Subject: [PATCH] chore: Upgrade Pact-Go version in gRPC/area_calculator/consumer-go --- .../gRPC/area_calculator/consumer-go/go.mod | 32 +- .../gRPC/area_calculator/consumer-go/go.sum | 31 ++ .../v2/internal/native/message_server.go | 308 ++++++++++++++++-- .../pact-go/v2/internal/native/mock_server.go | 86 ++--- .../pact-go/v2/internal/native/pact.h | 51 ++- .../pact-go/v2/internal/native/verifier.go | 210 +++++++++++- .../pact-foundation/pact-go/v2/log/log.go | 47 ++- .../v2/message/v4/asynchronous_message.go | 128 +++++--- .../pact-go/v2/message/v4/message.go | 18 +- .../v2/message/v4/synchronous_message.go | 99 ++++-- .../consumer-go/vendor/modules.txt | 2 +- 11 files changed, 837 insertions(+), 175 deletions(-) diff --git a/examples/gRPC/area_calculator/consumer-go/go.mod b/examples/gRPC/area_calculator/consumer-go/go.mod index 33c3829f..c90431af 100644 --- a/examples/gRPC/area_calculator/consumer-go/go.mod +++ b/examples/gRPC/area_calculator/consumer-go/go.mod @@ -4,19 +4,49 @@ go 1.18 require ( github.com/golang/protobuf v1.5.2 - github.com/pact-foundation/pact-go/v2 v2.0.0-beta.14.0.20220821133132-63f276fae621 + github.com/pact-foundation/pact-go/v2 v2.0.0-beta.21 google.golang.org/grpc v1.46.2 ) require ( + cloud.google.com/go v0.101.1 // indirect + cloud.google.com/go/compute v1.6.1 // indirect + cloud.google.com/go/iam v0.3.0 // indirect + cloud.google.com/go/storage v1.22.1 // indirect + github.com/aws/aws-sdk-go v1.44.20 // indirect + github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect github.com/davecgh/go-spew v1.1.1 // indirect + github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect + github.com/google/go-cmp v0.5.8 // indirect + github.com/google/uuid v1.3.0 // indirect + github.com/googleapis/gax-go/v2 v2.4.0 // indirect + github.com/googleapis/go-type-adapters v1.0.0 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect + github.com/hashicorp/go-getter v1.6.1 // indirect + github.com/hashicorp/go-safetemp v1.0.0 // indirect + github.com/hashicorp/go-version v1.5.0 // indirect github.com/hashicorp/logutils v1.0.0 // indirect + github.com/inconshreveable/mousetrap v1.0.0 // indirect + github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/klauspost/compress v1.15.4 // indirect + github.com/mitchellh/go-homedir v1.1.0 // indirect + github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/spf13/afero v1.6.0 // indirect + github.com/spf13/cobra v1.1.3 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/ulikunitz/xz v0.5.10 // indirect + go.opencensus.io v0.23.0 // indirect golang.org/x/net v0.0.0-20220520000938-2e3eb7b945c2 // indirect + golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect golang.org/x/text v0.3.7 // indirect + golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect + google.golang.org/api v0.80.0 // indirect + google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220524023933-508584e28198 // indirect google.golang.org/protobuf v1.28.1 // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/examples/gRPC/area_calculator/consumer-go/go.sum b/examples/gRPC/area_calculator/consumer-go/go.sum index 8b96ccf7..d5f26467 100644 --- a/examples/gRPC/area_calculator/consumer-go/go.sum +++ b/examples/gRPC/area_calculator/consumer-go/go.sum @@ -27,6 +27,7 @@ cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go v0.100.2/go.mod h1:4Xra9TjzAeYHrl5+oeLlzbM2k3mjVhZh4UqTZ//w99A= +cloud.google.com/go v0.101.1 h1:3+/0TAm9JD/PyhkrDWQWi2L197h3euCsM+H+J4iYTR8= cloud.google.com/go v0.101.1/go.mod h1:55HwjsGW4CHD3JrNuMdZtSDsgTs0CuCB/bBTugD+7AA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= @@ -38,10 +39,12 @@ cloud.google.com/go/compute v0.1.0/go.mod h1:GAesmwr110a34z04OlxYkATPBEfVhkymfTB cloud.google.com/go/compute v1.3.0/go.mod h1:cCZiE1NHEtai4wiufUhW8I8S1JKkAnhnQJWM7YD99wM= cloud.google.com/go/compute v1.5.0/go.mod h1:9SMHyhJlzhlkJqrPAc839t2BZFTSk6Jdj6mkzQJeu0M= cloud.google.com/go/compute v1.6.0/go.mod h1:T29tfhtVbq1wvAPo0E3+7vhgmkOYeXjhFvz/FMzPu0s= +cloud.google.com/go/compute v1.6.1 h1:2sMmt8prCn7DPaG4Pmh0N3Inmc8cT8ae5k1M6VJ9Wqc= cloud.google.com/go/compute v1.6.1/go.mod h1:g85FgpzFvNULZ+S8AYq87axRKuf2Kh7deLqV/jJ3thU= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk= +cloud.google.com/go/iam v0.3.0 h1:exkAomrVUuzx9kWFI1wm3KI0uoDeUFPB4kKGzx6x+Gc= cloud.google.com/go/iam v0.3.0/go.mod h1:XzJPvDayI+9zsASAFO68Hk07u3z+f+JrT2xXNdp4bnY= cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= @@ -53,6 +56,7 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= cloud.google.com/go/storage v1.22.0/go.mod h1:GbaLEoMqbVm6sx3Z0R++gSiBlgMv6yUi2q1DeGFKQgE= +cloud.google.com/go/storage v1.22.1 h1:F6IlQJZrZM++apn9V5/VfS3gbTUYg98PS3EMQAzqtfg= cloud.google.com/go/storage v1.22.1/go.mod h1:S8N1cAStu7BOeFfE8KAQzmyyLkK8p/vmRq6kuBTW58Y= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= @@ -65,9 +69,11 @@ github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hC github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM= +github.com/aws/aws-sdk-go v1.44.20 h1:nllTRN24EfhDSeKsNbIc6HoC8Ogd2NCJTRB8l84kDlM= github.com/aws/aws-sdk-go v1.44.20/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= @@ -126,6 +132,7 @@ github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= @@ -193,6 +200,7 @@ github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= @@ -200,7 +208,9 @@ github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pf github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/googleapis/gax-go/v2 v2.2.0/go.mod h1:as02EH8zWkzwUoLbBaFeQ+arQaj/OthfcblKl4IGNaM= github.com/googleapis/gax-go/v2 v2.3.0/go.mod h1:b8LNqSzNabLiUpXKkY7HAR5jr6bIT99EXz9pXxye9YM= +github.com/googleapis/gax-go/v2 v2.4.0 h1:dS9eYAjhrE2RjmzYw2XAPvcXfmcQLtFEQWn0CR82awk= github.com/googleapis/gax-go/v2 v2.4.0/go.mod h1:XOTVJ59hdnfJLIP/dh8n5CGryZR2LxK9wbMD5+iXC6c= +github.com/googleapis/go-type-adapters v1.0.0 h1:9XdMn+d/G57qq1s8dNc5IesGCXHf6V2HZ2JwRxfA2tA= github.com/googleapis/go-type-adapters v1.0.0/go.mod h1:zHW75FOG2aur7gAO2B+MLby+cLsWGBF62rFAi7WjWO4= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= @@ -212,18 +222,22 @@ github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBt github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= +github.com/hashicorp/go-getter v1.6.1 h1:NASsgP4q6tL94WH6nJxKWj8As2H/2kop/bB1d8JMyRY= github.com/hashicorp/go-getter v1.6.1/go.mod h1:IZCrswsZPeWv9IkVnLElzRU/gz/QPi6pZHn4tv6vbwA= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU= +github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= github.com/hashicorp/go-safetemp v1.0.0/go.mod h1:oaerMy3BhqiTbVye6QuFhFtIceqFoDHxNAB65b+Rj1I= github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU= github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.5.0 h1:O293SZ2Eg+AAYijkVK3jR786Am1bhDEh2GHT0tIVE5E= github.com/hashicorp/go-version v1.5.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/go.net v0.0.1/go.mod h1:hjKkEWcCURg++eb33jQU7oqQcI9XDCnUzHA0oac0k90= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= @@ -236,8 +250,10 @@ github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2p github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U= github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= @@ -249,6 +265,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= +github.com/klauspost/compress v1.15.4 h1:1kn4/7MepF/CHmYub99/nNX8az0IJjfSOU/jbnTVfqQ= github.com/klauspost/compress v1.15.4/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -267,8 +284,10 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= +github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -280,6 +299,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRW github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/pact-foundation/pact-go/v2 v2.0.0-beta.14.0.20220821133132-63f276fae621 h1:8WP3fG7lb7iQZ/jCnfirsfE0Yujvvo9GTLrAx/inzkM= github.com/pact-foundation/pact-go/v2 v2.0.0-beta.14.0.20220821133132-63f276fae621/go.mod h1:kB2X26JGY+sd07XdG9LI4OK+aY8cTQ/IB56oBg2wT9o= +github.com/pact-foundation/pact-go/v2 v2.0.0-beta.21 h1:slc1Hg+MQHHCb9OKe0yOqavqscFYN4AvK6IEY+J4PSg= +github.com/pact-foundation/pact-go/v2 v2.0.0-beta.21/go.mod h1:kB2X26JGY+sd07XdG9LI4OK+aY8cTQ/IB56oBg2wT9o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -312,11 +333,14 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.6.0 h1:xoax2sJ2DT8S8xA2paPFjDCScCNeWsg75VG0DLRreiY= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.1.3 h1:xghbfqPkxzxP3C/f3n5DdpAbdKLj4ZE4BWQI362l53M= github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -334,6 +358,7 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -348,6 +373,7 @@ go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= +go.opencensus.io v0.23.0 h1:gqCw0LfLxScz8irSi8exQc7fyQ0fKQU/qnC/X8+V/1M= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= @@ -460,6 +486,7 @@ golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220309155454-6242fa91716a/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= +golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -610,6 +637,7 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20220411194840-2f41105eb62f/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df h1:5Pf6pFKu98ODmgnpvkJ3kFUOQGGLIzLIkbzUHp47618= golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -649,6 +677,7 @@ google.golang.org/api v0.74.0/go.mod h1:ZpfMZOVRMywNyvJFeqL9HRWBgAuRfSjJFpe9QtRR google.golang.org/api v0.75.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.77.0/go.mod h1:pU9QmyHLnzlpar1Mjt4IbapUCy8J+6HD6GeELN69ljA= google.golang.org/api v0.78.0/go.mod h1:1Sg78yoMLOhlQTeF+ARBoytAcH1NNyyl390YMy6rKmw= +google.golang.org/api v0.80.0 h1:IQWaGVCYnsm4MO3hh+WtSXMzMzuyFx/fuR8qkN3A0Qo= google.golang.org/api v0.80.0/go.mod h1:xY3nI94gbvBrE0J6NHXhxOmW97HG7Khjkku6AFB3Hyg= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -656,6 +685,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= @@ -798,6 +828,7 @@ gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/message_server.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/message_server.go index 20ba564e..ae81e281 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/message_server.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/message_server.go @@ -10,6 +10,9 @@ typedef int bool; /// Wraps a Pact model struct typedef struct InteractionHandle InteractionHandle; +typedef struct PactMessageIterator PactMessageIterator; +typedef struct SynchronousMessage SynchronousMessage; +typedef struct Message Message; struct InteractionHandle { unsigned int interaction_ref; @@ -32,10 +35,12 @@ void pactffi_message_given(InteractionHandle message, const char *description); void pactffi_message_given_with_param(InteractionHandle message, const char *description, const char *name, const char *value); void pactffi_message_with_contents(InteractionHandle message, const char *content_type, const char *body, int size); void pactffi_message_with_metadata(InteractionHandle message, const char *key, const char *value); -char* pactffi_message_reify(InteractionHandle message); int pactffi_write_message_pact_file(PactHandle pact, const char *directory, bool overwrite); void pactffi_with_message_pact_metadata(PactHandle pact, const char *namespace, const char *name, const char *value); int pactffi_write_pact_file(int mock_server_port, const char *directory, bool overwrite); +bool pactffi_given(InteractionHandle interaction, const char *description); +bool pactffi_given_with_param(InteractionHandle interaction, const char *description, const char *name, const char *value); +void pactffi_with_specification(PactHandle pact, int specification_version); int pactffi_using_plugin(PactHandle pact, const char *plugin_name, const char *plugin_version); void pactffi_cleanup_plugins(PactHandle pact); @@ -45,11 +50,56 @@ int pactffi_interaction_contents(InteractionHandle interaction, int interaction_ int pactffi_create_mock_server_for_transport(PactHandle pact, const char *addr, int port, const char *transport, const char *transport_config); bool pactffi_cleanup_mock_server(int mock_server_port); char* pactffi_mock_server_mismatches(int mock_server_port); +bool pactffi_mock_server_matched(int mock_server_port); + +// Functions to get message contents + +// Get the length of the request contents of a `SynchronousMessage`. +size_t pactffi_sync_message_get_request_contents_length(SynchronousMessage *message); +struct PactSyncMessageIterator *pactffi_pact_handle_get_sync_message_iter(PactHandle pact); +struct SynchronousMessage *pactffi_pact_sync_message_iter_next(struct PactSyncMessageIterator *iter); + +// Async +// Get the length of the contents of a `Message`. +size_t pactffi_message_get_contents_length(Message *message); + +// Get the contents of a `Message` as a pointer to an array of bytes. +const unsigned char *pactffi_message_get_contents_bin(const Message *message); +struct PactMessageIterator *pactffi_pact_handle_get_message_iter(PactHandle pact); +struct Message *pactffi_pact_message_iter_next(struct PactMessageIterator *iter); + +// Need the index of the body to get +const unsigned char *pactffi_sync_message_get_response_contents_bin(const struct SynchronousMessage *message, size_t index); +size_t pactffi_sync_message_get_response_contents_length(const struct SynchronousMessage *message, size_t index); + +// Sync +// Get the request contents of a `SynchronousMessage` as a pointer to an array of bytes. +// The number of bytes in the buffer will be returned by `pactffi_sync_message_get_request_contents_length`. +const unsigned char *pactffi_sync_message_get_request_contents_bin(SynchronousMessage *message); +// Set Sync message request body - non binary +void pactffi_sync_message_set_request_contents(InteractionHandle *message, const char *contents, const char *content_type); + +// Set Sync message request body - binary +void pactffi_sync_message_set_request_contents_bin(InteractionHandle *message, const unsigned char *contents, size_t len, const char *content_type); + +// Set sync message response contents - non binary +void pactffi_sync_message_set_response_contents(InteractionHandle *message, size_t index, const char *contents, const char *content_type); + +// Set sync message response contents - binary +void pactffi_sync_message_set_response_contents_bin(InteractionHandle *message, size_t index, const unsigned char *contents, size_t len, const char *content_type); + +// Can be used instead of the above as a general abstraction for non-binary bodies +bool pactffi_with_body(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body); + +// Can be used instead of the above as a general abstraction for binary bodies +// bool pactffi_with_binary_file(InteractionHandle interaction, int interaction_part, const char *content_type, const uint8_t *body, size_t size); +bool pactffi_with_binary_file(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body, int size); */ import "C" import ( "encoding/json" + "errors" "fmt" "log" "unsafe" @@ -59,8 +109,19 @@ type MessagePact struct { handle C.PactHandle } +type messageType int + +const ( + MESSAGE_TYPE_ASYNC messageType = iota + MESSAGE_TYPE_SYNC +) + type Message struct { - handle C.InteractionHandle + handle C.InteractionHandle + messageType messageType + pact *MessagePact + index int + server *MessageServer } // MessageServer is the public interface for managing the message based interface @@ -106,7 +167,11 @@ func (m *MessageServer) NewSyncMessageInteraction(description string) *Message { defer free(cDescription) i := &Message{ - handle: C.pactffi_new_sync_message_interaction(m.messagePact.handle, cDescription), + handle: C.pactffi_new_sync_message_interaction(m.messagePact.handle, cDescription), + messageType: MESSAGE_TYPE_SYNC, + pact: m.messagePact, + index: len(m.messages), + server: m, } m.messages = append(m.messages, i) @@ -119,23 +184,31 @@ func (m *MessageServer) NewAsyncMessageInteraction(description string) *Message defer free(cDescription) i := &Message{ - handle: C.pactffi_new_message_interaction(m.messagePact.handle, cDescription), + handle: C.pactffi_new_message_interaction(m.messagePact.handle, cDescription), + messageType: MESSAGE_TYPE_ASYNC, + pact: m.messagePact, + index: len(m.messages), + server: m, } m.messages = append(m.messages, i) return i } -func (i *Message) Given(state string) *Message { +func (m *MessageServer) WithSpecificationVersion(version specificationVersion) { + C.pactffi_with_specification(m.messagePact.handle, C.int(version)) +} + +func (m *Message) Given(state string) *Message { cState := C.CString(state) defer free(cState) - C.pactffi_message_given(i.handle, cState) + C.pactffi_given(m.handle, cState) - return i + return m } -func (i *Message) GivenWithParameter(state string, params map[string]interface{}) *Message { +func (m *Message) GivenWithParameter(state string, params map[string]interface{}) *Message { cState := C.CString(state) defer free(cState) @@ -143,7 +216,7 @@ func (i *Message) GivenWithParameter(state string, params map[string]interface{} cState := C.CString(state) defer free(cState) - C.pactffi_message_given(i.handle, cState) + C.pactffi_given(m.handle, cState) } else { for k, v := range params { cKey := C.CString(k) @@ -152,24 +225,24 @@ func (i *Message) GivenWithParameter(state string, params map[string]interface{} cValue := C.CString(param) defer free(cValue) - C.pactffi_message_given_with_param(i.handle, cState, cKey, cValue) + C.pactffi_given_with_param(m.handle, cState, cKey, cValue) } } - return i + return m } -func (i *Message) ExpectsToReceive(description string) *Message { +func (m *Message) ExpectsToReceive(description string) *Message { cDescription := C.CString(description) defer free(cDescription) - C.pactffi_message_expects_to_receive(i.handle, cDescription) + C.pactffi_message_expects_to_receive(m.handle, cDescription) - return i + return m } -func (i *Message) WithMetadata(valueOrMatcher map[string]string) *Message { +func (m *Message) WithMetadata(valueOrMatcher map[string]string) *Message { for k, v := range valueOrMatcher { cName := C.CString(k) @@ -182,32 +255,71 @@ func (i *Message) WithMetadata(valueOrMatcher map[string]string) *Message { cValue := C.CString(v) defer free(cValue) - C.pactffi_message_with_metadata(i.handle, cName, cValue) + C.pactffi_message_with_metadata(m.handle, cName, cValue) } - return i + return m +} + +func (m *Message) WithRequestBinaryContents(body []byte) *Message { + cHeader := C.CString("application/octet-stream") + defer free(cHeader) + + // TODO: handle response + res := C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_REQUEST), cHeader, (*C.char)(unsafe.Pointer(&body[0])), C.int(len(body))) + + log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", int(res)) + + return m +} +func (m *Message) WithRequestBinaryContentType(contentType string, body []byte) *Message { + cHeader := C.CString(contentType) + defer free(cHeader) + + // TODO: handle response + res := C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_REQUEST), cHeader, (*C.char)(unsafe.Pointer(&body[0])), C.int(len(body))) + + log.Println("[DEBUG] WithRequestBinaryContents - pactffi_with_binary_file returned", int(res)) + + return m +} + +func (m *Message) WithRequestJSONContents(body interface{}) *Message { + value := stringFromInterface(body) + + log.Println("[DEBUG] message WithJSONContents", value) + + return m.WithContents(INTERACTION_PART_REQUEST, "application/json", []byte(value)) } -func (i *Message) WithBinaryContents(body []byte) *Message { - return i.WithContents("application/octet-stream", body) +func (m *Message) WithResponseBinaryContents(body []byte) *Message { + cHeader := C.CString("application/octet-stream") + defer free(cHeader) + + // TODO: handle response + C.pactffi_with_binary_file(m.handle, C.int(INTERACTION_PART_RESPONSE), cHeader, (*C.char)(unsafe.Pointer(&body[0])), C.int(len(body))) + + return m } -func (i *Message) WithJSONContents(body interface{}) *Message { +func (m *Message) WithResponseJSONContents(body interface{}) *Message { value := stringFromInterface(body) log.Println("[DEBUG] message WithJSONContents", value) - return i.WithContents("application/json", []byte(value)) + return m.WithContents(INTERACTION_PART_RESPONSE, "application/json", []byte(value)) } // TODO: note that string values here must be NUL terminated. -func (i *Message) WithContents(contentType string, body []byte) *Message { +// Only accepts JSON +func (m *Message) WithContents(part interactionPart, contentType string, body []byte) *Message { cHeader := C.CString(contentType) defer free(cHeader) - C.pactffi_message_with_contents(i.handle, cHeader, (*C.char)(unsafe.Pointer(&body[0])), C.int(len(body))) + res := C.pactffi_with_body(m.handle, C.int(part), cHeader, (*C.char)(unsafe.Pointer(&body[0]))) + log.Println("[DEBUG] response from pactffi_interaction_contents", (int(res) == 1)) - return i + return m } // TODO: migrate plugin code to shared struct/code? @@ -242,13 +354,13 @@ func (m *MessageServer) UsingPlugin(pluginName string, pluginVersion string) err } // NewInteraction initialises a new interaction for the current contract -func (i *Message) WithPluginInteractionContents(interactionPart interactionType, contentType string, contents string) error { +func (m *Message) WithPluginInteractionContents(part interactionPart, contentType string, contents string) error { cContentType := C.CString(contentType) defer free(cContentType) cContents := C.CString(contents) defer free(cContents) - r := C.pactffi_interaction_contents(i.handle, C.int(interactionPart), cContentType, cContents) + r := C.pactffi_interaction_contents(m.handle, C.int(part), cContentType, cContents) // 1 - A general panic was caught. // 2 - The mock server has already been started. @@ -279,6 +391,134 @@ func (i *Message) WithPluginInteractionContents(interactionPart interactionType, return nil } +// GetMessageContents retreives the binary contents of the request for a given message +// any matchers are stripped away if given +// if the contents is from a plugin, the byte[] representation of the parsed +// plugin data is returned, again, with any matchers etc. removed +func (m *Message) GetMessageRequestContents() ([]byte, error) { + log.Println("[DEBUG] GetMessageRequestContents") + if m.messageType == MESSAGE_TYPE_ASYNC { + iter := C.pactffi_pact_handle_get_message_iter(m.pact.handle) + log.Println("[DEBUG] pactffi_pact_handle_get_message_iter") + if iter == nil { + return nil, errors.New("unable to get a message iterator") + } + log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - OK") + + /////// + // TODO: some debugging in here to see what's exploding....... + /////// + + log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - len", len(m.server.messages)) + + for i := 0; i < len(m.server.messages); i++ { + log.Println("[DEBUG] pactffi_pact_handle_get_message_iter - index", i) + message := C.pactffi_pact_message_iter_next(iter) + log.Println("[DEBUG] pactffi_pact_message_iter_next - message", message) + + if i == m.index { + log.Println("[DEBUG] pactffi_pact_message_iter_next - index match", message) + + if message == nil { + return nil, errors.New("retrieved a null message pointer") + } + + len := C.pactffi_message_get_contents_length(message) + log.Println("[DEBUG] pactffi_message_get_contents_length - len", len) + if len == 0 { + // You can have empty bodies + log.Println("[DEBUG] message body is empty") + return nil, nil + } + data := C.pactffi_message_get_contents_bin(message) + log.Println("[DEBUG] pactffi_message_get_contents_bin - data", data) + if data == nil { + // You can have empty bodies + log.Println("[DEBUG] message binary contents are empty") + return nil, nil + } + ptr := unsafe.Pointer(data) + bytes := C.GoBytes(ptr, C.int(len)) + + return bytes, nil + } + } + + } else { + iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle) + if iter == nil { + return nil, errors.New("unable to get a message iterator") + } + + for i := 0; i < len(m.server.messages); i++ { + message := C.pactffi_pact_sync_message_iter_next(iter) + + if i == m.index { + if message == nil { + return nil, errors.New("retrieved a null message pointer") + } + + len := C.pactffi_sync_message_get_request_contents_length(message) + if len == 0 { + log.Println("[DEBUG] message body is empty") + return nil, nil + } + data := C.pactffi_sync_message_get_request_contents_bin(message) + if data == nil { + log.Println("[DEBUG] message binary contents are empty") + return nil, nil + } + ptr := unsafe.Pointer(data) + bytes := C.GoBytes(ptr, C.int(len)) + + return bytes, nil + } + } + } + + return nil, errors.New("unable to find the message") +} + +// GetMessageResponseContents retreives the binary contents of the response for a given message +// any matchers are stripped away if given +// if the contents is from a plugin, the byte[] representation of the parsed +// plugin data is returned, again, with any matchers etc. removed +func (m *Message) GetMessageResponseContents() ([][]byte, error) { + + responses := make([][]byte, len(m.server.messages)) + if m.messageType == MESSAGE_TYPE_ASYNC { + return nil, errors.New("invalid request: asynchronous messages do not have response") + } + iter := C.pactffi_pact_handle_get_sync_message_iter(m.pact.handle) + if iter == nil { + return nil, errors.New("unable to get a message iterator") + } + + for i := 0; i < len(m.server.messages); i++ { + message := C.pactffi_pact_sync_message_iter_next(iter) + + if message == nil { + return nil, errors.New("retrieved a null message pointer") + } + + // Get Response body + len := C.pactffi_sync_message_get_response_contents_length(message, C.ulong(i)) + if len == 0 { + return nil, errors.New("retrieved an empty message") + } + data := C.pactffi_sync_message_get_response_contents_bin(message, C.ulong(i)) + if data == nil { + return nil, errors.New("retrieved an empty pointer to the message contents") + } + ptr := unsafe.Pointer(data) + bytes := C.GoBytes(ptr, C.int(len)) + + responses[i] = bytes + } + + return responses, nil +} + // StartTransport starts up a mock server on the given address:port for the given transport // https://docs.rs/pact_ffi/latest/pact_ffi/mock_server/fn.pactffi_create_mock_server_for_transport.html func (m *MessageServer) StartTransport(transport string, address string, port int, config map[string][]interface{}) (int, error) { @@ -328,7 +568,7 @@ func (m *MessageServer) StartTransport(transport string, address string, port in } // NewInteraction initialises a new interaction for the current contract -func (m *MessageServer) CleanupPlugins(pluginName string, pluginVersion string) { +func (m *MessageServer) CleanupPlugins() { C.pactffi_cleanup_plugins(m.messagePact.handle) } @@ -363,8 +603,18 @@ func (m *MessageServer) MockServerMismatchedRequests(port int) []MismatchedReque return res } -func (i *Message) ReifyMessage() string { - return C.GoString(C.pactffi_message_reify(i.handle)) +// MockServerMismatchedRequests returns a JSON object containing any mismatches from +// the last set of interactions. +func (m *MessageServer) MockServerMatched(port int) bool { + log.Println("[DEBUG] mock server determining mismatches:", port) + + res := C.pactffi_mock_server_matched(C.int(port)) + + // TODO: why this number is so big and not a bool? Type def wrong? Port value wrong? + // log.Println("MATCHED RES?") + // log.Println(int(res)) + + return int(res) == 1 } // WritePactFile writes the Pact to file. diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/mock_server.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/mock_server.go index 5911abf5..38ec61e4 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/mock_server.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/mock_server.go @@ -116,9 +116,10 @@ void pactffi_with_query_parameter_v2(InteractionHandle interaction, const char * /// Sets the description for the Interaction // https://docs.rs/pact_mock_server_ffi/0.0.7/pact_mock_server_ffi/fn.with_body.html -void pactffi_with_body(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body); +bool pactffi_with_body(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body); -void pactffi_with_binary_file(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body, int size); +// bool pactffi_with_binary_file(InteractionHandle interaction, int interaction_part, const char *content_type, const uint8_t *body, size_t size); +bool pactffi_with_binary_file(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body, int size); int pactffi_with_multipart_file(InteractionHandle interaction, int interaction_part, const char *content_type, const char *body, const char *part_name); @@ -169,18 +170,19 @@ import ( "fmt" "log" "os" + "strings" "unsafe" ) -type interactionType int +type interactionPart int const ( - INTERACTION_PART_REQUEST interactionType = iota + INTERACTION_PART_REQUEST interactionPart = iota INTERACTION_PART_RESPONSE ) const ( - RESULT_OK interactionType = iota + RESULT_OK interactionPart = iota RESULT_FAILED ) @@ -208,11 +210,6 @@ const ( var logLevelStringToInt = map[string]logLevel{ "OFF": LOG_LEVEL_OFF, - "error": LOG_LEVEL_ERROR, - "warn": LOG_LEVEL_WARN, - "info": LOG_LEVEL_INFO, - "debug": LOG_LEVEL_DEBUG, - "trace": LOG_LEVEL_TRACE, "ERROR": LOG_LEVEL_ERROR, "WARN": LOG_LEVEL_WARN, "INFO": LOG_LEVEL_INFO, @@ -237,30 +234,29 @@ func Version() string { return C.GoString(v) } -// Init initialises the library -func Init() { - log.Println("[DEBUG] initialising rust mock server interface") - - // Log to file if specified - pactLogLevel := os.Getenv("PACT_LOG_LEVEL") - logLevel := os.Getenv("LOG_LEVEL") - - level := "INFO" - if pactLogLevel != "" { - level = pactLogLevel - } else if logLevel != "" { - level = logLevel - } +var loggingInitialised string - l, ok := logLevelStringToInt[level] - if !ok { - l = LOG_LEVEL_INFO - } +// Init initialises the library +func Init(logLevel string) { + log.Println("[DEBUG] initialising native interface") + logLevel = strings.ToUpper(logLevel) - if os.Getenv("PACT_LOG_PATH") != "" { - logToFile(os.Getenv("PACT_LOG_PATH"), l) + if loggingInitialised != "" { + log.Printf("log level ('%s') cannot be set to '%s' after initialisation\n", loggingInitialised, logLevel) } else { - logToStdout(l) + l, ok := logLevelStringToInt[logLevel] + if !ok { + l = LOG_LEVEL_INFO + } + log.Printf("[DEBUG] initialised native log level to %s (%d)", logLevel, l) + + if os.Getenv("PACT_LOG_PATH") != "" { + log.Println("[DEBUG] initialised native log to log to file:", os.Getenv("PACT_LOG_PATH")) + logToFile(os.Getenv("PACT_LOG_PATH"), l) + } else { + log.Println("[DEBUG] initialised native log to log to stdout") + logToStdout(l) + } } } @@ -573,7 +569,7 @@ func (m *MockServer) UsingPlugin(pluginName string, pluginVersion string) error } // NewInteraction initialises a new interaction for the current contract -func (m *MockServer) CleanupPlugins(pluginName string, pluginVersion string) { +func (m *MockServer) CleanupPlugins() { C.pactffi_cleanup_plugins(m.pact.handle) } @@ -591,13 +587,13 @@ func (m *MockServer) NewInteraction(description string) *Interaction { } // NewInteraction initialises a new interaction for the current contract -func (i *Interaction) WithPluginInteractionContents(interactionPart interactionType, contentType string, contents string) error { +func (i *Interaction) WithPluginInteractionContents(part interactionPart, contentType string, contents string) error { cContentType := C.CString(contentType) defer free(cContentType) cContents := C.CString(contents) defer free(cContents) - r := C.pactffi_interaction_contents(i.handle, C.int(interactionPart), cContentType, cContents) + r := C.pactffi_interaction_contents(i.handle, C.int(part), cContentType, cContents) // 1 - A general panic was caught. // 2 - The mock server has already been started. @@ -685,7 +681,7 @@ func (i *Interaction) WithResponseHeaders(valueOrMatcher map[string][]interface{ return i.withHeaders(INTERACTION_PART_RESPONSE, valueOrMatcher) } -func (i *Interaction) withHeaders(part interactionType, valueOrMatcher map[string][]interface{}) *Interaction { +func (i *Interaction) withHeaders(part interactionPart, valueOrMatcher map[string][]interface{}) *Interaction { for k, v := range valueOrMatcher { cName := C.CString(k) @@ -730,7 +726,7 @@ func (i *Interaction) WithJSONResponseBody(body interface{}) *Interaction { return i.withJSONBody(body, INTERACTION_PART_RESPONSE) } -func (i *Interaction) withJSONBody(body interface{}, part interactionType) *Interaction { +func (i *Interaction) withJSONBody(body interface{}, part interactionPart) *Interaction { cHeader := C.CString("application/json") defer free(cHeader) @@ -751,7 +747,7 @@ func (i *Interaction) WithResponseBody(contentType string, body []byte) *Interac return i.withBody(contentType, body, 1) } -func (i *Interaction) withBody(contentType string, body []byte, part interactionType) *Interaction { +func (i *Interaction) withBody(contentType string, body []byte, part interactionPart) *Interaction { cHeader := C.CString(contentType) defer free(cHeader) @@ -763,7 +759,7 @@ func (i *Interaction) withBody(contentType string, body []byte, part interaction return i } -func (i *Interaction) withBinaryBody(contentType string, body []byte, part interactionType) *Interaction { +func (i *Interaction) withBinaryBody(contentType string, body []byte, part interactionPart) *Interaction { cHeader := C.CString(contentType) defer free(cHeader) @@ -788,7 +784,7 @@ func (i *Interaction) WithResponseMultipartFile(contentType string, filename str return i.withMultipartFile(contentType, filename, mimePartName, INTERACTION_PART_RESPONSE) } -func (i *Interaction) withMultipartFile(contentType string, filename string, mimePartName string, part interactionType) *Interaction { +func (i *Interaction) withMultipartFile(contentType string, filename string, mimePartName string, part interactionPart) *Interaction { cHeader := C.CString(contentType) defer free(cHeader) @@ -823,8 +819,18 @@ func stringFromInterface(obj interface{}) string { if err != nil { panic(fmt.Sprintln("unable to marshal body to JSON:", err)) } - return string(bytes) + return quotedString(string(bytes)) + } +} + +// This fixes a quirk where certain "matchers" (e.g. matchers.S/String) are +// really just strings. However, whene we JSON encode them they get wrapped in quotes +// and the rust core sees them as plain strings, requiring then the quotes to be matched +func quotedString(s string) string { + if s[0] == '"' && s[len(s)-1] == '"' { + return s[1 : len(s)-1] } + return s } // Experimental logging options diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/pact.h b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/pact.h index e5ec0f71..519603f6 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/pact.h +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/pact.h @@ -2090,7 +2090,8 @@ bool pactffi_given_with_param(InteractionHandle interaction, * ```c * const char* value = "{\"value\":\"/path/to/100\", \"pact:matcher:type\":\"regex\", \"regex\":\"\\/path\\/to\\/\\\\d+\"}"; * pactffi_with_request(handle, "GET", value); - * + * ``` + * See [IntegrationJson.md](https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_ffi/IntegrationJson.md) */ bool pactffi_with_request(InteractionHandle interaction, const char *method, @@ -2141,6 +2142,7 @@ bool pactffi_with_query_parameter(InteractionHandle interaction, * const char* value = "{\"value\":\"2\", \"pact:matcher:type\":\"regex\", \"regex\":\"\\\\d+\"}"; * pactffi_with_query_parameter_v2(handle, "id", 0, value); * ``` + * See [IntegrationJson.md](https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_ffi/IntegrationJson.md) * * # Safety * The name and value parameters must be valid pointers to NULL terminated strings. @@ -2223,6 +2225,7 @@ bool pactffi_with_header(InteractionHandle interaction, * const char* value = "{\"value\":\"2\", \"pact:matcher:type\":\"regex\", \"regex\":\"\\\\d+\"}"; * pactffi_with_header_v2(handle, InteractionPart::Request, "id", 0, value); * ``` + * See [IntegrationJson.md](https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_ffi/IntegrationJson.md) * * # Safety * The name and value parameters must be valid pointers to NULL terminated strings. @@ -2248,7 +2251,8 @@ bool pactffi_response_status(InteractionHandle interaction, unsigned short statu * * `part` - The part of the interaction to add the body to (Request or Response). * * `content_type` - The content type of the body. Defaults to `text/plain`. Will be ignored if a content type * header is already set. - * * `body` - The body contents. For JSON payloads, matching rules can be embedded in the body. + * * `body` - The body contents. For JSON payloads, matching rules can be embedded in the body. See + * [IntegrationJson.md](https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_ffi/IntegrationJson.md) * * For HTTP and async message interactions, this will overwrite the body. With asynchronous messages, the * part parameter will be ignored. With synchronous messages, the request contents will be overwritten, @@ -2642,6 +2646,26 @@ void pactffi_verifier_set_provider_info(struct VerifierHandle *handle, unsigned short port, const char *path); +/** + * Adds a new transport for the given provider. Passing a NULL for any field will + * use the default value for that field. + * + * For non-plugin based message interactions, set protocol to "message" and set scheme + * to an empty string or "https" if secure HTTP is required. Communication to the calling + * application will be over HTTP to the default provider hostname. + * + * # Safety + * + * All string fields must contain valid UTF-8. Invalid UTF-8 + * will be replaced with U+FFFD REPLACEMENT CHARACTER. + * + */ +void pactffi_verifier_add_provider_transport(struct VerifierHandle *handle, + const char *protocol, + unsigned short port, + const char *path, + const char *scheme); + /** * Set the filters for the Pact verifier. * @@ -2661,10 +2685,14 @@ void pactffi_verifier_set_filter_info(struct VerifierHandle *handle, unsigned char filter_no_state); /** - * Set the provider state for the Pact verifier. + * Set the provider state URL for the Pact verifier. * - * `teardown` is a boolean value. Set it to greater than zero to turn the option on. - * `body` is a boolean value. Set it to greater than zero to turn the option on. + * `teardown` is a boolean value. If teardown state change requests should be made after an + * interaction is validated (default is false). Set it to greater than zero to turn the + * option on. + * `body` is a boolean value. Sets if state change request data should be sent in the body + * (> 0, true) or as query parameters (== 0, false). Set it to greater than zero to turn the + * option on. * * # Safety * @@ -2706,6 +2734,19 @@ int pactffi_verifier_set_verification_options(struct VerifierHandle *handle, int pactffi_verifier_set_coloured_output(struct VerifierHandle *handle, unsigned char coloured_output); +/** + * Enables or disables if no pacts are found to verify results in an error. + * + * `is_error` is a boolean value. Set it to greater than zero to enable an error when no pacts + * are found to verify, and set it to zero to disable this. + * + * # Safety + * + * This function is safe as long as the handle pointer points to a valid handle. + * + */ +int pactffi_verifier_set_no_pacts_is_error(struct VerifierHandle *handle, unsigned char is_error); + /** * Set the options used when publishing verification results to the Pact Broker * diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/verifier.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/verifier.go index bcc4b409..012c6282 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/verifier.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/internal/native/verifier.go @@ -3,6 +3,7 @@ package native /* // Library headers #include +#include typedef int bool; #define true 1 #define false 0 @@ -10,6 +11,27 @@ typedef int bool; char* pactffi_version(); void pactffi_free_string(char* s); int pactffi_verify(char* s); + +typedef struct VerifierHandle VerifierHandle; +struct VerifierHandle { + +}; +VerifierHandle *pactffi_verifier_new_for_application(const char *name, const char *version); +void pactffi_verifier_shutdown(struct VerifierHandle *handle); +void pactffi_verifier_set_provider_info(VerifierHandle *handle, const char *name, const char *scheme, const char *host, uint32_t port, const char *path); +void pactffi_verifier_set_filter_info(VerifierHandle *handle, const char *filter_description, const char *filter_state, bool filter_no_state); +void pactffi_verifier_set_provider_state(VerifierHandle *handle, const char *url, bool teardown, bool body); +int pactffi_verifier_set_verification_options(VerifierHandle *handle, bool disable_ssl_verification, unsigned long request_timeout); +int pactffi_verifier_set_publish_options(VerifierHandle *handle, const char *provider_version, const char *build_url, const char *const *provider_tags, uint32_t provider_tags_len, const char *provider_branch); +void pactffi_verifier_set_consumer_filters(VerifierHandle *handle, const char *const *consumer_filters, uint32_t consumer_filters_len); +void pactffi_verifier_add_custom_header(VerifierHandle *handle, const char *header_name, const char *header_value); +void pactffi_verifier_add_file_source(VerifierHandle *handle, const char *file); +void pactffi_verifier_add_directory_source(VerifierHandle *handle, const char *directory); +void pactffi_verifier_url_source(VerifierHandle *handle, const char *url, const char *username, const char *password, const char *token); +void pactffi_verifier_broker_source_with_selectors(VerifierHandle *handle, const char *url, const char *username, const char *password, const char *token, bool enable_pending, const char *include_wip_pacts_since, const char *const *provider_tags, uint32_t provider_tags_len, const char *provider_branch, const char *const *consumer_version_selectors, uint32_t consumer_version_selectors_len, const char *const *consumer_version_tags, uint32_t consumer_version_tags_len); +int pactffi_verifier_execute(VerifierHandle *handle); +void pactffi_verifier_add_provider_transport(VerifierHandle *handle, const char *protocol, uint32_t port, const char *path, const char *scheme); +void pactffi_verifier_set_no_pacts_is_error(VerifierHandle *handle, bool is_error); */ import "C" @@ -17,9 +39,12 @@ import ( "fmt" "log" "strings" + "unsafe" ) -type Verifier struct{} +type Verifier struct { + handle *C.VerifierHandle +} func (v *Verifier) Verify(args []string) error { log.Println("[DEBUG] executing verifier FFI with args", args) @@ -42,7 +67,7 @@ func (v *Verifier) Verify(args []string) error { case 3: return ErrVerifierPanic default: - return fmt.Errorf("an unknown error ocurred when verifying the provider (this indicates a defect in the framework") + return fmt.Errorf("an unknown error (%d) ocurred when verifying the provider (this indicates a defect in the framework)", int(result)) } } @@ -60,4 +85,185 @@ var ( //ErrVerifierFailed is the standard error if a verification failed (e.g. beacause the pact verification was not successful) ErrVerifierFailed = fmt.Errorf("the verifier failed to successfully verify the pacts, this indicates an issue with the provider API") + //ErrVerifierFailedToRun indicates the verification process was unable to run + ErrVerifierFailedToRun = fmt.Errorf("the verifier failed to execute (this is most likely a defect in the framework)") ) + +func NewVerifier(name string, version string) *Verifier { + cName := C.CString(name) + cVersion := C.CString(version) + defer free(cName) + defer free(cVersion) + + h := C.pactffi_verifier_new_for_application(cName, cVersion) + + return &Verifier{ + handle: h, + } +} + +func (v *Verifier) Shutdown() { + C.pactffi_verifier_shutdown(v.handle) +} + +func (v *Verifier) SetProviderInfo(name string, scheme string, host string, port uint16, path string) { + cName := C.CString(name) + defer free(cName) + cScheme := C.CString(scheme) + defer free(cScheme) + cHost := C.CString(host) + defer free(cHost) + cPort := C.uint(port) + cPath := C.CString(path) + defer free(cPath) + + C.pactffi_verifier_set_provider_info(v.handle, cName, cScheme, cHost, cPort, cPath) +} + +func (v *Verifier) AddTransport(protocol string, port uint16, path string, scheme string) { + log.Println("[DEBUG] Adding transport with protocol:", protocol, "port:", port, "path:", path, "scheme:", scheme) + cProtocol := C.CString(protocol) + defer free(cProtocol) + cPort := C.uint(port) + cPath := C.CString(path) + defer free(cPath) + cScheme := C.CString(scheme) + defer free(cScheme) + + C.pactffi_verifier_add_provider_transport(v.handle, cProtocol, cPort, cPath, cScheme) +} + +func (v *Verifier) SetFilterInfo(description string, state string, noState bool) { + cFilterDescription := C.CString(description) + defer free(cFilterDescription) + cFilterState := C.CString(state) + defer free(cFilterState) + + C.pactffi_verifier_set_filter_info(v.handle, cFilterDescription, cFilterState, boolToCInt(noState)) +} + +func (v *Verifier) SetProviderState(url string, teardown bool, body bool) { + cURL := C.CString(url) + defer free(cURL) + + C.pactffi_verifier_set_provider_state(v.handle, cURL, boolToCInt(teardown), boolToCInt(body)) +} + +func (v *Verifier) SetVerificationOptions(disableSSLVerification bool, requestTimeout int64) { + // TODO: this returns an int and therefore can error. We should have all of these functions return values?? + C.pactffi_verifier_set_verification_options(v.handle, boolToCInt(disableSSLVerification), C.ulong(requestTimeout)) +} + +func (v *Verifier) SetConsumerFilters(consumers []string) { + // TODO: check if this actually works! + C.pactffi_verifier_set_consumer_filters(v.handle, stringArrayToCStringArray(consumers), C.uint(len(consumers))) +} + +func (v *Verifier) AddCustomHeader(name string, value string) { + cHeaderName := C.CString(name) + defer free(cHeaderName) + cHeaderValue := C.CString(value) + defer free(cHeaderValue) + + C.pactffi_verifier_add_custom_header(v.handle, cHeaderName, cHeaderValue) +} + +func (v *Verifier) AddFileSource(file string) { + cFile := C.CString(file) + defer free(cFile) + + C.pactffi_verifier_add_file_source(v.handle, cFile) +} + +func (v *Verifier) AddDirectorySource(directory string) { + cDirectory := C.CString(directory) + defer free(cDirectory) + + C.pactffi_verifier_add_directory_source(v.handle, cDirectory) +} + +func (v *Verifier) AddURLSource(url string, username string, password string, token string) { + cUrl := C.CString(url) + defer free(cUrl) + cUsername := C.CString(username) + defer free(cUsername) + cPassword := C.CString(password) + defer free(cPassword) + cToken := C.CString(token) + defer free(cToken) + + C.pactffi_verifier_url_source(v.handle, cUrl, cUsername, cPassword, cToken) +} + +func (v *Verifier) BrokerSourceWithSelectors(url string, username string, password string, token string, enablePending bool, includeWipPactsSince string, providerTags []string, providerBranch string, selectors []string, consumerVersionTags []string) { + cUrl := C.CString(url) + defer free(cUrl) + cUsername := C.CString(username) + defer free(cUsername) + cPassword := C.CString(password) + defer free(cPassword) + cToken := C.CString(token) + defer free(cToken) + cIncludeWipPactsSince := C.CString(includeWipPactsSince) + defer free(cIncludeWipPactsSince) + cProviderBranch := C.CString(providerBranch) + defer free(cProviderBranch) + + C.pactffi_verifier_broker_source_with_selectors(v.handle, cUrl, cUsername, cPassword, cToken, boolToCInt(enablePending), cIncludeWipPactsSince, stringArrayToCStringArray(providerTags), C.uint(len(providerTags)), cProviderBranch, stringArrayToCStringArray(selectors), C.uint(len(selectors)), stringArrayToCStringArray(consumerVersionTags), C.uint(len(consumerVersionTags))) +} + +func (v *Verifier) SetPublishOptions(providerVersion string, buildUrl string, providerTags []string, providerBranch string) { + cProviderVersion := C.CString(providerVersion) + defer free(cProviderVersion) + cBuildUrl := C.CString(buildUrl) + defer free(cBuildUrl) + cProviderBranch := C.CString(providerBranch) + defer free(cProviderBranch) + + C.pactffi_verifier_set_publish_options(v.handle, cProviderVersion, cBuildUrl, stringArrayToCStringArray(providerTags), C.uint(len(providerTags)), cProviderBranch) +} + +func (v *Verifier) Execute() error { + // TODO: Validate + + result := C.pactffi_verifier_execute(v.handle) + + /// | Error | Description | + /// |-------|-------------| + /// | 1 | The verification process failed, see output for errors | + switch int(result) { + case 0: + return nil + case 1: + return ErrVerifierFailed + case 2: + return ErrVerifierFailedToRun + default: + return fmt.Errorf("an unknown error (%d) ocurred when verifying the provider (this indicates a defect in the framework)", int(result)) + } +} + +func (v *Verifier) SetNoPactsIsError(isError bool) { + C.pactffi_verifier_set_no_pacts_is_error(v.handle, boolToCInt(isError)) +} + +func stringArrayToCStringArray(inputs []string) **C.char { + if len(inputs) == 0 { + return nil + } + + output := make([]*C.char, len(inputs)) + + for i, consumer := range inputs { + output[i] = C.CString(consumer) + } + + return (**C.char)(unsafe.Pointer(&output[0])) +} + +func boolToCInt(val bool) C.int { + if val { + return C.int(1) + } + return C.int(0) +} diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/log/log.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/log/log.go index af72f44c..4d1d2313 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/log/log.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/log/log.go @@ -13,17 +13,27 @@ var defaultLogLevel = "INFO" const ( logLevelTrace logutils.LogLevel = "TRACE" - logLevelDebug = "DEBUG" - logLevelInfo = "INFO" - logLevelWarn = "WARN" - logLevelError = "ERROR" + logLevelDebug logutils.LogLevel = "DEBUG" + logLevelInfo logutils.LogLevel = "INFO" + logLevelWarn logutils.LogLevel = "WARN" + logLevelError logutils.LogLevel = "ERROR" ) -func InitLogging() { +func init() { + pactLogLevel := os.Getenv("PACT_LOG_LEVEL") + logLevel := os.Getenv("LOG_LEVEL") + + level := defaultLogLevel + if pactLogLevel != "" { + level = pactLogLevel + } else if logLevel != "" { + level = logLevel + } + if logFilter == nil { logFilter = &logutils.LevelFilter{ Levels: []logutils.LogLevel{logLevelTrace, logLevelDebug, logLevelInfo, logLevelWarn, logLevelError}, - MinLevel: logutils.LogLevel(defaultLogLevel), + MinLevel: logutils.LogLevel(level), Writer: os.Stderr, } log.SetOutput(logFilter) @@ -31,12 +41,10 @@ func InitLogging() { } } -// TODO: fail/warn if this is changed at runtime // TODO: use the unified logging method to the FFI // SetLogLevel sets the default log level for the Pact framework func SetLogLevel(level logutils.LogLevel) error { - InitLogging() switch level { case logLevelTrace, logLevelDebug, logLevelError, logLevelInfo, logLevelWarn: logFilter.SetMinLevel(level) @@ -54,3 +62,26 @@ func LogLevel() logutils.LogLevel { return logutils.LogLevel(defaultLogLevel) } + +func PactCrash(err error) { + log.Panicf(crashMessage, err.Error()) +} + +var crashMessage = `!!!!!!!!! PACT CRASHED !!!!!!!!! + +%s + +This is almost certainly a bug in Pact Go. It would be great if you could +open a bug report at: https://github.com/pact-foundation/pact-go/issues +so that we can fix it. + +There is additional debugging information above. If you open a bug report, +please rerun with SetLogLevel('trace') and include the +full output. + +SECURITY WARNING: Before including your log in the issue tracker, make sure you +have removed sensitive info such as login credentials and urls that you don't want +to share with the world. + +We're sorry about this! +` diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/asynchronous_message.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/asynchronous_message.go index 8b6fd68b..d0b3bf61 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/asynchronous_message.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/asynchronous_message.go @@ -11,15 +11,10 @@ import ( "github.com/pact-foundation/pact-go/v2/internal/native" mockserver "github.com/pact-foundation/pact-go/v2/internal/native" + logging "github.com/pact-foundation/pact-go/v2/log" "github.com/pact-foundation/pact-go/v2/models" ) -// AsynchronousMessage is a representation of a single, unidirectional message -// e.g. MQ, pub/sub, Websocket, Lambda -// AsynchronousMessage is the main implementation of the Pact AsynchronousMessage interface. -type AsynchronousMessage struct { -} - // Builder 1: Async with no plugin/transport // Builder 2: Async with plugin content no transport // Builder 3: Async with plugin content + transport @@ -90,6 +85,24 @@ type AsynchronousMessageWithPluginContents struct { rootBuilder *AsynchronousMessageBuilder } +func (s *AsynchronousMessageWithPluginContents) ExecuteTest(t *testing.T, integrationTest func(m AsynchronousMessage) error) error { + message, err := getAsynchronousMessageWithReifiedContents(s.rootBuilder.messageHandle, s.rootBuilder.Type) + if err != nil { + return err + } + + fmt.Println() + err = integrationTest(message) + + if err != nil { + return err + } + + s.rootBuilder.pact.messageserver.CleanupPlugins() + + return s.rootBuilder.pact.messageserver.WritePactFile(s.rootBuilder.pact.config.PactDir, false) +} + func (s *AsynchronousMessageWithPluginContents) StartTransport(transport string, address string, config map[string][]interface{}) *AsynchronousMessageWithTransport { port, err := s.rootBuilder.pact.messageserver.StartTransport(transport, address, 0, make(map[string][]interface{})) @@ -111,12 +124,15 @@ type AsynchronousMessageWithTransport struct { transport TransportConfig } -func (s *AsynchronousMessageWithTransport) ExecuteTest(t *testing.T, integrationTest func(tc TransportConfig, m SynchronousMessage) error) error { - message := SynchronousMessage{} +func (s *AsynchronousMessageWithTransport) ExecuteTest(t *testing.T, integrationTest func(tc TransportConfig, m AsynchronousMessage) error) error { + message, err := getAsynchronousMessageWithReifiedContents(s.rootBuilder.messageHandle, s.rootBuilder.Type) + if err != nil { + return err + } defer s.rootBuilder.pact.messageserver.CleanupMockServer(s.transport.Port) - err := integrationTest(s.transport, message) + err = integrationTest(s.transport, message) if err != nil { return err @@ -144,18 +160,9 @@ type AsynchronousMessageWithContents struct { rootBuilder *AsynchronousMessageBuilder } -// WithBinaryContent accepts a binary payload -func (m *UnconfiguredAsynchronousMessageBuilder) WithBinaryContent(contentType string, body []byte) *AsynchronousMessageWithContents { - m.rootBuilder.messageHandle.WithContents(contentType, body) - - return &AsynchronousMessageWithContents{ - rootBuilder: m.rootBuilder, - } -} - // WithContent specifies the payload in bytes that the consumer expects to receive func (m *UnconfiguredAsynchronousMessageBuilder) WithContent(contentType string, body []byte) *AsynchronousMessageWithContents { - m.rootBuilder.messageHandle.WithContents(contentType, body) + m.rootBuilder.messageHandle.WithContents(mockserver.INTERACTION_PART_REQUEST, contentType, body) return &AsynchronousMessageWithContents{ rootBuilder: m.rootBuilder, @@ -165,7 +172,7 @@ func (m *UnconfiguredAsynchronousMessageBuilder) WithContent(contentType string, // WithJSONContent specifies the payload as an object (to be marshalled to WithJSONContent) that // is expected to be consumed func (m *UnconfiguredAsynchronousMessageBuilder) WithJSONContent(content interface{}) *AsynchronousMessageWithContents { - m.rootBuilder.messageHandle.WithJSONContents(content) + m.rootBuilder.messageHandle.WithRequestJSONContents(content) return &AsynchronousMessageWithContents{ rootBuilder: m.rootBuilder, @@ -216,7 +223,7 @@ func NewAsynchronousPact(config Config) (*AsynchronousPact, error) { return nil, err } - native.Init() + native.Init(string(logging.LogLevel())) return provider, err } @@ -231,6 +238,7 @@ func (p *AsynchronousPact) validateConfig() error { } p.messageserver = mockserver.NewMessageServer(p.config.Consumer, p.config.Provider) + p.messageserver.WithSpecificationVersion(mockserver.SPECIFICATION_VERSION_V4) return nil } @@ -256,42 +264,15 @@ func (p *AsynchronousPact) AddAsynchronousMessage() *AsynchronousMessageBuilder // VerifyMessageConsumerRaw creates a new Pact _message_ interaction to build a testable // interaction. // -// // A Message Consumer is analagous to a Provider in the HTTP Interaction model. // It is the receiver of an interaction, and needs to be able to handle whatever // request was provided. func (p *AsynchronousPact) verifyMessageConsumerRaw(messageToVerify *AsynchronousMessageBuilder, handler AsynchronousConsumer) error { log.Printf("[DEBUG] verify message") - // 1. Strip out the matchers - // Reify the message back to its "example/generated" form - body := messageToVerify.messageHandle.ReifyMessage() - - log.Println("[DEBUG] reified message raw", body) - - var m MessageContents - err := json.Unmarshal([]byte(body), &m) + m, err := getAsynchronousMessageWithReifiedContents(messageToVerify.messageHandle, messageToVerify.Type) if err != nil { - return fmt.Errorf("unexpected response from message server, this is a bug in the framework") - } - log.Println("[DEBUG] unmarshalled into an AsynchronousMessage", m) - - // 2. Convert to an actual type (to avoid wrapping if needed/requested) - // 3. Invoke the message handler - // 4. write the pact file - t := reflect.TypeOf(messageToVerify.Type) - if t != nil && t.Name() != "interface" { - s, err := json.Marshal(m.Content) - if err != nil { - return fmt.Errorf("unable to generate message for type: %+v", messageToVerify.Type) - } - err = json.Unmarshal(s, &messageToVerify.Type) - - if err != nil { - return fmt.Errorf("unable to narrow type to %v: %v", t.Name(), err) - } - - m.Content = messageToVerify.Type + return err } // Yield message, and send through handler function @@ -315,3 +296,50 @@ func (p *AsynchronousPact) Verify(t *testing.T, message *AsynchronousMessageBuil return err } + +func getAsynchronousMessageWithContents(message *native.Message) (AsynchronousMessage, error) { + var m AsynchronousMessage + + contents, err := message.GetMessageRequestContents() + if err != nil { + return m, err + } + + return AsynchronousMessage{ + Contents: contents, + }, nil +} + +func getAsynchronousMessageWithReifiedContents(message *mockserver.Message, reifiedType interface{}) (AsynchronousMessage, error) { + var m AsynchronousMessage + var err error + + m, err = getAsynchronousMessageWithContents(message) + if err != nil { + return m, fmt.Errorf("unexpected response from message server, this is a bug in the framework: %v", err) + } + log.Println("[DEBUG] reified body raw", string(m.Contents)) + + // // 1. Strip out the matchers + // // Reify the message back to its "example/generated" form + // body, err := message.GetMessageRequestContents() + // if err != nil { + // return m, fmt.Errorf("unexpected response from message server, this is a bug in the framework: %v", err) + // } + + log.Println("[DEBUG] unmarshalled into an AsynchronousMessage", m) + + // 2. Convert to an actual type (to avoid wrapping if needed/requested) + t := reflect.TypeOf(reifiedType) + if t != nil && t.Name() != "interface" { + err = json.Unmarshal(m.Contents, &reifiedType) + + if err != nil { + return m, fmt.Errorf("unable to narrow type to %v: %v", t.Name(), err) + } + + m.Body = reifiedType + } + + return m, err +} diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/message.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/message.go index 988d025b..baa4d15e 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/message.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/message.go @@ -1,19 +1,27 @@ package v4 -type Body interface{} type Metadata map[string]interface{} +// AsynchronousMessage is a representation of a single, unidirectional message +// e.g. MQ, pub/sub, Websocket, Lambda +// AsynchronousMessage is the main implementation of the Pact AsynchronousMessage interface. +type AsynchronousMessage MessageContents + // AsynchronousConsumer receives a message and must be able to parse // the content -type AsynchronousConsumer func(MessageContents) error +type AsynchronousConsumer func(AsynchronousMessage) error // V3 Message (Asynchronous only) type MessageContents struct { // Message Body - Content Body `json:"contents"` + Contents []byte + + // Body is the attempt to reify the message body back into a specified type + // Not populated for synchronous messages + Body interface{} `json:"contents"` - // Message metadata - Metadata Metadata `json:"metadata"` + // Message metadata. Currently not populated for synchronous messages + // Metadata Metadata `json:"metadata"` } type Config struct { diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/synchronous_message.go b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/synchronous_message.go index ee9f5f78..28d9c8ea 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/synchronous_message.go +++ b/examples/gRPC/area_calculator/consumer-go/vendor/github.com/pact-foundation/pact-go/v2/message/v4/synchronous_message.go @@ -8,6 +8,8 @@ import ( "testing" "github.com/pact-foundation/pact-go/v2/internal/native" + mockserver "github.com/pact-foundation/pact-go/v2/internal/native" + logging "github.com/pact-foundation/pact-go/v2/log" "github.com/pact-foundation/pact-go/v2/models" ) @@ -23,8 +25,11 @@ type SynchronousPact struct { type SynchronousMessage struct { // TODO: should we pass this in? Probably need to be able to reify the message // in these cases - // Request MessageContents - // Response []MessageContents + Request MessageContents + + // Currently only support a single response, but support may be added for multiple + // responses to be given in the future + Response []MessageContents } // SynchronousMessageBuilder is a representation of a single, bidirectional message @@ -109,16 +114,9 @@ func (m *SynchronousMessageWithRequestBuilder) WithMetadata(metadata map[string] return m } -// WithBinaryContent accepts a binary payload -func (m *SynchronousMessageWithRequestBuilder) WithBinaryContent(contentType string, body []byte) *SynchronousMessageWithRequestBuilder { - m.messageHandle.WithContents(contentType, body) - - return m -} - // WithContent specifies the payload in bytes that the consumer expects to receive func (m *SynchronousMessageWithRequestBuilder) WithContent(contentType string, body []byte) *SynchronousMessageWithRequestBuilder { - m.messageHandle.WithContents(contentType, body) + m.messageHandle.WithContents(native.INTERACTION_PART_REQUEST, contentType, body) return m } @@ -126,7 +124,7 @@ func (m *SynchronousMessageWithRequestBuilder) WithContent(contentType string, b // WithJSONContent specifies the payload as an object (to be marshalled to WithJSONContent) that // is expected to be consumed func (m *SynchronousMessageWithRequestBuilder) WithJSONContent(content interface{}) *SynchronousMessageWithRequestBuilder { - m.messageHandle.WithJSONContents(content) + m.messageHandle.WithRequestJSONContents(content) return m } @@ -165,16 +163,10 @@ func (m *SynchronousMessageWithResponseBuilder) WithMetadata(metadata map[string return m } -// WithBinaryContent accepts a binary payload -func (m *SynchronousMessageWithResponseBuilder) WithBinaryContent(contentType string, body []byte) *SynchronousMessageWithResponseBuilder { - m.messageHandle.WithContents(contentType, body) - - return m -} - // WithContent specifies the payload in bytes that the consumer expects to receive +// May be called multiple times, with each call appeding a new response to the interaction func (m *SynchronousMessageWithResponseBuilder) WithContent(contentType string, body []byte) *SynchronousMessageWithResponseBuilder { - m.messageHandle.WithContents(contentType, body) + m.messageHandle.WithContents(native.INTERACTION_PART_RESPONSE, contentType, body) return m } @@ -182,7 +174,7 @@ func (m *SynchronousMessageWithResponseBuilder) WithContent(contentType string, // WithJSONContent specifies the payload as an object (to be marshalled to WithJSONContent) that // is expected to be consumed func (m *SynchronousMessageWithResponseBuilder) WithJSONContent(content interface{}) *SynchronousMessageWithResponseBuilder { - m.messageHandle.WithJSONContents(content) + m.messageHandle.WithResponseJSONContents(content) return m } @@ -209,13 +201,13 @@ type SynchronousMessageWithPluginContents struct { // ExecuteTest runs the current test case against a Mock Service. // Will cleanup interactions between tests within a suite // and write the pact file if successful -// NOTE: currently, this function is not very useful because without a transport, -// there is no useful way to test your actual code (because the message isn't passed back in) -// Use at your own risk ;) func (m *SynchronousMessageWithPluginContents) ExecuteTest(t *testing.T, integrationTest func(m SynchronousMessage) error) error { - message := SynchronousMessage{} + message, err := getSynchronousMessageWithContents(m.messageHandle) + if err != nil { + return err + } - err := integrationTest(message) + err = integrationTest(message) if err != nil { return err @@ -248,22 +240,29 @@ type SynchronousMessageWithTransport struct { } func (s *SynchronousMessageWithTransport) ExecuteTest(t *testing.T, integrationTest func(tc TransportConfig, m SynchronousMessage) error) error { - message := SynchronousMessage{} - - defer s.pact.mockserver.CleanupMockServer(s.transport.Port) - - err := integrationTest(s.transport, message) - + message, err := getSynchronousMessageWithContents(s.messageHandle) if err != nil { return err } + defer s.pact.mockserver.CleanupMockServer(s.transport.Port) + + err = integrationTest(s.transport, message) + + // matched := s.pact.mockserver.MockServerMatched(s.transport.Port) + // log.Println("MATHED??????????", matched) mismatches := s.pact.mockserver.MockServerMismatchedRequests(s.transport.Port) if len(mismatches) > 0 { return fmt.Errorf("pact validation failed: %+v", mismatches) } + if err != nil { + return err + } + + s.pact.mockserver.CleanupPlugins() + return s.pact.mockserver.WritePactFileForServer(s.transport.Port, s.pact.config.PactDir, false) } @@ -282,7 +281,7 @@ func NewSynchronousPact(config Config) (*SynchronousPact, error) { return nil, err } - native.Init() + native.Init(string(logging.LogLevel())) return provider, err } @@ -297,6 +296,7 @@ func (m *SynchronousPact) validateConfig() error { } m.mockserver = native.NewMessageServer(m.config.Consumer, m.config.Provider) + m.mockserver.WithSpecificationVersion(mockserver.SPECIFICATION_VERSION_V4) return nil } @@ -316,9 +316,12 @@ func (m *SynchronousPact) AddSynchronousMessage(description string) *Unconfigure // Will cleanup interactions between tests within a suite // and write the pact file if successful func (m *SynchronousMessageWithResponse) ExecuteTest(t *testing.T, integrationTest func(md SynchronousMessage) error) error { - message := SynchronousMessage{} + message, err := getSynchronousMessageWithContents(m.messageHandle) + if err != nil { + return err + } - err := integrationTest(message) + err = integrationTest(message) if err != nil { return err @@ -326,3 +329,31 @@ func (m *SynchronousMessageWithResponse) ExecuteTest(t *testing.T, integrationTe return m.pact.mockserver.WritePactFile(m.pact.config.PactDir, false) } + +func getSynchronousMessageWithContents(message *native.Message) (SynchronousMessage, error) { + var m SynchronousMessage + + contents, err := message.GetMessageRequestContents() + if err != nil { + return m, err + } + + responses, err := message.GetMessageResponseContents() + if err != nil { + return m, err + } + + response := make([]MessageContents, len(responses)) + for i, r := range responses { + response[i] = MessageContents{ + Contents: r, + } + } + + return SynchronousMessage{ + Request: MessageContents{ + Contents: contents, + }, + Response: response, + }, nil +} diff --git a/examples/gRPC/area_calculator/consumer-go/vendor/modules.txt b/examples/gRPC/area_calculator/consumer-go/vendor/modules.txt index 8385dbab..2fcee614 100644 --- a/examples/gRPC/area_calculator/consumer-go/vendor/modules.txt +++ b/examples/gRPC/area_calculator/consumer-go/vendor/modules.txt @@ -52,7 +52,7 @@ github.com/hashicorp/logutils ## explicit # github.com/mitchellh/go-testing-interface v1.14.1 ## explicit; go 1.14 -# github.com/pact-foundation/pact-go/v2 v2.0.0-beta.14.0.20220821133132-63f276fae621 +# github.com/pact-foundation/pact-go/v2 v2.0.0-beta.21 ## explicit; go 1.15 github.com/pact-foundation/pact-go/v2/internal/native github.com/pact-foundation/pact-go/v2/log