libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit 1b9e30d65782e2543b54599c98b8e55ed5cbeebf
parent 090bc0e537d120e0996aeefc9fa82c1929bd676c
Author: MS <ms@taler.net>
Date:   Wed, 12 Apr 2023 11:07:14 +0200

testing DB events

Diffstat:
Anexus/src/test/kotlin/DbEventTest.kt | 38++++++++++++++++++++++++++++++++++++++
Mnexus/src/test/kotlin/SandboxAccessApiTest.kt | 63+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Mnexus/src/test/kotlin/TalerTest.kt | 2+-
Dutil/src/test/kotlin/ibanTest.kt | 11-----------
4 files changed, 98 insertions(+), 16 deletions(-)

diff --git a/nexus/src/test/kotlin/DbEventTest.kt b/nexus/src/test/kotlin/DbEventTest.kt @@ -0,0 +1,37 @@ +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch +import kotlinx.coroutines.runBlocking +import org.jetbrains.exposed.sql.transactions.transaction +import org.junit.Test +import tech.libeufin.util.PostgresListenHandle +import tech.libeufin.util.postgresNotify + + +class DbEventTest { + + /** + * LISTENs to one DB channel but only wakes up + * if the payload is how expected. + */ + @Test + fun payloadTest() { + withTestDatabase { + val listenHandle = PostgresListenHandle("X") + transaction { listenHandle.postgresListen() } + runBlocking { + launch { + val isArrived = listenHandle.waitOnIoDispatchersForPayload( + timeoutMs = 1000L, + expectedPayload = "Y" + ) + assert(isArrived) + } + launch { + delay(500L); // Ensures the wait helper runs first. + transaction { this.postgresNotify("X", "Y") } + } + } + } + } +} +\ No newline at end of file diff --git a/nexus/src/test/kotlin/SandboxAccessApiTest.kt b/nexus/src/test/kotlin/SandboxAccessApiTest.kt @@ -6,15 +6,24 @@ import io.ktor.client.statement.* import io.ktor.http.* import io.ktor.server.testing.* import io.ktor.util.* +import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking +import kotlinx.coroutines.time.delay import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.transactions.transaction +import org.junit.Ignore import org.junit.Test import tech.libeufin.nexus.bankaccount.getBankAccount import tech.libeufin.sandbox.* +import java.util.* +import kotlin.concurrent.schedule class SandboxAccessApiTest { val mapper = ObjectMapper() + private fun getTxs(respJson: String): JsonNode { + val mapper = ObjectMapper() + return mapper.readTree(respJson).get("transactions") + } /** * Testing that ..access-api/withdrawals/{wopid} and @@ -139,10 +148,6 @@ class SandboxAccessApiTest { // Tests the time range filter of Access API's GET /transactions @Test fun timeRangedTransactions() { - fun getTxs(respJson: String): JsonNode { - val mapper = ObjectMapper() - return mapper.readTree(respJson).get("transactions") - } withTestDatabase { prepSandboxDb() testApplication { @@ -428,4 +433,54 @@ class SandboxAccessApiTest { } } + + /** + * This test checks that the bank hangs before responding with the list + * of transactions, in case there is none to return. The timing checks + * that the server hangs for as long as the unblocking payment takes place + * but NOT as long as the long_poll_ms parameter would suggest. This last + * check ensures that the response can only contain the artificial unblocking + * payment (that happens after a certain timeout). + */ + @Test + fun longPolledTransactions() { + val unblockingTxTimer = Timer() + val testStartTime = System.currentTimeMillis() + withTestDatabase { + prepSandboxDb() + testApplication { + application(sandboxApp) + runBlocking { + launch { + // long polls at most 50 seconds. + val R = client.get("/demobanks/default/access-api/accounts/foo/transactions?long_poll_ms=50000") { + expectSuccess = true + basicAuth("foo", "foo") + } + assert(getTxs(R.bodyAsText()).size() == 1) + val testEndTime = System.currentTimeMillis() + val timeDiff = (testEndTime - testStartTime) / 1000L + /** + * Now checking that the server responded after the unblocking tx + * took place and before the long poll timeout would occur. + */ + println(timeDiff) + assert(timeDiff in 4 .. 39) + } + unblockingTxTimer.schedule( + delay = 4000L, // unblocks the server in (at least) 4 seconds. + action = { + wireTransfer( + "admin", + "foo", + "default", + "#9", + "TESTKUDOS:2" + ) + } + ) + } + } + } + } } \ No newline at end of file diff --git a/nexus/src/test/kotlin/TalerTest.kt b/nexus/src/test/kotlin/TalerTest.kt @@ -118,7 +118,6 @@ class TalerTest { prepNexusDb() testApplication { application(nexusApp) - // This call blocks for 90 seconds val currentTime = System.currentTimeMillis() runBlocking { launch { @@ -133,6 +132,7 @@ class TalerTest { expectSuccess = true } val latestTime = System.currentTimeMillis() + // Checks that the call didn't hang for the whole long_poll_ms. assert(R.status.value == HttpStatusCode.OK.value && (latestTime - currentTime) < 2000 ) diff --git a/util/src/test/kotlin/ibanTest.kt b/util/src/test/kotlin/ibanTest.kt @@ -1,10 +0,0 @@ -import org.junit.Test -import tech.libeufin.util.getIban - -class IbanTest { - - @Test - fun genIban() { - println(getIban()) - } -} -\ No newline at end of file