commit 87d5e21cdcb554531e12c57ca6c73d99daf3e3a8
parent bb96fd4f635cd9b760363acc7aacb9f7d890cf89
Author: MS <ms@taler.net>
Date: Sat, 22 Apr 2023 10:02:43 +0200
Conversion service tests.
Fixing job cancellation.
Diffstat:
1 file changed, 43 insertions(+), 18 deletions(-)
diff --git a/nexus/src/test/kotlin/ConversionServiceTest.kt b/nexus/src/test/kotlin/ConversionServiceTest.kt
@@ -10,9 +10,6 @@ import tech.libeufin.nexus.server.nexusApp
import tech.libeufin.sandbox.*
class ConversionServiceTest {
- // Without this, "launch {}" never returns.
- val doNothingHandler = CoroutineExceptionHandler { _, _ -> }
-
/**
* Testing the buy-in monitor in the normal case: Nexus
* communicates a new incoming fiat transaction and the
@@ -44,15 +41,24 @@ class ConversionServiceTest {
testApplication {
application(nexusApp)
// Start the buy-in monitor to let it download the fiat transaction.
- val job = CoroutineScope(Dispatchers.IO).launch(doNothingHandler) {
- buyinMonitor(
- demobankName = "default",
- accountToCredit = "exchange-0",
- client = client
- )
+ runBlocking {
+ val job = launch {
+ /**
+ * The runInterruptible wrapper lets code without suspension
+ * points be cancel()'d. Without it, such code would ignore
+ * any call to cancel() and the test never return.
+ */
+ runInterruptible {
+ buyinMonitor(
+ demobankName = "default",
+ accountToCredit = "exchange-0",
+ client = client
+ )
+ }
+ }
+ delay(1000L) // Lets the DB persist.
+ job.cancelAndJoin()
}
- delay(1000L)
- job.cancel()
}
// Checking that exchange got the converted amount.
transaction {
@@ -95,15 +101,34 @@ class ConversionServiceTest {
)
testApplication {
application(nexusApp)
- CoroutineScope(Dispatchers.IO).launch(doNothingHandler) {
- cashoutMonitor(client)
- }
- delay(1000L) // Lets DB persist the information.
- transaction {
- assert(CashoutSubmissionEntity.all().count() == 1L)
- assert(CashoutSubmissionEntity.all().first().isSubmitted)
+ runBlocking {
+ val job = launch {
+ /**
+ * The runInterruptible wrapper lets code without suspension
+ * points be cancel()'d. Without it, such code would ignore
+ * any call to cancel() and the test never return.
+ */
+ runInterruptible {
+ /**
+ * Without the runBlocking wrapper, cashoutMonitor doesn't
+ * compile. That's because it is a 'suspend' function and
+ * it needs a coroutine environment to execute; runInterruptible
+ * does NOT provide one. Furthermore, replacing runBlocking
+ * with "launch {}" would nullify runInterruptible, due to other
+ * jobs that cashoutMonitor internally launches and would escape
+ * the interruptible policy.
+ */
+ runBlocking { cashoutMonitor(client) }
+ }
+ }
+ delay(1000L) // Lets DB persist the information.
+ job.cancelAndJoin()
}
}
+ transaction {
+ assert(CashoutSubmissionEntity.all().count() == 1L)
+ assert(CashoutSubmissionEntity.all().first().isSubmitted)
+ }
}
}