austek / pact-avro-plugin

Pact AVRO Plugin
https://austek.github.io/pact-avro-plugin/
MIT License
8 stars 3 forks source link

Problem matching bytes fields #48

Open creckord opened 1 week ago

creckord commented 1 week ago

I have a field like this in my Avro schema, and I'm struggling with how to write a match expression for it:

  [{
    "type": "record",
    "name": "LeEvent",
    "namespace": "org.example",
    "fields": [
      {
        "name": "hashes",
        "type": {
          "type": "map",
          "values": "bytes",
        }
      }]
  }]

My pact setup, written in Java, looks like this (following the example from the plugin docs):

builder.usingPlugin("avro", "0.0.6")
                .expectsToReceive("LeEvent", "core/interaction/message")
                .with(Map.of("message.contents",
                        ofEntries(
                                entry("pact:avro", schemasPath),
                                entry("pact:record-name", "LeEvent"),
                                entry("pact:content-type", "avro/binary"),
                                entry("hashes", Map.of(
                                             entry("sha-256", ???)
                                        ))
                        )))
                .toPact();

I can see in the plugin code that for bytes fields something is supposed to happen with AvroStrings, but I couldn't make heads or tails of it wrt how to write the matcher for the map entries. I tried unsuccessfully:

All those failed with various type conversion/class cast errors.

I also tried to write matchers at the "hashes" level:

But those failed, because the value for "hashes" was expected to be a Map, not a String.

Right now, the only way I could get it to run the pact successfully, was by providing an empty map as a value for "hashes".

YOU54F commented 1 week ago

👋🏾 Hey

There are eachKey and eachValue matching rules for dealing with maps/lists

Expressions can be composed

https://github.com/pact-foundation/pact-plugins/blob/main/docs/matching-rule-definition-expressions.md#composing-expressions

What expressions did you try with the following?

I also tried to write matchers at the "hashes" level:

entry("hashes", "atMost(2)") entry("hashes", "eachValue(...)")

Is it possible to create a minimal reproducible example either in this repo or a separate one. It would aid the core maintainer, and myself in trying to help you out.

An example from the protobuf plugin that may be useful

https://github.com/pact-foundation/pact-plugins/blob/5def99c8dc41c70e97ed1ae04bcb8e2961c95332/plugins/protobuf/README.md?plain=1#L129

creckord commented 1 week ago

Here's a repro with a bunch of different attempts at writing matchers for bytes and maps of non-string values:

https://github.com/creckord/pact-avro-48-map-bytes

creckord commented 1 week ago

An example from the protobuf plugin that may be useful

https://github.com/pact-foundation/pact-plugins/blob/5def99c8dc41c70e97ed1ae04bcb8e2961c95332/plugins/protobuf/README.md?plain=1#L129

That got me a little farther. I would never have gotten the bit with the pact:match entry from pact-plugins docs. I updated my example repo.

That took care of the atMost(2) expression, but lead to some new errors related to eachKey/eachValue, which I think I did 1:1 as in the protobuf example.

The problem with matching on a bytes value remains as well.