Stanislav Vodetskyi
02/01/2024, 1:26 AMatLeast(x)
condition here - does this mean that empty lists/maps are ok unless I restrict them using atLeast
? Thanks!Stanislav Vodetskyi
02/01/2024, 7:08 AMmap<string, string> labels = 4
in the .proto file).
I've tried:
"labels": {"pact:match": "eachKey(matching(type, 'some-key')), eachValue(matching(type, 'some-value'))"}
and got rpc error: code = FailedPrecondition desc = Failed to match the request message - BodyMismatches({"$.destination": [BodyMismatch { path: "$.destination.labels", expected: None, actual: None, mismatch: "Expected repeated field 'labels' to be empty but received 1 values" }]})
"labels": {"pact:match": "atLeast(0), eachKey(matching(type, 'some-key')), eachValue(matching(type, 'some-value'))"},
and it gave me an error 2024-01-31 22:44:50.5126 ┃ 2024-02-01T06:44:50.498712Z ERROR ThreadId(01) pact_ffi::plugins: Failed to call out to plugin - min-type is not a valid matching rule type
(or at least that's the error I found in the debug logs, in info it was the usual 'pact file contains no protobuf descriptors')Edd Schauman-Haigh
02/06/2024, 12:49 PMio.grpc.StatusRuntimeException: UNAVAILABLE: io exception
and ... Connection refused/[0:0:0:0:0:0:1]:63856
The tests work but the logs are full of these. Any advice on why?Stanislav Vodetskyi
02/07/2024, 12:12 AM[]byte
fields in grpc requests/responses? I'm currently converting it to string, smth like:
"bytes": "matching(type, '" + string(bytes) + "')",
is this the right way to go?Stanislav Vodetskyi
02/07/2024, 2:28 AMEdd Schauman-Haigh
02/07/2024, 9:56 AMbody: $ Messages with StartGroup wire type fields are not supported
. Anyone know what that means? I can't find anything obvious onlineEdd Schauman-Haigh
02/07/2024, 9:57 AMverifyInteraction()
function, on the first contract testChristopher Tonog
02/07/2024, 8:41 PMERROR ThreadId(01) pact_ffi::plugins: Failed to call out to plugin - Request to configure interaction failed: Failed to process protobuf: Failed to invoke protoc binary: exit code exit status: 1
ERROR ThreadId(01) pact_ffi::mock_server: Failed to start mock server - Mock server failed to start: Failed to start gRPC mock server: Pact file does not contain any Protobuf descriptors
I can imagine a number of things can be the cause of this (and I unfortunately can't post much more in the public channel), but I was wondering if there was a way to get more information on what specifically caused the protoc binary to exit? I set log levels to debug and trace but nothing really stood out to me. Thanks!Stanislav Vodetskyi
02/07/2024, 11:39 PM"response": [
{
"contents": {
"content": ""
},
"metadata": {
"contentType": "application/protobuf;message=Feature",
"grpc-message": "no feature was found at latitude:-1 longitude:-1",
"grpc-status": "NOT_FOUND"
}
}
],
Stanislav Vodetskyi
02/26/2024, 9:44 PM// provider state: given obj exists
{
"objs": {
"pact:match": "eachValue(matching($'obj')),atLeast(1)",
"obj": {
"field": "matching(type, 'sample')"
}
}
}
which is cool and exactly what I want to express.
However, if, theoretically speaking, my client code had branching like if len(objs) == 1 {} else {}
we would want our client code to hit both branches. Would we want a separate consumer test for that? What should we specify? I guess we could do provider state define multiple objects, but what would I put in the matcher then?Matt (pactflow.io / pact-js / pact-go)
Eric Deandrea
03/18/2024, 7:55 PM#pact-jvm
channel before I realized this one was here. Its rather lengthy, so rather than re-type it I’m just going to link to it if thats ok…
https://pact-foundation.slack.com/archives/C9UN99H24/p1710791089530159James DeMaine
03/27/2024, 4:38 PM2925Z WARN tokio-runtime-worker request{method=POST uri=<http://127.0.0.1:43899/io.pact.plugin.PactPlugin/VerifyInteraction> version=HTTP/2.0 headers={"te": "trailers", "content-type": "application/grpc", "authorization": Sensitive, "user-agent": "tonic/0.10.2"}}:decode_message: pact_protobuf_plugin::message_decoder: Was not able to decode field: Did not find a field with number 7 in the descriptor
2024-03-27T16:22:07.932940Z DEBUG tokio-runtime-worker pact_plugin_driver::child_process: Plugin(protobuf, 247654, STDOUT) || 2024-03-27T16:22:07.932935Z WARN tokio-runtime-worker request{method=POST uri=<http://127.0.0.1:43899/io.pact.plugin.PactPlugin/VerifyInteraction> version=HTTP/2.0 headers={"te": "trailers", "content-type": "application/grpc", "authorization": Sensitive, "user-agent": "tonic/0.10.2"}}:decode_message: pact_protobuf_plugin::message_decoder: Was not able to decode field: Did not find a field with number 8 in the descriptor
2024-03-27T16:22:07.932948Z DEBUG tokio-runtime-worker pact_plugin_driver::child_process: Plugin(protobuf, 247654, STDOUT) || 2024-03-27T16:22:07.932944Z WARN tokio-runtime-worker request{method=POST uri=<http://127.0.0.1:43899/io.pact.plugin.PactPlugin/VerifyInteraction> version=HTTP/2.0 headers={"te": "trailers", "content-type": "application/grpc", "authorization": Sensitive, "user-agent": "tonic/0.10.2"}}:decode_message: pact_protobuf_plugin::message_decoder: Was not able to decode field: Did not find a field with number 9 in the descriptor
I'm confused as to how we'd ever be able to deploy a change to the provider with new fields if the consumer is expecting an exact response rather than a minimum number of fields. I'd appreciate any help if I've either misunderstood or there is some kind of known issue with the protobuf pluginRinka Yoshida
03/30/2024, 12:58 AMEric Muller
04/08/2024, 3:59 PMRinka Yoshida
04/16/2024, 12:00 AMGetString()
method to Matcher type, so that instead of doing this:
grpcInteraction := struct {
PactProtoService string `json:"pact:proto-service"`
Request any `json:"request"`
Response any `json:"response,omitempty"`
}{
PactProtoService: "MyService",
Request: map[string]interface{}{
"user_id": "matching(integer, 100)",
},
Response: map[string]interface{}{
"first_name": "matching(type, 'random')",
"last_name": "matching(type, 'random')",
},
}
We can do below instead:
grpcInteraction := struct {
PactProtoService string `json:"pact:proto-service"`
Request string `json:"request"`
Response string `json:"response,omitempty"`
}{
PactProtoService: "MyService",
Request: StructMatcher{
"user_id": Integer(100),
}.ToString(),
Response: StructMatcher{
"first_name": Like("random"),
"last_name": Like("random"),
}.ToString(),
}
For example matchers.Integer(100).ToString()
would be {"specification":"3.0.0","pact:matcher:type":"integer","value":100}
.
I tried it on like which Integer users. However, I'm running into the issue of
Request to configure interaction failed: Failed to process protobuf: Field values must be configured with a string value, got Object {"pact:matcher:type": String("integer"), "specification": String("3.0.0"), "value": Number(100.0)}
I learnt that matching evaluation is not done recursively https://pact-foundation.slack.com/archives/C9UTHTFFB/p1712026514061369?thread_ts=1711759161.767629&cid=C9UTHTFFB, so I was wondering if you know there's another way we can get the string representation of match expressions? Or is there a way to bypass the recursion issue?Saif Farooqui
05/16/2024, 8:09 PMmessage Request {
string id = 1;
map<string, string> device_headers = 2;
map<string, string> params = 3;
repeated break_duration_ms = 4;
}
In my use case objects and arrays can be empty as well. I am not able to find some good resources/examples for the same in golang.
cc: @Praful PoudelMihai Zelina
05/17/2024, 10:15 AMArmen Chuljyan
05/17/2024, 11:16 AMMihai Zelina
06/20/2024, 1:01 PMrpc SayHellos (HelloRequest) returns (stream HelloReply) {}
service)? Additionally, are there any examples or instructions on how to implement such a test for a gRPC consumer-provider pair (I am mainly interested in how the interaction would look in e.g. Go, to be able to generate a mock server, if possible)?Eran Bergman
07/29/2024, 9:45 PMvalueFromProviderState
that the REST API has?
this is in case I would like to inject something like entity ID of an entity created during the state setup into the gRPC callEran Bergman
08/12/2024, 3:14 PMvalueFromProviderState
enhancement and found that injecting singular primitives works fine however injection of a collection from state provider isn't supported (example: a list of strings). Would it be possible to add such support as well, at least for primitive types?Stanislav Vodetskyi
11/07/2024, 1:25 AMGetUser
which returns User
object with username, full name, etc - I can have matchers on those and check that the fields I actually care about are present in the response. But if the user does not exist, my line u, err := client.GetUser(ctx, userRequest)
(I'm using go) would have a non-nil err
, and that's the only thing I'm checking - if err is not nil, I'll just return it without parsing.
In my consumer test I can specify a provider state saying "user x does not exist" or smth, and write a test case where I verify that mock server does return the error.
In my provider test I can read the state and make sure the user does not exist in the db.
But I'm not sure I see any value, because the contract literally says "there will be some error, we don't care which one".
Maybe I'm missing something? Thanks!Spencer
11/07/2024, 5:17 PMGrpcTransport
(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 🙂Stanislav Vodetskyi
11/19/2024, 8:52 PMerror
field on the proto (but not returning an error code, so the grpc return code is OK).
From what I understand there's no way to specify this in pact? https://docs.pact.io/getting_started/matching/gotchas#you-cannot-expect-a-field-to-not-be-present-in-a-responseStanislav Vodetskyi
11/19/2024, 8:54 PMGetUserResponse
contains non-nil user
field and nil error
field, but it's probably not ok if both are nil (but it's likely ok if both are non-nil)?Stanislav Vodetskyi
11/21/2024, 5:46 AMfromProviderState
matcher in protobuf plugin? the doc here doesn't mention it: https://github.com/pact-foundation/pact-plugins/blob/main/docs/matching-rule-definition-expressions.mdDustin Iser
11/21/2024, 2:02 PMPlugin protobuf failed to validate the interaction: Plugin configuration item with key 'ea4217bffbf17f94e01b461796d57ad4' is required. Received config ["794aed6a7e746a9d0688e0a45801456b"]
I have several questions about this:
• How do I debug it? When I look at the code it appears that these keys are MD5 hashes of the proto descriptors. How do I figure out what's different?
• How is it failing? When I debug the tests, it appears that it's failing with a request sent to the broker. When I look at the request payload, it appears that the expected descriptor keys are there. Yet the broker still returns an error.
• Why do I care about the descriptor keys? It's not immediately apparent to me why I should care if the descriptor keys are different. Isn't it possible that the protos used by the consumer and the provider to be different and yet the contracts still be satisfied?Stanislav Vodetskyi
01/30/2025, 9:25 PMequalTo
on every possible option, so the consumer will introduce new test which would use equalTo('D')
in the request and just assert no error received in the response. This means we have a separate test for each possible enum value though. Is it a good way to do things or is there a better way?Rohit Krishnan
04/25/2025, 2:58 PMmetadata.plugins[0].configuration.{hash}.protoDescriptors
changing. Would it be possible to either ignore descriptor changes that don't change the messages referenced by our consumer? We work in a pretty large codebase, so it results in frequent updates to the proto descriptors.