I've read articles like this one that suggest verifying contracts on the provider side that exist in a consumer's feature branch, in effect allowing the contract to be "pre-verified" before being merged to master. However, I've read other documentation from the Pact team stating the opposite. In The Steps to Reaching Pact Nirvana, it states "To keep a green build in your provider’s CI, rather than verifying the latest overall pact, it should verify the pact for the latest version tagged with “master” in the CI." Here, I'm assuming the words "latest overall pact" mean the pact that might exist in a consumer's feature branch that was published to the Pact Broker.
I'm confused. So as to not "make provider teams unhappy" as stated in The Steps to Reaching Pact Nirvana, what would be the purpose of ever publishing a pact from a consumer's feature branch if the provider would never verify that pact and only verify "master" and "production" pacts? Another way to ask this is when would/should pacts ever be published/verified from feature branches and solely not the master branches of consumers and providers against the "master" and "production" pacts?
Just noting that this is the latest guide on "effective Pact setup": https://docs.pact.io/best_practices/pact_nirvana. Hopefully this is clearer.
But in case it's not, pre-verifying feature branches is definitely a core feature of the Broker and something we would want to do. Once a change is in master, in 99% of the cases it should be smooth sailing (i.e. compatible). It's standard practice to either a) have a webhook that can trigger the pact verification step of a provider build to verify the new feature or b) have the corresponding feature branch in the provider verify the pact in CI when a change is pushed.
There is also a new feature coming out soon called "pending pacts", which will improve this situation drastically too, effectively allowing any new contracts to not break a providers' build, but still providing feedback to consumers if the change is supported.
Related
Been reading up on Corda (no actual use yet) and other DLTs to see if we could use it in a project. What I was wondering after reading all the Corda key concepts: what would be the way to share data with everyone, including nodes that are only added later?
I've been reading things like https://corda.net/blog/broadcasting-a-transaction-to-external-organisations/ and https://stackoverflow.com/a/53205303/1382108. But what if another node joins later?
As an example use case: say an organization wants to advertise goods it's selling to all nodes in a network, while price negotiations or actual sales can then happen in private. If a new node joins, what's the best/easiest way to make sure they are also aware of the advertised goods? With blockchain technologies I'd think they'd just replicate the chain that has these facts upon joining but how would it work in Corda? Any links or code samples would be greatly appreciated!
You can share transactions with other nodes that have not previously seen them, but this sort of functionality doesn't come out of the box and has to be implemented using flows by the CorDapp developer.
As the author of ONIXLabs, I've implemented much of this functionality generally to make it easier for CorDapp developers to consume. There are quite a few feature-rich APIs available on GitHub.
In order to publish a transaction, the ONIXLabs Corda Core API contains functions that extend FlowLogic<*> to provide generalised transaction publishing:
publishTransaction called on the initiating-side of the flow, specifies the transaction to be published, and to whom.
publishTransactionHandler called on the initiated-by/handler side of the flow specifies the transaction to be recorded and who it's from.
As an example of how these APIs are consumed, take a look at the ONIXLabs Corda Identity Framework, where we have a mechanism for publishing accounts from one node to a collection of counterparties.
PublishAccountFlow consumes the publishTransaction function.
PublishAccountFlowHandler consumes the publishTransactionHandler function.
We're implementing Pact framework for testing couple of microservices (Scala Backend & iOS-Android Frontend). So to test the Pact implementation itself, what sort of negative tests / defect seeding we can do to make sure that - the implemented Pact is catching what it supposed to catch?
i.e. once our Pact work’s complete we’re thinking to do defect seeding & see if errors like Query parameters, API response structure change , spelling changes in API paths etc are getting caught correctly by the PACT or not?
So on that line what other -ve tests & defect seeding, could we run on the implemented PACT framework? viz- Checklist for smoke test / exploratory tests to quickly test implemented PACT framework before its launched to live.
Thanks
Pact is not really designed for those types of tests. It can be done, but the extra variations in data often becomes an issue for providers [1].
There is a proposal to be able to "annotate" interactions by adding arbitrary labels for purposes such as this. If you'd like to add your thoughts to https://github.com/pact-foundation/pact-specification/issues/75 that would be helpful.
https://docs.pact.io/consumer#use-pact-for-isolated-unit-tests
I have a weird situation and I have no idea how to handle it:
Let's say I have a consumer C and a provider P.
We did not use Pact, when we implemented these services. So here is the problem: An older version of C needs a specific interface of P, where it provides some information via an url parameter. BUT the newest version of C is not even able to send this kind of request. Since there are still old versions of C out there, we need to ensure this interface is still provided by P and working correctly.
I'm using Pact-JVM and it looks like I have to send this request somehow, else the test will fail. I'm struggling with creating a meaningful test for this scenario. I could create a dummy, that sends the request, but that would not test anything. Does somebody have any idea what to do in this situation?
I would suggest that you check out out the commit of the old version of the consumer, make a new branch from it, add the pact test to that branch, and publish it as normal.
If all else fails (and I would never normally suggest this) you could take your most recently generated pact, hand modify it to match what the old consumer expects, and then manually publish it to the Pact Broker.
If I understand correctly, there are two (or more) versions of C in production with different versions of a contract on P. One option is to publish the old C with a separate name and verify it as normal. Another option is to publish a pact with the same name.
If you do the latter, you'll need to ensure you tag both versions as prod and then on the provider side, you can verify all prod versions the contract using consumer version selectors.
I'm currently experimenting with Pact and stumbled over a problem with the workflow and can't find a satisfying solution. So hopefully someone can help me. :-)
First of all, that's my current workflow for changes on the consumer side:
The consumer changes are uploaded to Github in a feature branch
Pact tests are run on the CI system and the resulting pact is uploaded to the pact broker with the tags [feature-branch-name] and verify_feature (currently I only use the latter one)
The consumer waits for the verification (using the can-i-deploy tool)
The pact broker triggers the provider via webhook (trigger: contract_content_changed)
The provider runs pact-verify for the latest version tagged verify_feature and uploads the result
The consumer checks the result, if verification was successful the branch can be merged
So far so good. The problem arises when the consumer introduces breaking changes:
After the consumer uploads the changes to Github, the process described above is executed and the provider verification fails which in turn causes the consumer build to fail as expected.
Now the necessary changes are made on the provider side. The provider runs pact-verify against the consumer version of the testing stage and - if successful - the new version is then merged and deployed.
Now the new consumer version should be able to be merged as well. Alas, it does not work, because this version has not been verified again. And when I restart the CI job, the pact is re-uploaded to the pact broker, but since the pact content does not change no webhook is triggered. The consumer version is never verified.
So, what am I doing wrong?
You need the new WIP pacts feature. It's currently under development, and could be available for beta testing in pact-js (and other languages that wrap the pact-ruby-standalone) within days if you wanted to try it out. If you're using pact-jvm, you'll have to wait a little longer, but we may be able to provide a work around. I've written a blog post on WIP pacts, but haven't published it yet because the feature is not ready for public release. You can find the post here http://blog.pact.io/p/51906e22-ccce-486b-9993-c21794e557d4/ I'd love to get your feedback on it.
Hop on to slack.pact.io and # me if you'd like to chat further about this.
What's the best way to maintain/approach contract upgrade of states in terms of flows.
Scenario.
Existing BondStateV1
and the flows are using class type of BondStateV1 i.e queryBy<BondStateV1>
Now. We want to upgrade BondStateV1 to BondStateV2.
How do we change the flows?
Do we keep the old flows, and deploy a new FlowCordappV2?
Or after migrating BondStateV1 to BondStateV2, do we deprecate/delete all the old FlowCordapp, refactor to handle V2 and redeploy?
State and contract upgrades happen independently of flows, by following the approach given here: https://docs.corda.net/upgrading-cordapps.html#contract-and-state-versioning.
But your flow will then need to handle the (potential) presence of both BondStateV1 and BondStateV2 states on the network. You can achieve this by following the instructions here: https://docs.corda.net/upgrading-cordapps.html#how-do-i-upgrade-my-flows.