pact-foundation / pact-net

.NET version of Pact. Enables consumer driven contract testing, providing a mock service and DSL for the consumer project, and interaction playback and verification for the service provider project.
https://pact.io
MIT License
842 stars 231 forks source link

Pact testing of protobuf messages failing due to content type JSON #489

Closed wessonben closed 7 months ago

wessonben commented 7 months ago

I'm really struggling to get .Net Pact testing of a protobuf format messages working. I have access to the Pact files and they are known to be correct and other teams in our organisation have created tests against them from Java code. I need to be able to do the same from C#.

I am using Nuget library pact-net v5.0.0 (I know it's pre-release) and have a unit test with code like this...

        var bufferWriter = new ArrayBufferWriter<byte>();
        ProtoBuf.Serializer.Serialize(bufferWriter, someMessageObject);

        var action = () => PactVerifier
            .WithMessages(messages => messages.Add("Pact Description", builder => builder
                .WithMetadata(new Dictionary<string, string> {{ "contentType", "application/protobuf; message=MessageType" }})
                .WithContent(() => bufferWriter.GetMemory())
            ))
            .WithUriSource(new Uri("http://adress-of-the-pact"))
            .Verify();

        action.Should().NotThrow();

The test results in the output below. The confusing part is that it appears acknowledge that the metadata is OK with the expected content type, but it complains that the body is of type "application/json" when I need it to be the same as the metadata (but nowhere have I set the content to be json format).

Verifier Output
---------------

Verifying a pact between producer-msg-type-consumer and producer-msg-type-provider

  Bet Stop (123ms loading, 144ms verification)

  Test Name: pact.ConsumerTest.consumeMessage(AsynchronousMessage)
    generates a message which
      includes metadata
        "contentType" with value "application/protobuf;message=BetStop" (OK)
      has a matching body (FAILED)

Failures:

1) Verifying a pact between producer-msg-type-consumer and producer-msg-type-provider - Message
    1.1) has a matching body
           expected a body of 'application/protobuf;message=BetStop' but the actual content type was 'application/json'

There were 1 pact failures

Also logged the question on stackoverflow:

adamrodger commented 7 months ago

Interesting. I've never actually tried that so can't confirm.

Would you be able to share the pact file and output logs? Or a minimal example that reproduces the problem anyway so that you aren't sharing private info.

I'm hoping this doesn't rely on plugin support because PactNet doesn't currently have that, but I'll know more with the extra details.

YOU54F commented 7 months ago

I would imagine that is the case, that plugin support is required, otherwise pact doesn't have the core capability to support a content type of application/protobuf.

Once would require use of

https://github.com/pactflow/pact-protobuf-plugin

and it integrating into Pact-Net

There are three of the methods exposed for plugins

https://docs.rs/pact_ffi/latest/pact_ffi/plugins/index.html

There is a pactffi_create_mock_server_for_transport method to support non http/https methods such as grpc. A plugin would be expected to provide this transport

https://docs.rs/pact_ffi/latest/pact_ffi/verifier/fn.pactffi_verifier_add_provider_transport.html

On the verifier side, one can register transports

https://docs.rs/pact_ffi/latest/pact_ffi/mock_server/fn.pactffi_create_mock_server_for_transport.html

Samples of plugin use with php/python through the ffi

We have a range of full examples of plugin use in different client libraries

https://github.com/pact-foundation/pact-plugins/tree/feat/pact-csv-plugin-linux-aarch64/examples

and it is currently possible to utilise plugins with the standalone mock server / verifier cli, which can provide a mechanism to utilise with a .NET project, whilst waiting for support in the pact-net library

wessonben commented 7 months ago

Thanks for the responses, I will try and put together a self contained reproduction of the issue.

However, it does use a plugin for the protobuf integration. I was actually getting a different error before installing the plugin, so the Pact processing at least seems to detect the plugin. Here is the confirmation from the CLI tool of the protobuf plugin...

PowerShell 7.4.1
PS C:\GitLab\PremiumCricket\pact-net-5.0.0-beta.1> ./pact-plugin-cli list
┌──────────┬─────────┬───────────────────┬─────────────────────────────────────────────────┬─────────┐
│ Name     ┆ Version ┆ Interface Version ┆ Directory                                       ┆ Status  │
╞══════════╪═════════╪═══════════════════╪═════════════════════════════════════════════════╪═════════╡
│ protobuf ┆ 0.3.12  ┆ 1                 ┆ C:\Users\b.wesson\.pact/plugins\protobuf-0.3.12 ┆ enabled │
└──────────┴─────────┴───────────────────┴─────────────────────────────────────────────────┴─────────┘
PS C:\GitLab\PremiumCricket\pact-net-5.0.0-beta.1>
adamrodger commented 7 months ago

Closed as plugins are not currently supported. Please see the linked issue for progress on that feature.