Hi Team; I've recently been dipping my toes into P...
# protobufs
s
Hi Team; I've recently been dipping my toes into Pact to create some basic consumer tests for the rpc definitions in a project's protobuf spec. I send requests matching the spec over a
GrpcTransport
(the consumer tests are written in TypeScript) with the host
host.docker.internal:8000
, as the project is made up of multiple Docker containers on a shared network. My requests are successful, as I can verify by manually inspecting the project's front-end for changes. However, when I use the
pact_verifier_cli
to "replay" my generated pacts specifying
grpc
transport and with the same hostname and port, I get
builder error for url (<grpc://host.docker.internal:8000>)
. I will note that 8000 hits an Envoy proxy, but any other port also gives me the same error. I also will note that I understand all the Pact Protobuf examples I've seen mock out a provider server instead of just hitting the "production" one directly, but for my uses this is okay and I'm not sure why this would influence me getting this error result either. Any thoughts on how I could remedy this? Thank you šŸ™‚
m
You should never mock out the provider during provider verification - what examples are you referring to? Mocking out dependencies and using mocks in the tests are ok, so long as you're testing the provider interface correctly. But that's besides the point here. You should be able to do what you're asking. I can't remember how you specify the grpc host when invoking the CLI. Let me check
I think you might need to pass the host to the primary host flag, and then just grpc:8000 for the --transports flag
Probably we should allow different hosts though
s
You're right, my mistake. The example code I've mostly been looking at is the js and go consumer/provider code for the "area calculator" example in the
pact-plugins
repo. Those examples don't mock out the provider; they just may start it as part of the test code (at least in the case of the Go one), whereas I'm not doing that on my side. I will try that, thank you Matt šŸ™‚
m
Ok yes, good to know - that's the "standard" approach, because it enables you to vary state through mocks etc. Let me know how you go (I'm not at my desk right now so can't try for myself)
s
--transport grpc:8000
and
-h host.docker.internal
give
builder error for url (grpc:<8000://host.docker.internal>)
hold on, I'll try
transports
option
error sending request for url (<http://host.docker.internal/>)
I will dig into the logs some more and report back šŸ™‚ this looks like progress!
seems to work better if I also specify the port with
-p 8000
along with
--transports grpc:8000
I then get back
Request to fetch message from provider failed: status 415
Copy code
hyper_util::client::legacy::connect::http: connecting to 192.168.65.254:8000
2024-11-07T22:41:54.347626Z DEBUG                 main hyper_util::client::legacy::connect::http: connected to 192.168.65.254:8000
2024-11-07T22:41:54.348437Z DEBUG                 main hyper_util::client::legacy::pool: pooling idle connection for ("http", host.docker.internal:8000)
2024-11-07T22:41:54.348454Z DEBUG                 main verify_provider{provider_name="backend-go"}:verify_interaction{interaction="A gRPC updateEndpoint request"}: pact_verifier::provider_client: Received native response: Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("host.docker.internal")), port: Some(8000), path: "/", query: None, fragment: None }, status: 415, headers: {"content-type": "application/grpc", "grpc-status": "3", "grpc-message": "invalid gRPC request content-type \"application/json\"", "x-envoy-upstream-service-time": "0", "date": "Thu, 07 Nov 2024 22:41:54 GMT", "server": "envoy", "content-length": "0"} }
2024-11-07T22:41:54.348492Z  INFO                 main verify_provider{provider_name="backend-go"}:verify_interaction{interaction="A gRPC updateEndpoint request"}: pact_verifier::provider_client: Received response: HTTP Response ( status: 415, headers: Some({"server": ["envoy"], "content-type": ["application/grpc"], "content-length": ["0"], "grpc-status": ["3"], "grpc-message": ["invalid gRPC request content-type \"application/json\""], "date": ["Thu, 07 Nov 2024 22:41:54 GMT"], "x-envoy-upstream-service-time": ["0"]}), body: Empty )
2024-11-07T22:41:54.348503Z DEBUG                 main verify_provider{provider_name="backend-go"}:verify_interaction{interaction="A gRPC updateEndpoint request"}: pact_verifier::provider_client: body:
seems to work better if I also specify the port with
-p 8000
along with
--transports grpc:8000
I then get back
Request to fetch message from provider failed: status 415
partial logs below, I think I may need to tweak my Envoy config
Copy code
hyper_util::client::legacy::connect::http: connecting to 192.168.65.254:8000

hyper_util::client::legacy::connect::http: connected to 192.168.65.254:8000

hyper_util::client::legacy::pool: pooling idle connection for ("http", host.docker.internal:8000)

pact_verifier::provider_client: Received native response: Response { url: Url { scheme: "http", cannot_be_a_base: false, username: "", password: None, host: Some(Domain("host.docker.internal")), port: Some(8000), path: "/", query: None, fragment: None }, status: 415, headers: {"content-type": "application/grpc", "grpc-status": "3", "grpc-message": "invalid gRPC request content-type \"application/json\"", "x-envoy-upstream-service-time": "0", "date": "Thu, 07 Nov 2024 22:41:54 GMT", "server": "envoy", "content-length": "0"} }

pact_verifier::provider_client: Received response: HTTP Response ( status: 415, headers: Some({"server": ["envoy"], "content-type": ["application/grpc"], "content-length": ["0"], "grpc-status": ["3"], "grpc-message": ["invalid gRPC request content-type \"application/json\""], "date": ["Thu, 07 Nov 2024 22:41:54 GMT"], "x-envoy-upstream-service-time": ["0"]}), body: Empty )

pact_verifier::provider_client: body:
m
interesting, I think we need to tidy those flags up.
y
Do you have provider states in your interaction by any chance? How are you running the verifier? In your own container, via the official image, or from your local host machine? I assume it is attached to the host network too. You should be able to run the verifier fine against a started service without needing to pass the transport (if there are not mixed interactions) https://github.com/pactflow/pact-protobuf-plugin?tab=readme-ov-file#service-method-provider
Copy code
pact_verifier_cli -f ../consumer-jvm/build/pacts/protobuf-consumer-area-calculator-provider.json -p 37621
I wonder if there is state being passed in that is expected to be handled by a http message proxy, which is receiving the
application/json
content message
s
I am running the verifier in a container attached to the same docker network as the container running the provider. My fairly naive answer about provider states (after reading https://docs.pact.io/getting_started/provider_states and looking at some example) is that I don't think so. I'm just sending 1 request per test to test 1 specific scenario on a given rpc at a time. No provider manipulation outside the pact. I was thinking the same as per your last point, Yousaf, I will look more into that today.
Couldn't discern anything meaningful from picking through my
envoy.yaml
for the provider so far, unfortunately. If you guys think it would be useful, I could share the consumer test code and the generated pact privately.
y
a repro is always useful, I’m juggling a few things this week but feel free to send it over to us both what language/framework is the provider running? what is envoys role as a proxy? do you also have a url for the grpc provider service? can you access the service using your url and constructing a message similar to that in the pact with something like evans https://github.com/ktr0731/evans
s
Hi, sorry for the long delay. The provider is running Golang. Envoy's role as a proxy is essentially for security, to make sure only certain headers are allowed along certain routes. The gRPC provider service is exposed on a port that I can (should) also be able to hit directly (Pretty sure this was giving the same results as going through the proxy but I'll try it again). I've downloaded evans and will give it a go as well.
hey folks, happy new year - reviving this to say I'm trying your recent suggestions (finally), will send over repros soon!