2017-01-06 11:05:37 +00:00
|
|
|
Integration testing
|
|
|
|
===================
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
Integration testing involves bringing up nodes locally and testing
|
|
|
|
invariants about them by starting flows and inspecting their state.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
In this tutorial we will bring up three nodes - Alice, Bob and a
|
|
|
|
notary. Alice will issue cash to Bob, then Bob will send this cash
|
2016-11-28 13:37:38 +00:00
|
|
|
back to Alice. We will see how to test some simple deterministic and
|
|
|
|
nondeterministic invariants in the meantime.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
.. note:: This example where Alice is self-issuing cash is purely for
|
|
|
|
demonstration purposes, in reality, cash would be issued by a bank
|
|
|
|
and subsequently passed around.
|
2016-11-28 11:50:12 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
In order to spawn nodes we will use the Driver DSL. This DSL allows
|
|
|
|
one to start up node processes from code. It manages a network map
|
|
|
|
service and safe shutting down of nodes in the background.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
|
|
|
.. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
|
|
|
|
:language: kotlin
|
|
|
|
:start-after: START 1
|
|
|
|
:end-before: END 1
|
2017-10-01 22:33:15 +00:00
|
|
|
:dedent: 8
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
The above code starts three nodes:
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
* Alice, who has user permissions to start the ``CashIssueFlow`` and
|
|
|
|
``CashPaymentFlow`` flows
|
|
|
|
* Bob, who only has user permissions to start the ``CashPaymentFlow``
|
|
|
|
* A notary that offers a ``ValidatingNotaryService``. We won't connect
|
|
|
|
to the notary directly, so there's no need to provide a ``User``
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
The ``startNode`` function returns a future that completes once the
|
|
|
|
node is fully started. This allows starting of the nodes to be
|
|
|
|
parallel. We wait on these futures as we need the information
|
2017-10-01 22:33:15 +00:00
|
|
|
returned; their respective ``NodeHandles`` s.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
|
|
|
.. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
|
|
|
|
:language: kotlin
|
|
|
|
:start-after: START 2
|
|
|
|
:end-before: END 2
|
2017-10-01 22:33:15 +00:00
|
|
|
:dedent: 12
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
After getting the handles we wait for both parties to register with
|
|
|
|
the network map to ensure we don't have race conditions with network
|
|
|
|
map registration. Next we connect to Alice and Bob respectively from
|
|
|
|
the test process using the test user we created. Then we establish RPC
|
|
|
|
links that allow us to start flows and query state.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
|
|
|
.. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
|
|
|
|
:language: kotlin
|
|
|
|
:start-after: START 3
|
|
|
|
:end-before: END 3
|
2017-10-01 22:33:15 +00:00
|
|
|
:dedent: 12
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
We will be interested in changes to Alice's and Bob's vault, so we
|
|
|
|
query a stream of vault updates from each.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
Now that we're all set up we can finally get some cash action going!
|
2016-11-25 15:26:00 +00:00
|
|
|
|
|
|
|
.. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
|
|
|
|
:language: kotlin
|
|
|
|
:start-after: START 4
|
|
|
|
:end-before: END 4
|
2017-10-01 22:33:15 +00:00
|
|
|
:dedent: 12
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
The first loop creates 10 threads, each starting a ``CashFlow`` flow
|
|
|
|
on the Alice node. We specify that we want to issue ``i`` dollars to
|
2017-10-01 22:33:15 +00:00
|
|
|
Bob, setting our notary as the notary responsible for notarising the
|
2016-11-28 13:37:38 +00:00
|
|
|
created states. Note that no notarisation will occur yet as we're not
|
2017-10-01 22:33:15 +00:00
|
|
|
spending any states, only creating new ones on the ledger.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
We started the flows from different threads for the sake of the
|
|
|
|
tutorial, to demonstrate how to test non-determinism, which is what
|
|
|
|
the ``expectEvents`` block does.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
The Expect DSL allows ordering constraints to be checked on a stream
|
|
|
|
of events. The above code specifies that we are expecting 10 updates
|
|
|
|
to be emitted on the ``bobVaultUpdates`` stream in unspecified order
|
2017-10-01 22:33:15 +00:00
|
|
|
(this is what the ``parallel`` construct does). We specify an
|
2016-11-28 13:37:38 +00:00
|
|
|
(otherwise optional) ``match`` predicate to identify specific updates
|
|
|
|
we are interested in, which we then print.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
If we run the code written so far we should see 4 nodes starting up
|
2017-10-01 22:33:15 +00:00
|
|
|
(Alice, Bob, the notary and an implicit Network Map service), then
|
|
|
|
10 logs of Bob receiving 1,2,...10 dollars from Alice in some unspecified
|
|
|
|
order.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2017-10-01 22:33:15 +00:00
|
|
|
Next we want Bob to send this cash back to Alice.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
|
|
|
.. literalinclude:: example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt
|
|
|
|
:language: kotlin
|
|
|
|
:start-after: START 5
|
|
|
|
:end-before: END 5
|
2017-10-01 22:33:15 +00:00
|
|
|
:dedent: 12
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
This time we'll do it sequentially. We make Bob pay 1,2,..10 dollars
|
|
|
|
to Alice in order. We make sure that a the ``CashFlow`` has finished
|
|
|
|
by waiting on ``startFlow`` 's ``returnValue``.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
Then we use the Expect DSL again, this time using ``sequence`` to test
|
|
|
|
for the updates arriving in the order we expect them to.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
Note that ``parallel`` and ``sequence`` may be nested into each other
|
|
|
|
arbitrarily to test more complex scenarios.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
That's it! We saw how to start up several corda nodes locally, how to
|
|
|
|
connect to them, and how to test some simple invariants about
|
|
|
|
``CashFlow``.
|
2016-11-25 15:26:00 +00:00
|
|
|
|
2016-11-28 13:37:38 +00:00
|
|
|
To run the complete test you can open
|
|
|
|
``example-code/src/integration-test/kotlin/net/corda/docs/IntegrationTestingTutorial.kt``
|
|
|
|
from IntelliJ and run the test, or alternatively use gradle:
|
2016-11-25 15:26:00 +00:00
|
|
|
|
|
|
|
.. sourcecode:: bash
|
|
|
|
|
|
|
|
# Run example-code integration tests
|
2017-10-01 22:33:15 +00:00
|
|
|
./gradlew docs/source/example-code:integrationTest -i
|