matt.fellows
2022-10-24 12:35
has joined #pact-plugins

yousafn
2022-10-24 12:35
has joined #pact-plugins

uglyog
2022-10-24 12:35
has joined #pact-plugins

glenn
2022-10-24 12:35
has joined #pact-plugins

ali.ustek
2022-10-24 12:35
has joined #pact-plugins

matt.fellows
2022-10-24 12:36
Just getting a place for us to discuss the creation of plugins. I?m heading off for the night, but will pop back in here tomorrow with some goodies on next steps :slightly_smiling_face:

yousafn
2022-10-24 12:37
Thanks Matt! Looking forward to welcoming newcomers and old faces to a world of possibilities :slightly_smiling_face:

jaswanth.ooty
2022-11-15 00:17
has joined #pact-plugins

jason.taylor2
2022-11-15 18:01
has joined #pact-plugins

orbit
2022-12-01 15:45
has joined #pact-plugins

aforeman
2022-12-05 02:26
has joined #pact-plugins

sameena9010
2022-12-06 11:38
has joined #pact-plugins

tjones
2022-12-06 11:50
has joined #pact-plugins

yousafn
2022-12-06 12:11
Hey @sameena9010, I saw your question in general, had a go at answering a few below https://pact-foundation.slack.com/archives/C5F4KFKR8/p1670325812233529 Thanks for joining the channel. You asked say 4 q's 1. Can you automate testing of gRPC with Pact a. Yes. with the Pact-protobuf-plugin. https://github.com/pactflow/pact-protobuf-plugin 2. Can you test Kafka with Pact. a. We have some examples with the existing Pact framework (some are Pactflow branded but work with the OSS broker) i. https://docs.pact.io/recipes/kafka ii. https://docs.pactflow.io/docs/examples/kafka/js/consumer iii. https://docs.pactflow.io/docs/examples/kafka/java/consumer iv. https://docs.pactflow.io/docs/examples/kafka/java/provider b. We do not currently have a Kafka plugin, You can request or vote for one of our Canny feature request board https://pact.canny.io/ 3. gRPC testing is only available through plugins - https://docs.pact.io/plugins 4. Plugins will be supported by any Pact implementation using the underlying Rust framework, that supports V4 Pact specification (and utilses plugins) a. There is some small amount of work to do, to introduce plugin support to pact-net. We can help provide advice to yourself to aid the main maintainer Adam Rodgers. b. If the language doesn't support it, but is capable of supporting FFI calls, a user could build out a Pact framework with support for plugins. I am fairly new to the world of gRPC and haven't used Kafka in production, but always happy to learn new things and help you along

sameena9010
2022-12-06 12:16
Thanks @yousafn for the detailed info, i just started looking in to these implementations. I will post my future questions in this channel if i see any issues while doing a poc

yousafn
2022-12-06 12:20
Please do! We look forward to following your journey and wish you all the success

matt.fellows
2022-12-06 20:47
It should be noted that we don?t yet have support in Pact .NET (C#), but as we produce more developer/maintainer material we?d hope to work with the language maintainers to adopt the framework/feature

phil.vint
2022-12-08 12:47
has joined #pact-plugins

manishmitraba
2022-12-13 03:50
has joined #pact-plugins

sambhavi.chinnu
2022-12-13 04:35
has joined #pact-plugins

dmitrij.bogomyakov
2022-12-13 16:19
has joined #pact-plugins

sameena9010
2022-12-15 06:16
Hi I want to explore on the gRPC plugin with maven example, so i installed the protobuf plugin and now im trying to run consumer test its failing with below reason. Can someone help me what i am missing here ```<<< FAILURE! - in io.pact.example.grpc.maven.PactConsumerTest calculateRectangleArea{MockServer, SynchronousMessages} Time elapsed: 1.542 s <<< ERROR! kotlin.UninitializedPropertyAccessException: lateinit property process has not been initialized at io.pact.example.grpc.maven.PactConsumerTest.calculateRectangleArea(PactConsumerTest.java:45)```

uglyog
2022-12-15 06:34
`lateinit property process has not been initialized` means there is a property that has to be initialized before the object can be used. What do you have at `PactConsumerTest.java:45`?

sameena9010
2022-12-15 06:35
which plugin to use ```.usingPlugin("protobuf","0.2.1")```

uglyog
2022-12-15 06:37
Hmm, try plugin version "0.2.2" as "0.2.1" is not good.

sameena9010
2022-12-15 06:48
yeah this one worked

nathan.deamer
2022-12-19 09:41
has joined #pact-plugins

sameena9010
2022-12-20 08:25
I created a repo with go plugin template and made the changes following readme, now when I try to install it i'm getting below error ```pact-plugin-cli.exe install https://github.com/sameena-ops/pact-sample-plugin/releases/tag/v0.0.5 Installing plugin pact-sample-plugin version 0.0.4 ? Plugin with name 'pact-sample-plugin' and version '0.0.4' already exists. Overwrite it? Yes Error: Did not find a matching file pattern on GitHub to install```

matt.fellows
2022-12-20 08:59
Try adding the verbose flag, it should show what targets it's trying to find

matt.fellows
2022-12-20 09:01
Aha it looks like the version in the plugin json is incorrect :thinking_face:(still 0.0.4) I wonder if there is a bug in the code that updates that?

sameena9010
2022-12-20 09:07
yeah right i missed updating to 0.0.5 in plugin json, let me change and check

sameena9010
2022-12-20 09:10
but still its looking for 0.0.4 ```Installing plugin pact-sample-plugin version 0.0.4 ? Plugin with name 'pact-sample-plugin' and version '0.0.4' already exists. Overwrite it? Yes 2022-12-20T09:09:22.400911Z INFO pact_plugin_cli::install: Deleting contents of plugin directory 2022-12-20T09:09:22.408563Z INFO pact_plugin_cli::install: Writing plugin manifest file 2022-12-20T09:09:22.415874Z DEBUG pact_plugin_cli::install: Detected OS: Windows 10.0.19044 (Windows 10 Enterprise) [64-bit] 2022-12-20T09:09:22.417143Z DEBUG pact_plugin_cli::install: Checking existence of file from https://github.com/sameena-ops/pact-sample-plugin/releases/download/v0.0.5/pact-pact-sample-plugin-plugin-windows-x86_64.exe.gz 2022-12-20T09:09:22.420079Z DEBUG hyper::client::pool: reuse idle connection for ("https", http://github.com) 2022-12-20T09:09:22.420977Z DEBUG Connection{peer=Client}: h2::codec::framed_write: send frame=Headers { stream_id: StreamId(5), flags: (0x5: END_HEADERS | END_STREAM) } 2022-12-20T09:09:22.635027Z DEBUG Connection{peer=Client}: h2::codec::framed_read: received frame=Headers { stream_id: StreamId(5), flags: (0x5: END_HEADERS | END_STREAM) } 2022-12-20T09:09:22.636942Z DEBUG hyper::client::client: client connection error: connection error: broken pipe Error: Did not find a matching file pattern on GitHub to install```

sameena9010
2022-12-20 09:15
If I change plugin json later then do I need to publish the new version of plugin with the same version in plugin json?

sameena9010
2022-12-20 09:21
And also its taking the gz file path as https://github.com/sameena-ops/pact-sample-plugin/releases/download/v0.0.5/*pact*-pact-sample-*plugin*-plugin-windows-x86_64.exe.gz does it mean the entry point or somewhere i should give only sample instead of full project name.?

matt.fellows
2022-12-20 09:30
in your `pact-plugin.json` file, the name of your plugin shouldn?t be `pact-sample-plugin` but just `sample`


matt.fellows
2022-12-20 09:32
the make actions should set the name of the plugin in `pact-plugin.json` based on the value of `PROJECT` in `Makefile`

matt.fellows
2022-12-20 09:32
It?s possible there is a bug in that though, given it didn?t seem to update the version in the `pact-plugin.json`. If you can track down what happened and raise an issue, that would be great

sameena9010
2022-12-20 09:32
yeah looks same what i have is ```{ "pluginInterfaceVersion": 1, "name": "sample", "version": "0.0.5", "executableType": "exec", "minimumRequiredVersion": null, "entryPoint": "pact-sample-plugin", "entryPoints": {}, "dependencies": null, "pluginConfig": {}}```


matt.fellows
2022-12-20 09:33
what does your makefile look like?

sameena9010
2022-12-20 09:35
yeah version mismatch is there in make file # Update this version VERSION=0.0.4 # Update to your project name PROJECT=pact-sample-plugin

matt.fellows
2022-12-20 09:35
yep, the project name is wrong too (see above)

matt.fellows
2022-12-20 09:35
it should just be `sample`

matt.fellows
2022-12-20 09:35
TL;DR - you shouldn?t need to manually touch `pact-plugin.json`


sahoo.skumar
2022-12-20 13:46
has joined #pact-plugins

sahoo.skumar
2022-12-20 13:49
We are using pact-protobuf-plugin version : v-0.2.3, The protobuf under contract test imports another protobuf, could you please help me out how we can pass multiple protobuf into V4Pact builder

uglyog
2022-12-21 00:26
For the moment, you need to add the additional import directories in the plugin manifest file. See https://github.com/pactflow/pact-protobuf-plugin#additionalincludes-string-or-liststring

uglyog
2022-12-21 00:27
We are currently working on allowing it to be configured in the test

yousafn
2022-12-21 11:01
Protodoc is a pretty cool tool for visualising your proto files. Here is an example with our plugin.proto file https://gist.github.com/YOU54F/5a1ac48da75bea30a2cf019d9d1929a1

yousafn
2022-12-21 11:08
I noted that in a consumer pact test we need to specify the version of the pact plug-in, at least in pact-js If we do, we use the latest version of the plug-in in the plug-in directory, regardless of the version specified in the test. This means the pact gets encoded with the protobuf plug-in later version than specified. On the provider side, the provider test reads the required plug-in version from the file. I had ran my provider test after deleting the latest plug-in from my plug-in folder, which causes my provider test to fail. It might be nice for 1. Use the specified version always, or inform user that you are using a later on on consumer side 2. Provider side - should it alert if it can?t find the correct version plug-in, should it automatically try and download it, if it doesn?t exist Otherwise how do we easily make it visible to a provider, which plugins they require in order to run a particular set of pact verifications. Could there be an ability to retrieve the plugins used for a specific verification, same could be extended to provider states. I could do something with some api calls, get pacts for verification, pull down contents, filter through for provider states and pact plugin entries and print back to the user

matt.fellows
2022-12-21 11:47
I think a user specified semver option might be a way to go. I think Ron uses a semver library under the hood so that behaviour could possibly be improved.

matt.fellows
2022-12-21 11:48
Also, if the framework could auto install that would be really cool

uglyog
2022-12-21 22:30
The idea was to use the specified version or a later semver compatible one. But the logic hasn't been tested, so it may not work.

uglyog
2022-12-21 22:32
To auto-install a plugin, the framework needs a way to know where the plugin installation files are. We have had this idea of a plugin repository that can be queried for that info.

tjones
2022-12-22 03:00
Why not just use the package manager of whatever ecosystem is being used? The need to manage the versions ourselves seems like a strange design choice to me.

uglyog
2022-12-22 03:08
You mean the plugin author should package their plugins using every package manager out there? I.e. Maven repo, NPM, Rust crate, Cocopod, homebrew, ...

tjones
2022-12-22 03:12
No, just the ones we support :wink:

tjones
2022-12-22 03:12
otherwise, where are they going to get them from?

tjones
2022-12-22 03:13
You could even script it into a pact-plugin-publish CLI or something

sahoo.skumar
2022-12-22 03:30
We are unable to make it work with protobuf-config and additionalIncludes. The test is a simple messaging test. The code block look like as

sahoo.skumar
2022-12-22 03:30
```@Pact(consumer = "test-consumer") V4Pact configureInteractionMessage(PactBuilder builder) { return builder .usingPlugin("protobuf") .expectsToReceive("State Interaction message", "core/interaction/message") .with(Map.of( "message.contents", Map.of( "pact:proto", filePath("target/test-resources/com/ap/proto/v1/health.proto"), "pact:message-type", "DeviceHealth", "pact:content-type", "application/protobuf", "pact:protobuf-config", Map.of( "additionalIncludes", List.of( filePath("target/test-resources/com/ap/proto/v1/enums.proto") ) ) ) )) .toPact(); }```

sahoo.skumar
2022-12-22 03:31
health.proto referencing enums.proto

uglyog
2022-12-22 03:31
`additionalIncludes` must be the directory, not the file

sahoo.skumar
2022-12-22 03:40
Thanks, still we dont have any luck, we are using latest v0.2.4, any hint if you could see we are missing something ?

sahoo.skumar
2022-12-22 03:42
or any sample example would be great, Thanks


sahoo.skumar
2022-12-25 03:32
can we have an example of message interaction instead of GRPC, it seems the "pact:protobuf-config" is not working with only message type interaction.

sahoo.skumar
2022-12-25 03:33
```@Pact(consumer = "test-consumer") V4Pact configureInteractionMessage(PactBuilder builder) { return builder .usingPlugin("protobuf") .expectsToReceive("State Interaction message", "core/interaction/message") .with(Map.of( "message.contents", Map.of( "pact:proto", filePath("target/test-resources/com/ap/proto/v1/health.proto"), "pact:message-type", "DeviceHealth", "pact:content-type", "application/protobuf", "pact:protobuf-config", Map.of( "additionalIncludes", List.of( filePath("target/test-resources/com/ap/proto/v1") ) ) ) )) .toPact(); }```

sahoo.skumar
2022-12-25 03:34
The trace we have

sahoo.skumar
2022-12-25 03:34
org.junit.jupiter.api.extension.ParameterResolutionException: Failed to resolve parameter [http://au.com.dius.pact.core.model.V4Interaction$AsynchronousMessage message] in method [void com.aruba.contract.consumer.ConsumerMessagePactTest.consumeConfigureInteractionPersonMessage(http://au.com.dius.pact.core.model.V4Interaction$AsynchronousMessage) throws com.google.protobuf.InvalidProtocolBufferException]: Failed to set the interaction: Failed to process protobuf: Failed to invoke protoc binary: exit code exit status: 1 at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:239) at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:183) at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameters(ExecutableInvoker.java:144) at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:96) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:210) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:206) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:131) at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:65) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:143) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:129) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:127) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:126) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:84) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:108) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67) at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:96) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:75) at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:71) at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38) at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: http://au.com.dius.pact.consumer.dsl.InteractionConfigurationError: Failed to set the interaction: Failed to process protobuf: Failed to invoke protoc binary: exit code exit status: 1 at http://au.com.dius.pact.consumer.dsl.PactBuilder.setupMessageContents(PactBuilder.kt:276) at http://au.com.dius.pact.consumer.dsl.PactBuilder.with(PactBuilder.kt:182) at com.aruba.contract.consumer.ConsumerMessagePactTest.configureInteractionPersonMessage(ConsumerMessagePactTest.java:34) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:688) at org.junit.platform.commons.support.ReflectionSupport.invokeMethod(ReflectionSupport.java:198) at http://au.com.dius.pact.consumer.junit5.PactConsumerTestExt.lookupPact(PactConsumerTestExt.kt:415) at http://au.com.dius.pact.consumer.junit5.PactConsumerTestExt.resolveParameterForProvider(PactConsumerTestExt.kt:132) at http://au.com.dius.pact.consumer.junit5.PactConsumerTestExt.resolveParameter(PactConsumerTestExt.kt:108) at org.junit.jupiter.engine.execution.ExecutableInvoker.resolveParameter(ExecutableInvoker.java:216) ... 52 more

sahoo.skumar
2022-12-25 03:35
Any help on this would be appreciable.

anandhiemail
2022-12-29 18:25
has joined #pact-plugins

fabio.rodrigues
2023-01-03 11:34
has joined #pact-plugins

mario.pires
2023-01-03 11:42
has joined #pact-plugins

fabio.rodrigues
2023-01-04 15:24
Hi all In relation to pact plugins, we at OutSystems are trying to check if we can write a plugin to do contract testing that use NATS as the delivery system of messages between systems to test. That is the services communicate via message exchange with NATS (https://nats.io/) (that messages are json payload to a specific topic). That made us checking the plugins documentation and examples and some questions were raised: ? Can we currently do a plugin that would connect to Nats like a client and subscribe to topic to either receive or publish messages, and verify the content of those messages (like Grpc or protobuf or kafka) ? Can we use .Net for creating the plugin? If not, since pact-net is a wrapper for the Rust common engine, do we need to use Rust. Or can we use Kotlin? ? Does pact-net already support plugin usage like pact-rust or pact-jvm? And if not, when can we expect that to happen, if at all? ? How does contract visualization occur on the pactflow site? ? What kind of support can we expect from Pactflow/Smartbear team for this endeavor?

uglyog
2023-01-05 00:14
Hi @fabio.rodrigues I'll try answer all the questions: ? Can we currently do a plugin that would connect to Nats like a client and subscribe to topic to either receive or publish messages, and verify the content of those messages (like Grpc or protobuf or kafka) This is what the plugin framework was designed to do. We tried to make it as generic as possible to support all the different use cases that we are aware of. However, the general strategy we are aiming for is to emulate systems like Nats. I.e., with Grpc the plugin provides a mock server to use, and with Kafka we don't actually connect to a real Kafka topic during the tests. ? Can we use .Net for creating the plugin? If not, since pact-net is a wrapper for the Rust common engine, do we need to use Rust. Or can we use Kotlin? Currently plugin support is available with Pact-JVM, Pact-Rust and Pact-Go, so you will need to write the tests in a language supported by one of those frameworks. So Rust or Kotlin will work. ? Does pact-net already support plugin usage like pact-rust or pact-jvm? And if not, when can we expect that to happen, if at all? I think Pact-JS is the next target, and the support for it is in development. Once that is released, Pact-Net will probably be the next framework to target. I would imagine that work on that will start around middle of 2023. ? How does contract visualization occur on the pactflow site? Pactflow does not currently support the plugin and V4 Pact formats, so will try render it in a very basic manor. Plugin support was scheduled to begin Q1 2023, so that work should kick off shortly. ? What kind of support can we expect from Pactflow/Smartbear team for this endeavor? Plugins is on the Pactflow feature roadmap, so new features for it are supported by the budget from Smartbear for Pactflow features. For maintenance and issues with Pact frameworks, Smartbear allows the engineering teams to spend up to about 20% of their budgets on OSS maintenance. So with those constraints, we will try to support any plugin work as it is important to us.

jeroen.vandijk
2023-01-10 09:07
has joined #pact-plugins

james_fraser
2023-01-23 09:43
has joined #pact-plugins

jwang
2023-01-27 23:35
has joined #pact-plugins

joseph.joyce
2023-03-15 09:20
has joined #pact-plugins

adam.cox
2023-03-15 09:58
has joined #pact-plugins

tien.xuan.vo
2023-03-16 02:52
has joined #pact-plugins

adam.cox
2023-03-21 12:05
Hello Pact, I am still working on trying to get a WebSockets plugin (rust) up and running and are hitting some issues. We have implemented the start_mock_server and stop_mock_server requests and when invoked manually using gRPC and calling the enpoints the WS server starts up and can be interacted with. Calling the Shutdown RPC then closes all connections and returns the match results (of which there are none). We are now trying to implement the consumer test so that it submits the interactions to the server. This is where we are struggling a bit: 1. The pact is being sent to the plugin successfully. The interaction we are setting up is present and looks correct. However when we decode the JSON to a v4 Pact the transport value is always None - does this matter? 2. When running the consumer test the start mock server request is sent and the server is stood up. However the plugin immediately starts shutting down, we get no configure_interaction request and there is a panic on main where the shutdown request was sent but the plugin has already gone away. 3. When we pact_builder.synchronous_messages() in the consumer test the vector is always empty, we therefore cannot loop to perform the tests. Switching to sending the message manually doesn?t fix the problem highlighted in 2. We are trying to follow the pact-plugin-protobuf from the pactflow repo and everything looks the setup the same. But obviously we are missing something here. Is it possible to get some pointers with this? Thanks,

adam.cox
2023-03-21 13:56
I think I have solved some of this actually. Previously our code looked like this: ```let mut pact_builder = PactBuilder::new_v4("message-consumer", "message-provider"); // Define the message consumer and provider by name let mock_server = pact_builder .using_plugin("websockets", None) .await // Adds an interaction given the message description and type. .synchronous_message_interaction("Mallory Message", |mut i| async move { /// ... }) .await .start_mock_server_async(Some("websockets/transport/websockets")) .await; pact_builder .synchronous_messages() .collect::<Vec<SynchronousMessage>>().len() // 0```

adam.cox
2023-03-21 13:57
However if I change it to: ```let mut pact_builder = PactBuilder::new_v4("message-consumer", "message-provider"); // Define the message consumer and provider by name let mut pact_builder_async = pact_builder.using_plugin("websockets", None).await; let mock_server = pact_builder_async .synchronous_message_interaction("Mallory Message", |mut i| async move { // ... }) .await .start_mock_server_async(Some("websockets/transport/websockets")) .await; pact_builder_async .synchronous_messages() .collect::<Vec<SynchronousMessage>>() .len() // 0 ```

adam.cox
2023-03-21 13:59
Then the interactions vector has 1 element and also the server does not go away and the shutdown method is called and is successful. I guess the original PactBuilder becomes redundant once we do `using_plugin` and get the PactBuilderAsync. The async one then becomes the one we need to work with and keeping the reference to it in stop is what stops the server from shutting down

adam.cox
2023-03-21 14:05
We still do not get configure_interaction requests though. When should we expect to get thosE?

yousafn
2023-03-21 17:38
Hey Adam, Thanks for posting up and bravo for jumping in to the world of Pact plugins! I saw in general you have already spoken to a couple of the core maintainers! They are based over in Aus so will catch up with this overnight. Is there a shareable codebase? It would help the maintainers and myself in additional investigations (no worries if not) I'll try my best to answer you questions when I get some free time but feel free to keep posting as you work along, as we will support you as best as we can! We are totally invested in bringing more plugins and plugin authors to the fold :)

uglyog
2023-03-21 22:19
Oh, that could be a trap for lots of people. I'll need to think of a way to get the first builder to hold the reference to the second one.

adam.cox
2023-03-22 09:05
@yousafn I?m not sure about shareable codebase. I realise that makes things very difficult but its currently hosted in Comcast Sky?s GitHub org and is private. I?ll have a chat with the powers that be and see what would be best for getting code in front of you guys as its basically impossible to help without looking at the code yourself. I certainly know how that is :smile:

adam.cox
2023-03-22 09:07
> Oh, that could be a trap for lots of people. I?ll need to think of a way to get the first builder to hold the reference to the second one. For the signature of use_plugin could you just do `self` instead of `&self` and move the ownership?

adam.cox
2023-03-22 09:10
A different question, are `configure_interaction`, `generate_content` and `compare_contents` only relevant if we are adding new Generator and Matcher catalogue entries? We aren?t adding those so do we need to worry much about their implementation. btw, I think the plugin architecture is a brilliant idea and bravo for moving everything to Rust. The tooling is so much more portable and extensible this way and it allows us to get things done as we need to. Great job!

oloruntobi.ayilara
2023-03-22 09:25
has joined #pact-plugins

haiyang.huang
2023-03-22 10:30
has joined #pact-plugins

uglyog
2023-03-22 22:14
> A different question, are configure_interaction, generate_content and compare_contents only relevant if we are adding new Generator and Matcher catalogue entries? We aren?t adding those so do we need to worry much about their implementation. Yes, that is correct. You should be able to just ignore anything you don't need, and if your plugin never provides catalogue entries for those types of things, they will never be called.

praveen.em
2023-03-24 08:15
has joined #pact-plugins

tien.xuan.vo
2023-03-25 04:07
Hi, Can I reify protobuf message (async message) like a normal message? I expect to able to get message object without any matching and pass it to a callback/handler.


tjones
2023-03-25 07:53
Oh wait, sorry, I misread the question. I don?t actually know - but I would assume you can


tien.xuan.vo
2023-03-25 09:11
when I call ffi method `pactffi_message_reify` I cant get something that I can decode into original object

matt.fellows
2023-03-25 09:59
There is a way to get it Tien, when I'm at my computer I'll check. There is a message iterator you can use to get the raw btye array, which you can use to pass it back on to the test without matchers etc

tien.xuan.vo
2023-03-25 15:58
Never mind. I think I went to the wrong direction. After adding `debug!` and compiling `rust_ffi` I think `assume you can` from Timothy is the correct answer for now. I got an error before I can confirm. I will ask in another thread.

tien.xuan.vo
2023-03-25 16:02
I got this error when working with protobuf plugin: ```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``` According to this https://github.com/pactflow/pact-protobuf-plugin#logging, how can I set env `LOG_LEVEL` exactly? I checked `/path/to/plugins/protobuf/log/*.log.Y-M-D` , all files are empty, and I can't see the real problem. I tried this but it doesn't work: ```LOG_LEVEL=debug PACT_LOGLEVEL=trace phpunit example/async-message/consumer/tests/Contract/```

tien.xuan.vo
2023-03-27 01:02
I can confirm the answer is `yes`

tien.xuan.vo
2023-03-27 01:46
Is it a good idea to support loading plugins from multiple directories? e.g. Support multiple values for `PACT_PLUGIN_DIR` , or introduce new var `PACT_PLUGIN_DIRS`

uglyog
2023-03-27 02:03
This needs to be configured in the Pact-PHP integration. The default is to use the `LOG_LEVEL` environment variable, but just note that this is a Node.js/Ruby specific way. But there are FFI functions to setup the logging.

uglyog
2023-03-27 02:04
But, even then, `Failed to invoke protoc binary: exit code exit status: 1` means the protoc command failed with an error, and the log level will not control that tools output. I think it writes to stderr.

uglyog
2023-03-27 02:05
Why would you want this?

matt.fellows
2023-03-27 02:24
So yes, you can get them via the message iterator, i.e. these messages ```pactffi_pact_handle_get_message_iter pactffi_pact_message_iter_next pactffi_message_get_contents_length pactffi_message_get_contents_bin```

matt.fellows
2023-03-27 02:25
There are two `sync` versions of the iterator also.

matt.fellows
2023-03-27 02:25
Is that right @uglyog?

matt.fellows
2023-03-27 02:25
(or rather, that?s what I?m doing - I hope it?s right)

tien.xuan.vo
2023-03-27 02:39
Because (currently it's only me, these reasons doesn't represent the entire pact-php team, because my PRs are not reviewed and merged yet): 1. `pact-php` project only contains "core" features (http + v3 async message), it doesn't include any code that support plugins 2. Instead of supporting all plugins in `pact-php` project like I did before, I split into multiple projects: `pact-php-csv` , `pact-php-protobuf` . The reasons are: a. Not everybody want and use plugins to test their project b. Download binaries need time, and disk storage. c. Support all plugins in `pact-php` only make the code base bigger and bigger overtime 3. Each projects has it own `PACT_PLUGIN_DIR` . For example: `/path/to/pact-php-csv/bin/pact-plugins/csv` and `/another/path/to/pact-php-protobuf/bin/pact-plugins/protobuf` 4. While writing consumer test, setting `PACT_PLUGIN_DIR` before each test is enough for running the test. 5. But when verifying provider, currently only set 1 value for `PACT_PLUGIN_DIR` , so only verify pacts for 1 plugin.

tien.xuan.vo
2023-03-27 02:44
I don't need to call those ffi methods. I just need to call `pactffi_message_reify` . The reason it doesn't work before is I went to the wrong direction (typo in pact:proto, missing content type `application/protobuf`, wrong matching format...)

tien.xuan.vo
2023-03-27 02:50
Currently in Pact-PHP I only call `pactffi_init_with_log_level('debug')` . I don't know what I am missing.

uglyog
2023-03-27 02:51
That will enable debug logs to standout, but not change the protoc error output. You can try trace to see if it makes a difference.

tien.xuan.vo
2023-03-27 02:53
I did try `trace` before but it doesn't help.

tien.xuan.vo
2023-03-27 02:53
btw, don't worry about the error `Failed to invoke protoc binary: exit code exit status: 1` . It's just because a typo that make the path to proto file invalid

tien.xuan.vo
2023-03-27 02:54
Currently `/path/to/plugins/protobuf/log/*.log.Y-M-D files are empty` is the problem I am facing

uglyog
2023-03-27 02:56
I can see the protoc entries in

tien.xuan.vo
2023-03-27 02:57
yes, me too, but all of them are empty

uglyog
2023-03-27 03:01
Something is going wrong with the log level then, it is meant to set the `LOG_LEVEL` for the plugin process based on what you have setup. Do you see any entries in the console for the tests?

tien.xuan.vo
2023-03-27 03:06
> it is meant to set the `LOG_LEVEL` for the plugin process based on what you have setup ahhh, yess?? I am wondering how to do that


matt.fellows
2023-03-27 03:16
on wow, that returns back the byte array? I thought I tried that and it didn?t work. that?s MUCH easier :laughing:

matt.fellows
2023-03-27 03:17
I guess the type declaration is `char*`, but that?s just an array of bytes

tien.xuan.vo
2023-03-27 03:21
It return json like this https://github.com/tienvx/pact-php-protobuf/blob/main/example/async-message/broker/pacts/protobufMessageConsumer-protobufMessageProvider.json#L7 All I need to do is `base64_decode` and merge to object then pass to callback

tien.xuan.vo
2023-03-27 07:08
Another idea is adding `--filter-plugin=NAME` and `--filter-no-plugin` to pact verifier

tien.xuan.vo
2023-03-27 09:16
I will try creating hooks to copy/symlink plugins into 1 places so pact verifier can use it

tien.xuan.vo
2023-03-31 14:12
The solution above has been implemented. Pact plugin directories has been symlinked into single directory, and the path to that directory will be set as value of `PACT_PLUGIN_DIR`

tien.xuan.vo
2023-04-03 05:06
About csv plugin https://docs.pact.io/implementation_guides/pact_plugins/plugins/csv#csv-matching-definitions: If we use headers, mock server will response with columns that are sorted by column's name in ascending order. For example: ```$response ->setStatus(200) ->setBody([ 'csvHeaders' => true, 'column:id' => "matching(regex, '^[0-9a-f]{8}(-[0-9a-f]{4}){3}-[0-9a-f]{12}$','{$id}')", 'column:name' => "matching(type,'{$name}')", 'column:gender' => "matching(regex, 'male|female|other','{$gender}')", ]) ->setContentType('text/csv') ;``` Mock server will return: ```gender,id,name $gender,$id,$name``` Is this expected behavior?

uglyog
2023-04-03 05:12
You mean, was this planned behaviour? No, I don't think so, but it kind of makes sense.

tien.xuan.vo
2023-04-03 05:22
It makes sense to me also. Currently I'm fine with it because the order of columns isn't important to me. But I think checking for the order of columns is important for some users. I'm thinking about this solution: Add `"csvColumns": "id,name,gender"` so: ? Mock server will return columns in this order ? Provider verifier will verify csv's columns in this order What do you think?

uglyog
2023-04-03 05:24
You are probably right

tien.xuan.vo
2023-04-03 05:26
I will create a minor ticket for this improvement so we can discuss more about it in that ticket


tien.xuan.vo
2023-04-03 05:51
Currently when provider verifier can't find the required plugin, it simply shutdown without any error message: ```PACT_LOGLEVEL=debug phpunit example/provider/ 12:41:36 Xdebug: [Step Debug] Could not connect to debugging client. Tried: 127.0.0.1:9003 (through xdebug.client_host/xdebug.client_port). PHPUnit 9.5.20 #StandWithUkraine 2023-04-03T05:41:46.951993Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_add_directory_source FFI function invoked 2023-04-03T05:41:46.952030Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_execute FFI function invoked 2023-04-03T05:41:46.952033Z DEBUG ThreadId(01) pact_ffi::verifier::handle: Pact source to verify = Dir(/home/myname/Projects/pact-php-csv/example/provider/tests/Contract/../../../broker/pacts) 2023-04-03T05:41:46.952639Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries: core/content-generator/binary core/content-generator/json core/content-matcher/json core/content-matcher/multipart-form-data core/content-matcher/text core/content-matcher/xml 2023-04-03T05:41:46.952667Z DEBUG ThreadId(01) pact_plugin_driver::catalogue_manager: Updated catalogue entries: core/matcher/v1-equality core/matcher/v2-max-type core/matcher/v2-min-type core/matcher/v2-minmax-type core/matcher/v2-regex core/matcher/v2-type core/matcher/v3-content-type core/matcher/v3-date core/matcher/v3-datetime core/matcher/v3-decimal-type core/matcher/v3-includes core/matcher/v3-integer-type core/matcher/v3-null core/matcher/v3-number-type core/matcher/v3-time core/matcher/v4-array-contains core/matcher/v4-equals-ignore-order core/matcher/v4-max-equals-ignore-order core/matcher/v4-min-equals-ignore-order core/matcher/v4-minmax-equals-ignore-order core/matcher/v4-not-empty core/matcher/v4-semver 2023-04-03T05:41:46.952718Z DEBUG ThreadId(01) pact_verifier: Scanning "/home/myname/Projects/pact-php-csv/example/provider/tests/Contract/../../../broker/pacts" 2023-04-03T05:41:46.952871Z INFO ThreadId(01) pact_verifier: Pact file requires plugins, will load those now 2023-04-03T05:41:46.952881Z DEBUG ThreadId(01) pact_plugin_driver::plugin_manager: Loading plugin PluginDependency { name: "csv", version: Some("0.0"), dependency_type: Plugin } 2023-04-03T05:41:46.952894Z DEBUG ThreadId(01) pact_plugin_driver::plugin_manager: Did not find plugin, will start it 2023-04-03T05:41:46.952896Z DEBUG ThreadId(01) pact_plugin_driver::plugin_manager: Loading plugin manifest for plugin PluginDependency { name: "csv", version: Some("0.0"), dependency_type: Plugin } 2023-04-03T05:41:46.952902Z DEBUG ThreadId(01) pact_plugin_driver::plugin_manager: Looking for plugin in "/home/myname/.pact/plugins" 2023-04-03T05:41:46.953001Z DEBUG ThreadId(01) pact_ffi::verifier: pact_ffi::verifier::pactffi_verifier_shutdown FFI function invoked F 1 / 1 (100%) Time: 00:00.080, Memory: 28.32 MB There was 1 failure: 1) App\Provider\Tests\Contract\PactVerifyTest::testPactVerifyConsumer Failed asserting that false is true. /home/myname/Projects/pact-php-csv/example/provider/tests/Contract/PactVerifyTest.php:58 FAILURES! Tests: 1, Assertions: 1, Failures: 1.``` I think it should log an error message like: ```Can't find plugin csv in /home/myname/.pact/plugins``` Do you think so?


uglyog
2023-04-03 05:56
Oh, this is during verification

tien.xuan.vo
2023-04-03 05:57
yes, during verification


uglyog
2023-04-03 05:58
Oops!

tien.xuan.vo
2023-04-03 06:01
I will create a ticket for this improvement then


yousafn
2023-04-03 11:08
Good spot @tien.xuan.vo

jordan.brooks
2023-04-18 13:15
has joined #pact-plugins

jordan.brooks
2023-04-18 13:23
Hey :wave: Is anyone here aware of the status of plugins for pact ruby? I don't see it on the roadmap https://github.com/pact-foundation/pact-ruby/blob/master/ROADMAP.md and we have a use case for pact that would require us to be able to use plugins from ruby.

yousafn
2023-04-18 13:33
Hi, It isn't currently on the roadmap (mainly due to maintainer capacity, rather than a lack of wanting to support it) but it is possible to write your own lanaguage implementation, by utilising the pact-reference core (written in rust) - https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_ffi/README.md exposed via an FFI (c shared libraries) There are simple implementation examples in a few languages in the repo ? https://github.com/pact-foundation/pact-reference/tree/master/javascript ? https://github.com/pact-foundation/pact-reference/tree/master/php ? https://github.com/pact-foundation/pact-reference/tree/master/ruby I created my own examples a little while back https://github.com/YOU54F/pact-ruby-ffi/blob/main/examples/area_calculator/spec/pactffi_create_plugin_pact_spec.rb https://github.com/YOU54F/pact-ruby-ffi/blob/main/lib/pact_ruby_ffi.rb Maybe you could use that as a source of inspiration to at least get you moving, and share it back with the community

yousafn
2023-04-18 13:36
There are some other examples of loading the shared libraries with Ruby here https://github.com/YOU54F/hello_ffi/tree/main/ruby and tested with GH actions here https://github.com/YOU54F/hello_ffi/blob/6f36442dc52c0624d7c6e146426c50b233db210b/.github/workflows/action.yml#L9-L31 I fix to 2.7.6 of Ruby for gRPC support, as it currently isn't in Ruby 3.x The FFI libs worked with Ruby 3.x when I tested it last

yousafn
2023-04-18 13:38
I also hacked about a ffi interface generator for Deno, to generate the same for Ruby https://github.com/YOU54F/deno-ffigen/commit/52635a822339f3715e694b6f72806820fa2cebc9 which is pretty neat for being able to pull in the appropriate methods in a more automated fashion, than mapping manually

jordan.brooks
2023-04-18 13:46
Awesome - thanks for the link, will see if we would be willing to go that route.

adam.cox
2023-04-28 14:18
Hello again, I have another query about plugins that provide a transport. With the WebSocket plugin that we are creating we need to be able to support `ws` and `wss` connections, mostly to providers at the moment but it may be that we need it for consumers also. Currently our plugin just adds one "transport" to the catalogue: `websockets`. But this means that when verifying contracts there is no way to tell the pact-standalone-verifier to use a `wss` scheme when connecting to the provider server. We noticed that the `ProviderInfo` struct has a `scheme` field which looks like it would be perfect for our use case but the pact-standalone-verifier does not expose this option. Looking at the source code here [1] it looks like it used to, but this is not listed in the docs a the top. We considered having the plugin create two transports `ws` and `wss` but this then meant that the consumer would have to determine which transport to choose so that it is written into the contract. We weren't sure if this was correct as it doesn't really matter for the contract contents if the connection is secure or not. Also we wanted to avoid consumer users from having to create self-signed certs to create contracts unless they really wanted to test with the mock server over wss. Guidance as to the intended approach would be most appreciated :slightly_smiling_face: Side, but related, note: in pact-consumer it looks like `tls` is hard-coded to false [2]. Why is that? Has this not been implemented yet or are secure connections supposed to be solved a different way? [1] https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_verifier_cli/src/main.rs#L673 [2] https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_consumer/src/mock_server/plugin_mock_server.rs#L64

matt.fellows
2023-05-01 08:28
Interesting. I didn?t quite get why you needed `wss` though, is that because your providers only run on TLS? I usually don?t consider TLS a helpful thing in contract testing (i.e. we don?t learn anything new usually), but I know a lot of tooling is making it harder / the default to use TLS so it?s something to consider. @uglyog might be able to answer tomorrow (he?s just returned from PTO, so bare with him as he wades through the inevitable pile of emails/slack messages :laughing: )

uglyog
2023-05-01 23:07
TLS doesn't provide any benefit, but adds a whole bunch of complexity (needing to then deal with keystores/truststores, self-signed certs, custom root CAs, etc). It is not as easy as just saying tls=true. We have support for it for where people have no other option, but it is not currently well supported (at the moment it only supports the use of self-signed certs).

uglyog
2023-05-01 23:09
The way the use transports are designed, the plugin can support as many as required, and the consumer test then specifies the transport that is required, and then there is a new attribute added to the V4 interaction to store this.

uglyog
2023-05-01 23:13
The `ProviderInfo` struct doesn't have a scheme field? It does have a list of transports. ```/// Information about the Provider to verify #[derive(Debug, Clone)] pub struct ProviderInfo { /// Provider Name pub name: String, /// Provider protocol, defaults to HTTP #[deprecated(note = "Use transports instead")] pub protocol: String, /// Hostname of the provider pub host: String, /// Port the provider is running on, defaults to 8080 #[deprecated(note = "Use transports instead")] pub port: Option<u16>, /// Base path for the provider, defaults to / #[deprecated(note = "Use transports instead")] pub path: String, /// Transports configured for the provider pub transports: Vec<ProviderTransport> }```


matt.fellows
2023-05-02 00:49
Ah, yes!

adam.cox
2023-05-02 11:35
This is coming from a scenario we currently face where a consumer has submitted a contract using the `websockets` transport and we are trying to verify it against a provider. This provider only accepts `wss` TLS connections but another provider we have supports only `ws` connections. We didn't want the consumer to have to decide if the provider would be tested with or without TLS because, as you say, it doesn't change the contract and it adds a lot of complications in creating, trusting and using self-signed certs. So it felt odd for the consumer to say "this contract is for wss", "this contract is for ws" as really we only care about this when verifying the contract. What we landed on for now is to use a plugin config item "useSecureSocket" which when set to true will set the mock WS server hostname to `localhost` and send messages over `wss` instead of `ws` which allows a provider to choose whether or not to test using TLS. The problem then becomes verifying two providers on the same host (or rather same CI build container image) which want different config values as it needs to be changed / configured before running the verification. So the recommendation would be the following? ? Do not support using TLS during consumer testing ? Have the plugin offer two transports - `ws` and `wss` ? Have the consumer specify whether or not to use `wss` or `ws` when creating the consumer contract ? Verify the provider according to the transport in the contract. I am not sure if this would be better to the plugin config method or not :thinking_face:

matt.fellows
2023-05-05 11:39
I think you could let the contract record `ws` or `wss` but let both sides choose whether or not to use the secure variant. A config seems a reasonable option to expose that, but i?d default to non-secure for most people (because of the reasons listed by Ron above)

matt.fellows
2023-05-05 11:40
I think it?s OK to expose both options. But even in regular Pact world, I?ve rarely seen the SSL variant used (it?s mostly only needed when you?re testing against a real endpoint, and that real endpoint has a stupid self-signed certificate on it so you need to be able to disable or configure the transport).

adam.cox
2023-05-05 12:09
If the user will set config and decide whether or not to use a secure connection then we do not really need to expose two transports do we? We can just expose the transport `websockets` as we are now and hide the scheme choice from the users. I think consumer side TLS/SSL is going to be an extremely rare or even non-existent use case but secure providers is something that will (has) come up because the binaries we are testing (and will deploy) use self-signed certificates for inter component communication on a device. We are testing against binaries that will be deployed to devices and they are configured in this way. The cert is embedded in the provider and the host running the tests is configured to trust it. We currently have the config value default to false

matt.fellows
2023-05-08 00:39
yes, that makes sense to me!

adam.cox
2023-05-09 13:28
How can we add plugin config to a contract for a given interaction when that interaction uses a core matcher? We are using JSON-RPC payloads over a WebSocket connection so the content matching is done with the core JSON matcher. However on a given interaction we need to be able to set the following: ? Path to connect to the WS server on. e.g. `` - specifically the `/jsonrpc` bit ? Headers to send in the connection request ? Message payload encoding as text or binary We are using synchronous message contracts to do the verification and we are trying to extend the plugin so that these metadata properties can be set, however we are struggling to find the code path that allows plugin config to be added to the contract files when a core matcher is being used. Advice/guidance on how to achieve this would be greatly appreciated

adam.cox
2023-05-09 16:47
I think I have been approaching this from the wrong angle. If we ignore the message encoding (which for now can always be text anyway) then I can just use the ProviderInfo.transports.path and customHeaders. Then when verifying contracts these just need to be passed to the verifier. I guess if some contracts are using Sec-WebSocket-Protocol header and path different to other contracts then this information should be in the contract itself (or maybe these are 2 providers in that case??) but for now we can just take it from the verifier CLI args. I just need to implement support for those args in the verification side of the plugin.

adam.cox
2023-05-10 08:03
One concern with adding the headers and path only when doing verification is that it does not ensure the client implements these details - specifically the header - which is required for the implementation to work.

yousafn
2023-05-10 11:32
when you say core matcher, are you talking about traditional matchers used in http and message pact tests, not the plugin matchers? https://docs.pact.io/implementation_guides/pact_plugins/docs/matching-rule-definition-expressions

adam.cox
2023-05-10 12:23
Yes that is what I mean

adam.cox
2023-05-10 12:23
Our plugin is not adding any new matchers

adam.cox
2023-05-10 12:26
Also, looking at the pact_verifier it doesn't look like the `path` property of the ProviderInfo is being added to the verifyInteraction request. I can only see host and port being sent in the config


yousafn
2023-05-10 12:31
the pact plugin framework only support the matchers in my linked document at the moment

adam.cox
2023-05-10 12:38
I think I mean Content Matcher :thinking_face:

adam.cox
2023-05-10 12:40
Maybe I am phrasing my question/intention incorrectly. We have a consumer that communicates with a provider over WS so we have created a plugin that adds the WS transport. When the consumer interacts with the provider they need to provide a base path and an appropriate header to establish the WS connection. We are using synchronous message interactions to capture the contracts. The messages are JSON payloads. We the consumer to be able to specify the base-path and header in the contract so that during verification they can be sent to the provider. Currently it does not look possible to any of the following: ? Add custom data in the consumer contract for use with a transport plugin ? Specify path / headers / metadata for sync message contracts ? Pass the path property for a transport from the verifier API over to a plugin handling verification requests

yousafn
2023-05-10 15:34
Ok so I think you need to define your own interaction type, and you can set your own properties, your code just needs to know to look for them, and then write the appropriate values https://github.com/pact-foundation/pact-plugins/blob/bfb1fa52506ec42add5abda5e824533c8af0e252/plugins/protobuf/src/main/kotlin/io/pact/protobuf/plugin/PluginApp.kt#L314-L323 your provider side, will expect those keys and can do whatever you need You can define your own shape of your plugin interaction, it may just align to the async/sync message and http specs shapes defined by the v4 spec

yousafn
2023-05-10 15:34
don't know if that helps

yousafn
2023-05-10 15:35
> ? Add custom data in the consumer contract for use with a transport plugin Your consumers can add whatever they want in, ideally to a known spec, so the plugin knows where to read it

yousafn
2023-05-10 15:36
> ? Specify path / headers / metadata for sync message contracts only if you are adhering to the pact specification, the idea with plugins is you can step outside these bounds

yousafn
2023-05-10 15:37
> ? Pass the path property for a transport from the verifier API over to a plugin handling verification requests Your verifier side of the plugin needs to aware of the key in the contract, which is can use to do whatever it needs to do, to get in the right state

yousafn
2023-05-10 15:39
> I guess if some contracts are using Sec-WebSocket-Protocol header and path different to other contracts then this information should be in the contract itself (or maybe these are 2 providers in that case??) could that header be optional? and therefore the plugin verifier is agnostic so it being set or not, if it is set use it, if the path differs from normal use that, otherwise ignore the header and path? maybe some diagrams might help our mentalmodel :slightly_smiling_face:

adam.cox
2023-05-11 09:30
*Consumer Custom Data* If I look in the whole pact-reference code base I cannot find "message-type" anywhere. If I look at https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_consumer/src/builders/sync_message_builder.rs#L139 which can be used for a consumer to set up a sync interaction the `add_plugin_data` function is only called when the content matcher is not a core matcher. So are we saying here that we need our plugin to add a new content matcher which is essentially the same as the core application/json one but it facilitates us adding the custom plugin data fields? On the verifier side I can see how to read the content from the plugin data in the contract but I cannot work out how to get it in the contract using the pact_consumer library. *Consumer Contract Metadata* Again, looking at the https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_consumer/src/builders/sync_message_builder.rs#L147 for defining consumer contracts it doesn't look like a metadata field is supported for either core or plugin based content types. We can set the request and response bodies but not much else. *Pact Verifier* ProviderInfo struct has a https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_verifier/src/lib.rs#L197 which contains the transports and their config. We have a websockets transport in here with a port number. The ProviderTransport struct has a https://github.com/pact-foundation/pact-reference/blob/master/rust/pact_verifier/src/lib.rs#L153. However it seems impossible to set the path property when using the pact-standalone-verifier and even if we could set it it doesn't get sent over to the plugin at any point. Only the host and port get sent as part of the "config" in the verifyInteraction request. https://github.com/pact-foundation/pact-reference/blob/46628a8bf6b4d514adcb317d749fb8a79130b472/rust/pact_verifier/src/lib.rs#L459 https://github.com/pact-foundation/pact-reference/blob/46628a8bf6b4d514adcb317d749fb8a79130b472/rust/pact_verifier/src/lib.rs#LL427C25-L427C25 https://github.com/pact-foundation/pact-plugins/blob/main/drivers/rust/driver/src/plugin_manager.rs#L579 From looking at this code I cannot work out how to get the additional info we need into the config in the contract in order for it to be sent to the provider when doing the verifications. *Diagrams* Let me see if I can put something together to help illustrate what we are trying to do. Thank you very much for taking the time to assist us with this.

adam.cox
2023-05-11 10:32
I have a simple diagram here which (hopefully!) illustrates the use case. 1. The consumer (C) sends a HTTP request to the WS server (P). This request is on a specific path on the server and requires the Sec-WebSocket-Protocol header to be sent. If the path is wrong or the header is missing / value is wrong the connection will not be established. 2. The WS server responds that the protocol can switched over WS and a connection is established 3. The client sends a JSON payload to the server 4. The server processes the payload and sends a response Currently our contract just has the JSON payloads from 3 + 4 in it. However when verifying the contract it fails as the messages are being sent to the server base path (e.g. localhost:9998 - no base path) and without the correct header. This meant that the WS connection was never established and so the payloads from the contract could not be sent.

adam.cox
2023-05-11 10:42
I guess there are a few questions on how best to handle this: 1. Should the path and header be on the contract at all? I'm torn because if these details are missed by the consumer then the integration won't work in prod. But maybe this should be tested elsewhere? 2. If not in the contract how can we configure the provider verification to establish the connection in the correct place? 3. If multiple request/response interactions are happing over a single connection (rather than a connection created for each interaction) does the connection info even belong in the contract and should the plugin setup the connection before verifying the interactions? If so where would this connection be best made in the verification workflow

yousafn
2023-05-12 11:35
Hey Adam, I have read this and super appreciative for the diagrams. I will invite @uglyog in for some noodling as he is our plugin Jedi. I don't think I'll be super valuable at the moment as I am generally newish to the plugin framework, know nothing about websockets/json-rpc so you are well further ahead in the field that I am on both fronts :slightly_smiling_face:

adam.cox
2023-05-12 14:51
Thanks @yousafn. I think your questions have lead me to outline the thoughts/problems much better so I really appreciate your input on this so far :slightly_smiling_face:

uglyog
2023-05-15 03:11
Any data required should be stored in the metadata associated with the interaction. This is up to the plugin to decide how these are interpreted. I.e., you can maybe add a headers key to the metadata.

uglyog
2023-05-15 03:14
The Pact provider verifier won't know how to verify these interactions or interpret those values. This is why the plugin needs to implement `PrepareInteractionForVerification` and `VerifyInteraction` to do the actual verification.

uglyog
2023-05-15 03:16
> should the plugin setup the connection before verifying the interactions? This is up to the plugin author to decide how best to handle this. It will depend on the protocol being used. For websockets, this does make sense as it is an upgrade over standard HTTP.

uglyog
2023-05-15 03:17
The current workflow doesn't have any way to directly support that, it would have to be done in a lazy manner, i.e. create the connection the first time it is needed and then cache it.

uglyog
2023-05-15 03:18
Also, depending how the test framework runs things, the plugin may not always be running for the duration of all the tests.

adam.cox
2023-05-15 07:58
Thanks @uglyog. This is very helpful. How can we get data into the metadata of the sync message contracts? I can't see how to add request metadata using `contents_from` or the sync message builder api.

uglyog
2023-05-15 08:00
hmm, let me check that



adam.cox
2023-05-15 08:07
Thank you. I'll take another look. I couldn't see any reference of `requestMetadata` in the rust pact_consumer for handling sync messages. Let me see if it works

adam.cox
2023-05-15 08:20
I have just tried the following and the metadata is not present in the contract. ```let ms = pb .synchronous_message_interaction("sync message example", |mut i| async move { i.contents_from(json!({ "pact:content-type": "application/json-rpc", "request": { "query": "matching(string, 'getMacAddress')" }, "requestMetadata": { "headers": { "Sec-WebSocket-Protocol": "jsonrpc" } }, "response": { "data": "matching(string, '00-B0-D0-63-C2-26')" } })) .await; i.test_name("sync message example"); i }) .await .start_mock_server_async(Some("websockets/transport/websockets")) .await;```

adam.cox
2023-05-15 08:20
```{ "consumer": { "name": "message-consumer" }, "interactions": [ { "comments": { "testname": "sync message example" }, "description": "sync message example", "key": "8e58be3b3ff9c72b", "pending": false, "request": { "contents": { "content": { "query": "matching(string, 'getMacAddress')" }, "contentType": "application/json-rpc", "encoded": false } }, "response": [ { "contents": { "content": { "data": "matching(string, '00-B0-D0-63-C2-26')" }, "contentType": "application/json-rpc", "encoded": false } } ], "type": "Synchronous/Messages" } ], "metadata": { "pactRust": { "consumer": "0.10.5", "models": "1.0.13" }, "pactSpecification": { "version": "4.0" }, "plugins": [ { "configuration": {}, "name": "websockets", "version": "test" } ] }, "provider": { "name": "message-provider" } }```

adam.cox
2023-05-15 08:34
Its doesn't look like the pact_consumer in rust looks for these other fields in the sync_message_builder and so they are ignored.

adam.cox
2023-05-15 08:46
So I suppose in the short term, would it work if we provide the `application/json` content type from the plugin and then use the generate_content functionality to support metadata? It seems like more work than the plugin should need to do but I can't see another way of doing it right now

adam.cox
2023-05-15 10:23
~generate_content~ configure_interaction

uglyog
2023-05-15 23:18
pact_consumer won't set those values, it all gets passed to the plugin to configure.

uglyog
2023-05-15 23:19
You can specify what ever format you want, and the plugin then needs to read that format and configure the interaction appropriately during the `configure_interaction` call

adam.cox
2023-05-16 08:07
I was trying to avoid having to implement the configure_interaction call as I am essentially re-implementing the core application/json content-matcher but adding support for a "metadata" field. The application/json matcher works very well for us already but using it offers no ability to add anything extra to the `metadata` field of the contract.

adam.cox
2023-06-02 09:51
Hello Team! I have a new question about the Configure Interaction request and numeric data types. When a user creates a contract with a definition such as: ```"request": { "id": 1 },``` The configure interaction request receives a payload like this: ```"request": Value { kind: Some(StructValue(Struct { fields: {"id": Value { kind: Some(NumberValue(1.0)) } } })) }``` Now in the contract the the value to match against is `1.0` and not `1` . In the consumer test a message is sent to the mock server with the payload: ```{ "id": 1 }``` When the mock server receives this request we try to match against all interactions in the pact but we get a mismatch for this field as: ```1.1) [$.id] Expected '0.0' to be equal to '0'``` I have been trying to debug and fix this issue and it looks to me like the following is happening: 1. The pact framework is taking the consumer contract and converting it to a protobuf payload to send to the plugin 2. This process converted the id field to a Value::Kind::Number(&f64) 3. In the plugin we decode the protobuf payload using `proto_value_to_json` (I think I took this directly from your protobuf plugin) and for a number Kind it runs: `serde_json::json!(n)` 4. serde is seeing the f64 and creating a Value::Number(Number::Float)) 5. So now we have lost the information that the original number was an int and not a float and our comparison fails when we receive an int It seems to me that serde has a good way of handling the different number types but the prost_types definition of `Kind::NumberValue(f64),` is reducing the amount of information that can be conveyed to the plugin about a numeric field during the configure interaction request. I had a search online around protobuf number types and it looked like different types of numbers are supported so I'm not understanding why prost_types treats all numbers as floats. I am not very familiar with protobuf at all though so I probably am just missing something. In the mean time we are encouraging the users to define the contract as `{ "id": "matching(integer, 1)" }` but I think it should be possible for them to just specify the contract as `{ "id": 1 }` and have it work. This did work when we were using the core application/json matcher but I am assuming that is because the type information is not lost when passing the values around in rust.

uglyog
2023-06-04 23:24
Ah, right! That's because this is the proto definition for Struct: ```// `Value` represents a dynamically typed value which can be either // null, a number, a string, a boolean, a recursive struct value, or a // list of values. A producer of value is expected to set one of these // variants. Absence of any variant indicates an error. // // The JSON representation for `Value` is JSON value. message Value { // The kind of value. oneof kind { // Represents a null value. NullValue null_value = 1; // Represents a double value. double number_value = 2; // Represents a string value. string string_value = 3; // Represents a boolean value. bool bool_value = 4; // Represents a structured value. Struct struct_value = 5; // Represents a repeated `Value`. ListValue list_value = 6; } }```

uglyog
2023-06-04 23:24
Numbers are represented with doubles.

uglyog
2023-06-04 23:27
I'll need to think about how to deal with this.

matt.fellows
2023-06-05 00:32
Looks like we?re running into problem #5 :stuck_out_tongue:

matt.fellows
2023-06-05 00:33
(kind of, I suppose technically in this case protobuf does support other number types)

adam.cox
2023-06-14 13:51
I'm trying to get some metadata_rules added to the contract via the confiure_interaction request and I can't seem to work out why it doesn't work. I have added them into the metadata_rules field of the request part of the interaction and they are going back to the driver. However when I get the start_mock_server request and parse the pact I cannot see any metadata rules in the contract. In my debugging journey I noticed this: https://github.com/pact-foundation/pact-plugins/blob/main/drivers/rust/driver/src/content.rs#L313 The matching rule category is always set to BODY. Could that be related to my issue? Looking at the Category enum it seems that Contents and Metadata are also available and I wonder if those would be more appropriate for message contents and metadata rules.

adam.cox
2023-06-14 14:44
While I am asking questions actually, I may as well explain my true aim. In the metadata field of the request I want a nested object which will match when there are more keys than are specified in the contract. Currently I get this error from the matching ```1) c9d8b50f42b5d1e7 - the following mismatches occurred: 1.1) [] Expected metadata key 'headers' to have value '{"sec-websocket-protocol":"json-rpc"}' but was '{"connection":"upgrade","host":"[::1]:64257","sec-websocket-key":"qtwa71ue1dhx8b0ffbiqyw==","sec-websocket-protocol":"json-rpc","sec-websocket-version":"13","upgrade":"websocket"}' - Expected '{"sec-websocket-protocol":"json-rpc"}' to be equal to '{"connection":"upgrade","host":"[::1]:64257","sec-websocket-key":"qtwa71ue1dhx8b0ffbiqyw==","sec-websocket-protocol":"json-rpc","sec-websocket-version":"13","upgrade":"websocket"}'``` The contract specifies the `"sec-websocket-protocol":"json-rpc"` header, but the request comes in with a lot of others. We only need the one header validated in the contract. The connection request we are establishing has the header and it has the correct value so this should pass. However as the contract doesn't contain all the other headers it fails. I'd like to make the matching work like the header matching in HTTP contracts, however I want the headers in an object called headers and not on the root of the metadata object. This is because we are now trying to add query params as well and I'd like to keep the two separate.

uglyog
2023-06-15 00:02
Ok, let me confirm, this may be a bug

uglyog
2023-06-15 00:04
This would need changes in the Pact libs. I think it treats the metadata as a flat collection.

uglyog
2023-06-15 00:05
What you are asking makes sense, it will just take a bit of effort to implement.

uglyog
2023-06-15 00:05
@matt.fellows :point_up:

uglyog
2023-06-15 01:27
Looks like both the JVM and Rust implementations have this behaviour. I think we need to add a field to indicate which category the matching rules should be assigned too.

uglyog
2023-06-15 01:28
I'm a bit hesitant to change this (your comment is correct, it should be using the "content" category for messages), but I don't know the side-effects this change could have.

adam.cox
2023-06-15 08:41
Yes I thought that might be the case with changing BODY -> CONTENT. But adding new ones for METADATA should be ok?

adam.cox
2023-06-15 09:22
At the moment it looks to me like the metadata is treated how I want my nested property to be. i.e. it ignores unexpected keys. This seems to be coming from the `DiffConfig::AllowUnexpectedKeys` on the matching context. However nested values are compared with Equality. So it would be great if we could apply the DiffConfig setting at least one level down. Also it seems impossible to actually change the matching context for metadata at the moment so if we wanted a different behaviour on metadata we wouldn't actually be able to do it. Although isn't a feature we actually need so not too bothered about that

uglyog
2023-06-16 00:03
Yeah, METADATA should work ok

mich.krzyzanowski
2023-06-17 15:25
has joined #pact-plugins

uglyog
2023-06-19 00:16
@adam.cox @tien.xuan.vo @ali.ustek we are planning to make some improvements to the plugin interface. This will probably just be a minor update to the current interface, if possible. The place to start would be to let us know what the biggest issues you have had using or building the plugins. One area we are definitely looking to improve is the verification sequence, but this will be the opportunity to make other improvements as well.

tien.xuan.vo
2023-06-19 03:51
For me this feature is in my wishlist: auto download binary and meta files for plugins https://pact-foundation.slack.com/archives/G9VHV9VJ9/p1683866419534919?thread_ts=1683820689.902969&cid=G9VHV9VJ9

uglyog
2023-06-19 04:03
The latest FFI should already have that capability.

tien.xuan.vo
2023-06-19 12:21
For me the biggest issue when start using plugin is I can't see its logs, so I really don't know what is going on. For now my understanding about plugins is a bit better so I don't have to read its logs, but I am always afraid of it. Here is the related thread https://pact-foundation.slack.com/archives/C047TCR7B6W/p1679760157876359

adam.cox
2023-06-20 08:29
In order of importance for us: ? Configure interaction to support metadata matching rules. This not working is a pain for us at the moment and is holding us up on making progress without workarounds for one of our providers. ? Nested metadata matching. Being able to configure metadata matching at one or more levels deep and ignoring additional keys would also help us configure the metadata in contracts how we want to. ? Configure Interaction to support different number types other than double. ? Not having to create our own content type to add metadata to contracts. We have had to make the "application/json" content matcher again so that we can add metadata fields into the contract. This means that we have had to find the core implementation of application/json and copy bits of code to keep the same behaviour and then try to add the metadata on top. ? Easy to use / documented core library and utility functions for matching. For example a function we can call with a JSON message payload and a pact and find which contract is the best match. Currently we have pieced together bits of pact_matching with our own transformations from a JSON message and some metadata to match websocket messages as they come in. We also reimplemented the loop that goes over the contract and calls the comparison for each one. This process feels like it could be a bit easier for plugin developers if they want a consistent and out of the box feel for the plugin behaviour. ? The logging point is a good one. It used to be possible to use RUST_LOG when using the plugin for consumer tests and we would see all of the child_process logs but this seems to have stopped. Being about to log to a file would be nice, capturing any stdout from the plugin process. This would also make the logs easier to read/parse as using the tracing crate in both the plugin and the driver means the child_process lines are quite noisy. Very low priority ? Support for downloading plugins from non-open source GitHub repositories ? ARM based docker files for building releases. Currently I am spinning up an x86 EC2 in order to compile the Linux plugin builds as the docker images and cross don't play well on my M2 mac. I think most of these are points we have already covered in other threads but if you want more detail or need any clarification from me then I am happy to provide. I am still working on getting our plugin open sourced.

uglyog
2023-06-22 23:40
Thanks for the feedback, I'm going to raise some cards in our backlog for these items.

praveen.em
2023-07-14 14:15
Hello there. I tried using avro plugin few weeks ago. Looks like it requires java 17. Just wanted to check if there is any plan to make the plugin java 11 compatible?

praveen.em
2023-07-14 14:15
Also wanted to get your thoughts in terms of any preferred programming languages for these pact plugins in general. In the documentation, there was a suggestion to choose a language (like golang or rust) which can be compiled to create a single executable to multiple languages. Are those type of languages strongly recommended for plugins or they don?t matter too much?

praveen.em
2023-07-14 14:19
Btw, I am keen to contribute especially to avro stuff as we have use cases within our org. I tried the plugin creation workshop to get a feel of what is involved in building a plugin. I found https://github.com/pact-foundation/pact-plugin-template-golang quite useful. As a follow on to the workshop, I played with it little bit making use of ANTLR to auto generate parsers for https://github.com/pact-foundation/pact-plugins/blob/main/docs/matching-rule-definition.g4. Then added bit of logic on top of that to create interaction with matching rules for message payload using avro. This is all to get a feel of what is involved and didn?t want to go any further than that. This all looks interesting and I am keen to contribute either to the existing avro plugin or continue creating a version of it using golang if that is the preferred language.

yousafn
2023-07-14 14:22
Hey Pravs, @ali.ustek is the author and there is an #avro channel. I believe its meant to come with into own mini JVM so the user doesn?t need java. https://github.com/pact-foundation/pact-go/pull/291#issuecomment-1631685596

ali.ustek
2023-07-14 14:25
There is discussion thread going on: https://github.com/austek/pact-avro-plugin/issues/26

yousafn
2023-07-14 14:26
we recommend languages that cross compile easily into a single binary, and don?t require end user intervention just for each of use. The pactflow supported plugins are most likely to be written in Rust like https://github.com/pactflow/pact-protobuf-plugin just due to @uglyog being in Rust land most of the time. There are some JVM examples. GoLang is also good but there is less shared experience, @matt.fellows is probably our most versed in golang across the maintainer group. I wouldn?t let it stop you at the moment, as the avro plugin that has been built it still at an early stage, so even if playing via golang is useful to help get your head around the plugin concepts in a language most familiar and then can port across to the avro jvm version, or otherwise maintain your own version.

yousafn
2023-07-14 14:27
:wave: Hey Pravs, Been meaning to catch up with you about all things Pact anyway, so nice timing. Sounds like your have a nice adventure!

yousafn
2023-07-14 14:28
ty @ali.ustek! Hope you are well

praveen.em
2023-07-14 14:50
Thanks @yousafn and @ali.ustek. I will keep an eye on that issue.

praveen.em
2023-07-14 14:56
Hey Yousaf :wave:. Yeah, having bit of fun with plugins last few weeks. Hope all is well with you. Btw, looking forward to the community meetings you were planning to setup :slightly_smiling_face:

praveen.em
2023-07-14 15:00
Great! will continue with Golang in that case at least for time being. Right now, it?s in my own repo. It is most likely to move to our org?s external public repo with some support. will let you know if/when that happens.

praveen.em
2023-07-14 15:18
Just so you know, golang is new to me as well. I just happened to use it as the workshop used golang template. After using it for couple of weeks, i started liking it. There is also bit of resemblance with C which I used to love very much (my first programming language). And in our org we have growing population using Golang for helm charts and kubernetes operators.

yousafn
2023-07-14 15:24
We were just discussing that yesterday, we should be making an announcement on Monday, maybe looking to align times on Thursday with the Cucumber community as they have a session as 3pm and if we are around the same time maybe we can cross pollinate. We?ve been considering having a couple of time slots too, due to having a fair few on different sides of the pond

yousafn
2023-07-14 15:27
golang is pretty cool to be honest, I?ve been writing some github extensions of late

yousafn
2023-07-14 15:28
I particularly like its cross compiling and tiny binaries, and its really fast when doing parallel tasks, over a bash script that is getting overly complicated. I never did C much bar at uni and some programming books off my Dad?s

rohitkrishnan
2023-07-25 20:38
has joined #pact-plugins

rohitkrishnan
2023-07-25 20:39
Is there an estimate of when Pact JS would support plugins? (even a sketchy branch would suffice)


wongkoonwai
2023-07-27 04:02
has joined #pact-plugins

rohitkrishnan
2023-07-27 12:31
Oh wonderful thanks!

yousafn
2023-08-03 11:07
:blobwave: Hey Pact Plugin friends! I?ve been promising a community meet for a while and it?s slow trying to get everything organised. In the interim would people be up for a Plugin show and tell session? It can be pretty informal just in a Slack huddle, or we can do something recorded. cc: @praveen.em / @ali.ustek / @adam.cox

ali.ustek
2023-08-04 08:05
Could do, I don't know if there is much to show on a plugin

praveen.em
2023-08-06 14:31
I can show my journey so far of trying to build using golang plugin template but I feel it might be bit too early though to show something meaningful in my case as I am somewhat in early stages.

yousafn
2023-08-07 11:04
Thanks for the replies gents, was more hoping to give you all a place just to discuss and collab, or just the chance to meet each other and say hello, rather than it being a big demo fanfare. For me its a chance to listen to some feedback on how you've got on, and if there is anything we can do to help. Happy doing it async otherwise.

elenadoty
2023-08-15 18:48
has joined #pact-plugins

elenadoty
2023-08-16 20:42
Hi all! Is there a way to modify the consumer's request in the provider test when using the gRPC plugin with Golang? I'm assuming RequestFilter/BeforeEach/AfterEach are out of the picture, and it doesn't seem like there's an equivalent to the way of doing it with JVM https://github.com/pact-foundation/pact-plugins/blob/818119cc39e0f8921b0f471ebf0ca784663cc58b/examples/gRPC/metadata/provider-jvm/server/src/test/java/io/pact/example/grpc/provider/PactVerificationTest.java#L59. For context, I'm hoping to be able to add an auth header during the provider test so that we don't have to worry about it expiring after being generated/set during the consumer test. I've been able to set it using the requestMetadata field in the consumer test, so I may plan to just write a method that will modify the contract to overwrite the token during the test, but I wanted to make sure there wasn't a better way to do it first. Thanks!

tjones
2023-08-20 21:16
Can you not do this with provider state variables?

joshua.ellis
2023-09-20 06:41
has joined #pact-plugins

srijan.c
2023-10-16 10:16
has joined #pact-plugins

christopher.tonog
2024-01-29 18:01
has joined #pact-plugins

christopher.tonog
2024-01-29 18:06
:wave: Hi all, apologies in advance if the location is obvious, I'm trying to find an example of using the gRPC plugin with a JS consumer. So far I've only found jvm, go, and rust examples here https://docs.pact.io/implementation_guides/pact_plugins/examples/grpc. The provider is a go app with protobuf, so I have been able to find examples with that. Thanks so much!

yousafn
2024-01-29 18:19
Hey, It isn't obvious no, we don't have one under the pact-foundation at the moment, here is one I created a while back https://github.com/YOU54F/pluginopedia/tree/main/example-project-js-grpc-plugin/test

christopher.tonog
2024-01-29 19:08
Ah thanks, that is helpful :bow: I couldn't find the documentation on the `usingPlugin`, `addSynchronousInteraction`, etc APIs. I checked here https://docs.pact.io/implementation_guides/javascript/docs/consumer#api , is there somewhere else that information is located? Thanks again!

matt.fellows
2024-01-29 21:59
It is currently a little hidden, mostly because it?s hidden behind the feature flag. There is an example v4 project in the repo

matt.fellows
2024-01-29 21:59
I think we should release it and add the docs, despite it not being feature complete yet (e.g. no async messages in the V4 interface yet)

jo.laing
2024-02-06 14:04
has joined #pact-plugins

maciej.harapinski
2024-02-19 09:46
has joined #pact-plugins