https://pact.io logo
Join Slack
Powered by
# protobufs
  • s

    Stanislav Vodetskyi

    02/01/2024, 1:26 AM
    Hey folks, for
    atLeast(x)
    condition here - does this mean that empty lists/maps are ok unless I restrict them using
    atLeast
    ? Thanks!
    r
    • 2
    • 3
  • s

    Stanislav Vodetskyi

    02/01/2024, 7:08 AM
    It might be a dumb question, but are there any good examples on how to specify matching rules for values in a map? I'm struggling to understand the syntax tbh, like where do you put the matching rules. Like how can we say the map accepts 0+ fields and both key and value are strings (basically
    map<string, string> labels = 4
    in the .proto file). I've tried:
    Copy code
    "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" }]})
    Copy code
    "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')
    r
    • 2
    • 10
  • e

    Edd Schauman-Haigh

    02/06/2024, 12:49 PM
    When I run a test I get a few errors:
    io.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?
    r
    • 2
    • 4
  • s

    Stanislav Vodetskyi

    02/07/2024, 12:12 AM
    What's the right way to specify matching
    []byte
    fields in grpc requests/responses? I'm currently converting it to string, smth like:
    Copy code
    "bytes": "matching(type, '" + string(bytes) + "')",
    is this the right way to go?
    r
    • 2
    • 6
  • s

    Stanislav Vodetskyi

    02/07/2024, 2:28 AM
    Another issue found, sorry! 😅 https://github.com/pactflow/pact-protobuf-plugin/issues/45 @Rinka Yoshida has also ran into a similar issue with strings and booleans, but I haven't been able to reproduce on my end yet, will update the ticket if I can.
  • e

    Edd Schauman-Haigh

    02/07/2024, 9:56 AM
    My provider is throwing this error:
    body: $ Messages with StartGroup wire type fields are not supported
    . Anyone know what that means? I can't find anything obvious online
    r
    • 2
    • 1
  • e

    Edd Schauman-Haigh

    02/07/2024, 9:57 AM
    It's thrown during the
    verifyInteraction()
    function, on the first contract test
  • c

    Christopher Tonog

    02/07/2024, 8:41 PM
    Hi all 👋 I'm having some issues getting the protobuf/gRPC plugin to work. I've been specifically getting these error messages when running a js consumer test:
    Copy code
    ERROR 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!
    p
    m
    +2
    • 5
    • 13
  • s

    Stanislav Vodetskyi

    02/07/2024, 11:39 PM
    According to the doc here: https://github.com/pactflow/pact-protobuf-plugin?tab=readme-ov-file#verifying-grpc-error-responses-031 you can specify a matcher on metadata fields, but when I ran the test with pact-go, my pact file doesn't contain any matchers for the metadata value. When I read through the pact v4 spec, it doesn't look like you can specify matchers for metadata at all, but I could've missed it, it's a big doc 😅 Are matchers supported on metadata fields?
    Copy code
    "response": [
            {
              "contents": {
                "content": ""
              },
              "metadata": {
                "contentType": "application/protobuf;message=Feature",
                "grpc-message": "no feature was found at latitude:-1  longitude:-1",
                "grpc-status": "NOT_FOUND"
              }
            }
          ],
    r
    y
    • 3
    • 32
  • s

    Stanislav Vodetskyi

    02/26/2024, 9:44 PM
    Hey folks, I'm still trying to correctly test collections. I can do something like this, which seems to mean `objs should contain at least one item, each matching "obj" below`:
    Copy code
    // 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?
    r
    • 2
    • 7
  • m

    Matt (pactflow.io / pact-js / pact-go)

    03/13/2024, 1:08 AM
    Anybody able to help https://stackoverflow.com/questions/78140020/java-grpc-pact-testing-pactpluginmockservererrorexception It looks to be around how to use the additional includes option
  • e

    Eric Deandrea

    03/18/2024, 7:55 PM
    Hi folks. I posted a question in the
    #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/p1710791089530159
  • j

    James DeMaine

    03/27/2024, 4:38 PM
    Hi all, I'm currently implementing some protobuf contract testing on our project. My understanding of a consumer contract is that it is the minimum information the consumer requires from the provider, but when we tried to make a change to the provider to include some new fields, we have downstream contracts (deployed and in main) using the old version of the consumer (without the new fields required) failing when the provider still provides the new and old fields. I believe we're running into a similar issue as https://github.com/pactflow/pact-protobuf-plugin/issues/45 I ran the provider tests in debug mode and found output as below - this shows the field numbers of the new fields we added.
    Copy code
    2925Z  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 plugin
    r
    j
    • 3
    • 4
  • r

    Rinka Yoshida

    03/30/2024, 12:58 AM
    Hi all! Cross-posting a question about matching array/map here: https://pact-foundation.slack.com/archives/C9UTHTFFB/p1711759161767629
  • e

    Eric Muller

    04/08/2024, 3:59 PM
    Hi all, I recently encountered an issue when a proto package imports another package which contains a message with the same name. When running the consumer test, the message schema from the imported package is being validated against instead of the message schema for the package being tested. I’ve created a test in pact-go that reproduces the issue, but I suspect the issue is in https://github.com/pactflow/pact-protobuf-plugin.
    c
    r
    +2
    • 5
    • 106
  • r

    Rinka Yoshida

    04/16/2024, 12:00 AM
    Hi all! We were thinking about somehow integrating StructMatcher and implementing
    GetString()
    method to Matcher type, so that instead of doing this:
    Copy code
    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:
    Copy code
    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
    Copy code
    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&amp;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?
    👋 1
    m
    r
    • 3
    • 12
  • s

    Saif Farooqui

    05/16/2024, 8:09 PM
    Hi, I am trying to implement request/response proto matcher in golang for something similar mentioned below
    Copy code
    message 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 Poudel
    m
    s
    • 3
    • 7
  • m

    Mihai Zelina

    05/17/2024, 10:15 AM
    Hello. I have a couple of questions regarding features, in case anyone knows or has also tried doing this. 1. Is there any way of performing some sort of BDCT with gRPC/protobufs? Personally, I tried to do something with a dummy HelloWorld consumer-provider project. I know that only OAS provider contracts are supported in Pactflow, so I tried with translating a protobuf specification into OAS (I also know some protobuf features might be impossible to port, but I don't mind that for now), but I still could not get it to work right. Seems it just gives "Compatible" every time, regardless of whether the consumer and provider contract are indeed matching (my guess is because Pactflow does not support Plugin pacts, so a protobuf consumer pact is bypassed entirely?). Any help is appreciated. 2. For CDCT, are there any examples regarding sequential/streaming communication, or is it not implemented yet?
    y
    • 2
    • 3
  • a

    Armen Chuljyan

    05/17/2024, 11:16 AM
    Hello! Is there a way to provide metadata to the pact verifier so it can inject it into the grpc call? for example if we need to provide an access token to a provider in RPC call. For REST requests we use requestFilter. What can be done for grpc pact verifier?
    r
    m
    • 3
    • 7
  • m

    Mihai Zelina

    06/20/2024, 1:01 PM
    Hi again. Circling back to question 2 from my previous message, I see at this link https://github.com/pact-foundation/pact-specification/tree/version-4?tab=readme-ov-file#synchronousmessages that, technically, there is a pact specification for messaging where a consumer may send one message and receive back multiple messages. I am wondering, wouldn't this cover the case of server-side streaming communication (e.g. a
    rpc 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)?
    m
    • 2
    • 2
  • e

    Eran Bergman

    07/29/2024, 9:45 PM
    Hello, I'm trying to implement gRPC/protobuf tests for my application and I'm wondering if the gRPC/protobuf plugin has something like the
    valueFromProviderState
    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 call
    m
    r
    • 3
    • 26
  • e

    Eran Bergman

    08/12/2024, 3:14 PM
    Hi @Matt (pactflow.io / pact-js / pact-go) @rholshausen, I've been trying out the
    valueFromProviderState
    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?
    m
    r
    • 3
    • 28
  • s

    Stanislav Vodetskyi

    11/07/2024, 1:25 AM
    I have a conceptual question: is there any value in writing a contract test for the error case if we don't actually care what error code it was, or about the error message? Let's say I have a grpc call
    GetUser
    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!
    m
    • 2
    • 3
  • s

    Spencer

    11/07/2024, 5:17 PM
    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
    y
    • 3
    • 17
  • s

    Stanislav Vodetskyi

    11/19/2024, 8:52 PM
    Hey folks, some of our internal grpc services communicate failure by setting
    error
    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-response
    r
    • 2
    • 1
  • s

    Stanislav Vodetskyi

    11/19/2024, 8:54 PM
    Related to that, how do I specify a proto message field that must be non-nil, but I don't particularly care about it's fields? According to this doc: https://docs.pact.io/getting_started/matching/gotchas#an-empty-hash-in-the-response-means-allow-any-hash - any content is valid for that field, and that includes nils, but in some cases I care that e.g.
    GetUserResponse
    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)?
    r
    • 2
    • 14
  • s

    Stanislav Vodetskyi

    11/21/2024, 5:46 AM
    can I use smth like
    fromProviderState
    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.md
    r
    m
    • 3
    • 2
  • d

    Dustin Iser

    11/21/2024, 2:02 PM
    Hello team. I'm getting started using the protobuf plugin for gRPC contract testing. I'm currently getting this error when my provider tests run:
    Copy code
    Plugin 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?
    y
    r
    • 3
    • 5
  • s

    Stanislav Vodetskyi

    01/30/2025, 9:25 PM
    Hi folks, What's a canonical way to test a new enum value being introduced? Like if we have enum fields A,B and C, and newer version of a proto lib used by both provider and the consumer introduces D value. Consumer updates, provider doesn't update at first, but then does it too. How do we test this in Pact? Our team is currently using
    equalTo
    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?
    m
    • 2
    • 3
  • r

    Rohit Krishnan

    04/25/2025, 2:58 PM
    Hey team - we are checking in our pact contracts into Git, and noticed that whenever any upstream proto that is referenced changes, it results in
    metadata.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.