Is there anyway to let rebus publish all message synchronously so that I can assert on some value after all message have been processed?
Or what is the best way to do an integration test:
Publish event
handle by saga, send command
Handle command, publish another event
Saga marked as completed
the another event handler update the database
assert or database
Thanks
Regards
Yin
For testing a single saga and its behavior you should take a look at the blog post I wrote, Unit testing sagas with Rebus, which is an example on how SagaFixture and FakeBus can be used - I think it supports everything you're mentioning that you want to test.
If you're interested in testing more complicated scenarios, possibly involving other handlers and longer message correspondences etc, you might benefit from some strategic use of ManualResetEvent - Rebus has several integration tests that start up a bus and do some stuff, doing a resetEvent.Set() when the scenario is over - this way, the test can do a resetEvent.WaitOne(timeout) to block while the test is running and continue immediately when it's over.
Related
We have 5 microservices (more on the way) that communicate with each other asynchronously. 3 of these microservices do not have any API. Those consume data from a message queue, do some processing, and write data into another queue. 2 of these microservices do have APIs, and those also consume data from the queues but send the response back to the caller.
Given that, for testing the service interactions, correctness of contracts, and end-to-end flow:
what would be the best way to test the asynchronous services that read from and write to queues?
would consumer-contract test be applicable anywhere?
I feel end-to-end production testing is possible, but can something more granular and effective be done?
First, let's correct one thing - you do have APIs. The messages that the "API-less" services read must have some defined content or format. That's an API. You should be testing it, both positive and negative.
Before you get to whole-system testing (in a test or staging environment that mimics your production environment) your testing should probably be in layers, much as in any other system.
Unit tests to test the behavior of each class. In your message-handling classes, for example, call each with messages that prompt specific actions and test that it works correctly. These can usually be run very quickly so it's easy to run them often while developing code.
Integration tests to make sure your interaction with next-level external systems works. You can use, for example, testcontainers to run isolated instances of the queueing system that your services interact with.
Exactly what form these tests take depends on what languages and frameworks your system is built with. I briefly looked at the Pact tool you referenced and it is taking a similar approach.
Looks like with Pact it is possible to do message-based contract testing. I think I have a path forward with this.
What is the meaning of Synchronous and Asynchronous in general?
What are the use of Synchronous and Asynchronous communication in microservice? When to use synchronous and when to use Asynchronous.
Please explain with example thanks in advance.
Under synchronous, the communication between components is live all the time. An example would be a service making a GET/ POST call and waiting for the response to proceed to the immediate next step.
Asynchronous meaning one component does not wait for the other components to react. An example would be a service publishing message to a Kafka topic. The service which creates the event does not know when the clients will consume it.
I would start thinking about the application end-user use case to decide when I should use what.
I need to call one service from the other so I want to be sure it's ready before I use it. In my case, both microservices are running in the same database.
In the startup script, I would like to wait until the dependency is operational and abort if it isn't ready after a specified time. So this leads to the questions:
How do I detect whether another microservice is started?
What is the best approach to wait for another microservice to start.
If it doesn't start what is the right way to abort starting the current microservice.
Thanks.
Looks like it's actually easy. I set up the "provides" and "dependencies" in the respective foxx manifests. This prevents the dependent service from being mounted before the "provider" is ready to accept requests.
I have a situation where I have an #InitiatingFlow, called ProposeMemberFlow, and a corresponding #InitiatedBy ProposeMemberFlowResponder. I would like include in my integration test something that tests that the responder has one of the transaction output states post the FinalityFlow sub flow having been kicked off by the initiating flow.
I naively called waitForLedgerCommit in the responding flow, post responding to the CollectSignaturesFlow, but I'm finding that the initiating flow finishes before the responding flow does - presumably the latter is waiting for the vault update.
I'm integration testing through a CordaService - is "the corda way" to use expectEvents to wait for VaultUpdates so that I then know when it's safe to test against the CordaService? Much like here?
Thanks
I haven't heard of integration testing via a CordaService. Generally, you would write integration tests using the node driver.
Here's an example: https://github.com/corda/cordapp-template-kotlin/blob/release-V2/cordapp/src/integrationTest/kotlin/com/template/DriverBasedTest.kt
This piece of code starts a set of nodes, then uses RPC to check some conditions of the node.
In your case, you'd want to use the following set of RPC operations in the node driver:
CordaRPCOps.startFlowDynamic on node A's RPC handle to run the ProposeMemberFlow
CordaRPCOps.vaultQueryBy on node B's RPC handle to check that the correct state has been written to the vault
Another option would be to use the mock network (e.g. https://github.com/corda/cordapp-example/blob/release-V2/kotlin-source/src/test/kotlin/com/example/flow/IOUFlowTests.kt). You could argue that this isn't an integration test, since you are running mock nodes instead of real nodes. However, the mock nodes are just another implementation of the AbstractNode interface, and should behave like normal nodes for the purposes of testing.
Team:
I need to invoke a WF activity (XAML) from a WF service (XAMLX) asynchronously. I am already referencing the Microsoft.Activities.Extensions framework and I'm running on the Platform Update 1 for the state machine -- so if the solution is already in one of those libraries I'm ready!
Now, I need to invoke that activity (XAML) asynchronously -- but it has an output parameter that needs to set a variable in the service (XAMLX). Can somebody please provide me a solution to this?
Thanks!
* UPDATE *
Now I can post pictures, * I think *, because I have enough reputation! Let me put a couple out here and try to better explain my problem. The first picture is the WF Service that has the two entry points for the workflow -- the second is the workflow itself.
This workflow is an orchestration mechanism that constantly restarts itself, and has some failover mechanisms (e.g. exit on error threshold and soft exit) so that we can manage our queue of durable transactions using WF!
Now, we had this workflow working great when it was all one WF Service because we could call the service, get a response back and send the value of that response back into another entry point in a trigger to issue a soft exit. However, a new requirement has arrisen asking us to make the workflow itself a WF activity in another project and have the Receive/Send-Reply sequences in the WF Service Application project.
However, we need to be able to startup this workflow and forget about it -- then let it know somehow that a soft exit is necessary later on down the road -- but since WF executes on a single thread this has become a bit challenging at best.
Strictly speaking in XAML activities Parallel and ParallelForEach are how you perform asynchrony.
The workflow scheduler only uses a single thread (much like UI) so any activity that is running will typically be running on the same thread, unless it implements AsyncCodeActivity, in which case you are simply handing back the scheduler thread to the runtime while waiting for a callback from whichever async code your AsyncCodeActivity implementation is calling.
Therefore are you sure this is what you want to achieve? Do you mean you want to run it after you have sent your initial response? In this case place your activity after the Send Reply.
Please provide more info if these suggestions don't answer your question./
Update:
The original requirement posed (separating implementation from the service Receive/Send activities) may actually be solved by hosting the target activity as a service. See the following link
http://blog.petegoo.com/index.php/2011/09/02/building-an-enterprise-workflow-system-with-wf4/