Hey hey, I am trying to figure out an issue we're ...
# pact-js
a
Hey hey, I am trying to figure out an issue we're seeing on the provider verification side when it is invoked by a webhook. We have 2 providers in one repository and when the pact url is specified and we run that verifier flow, it's executing against more than the single provider the pact specifies within the consumer contract. I would assume that if a pact url is specified but the provider does not match my providers (provider-a) verification that it will ignore any pacts desinted for provider-b. Is there another step required to filter the provider verification tests to only run against the provider the pact is for?
blobwave 1
y
what parameters are you passing when doing a verification by pact url? you should be omitting any consumer version selectors, enabling pending and wip pacts
a
Copy code
const failIfNoPactsFound = false

  const coreOptions: PactMessageProviderOptions = {
    messageProviders: options.messageProviders,
    publishVerificationResult: options.pipelineExecution,
    provider: options.provider,
    pactBrokerUsername: options.authentication.username,
    pactBrokerPassword: options.authentication.password,
    providerVersion: options.version,
    providerVersionBranch: options.branch,
    logLevel: options.logLevel || 'error',
    failIfNoPactsFound,
  }

  const buildOptions = {
    pactBrokerUrl: config.pactBrokerUrl,
    enablePending: true,
    consumerVersionSelectors: [
      {
        mainBranch: true,
      },
      { deployedOrReleased: true },
      { matchingBranch: true },
    ],
    includeWipPactsSince: options.workInProgressPactsSince,
  }

  const verifierOptions = options.pactUrl
    ? { ...coreOptions, pactUrls: [options.pactUrl], ...customOptions }
    : { ...coreOptions, ...buildOptions, ...customOptions }

  const verifier = new MessageProviderPact(verifierOptions)

  return verifier.verify()
So as the pactUrl is specified, it omits the
buildOptions
therefore it doesn't verify any pending pacts, wip pacts, or have any consumer version selectors. The verification when the provider is being changed and ensuring it's not breaking any existing pacts is great, it's when the pact url is specified and there are multiple providers in this one repository.
I'd have thought that if you specify
pactUrls
and those are the only pacts you will verify, the providers specified in the pact contract contents must match the provider being ran 😕
y
I don’t believe it will consider the
provider
option and instead verify whatever is in the url, when doing an url based verification it isn’t acting as a filter, as you are expecting, I would need to check the source. there is a consumer filter
pactffi_verifier_set_consumer_filters
where you can filter consumers, again not sure if that takes effect if the pact url is set, or just on dynamically fetched pacts, we would need to check the pact-js verifier code and the rust verifier code.
so when the pact url is used, I assume this is being invoked by a webhook? the webhook says for example consumer-blah-provider-a Are you receiving one single webhook? are you then invoking one single verifier job? or are you invoking two?
``` const verifierOptions = options.pactUrl
? { ...coreOptions, pactUrls: [options.pactUrl], ...customOptions }
: { ...coreOptions, ...buildOptions, ...customOptions }```
This looks right to me. sounds like you have a pact url called
example consumer-blah-provider-a
provider opt of
provider-b
and your expectation is that it shouldn’t run a test?
We have 2 providers in one repository and when the pact url is specified and we run that verifier flow, it’s executing against more than the single provider the pact specifies within the consumer contract.
I think I need a bit more detail around this. When is the pact url being specified how do you isolate the verifications between the two separate providers, that reside in the same codebase are they using the same file?
a
so when the pact url is used, I assume this is being invoked by a webhook?
Yes. Each provider in this single repository has its own webhook. This URL is an example of the PACT_URL being provided by the webhook invoked triggerd https://pact-broker.localhost.io/pacts/provider/provider-a/consumer/consumer-a/pact-versi[…]3e074effa27e9192f566/metadata/Y3ZuPWNiZGNjZmEyJnc9dHJ1ZQ.
Are you receiving one single webhook?
Yes, each provider in this repository has its own webhook defined and will specify in the url the provider it is so provider-a or provider-b. I am receiving 1 webhook triggered pipeline with the above url. So no mention anywhere in the pipeline being triggered of
provider-b
.
provider opt of
provider-b
and your expectation is that it shouldn’t run a test?
Yes exactly that. The above url is being specified and running the 'webhook verify flow' in our pipeline. It is running each of the unique provider verification test files in the repo with the pact url. The provider that has a different matching name than what's in that URL (i.e. url says provider-a but provider-b is executing too) or within the contract file itself is being executed and failing. `provider-a`verification is running as expected and passing but
provider-b
is also being executed and failing.
how do you isolate the verifications between the two separate providers, that reside in the same codebase are they using the same file?
So they are two completely separate verification test files that use the options specified https://pact-foundation.slack.com/archives/C9VBGLUM9/p1689001131963479?thread_ts=1689000821.597169&cid=C9VBGLUM9 and the only major difference is the provider name and any messageProviders/stateHandlers. Unless I am missing a simple way to support multiple providers in the same project each with their own unique webhook (1 webhook per provider) then I think there may be only one solution. When the pact url is specified there needs to be manual filtering of which provider verification test files to run as it doesn't look like the pact url provider or the provider within the consumer contract are checked when the provider is ran.
y
ahh so any time one of two webhooks fire, both verification jobs fire, because they hit a single pipeline task. Gotcha. So for now I would use a webhook param to identify the provider name and only trigger the relevant one of the two verification jobs. For it pact side - Would probably need to get the thinking hat on as to what the user facing behaviour would or should be the case if. you provide a pact url for a provider, but specify a different provider • should the test fail, pass or warn? its quite an assumption that only one of the three would be relevant as people may have separate use cases, some may want to know as they may have a misconfigured webhook.
a
Hmmm yes. Thanks, I'll solve it for my company but I'd be interested to see if it could progress somehow in to the pact verification flow itself. However it works, if the contract specified provider != the provider being ran, it should have a flow that doesn't execute the incorrect expectations on a different provider 😄
Cheers for the help @Yousaf Nabi (pactflow.io)
Is there an applicable repo I should raise an issue for to discussion this?
This is what I've got a the minute to circumvent this issue if the verification is executed with a pact file for a different provider
t
I feel like this is a bug in the pact core. If you get given a contract file that is not for you, you should warn and ignore it I reckon
(You being the pact core, in this case)
m
Yeah, it’s probably just not a scenario that has been considered. The
provider
name was previously only used as a selector to discover pacts in the broker, and not for much else
in the world of (more) monorepos, this could be a nice quality of life improvement
t
In 2000, everything was a monorepo. We have come full circle
m
haha
There are some filter options on the CLI (which is essentially a different interface to the same verification code): https://github.com/pact-foundation/pact-reference/tree/master/rust/pact_verifier_cli Mind raising a feature request there to discuss this use case. Perhaps the solution is to essentially
--filter-provider
(by default) or have that as an explicit option
t
I’m not sure that filter is the right fit, because filtered results (shouldn’t) be publishable
y
that would be my assumption too, that filtered shouldn’t be publishable. I’d probably start by testing both the rust and ruby core via the cli, as to what happens in this use case (with provider name diff to that in a file), both with a local file and remote file and see if that makes any diff
that would be assumption too, that filtered shouldn’t be publishable.
Should that apply to all filters, filtered desc vs filtered consumer
t
that would be assumption too, that filtered shouldn’t be publishable.
It definitely shouldn’t, because if you filter the contract, you’re not adhering to the expectations of the consumer.
👍 1
y
filtered consumer imo should be okay, filtered desc not so okay
the other three opts there look pact file specific (desc/int/state)
t
I think they’re different kinds of filter.
y
yessum, one being a filter of contracts, one being a filter of interactions within contracts.
whether either considers which when publishing verification results, is a separate yak shave / disco session :)
good thing I’m deep diving into the world of verifications this week 😅 - party yak 🪒