Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ConsumerVersionSelector - Pacticipant and Version Not Honored. #285

Closed
athurner opened this issue Apr 27, 2021 · 8 comments
Closed

ConsumerVersionSelector - Pacticipant and Version Not Honored. #285

athurner opened this issue Apr 27, 2021 · 8 comments
Labels
bug Indicates an unexpected problem or unintended behavior

Comments

@athurner
Copy link

  • OS: Mac OSX 10.15.7_
  • Pact: 9.15.5
  • Pact Node version: 10.12.2
  • Node Version: 12.13.0

Im sure I'm doing something wrong, but I'm not sure how to get that working. Or is there maybe a bug?

I have 2 clients (ClientA and ClientB) that have contracts (each tagged 'master') published to the pact broker (version 2.79.1) with provider DemoService.

Pact-Broker Matrix (simplified):

Consumer Version Tag Provider Version Verified
ClientA 1.0.1-2726fe4 master - DemoService 1.0.0-a6b2678
ClientA 1.0.0-12ab763 master - DemoService 1.0.0-a6b2678
ClientB 1.0.1-6fe3cb5 master - DemoService 1.0.0-a6b2678
ClientB 1.0.0-ec71b62 master - DemoService 1.0.0-a6b2678

I try to setup a ConsumerVersionSelector to validate a specific version of a contract for ClientA with the provider.

import { Verifier} from "@pact-foundation/pact";
import { ConsumerVersionSelector } from "@pact-foundation/pact-node/src/verifier";

describe("PACT Verification", () => {
  test(`Validates the expectations of Provider: DemoService`, () => {   
    return new Verifier({
        providerBaseUrl: `http://${config.app_server_host}:${config.app_port}/`,
        pactBrokerUrl: 'https://local/pactbroker/',
        provider: 'DemoService',
        providerVersion: '1.0.0-a6b2678',
        providerVersionTags: 'master',

        logLevel: 'debug',
        logDir: 'log',

        consumerVersionSelectors: [{
          all: false,
          latest: false,
          tag: 'master',
          version: '1.0.0-2726fe4',
          pacticipant: 'ClientA'
        } as ConsumerVersionSelector],

        publishVerificationResult: true,
        pactBrokerUsername: 'admin',
        pactBrokerPassword: 'password',

      })
      .verifyProvider()
      .then((output) => {
        console.log(output);
      })
      .then(() => {
        expect("A").toEqual("A");
      });
  });
});

It looks like the version and pacticipant is not honored. Contracts for both consumers are pulled from the pact broker. The log has the following statement:

    
    DEBUG: The pact at https://local/pactbroker/pacts/provider/DemoService/consumer/ClientA/pact-version/1d59c1e8b3944bb34c72cafd0de47e0b07162685 is being verified because it matches the following configured selection criterion: pacts for all consumer versions tagged 'master'
    DEBUG: The pact at https://local/pactbroker/pacts/provider/DemoService/consumer/ClientB/pact-version/0713c326c33c47a08901c676c575244bfefd394a is being verified because it matches the following configured selection criterion: pacts for all consumer versions tagged 'master'

I have the impression this is a bug because the obvious way to configure the selector does not work. (I'm sorry if I'm wrong and have overlooked something important.)

Thank you for looking into this.

@athurner athurner added the bug Indicates an unexpected problem or unintended behavior label Apr 27, 2021
@TimothyJones
Copy link
Contributor

Thanks for the report.

Would you be able to attach the part of the debug log where the verifier binary arguments are called, please? (Note that depending on your setup, there may be tokens in the log, which you'll want to remove).

@athurner
Copy link
Author

Thank you for looking into this.

There is one important point I forgot to mention:
I'm running this in a 'node:alpine' docker container.

this is the part of the log that shows the correct / complete consumer-version-selector but then fetches from the broker everything that matches the tag value of the selector:

DEBUG (21 on a0116bf660b0): pact@9.15.5: non-local provider address http://DemoService:5000/ detected, setting 'changeOrigin' to 'true'. This property can be overridden.
INFO (21 on a0116bf660b0): pact@9.15.5: Verifying provider
INFO (21 on a0116bf660b0): pact@9.15.5: debug request/response logging enabled
INFO (21 on a0116bf660b0): pact-node@10.12.2: Verifying Pacts.
INFO (21 on a0116bf660b0): pact-node@10.12.2: Verifying Pact Files
DEBUG (21 on a0116bf660b0): pact-node@10.12.2: Starting pact binary 'standalone/linux-x64-1.88.49/pact/bin/pact-provider-verifier', with arguments [--provider-states-setup-url http://localhost:36437/_pactSetup --provider-base-url http://localhost:36437 --pact-broker-base-url https://local/pactbroker --provider DemoService --provider-app-version 1.0.0-a6b2678 --provider-version-tag master --log-level debug --log-dir log --consumer-version-selector {"all":false,"latest":false,"tag":"master","version":"1.0.0-2726fe4","pacticipant":"ClientA"} --publish-verification-results true --broker-username admin --broker-password password --verbose true]
DEBUG (21 on a0116bf660b0): pact-node@10.12.2: Created 'standalone/linux-x64-1.88.49/pact/bin/pact-provider-verifier' process with PID: 36
DEBUG (21 on a0116bf660b0): pact-node@10.12.2: opening connection to local:443...
opened
starting SSL for local:443...
SSL established
<- "GET ....

INFO: Fetching pacts for DemoService from https://local/pactbroker with the selection criteria: all for tag master
opening connection to local:443...
opened
starting SSL for local:443...
SSL established
<- "POST /pactbroker/pacts/provider/DemoService/for-verification HTTP/1.1\r\nAccept-Encoding: gzip;q=1.0,deflate;q=0.6,identity;q=0.3\r\nAccept: application/hal+json\r\nUser-Agent: Ruby\r\nContent-Type: application/json\r\nAuthorization: [redacted]\r\n"
<- "{\"consumerVersionSelectors\":[{\"all\":false,\"latest\":false,\"tag\":\"master\",\"version\":\"1.0.0-2726fe4\",\"pacticipant\":\"ClientA\"}],\"providerVersionTags\":[\"master\"]}"
-> "HTTP/1.1 200 OK\r\n"
....
-> "\r\n"
reading 1628 bytes...
-> "{\"_embedded\":{\"pacts\":[{\"shortDescription\":\"one of master\",\"verificationProperties\":{\"notices\":[{\"when\":\"before_verification\",\"text\":\"The pact at https://local/pactbroker/pacts/provider/DemoService/consumer/ClientB/pact-version/1d...5 is being verified because it matches the following configured selection criterion: pacts for all consumer versions tagged 'master'\"}]},\"_links\":{\"self\":{\"href\":\"https://local/pactbroker/pacts/provider/DemoService/consumer/ClientB/pact-version/1d...5/metadata/c1t...LjA=\",\"name\":\"Pact between ClientB (1.0.0) and DemoService\"}}},{\"shortDescription\":\"one of master\",\"verificationProperties\":{\"notices\":[{\"when\":\"before_verification\",\"text\":\"The pact at https://local/pactbroker/pacts/provider/DemoService/consumer/ClientA/pact-version/07...4a is being verified because it matches the following configured selection criterion: pacts for all consumer versions tagged 'master'\"}]},\"_links\":{\"self\":{\"href\":\"https://local/pactbroker/pacts/provider/DemoService/consumer/ClientA/pact-version/07...4a/metadata/c1t...ZlNA==\",\"name\":\"Pact between ClientA (1.0.0-2726fe4) and DemoService\"}}}]},\"_links\":{\"self\":{\"href\":\"https://local/pacts/provider/DemoService/for-verification\",\"title\":\"Pacts to be verified\"}}}"
read 1628 bytes
Conn keep-alive
INFO: Reading pact at https://..../pactbroker/pacts/provider/DemoService/consumer/ClientB/pact-version/1d...5/metadata/c1t...LjA=
...

DEBUG (21 on a0116bf660b0): pact-node@10.12.2: DEBUG: The pact at https://local/pactbroker/pacts/provider/DemoService/consumer/ClientB/pact-version/1d...5 is being verified because it matches the following configured selection criterion: pacts for all consumer versions tagged 'master'

...

@TimothyJones
Copy link
Contributor

Thanks, that log is very helpful.

@bethesque Can you take a look at the POST body in the log above? I'm not sure here whether the problem is pact-js not doing the right thing, or the broker not behaving correctly. The post body looks right to me, but perhaps I don't have the right meaning for the query. I had thought the consumerVersionSelectors would reduce the set from the providerVersionTag of master.

@bethesque
Copy link
Member

Docs are here http://docs.pact.io/consumer_version_selectors. The properties you're using aren't supported.

@athurner
Copy link
Author

athurner commented May 4, 2021

Thank you for your answer. Does that mean that the Pact Broker and the pact-js library currently are not compatible?

According to the Pact Broker documentation the Consumer Version Selectors support tag, latest, consumer, fallbackTag.

But it looks to me that the pact-js library has a different definition:

see verifier.ts line 7 referes to VerifierOptions in pact-node.

Following that reference brings me to the verifier.ts in pact-js-core line 291.

// A ConsumerVersionSelector is a way we specify which pacticipants and
// versions we want to use when configuring verifications.
//
// See https://docs.pact.io/selectors for more
export interface ConsumerVersionSelector {
  pacticipant?: string;
  tag?: string;
  version?: string;
  latest?: boolean;
  all?: boolean;
}

The code comments refer to a dead link https://docs.pact.io/selectors

The DepricatedVerifierOptions verifier.ts in pact-js-core line 324 are also not offering the properties that are used by the Pact Broker.

interface DeprecatedVerifierOptions {
  consumerVersionTag?: string | string[];
  providerStatesSetupUrl?: string;
  providerVersionTag?: string | string[];
  tags?: string[];
}

I'm sorry if I don't understand things correctly. But this looks confusing to me.

@bethesque
Copy link
Member

Looks like pact-js has incorrect expectations. Is that something you can look at @TimothyJones? The docs for the fields are here: pact-foundation/pact_broker#307

@mefellows
Copy link
Member

Looks like a simple mapping problem.

It will be a backwards incompatible type change, so we could wrap that and emit a warning (deprecate) or just update the type so that it's correct. I think the latter is better, because the current behaviour is possibly hiding bugs.

@athurner for now, you will have to work around it by passing the correct shape through and casting the object

@bethesque
Copy link
Member

In the backend, the field is "latest".

              optional(:latest).filled(included_in?: [true, false])

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Indicates an unexpected problem or unintended behavior
Projects
None yet
Development

No branches or pull requests

4 participants