Stefan Tertan
11/01/2022, 3:04 PMPortalUI (react app; pact consumer) - publishes a pact for HTTP interactions to Pactflow
• ProfileService (expressjs api; pact provider) - publishes OpenAPI (& Dredd results) to Pactflow
• CardService (expressjs api; pact provider) -- publishes messages to Kafka
• AuditService (kafkajs consumer; pact consumer) - publishes a pact for message interactions to Pactflow
The issue that I am facing is with running builds for CardService, where it needs to verify the pacts for its consumers (both http & async):
• PortalUI (http)
• AuditService (async)
I need to use different verifiers: Verifier vs MessageProviderPact (from @pact-foundation/pact). I wrote different test suites (with one test each) to accommodate for that:
describe('Pact Verification - Regular build - one or more pacts', () => {
const HTTPConsumers = ['PortalUI'];
const AsyncConsumers = ['AuditService'];
describe('HTTP Consumers', httpConsumerTests.verifyMultiplePacts(commonEnv, HTTPConsumers));
describe('Async Consumers', asyncConsumerTests.verifyMultiplePacts(commonEnv, AsyncConsumers));
});
The gist of the code for HTTP consumers looks like so:
const verifyMultiplePacts = (commonEnv, HTTPConsumers) => () => {
let server;
beforeEach(() => server = app.listen(PROVIDER_HTTP_API_PORT)); // Create server
afterEach((done) => server.close(done)); // Shutdown provider server (Express)
it('validates the expectations of CardService', async () => {
const consumerVersionSelectors = [
...HTTPConsumers.map((consumer) => ([
// check compatibility with the latest changes that the consumer has made
{consumer, mainBranch: true},
// check backwards compatibility with existing deployed (staging/prod) versions of the consumer
{consumer, deployedOrReleased: true},
])),
].flat();
console.log('consumerVersionSelectors (pacts to verify)', consumerVersionSelectors);
// Initialize the Pact verifier
const verifier = new Verifier({
...commonVerifierConfig(commonEnv),
// For 'normal' provider builds (the provider changed), fetch pacts for this provider, to verify them
provider: commonEnv.PROVIDER,
pactBrokerUrl: process.env.PACT_BROKER_BASE_URL,
pactBrokerToken: process.env.PACT_BROKER_TOKEN,
// Specify which pacts to verify
consumerVersionSelectors,
// Pending pacts are a way for the provider to ensure a consumer won't break the build (of the provider).
// See <https://www.youtube.com/watch?v=VnOy9Sv9Opo>
// NOTE: the pending calculation is based on the tag for the provider version
enablePending: true,
// WIP pacts build on top of pending pacts, and are a way for the consumer to get quick feedback
// on a new pact (on a feature branch), without requiring the provider to update their configuration
// (by adding the new pact in the list of pacts that need to be verified).
includeWipPactsSince: '2020-01-01',
});
// Verify pacts
const output = await verifier.verifyProvider();
console.log(output);
});
}
consumerVersionSelectors resolves to:
console.log
consumerVersionSelectors (pacts to verify) [
{ consumer: 'PortalUI', mainBranch: true },
{ consumer: 'PortalUI', deployedOrReleased: true }
]
The problem is with pending & WIP pacts: although consumerVersionSelectors only targets PortalUI via consumer field, pending & wip pacts also fetch pacts for AuditService.
Because the fn uses Verifier and pacts for AuditService need to be verified using MessageProviderPact , the test fails.
Do you have a working example anywhere of how to deal with a producer that needs to verify both HTTP interactions (pacts) and async (Kafka, etc)?Matt (pactflow.io / pact-js / pact-go)
Stefan Tertan
11/02/2022, 10:29 AMCardServiceHttp and CardServiceAsync, right?