From 454698a2eb1b62b29fc265ef78f19f207c4d7d52 Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 18 May 2022 11:29:45 +0430 Subject: [PATCH 01/18] Starting test --- .../core/service/FeeCalculatorImplTest.kt | 87 ++++ .../core/service/OrderManagerImplTest.kt | 370 +++++++++--------- 2 files changed, 272 insertions(+), 185 deletions(-) create mode 100644 accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt new file mode 100644 index 000000000..7b5aff6a5 --- /dev/null +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt @@ -0,0 +1,87 @@ +package co.nilin.opex.accountant.core.service + +import co.nilin.opex.accountant.core.inout.OrderStatus +import co.nilin.opex.accountant.core.model.Order +import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent +import co.nilin.opex.matching.engine.core.model.MatchConstraint +import co.nilin.opex.matching.engine.core.model.OrderDirection +import co.nilin.opex.matching.engine.core.model.OrderType +import co.nilin.opex.matching.engine.core.model.Pair +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test +import java.math.BigDecimal + +internal class FeeCalculatorImplTest { + + private val feeCalculator = FeeCalculatorImpl("0x0") + + @Test + fun test() = runBlocking { + val maker = Order( + "btc_usdt", + "order_1", + 1, + 0.01, + 0.01, + 0.00001, + 0.01, + "user_1", + "*", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 50_000, + 1000, + 0, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.NEW.code + ) + + val taker = Order( + "btc_usdt", + "order_2", + 2, + 0.01, + 0.01, + 0.00001, + 0.01, + "user_2", + "*", + OrderDirection.ASK, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 50_000, + 1000, + 0, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.NEW.code + ) + val trade = TradeEvent( + 1, + Pair("btc", "usdt"), + "order_2", + "user_2", + 2, + OrderDirection.ASK, + 50_000, + 0, + "order_1", + "user_1", + 1, + OrderDirection.BID, + 50_000, + 0, + 1000 + ) + val actions = feeCalculator.createFeeActions() + } + +} \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt index 224b67815..ce8aa3a63 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt @@ -1,185 +1,185 @@ -package co.nilin.opex.accountant.core.service - -import co.nilin.opex.accountant.core.api.OrderManager -import co.nilin.opex.accountant.core.model.FinancialAction -import co.nilin.opex.accountant.core.model.PairConfig -import co.nilin.opex.accountant.core.model.PairFeeConfig -import co.nilin.opex.accountant.core.spi.* -import co.nilin.opex.matching.engine.core.eventh.events.SubmitOrderEvent -import co.nilin.opex.matching.engine.core.model.MatchConstraint -import co.nilin.opex.matching.engine.core.model.OrderDirection -import co.nilin.opex.matching.engine.core.model.OrderType -import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Assertions.assertEquals -import org.junit.jupiter.api.Test -import org.mockito.ArgumentMatchers.anyString -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.MockitoAnnotations -import java.time.LocalDateTime - -internal class OrderManagerImplTest() { - - @Mock - lateinit var financialActionPersister: FinancialActionPersister - - @Mock - lateinit var financialActionLoader: FinancialActionLoader - - @Mock - lateinit var orderPersister: OrderPersister - - @Mock - lateinit var tempEventPersister: TempEventPersister - - @Mock - lateinit var tempEventRepublisher: TempEventRepublisher - - @Mock - lateinit var pairConfigLoader: PairConfigLoader - - @Mock - lateinit var richOrderPublisher: RichOrderPublisher - - val orderManager: OrderManager - - init { - MockitoAnnotations.openMocks(this) - orderManager = OrderManagerImpl( - pairConfigLoader, - financialActionPersister, - financialActionLoader, - orderPersister, - tempEventPersister, - tempEventRepublisher, - richOrderPublisher - ) - runBlocking { - Mockito.`when`(tempEventPersister.loadTempEvents(anyString())).thenReturn(emptyList()) - } - } - - @Test - fun givenAskOrder_whenHandleRequestOrder_thenFAMatch() { - runBlocking { - //given - val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") - val pairConfig = PairConfig( - pair.toString(), pair.leftSideName, pair.rightSideName, 1.0, 0.001 - ) - val submitOrderEvent = SubmitOrderEvent( - "ouid", "uuid", null, pair, 30, 60, 0, OrderDirection.ASK, MatchConstraint.GTC, OrderType.LIMIT_ORDER - ) - Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) - .thenReturn( - PairFeeConfig( - pairConfig, - submitOrderEvent.direction.toString(), - "", - 0.1, - 0.12 - ) - ) - Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) - .then { - return@then it.getArgument>(0) - } - - //when - val financialActions = orderManager.handleRequestOrder(submitOrderEvent) - - //then - assertEquals(1, financialActions.size) - val expectedFinancialAction = FinancialAction( - null, - SubmitOrderEvent::class.simpleName!!, - submitOrderEvent.ouid, - pair.leftSideName, - pairConfig.leftSideFraction.toBigDecimal().multiply(submitOrderEvent.quantity.toBigDecimal()), - submitOrderEvent.uuid, - "main", - submitOrderEvent.uuid, - "exchange", - LocalDateTime.now() - ) - assertEquals(expectedFinancialAction.eventType, financialActions[0].eventType) - assertEquals(expectedFinancialAction.symbol, financialActions[0].symbol) - assertEquals(expectedFinancialAction.amount, financialActions[0].amount) - assertEquals(expectedFinancialAction.sender, financialActions[0].sender) - assertEquals(expectedFinancialAction.senderWalletType, financialActions[0].senderWalletType) - assertEquals(expectedFinancialAction.receiver, financialActions[0].receiver) - assertEquals(expectedFinancialAction.receiverWalletType, financialActions[0].receiverWalletType) - } - } - - @Test - fun givenBidOrder_whenHandleRequestOrder_thenFAMatch() { - runBlocking { - //given - val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") - val pairConfig = PairConfig( - pair.toString(), pair.leftSideName, pair.rightSideName, 1.0, 0.001 - ) - val submitOrderEvent = SubmitOrderEvent( - "ouid", "uuid", null, pair, 35, 14, 0, OrderDirection.BID, MatchConstraint.GTC, OrderType.LIMIT_ORDER - ) - Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) - .thenReturn( - PairFeeConfig( - pairConfig, submitOrderEvent.direction.toString(), "", 0.08, 0.1 - ) - ) - Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) - .then { - return@then it.getArgument>(0) - } - - //when - val financialActions = runBlocking { - orderManager.handleRequestOrder(submitOrderEvent) - } - - //then - assertEquals(1, financialActions.size) - val expectedFinancialAction = FinancialAction( - null, - SubmitOrderEvent::class.simpleName!!, - submitOrderEvent.ouid, - pair.rightSideName, - pairConfig.leftSideFraction.toBigDecimal().multiply(submitOrderEvent.quantity.toBigDecimal()) - .multiply(pairConfig.rightSideFraction.toBigDecimal()) - .multiply(submitOrderEvent.price.toBigDecimal()), - submitOrderEvent.uuid, - "main", - submitOrderEvent.uuid, - "exchange", - LocalDateTime.now() - ) - assertEquals(expectedFinancialAction.eventType, financialActions[0].eventType) - assertEquals(expectedFinancialAction.symbol, financialActions[0].symbol) - assertEquals(expectedFinancialAction.amount, financialActions[0].amount) - assertEquals(expectedFinancialAction.sender, financialActions[0].sender) - assertEquals(expectedFinancialAction.senderWalletType, financialActions[0].senderWalletType) - assertEquals(expectedFinancialAction.receiver, financialActions[0].receiver) - assertEquals(expectedFinancialAction.receiverWalletType, financialActions[0].receiverWalletType) - } - } - - @Test - fun handleNewOrder() { - } - - @Test - fun handleUpdateOrder() { - } - - @Test - fun handleRejectOrder() { - } - - @Test - fun handleCancelOrder() { - } -} - - +package co.nilin.opex.accountant.core.service + +import co.nilin.opex.accountant.core.api.OrderManager +import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.accountant.core.model.PairConfig +import co.nilin.opex.accountant.core.model.PairFeeConfig +import co.nilin.opex.accountant.core.spi.* +import co.nilin.opex.matching.engine.core.eventh.events.SubmitOrderEvent +import co.nilin.opex.matching.engine.core.model.MatchConstraint +import co.nilin.opex.matching.engine.core.model.OrderDirection +import co.nilin.opex.matching.engine.core.model.OrderType +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.Test +import org.mockito.ArgumentMatchers.anyString +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations +import java.time.LocalDateTime + +internal class OrderManagerImplTest { + + @Mock + lateinit var financialActionPersister: FinancialActionPersister + + @Mock + lateinit var financialActionLoader: FinancialActionLoader + + @Mock + lateinit var orderPersister: OrderPersister + + @Mock + lateinit var tempEventPersister: TempEventPersister + + @Mock + lateinit var tempEventRepublisher: TempEventRepublisher + + @Mock + lateinit var pairConfigLoader: PairConfigLoader + + @Mock + lateinit var richOrderPublisher: RichOrderPublisher + + val orderManager: OrderManager + + init { + MockitoAnnotations.openMocks(this) + orderManager = OrderManagerImpl( + pairConfigLoader, + financialActionPersister, + financialActionLoader, + orderPersister, + tempEventPersister, + tempEventRepublisher, + richOrderPublisher + ) + runBlocking { + Mockito.`when`(tempEventPersister.loadTempEvents(anyString())).thenReturn(emptyList()) + } + } + + @Test + fun givenAskOrder_whenHandleRequestOrder_thenFAMatch() { + runBlocking { + //given + val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") + val pairConfig = PairConfig( + pair.toString(), pair.leftSideName, pair.rightSideName, 1.0, 0.001 + ) + val submitOrderEvent = SubmitOrderEvent( + "ouid", "uuid", null, pair, 30, 60, 0, OrderDirection.ASK, MatchConstraint.GTC, OrderType.LIMIT_ORDER + ) + Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) + .thenReturn( + PairFeeConfig( + pairConfig, + submitOrderEvent.direction.toString(), + "", + 0.1, + 0.12 + ) + ) + Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) + .then { + return@then it.getArgument>(0) + } + + //when + val financialActions = orderManager.handleRequestOrder(submitOrderEvent) + + //then + assertEquals(1, financialActions.size) + val expectedFinancialAction = FinancialAction( + null, + SubmitOrderEvent::class.simpleName!!, + submitOrderEvent.ouid, + pair.leftSideName, + pairConfig.leftSideFraction.toBigDecimal().multiply(submitOrderEvent.quantity.toBigDecimal()), + submitOrderEvent.uuid, + "main", + submitOrderEvent.uuid, + "exchange", + LocalDateTime.now() + ) + assertEquals(expectedFinancialAction.eventType, financialActions[0].eventType) + assertEquals(expectedFinancialAction.symbol, financialActions[0].symbol) + assertEquals(expectedFinancialAction.amount, financialActions[0].amount) + assertEquals(expectedFinancialAction.sender, financialActions[0].sender) + assertEquals(expectedFinancialAction.senderWalletType, financialActions[0].senderWalletType) + assertEquals(expectedFinancialAction.receiver, financialActions[0].receiver) + assertEquals(expectedFinancialAction.receiverWalletType, financialActions[0].receiverWalletType) + } + } + + @Test + fun givenBidOrder_whenHandleRequestOrder_thenFAMatch() { + runBlocking { + //given + val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") + val pairConfig = PairConfig( + pair.toString(), pair.leftSideName, pair.rightSideName, 1.0, 0.001 + ) + val submitOrderEvent = SubmitOrderEvent( + "ouid", "uuid", null, pair, 35, 14, 0, OrderDirection.BID, MatchConstraint.GTC, OrderType.LIMIT_ORDER + ) + Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) + .thenReturn( + PairFeeConfig( + pairConfig, submitOrderEvent.direction.toString(), "", 0.08, 0.1 + ) + ) + Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) + .then { + return@then it.getArgument>(0) + } + + //when + val financialActions = runBlocking { + orderManager.handleRequestOrder(submitOrderEvent) + } + + //then + assertEquals(1, financialActions.size) + val expectedFinancialAction = FinancialAction( + null, + SubmitOrderEvent::class.simpleName!!, + submitOrderEvent.ouid, + pair.rightSideName, + pairConfig.leftSideFraction.toBigDecimal().multiply(submitOrderEvent.quantity.toBigDecimal()) + .multiply(pairConfig.rightSideFraction.toBigDecimal()) + .multiply(submitOrderEvent.price.toBigDecimal()), + submitOrderEvent.uuid, + "main", + submitOrderEvent.uuid, + "exchange", + LocalDateTime.now() + ) + assertEquals(expectedFinancialAction.eventType, financialActions[0].eventType) + assertEquals(expectedFinancialAction.symbol, financialActions[0].symbol) + assertEquals(expectedFinancialAction.amount, financialActions[0].amount) + assertEquals(expectedFinancialAction.sender, financialActions[0].sender) + assertEquals(expectedFinancialAction.senderWalletType, financialActions[0].senderWalletType) + assertEquals(expectedFinancialAction.receiver, financialActions[0].receiver) + assertEquals(expectedFinancialAction.receiverWalletType, financialActions[0].receiverWalletType) + } + } + + @Test + fun handleNewOrder() { + } + + @Test + fun handleUpdateOrder() { + } + + @Test + fun handleRejectOrder() { + } + + @Test + fun handleCancelOrder() { + } +} + + From 77fff598d072aa97d50c77a5f85e510d6d17d8b3 Mon Sep 17 00:00:00 2001 From: Peyman Date: Tue, 24 May 2022 16:55:08 +0430 Subject: [PATCH 02/18] Write test for fee calculator --- accountant/accountant-core/pom.xml | 9 +- .../core/service/FeeCalculatorImplTest.kt | 155 ++++++++++-------- .../core/service/TradeManagerImplTest.kt | 1 - 3 files changed, 96 insertions(+), 69 deletions(-) diff --git a/accountant/accountant-core/pom.xml b/accountant/accountant-core/pom.xml index 022876966..769b1ff41 100644 --- a/accountant/accountant-core/pom.xml +++ b/accountant/accountant-core/pom.xml @@ -50,8 +50,13 @@ provided - org.mockito - mockito-core + org.mockito.kotlin + mockito-kotlin + + + org.jetbrains.kotlinx + kotlinx-coroutines-core + test diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt index 7b5aff6a5..ec50eaf2c 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt @@ -8,80 +8,103 @@ import co.nilin.opex.matching.engine.core.model.OrderDirection import co.nilin.opex.matching.engine.core.model.OrderType import co.nilin.opex.matching.engine.core.model.Pair import kotlinx.coroutines.runBlocking +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import java.math.BigDecimal internal class FeeCalculatorImplTest { - private val feeCalculator = FeeCalculatorImpl("0x0") + private val receiverAddress = "0x0" + private val feeCalculator = FeeCalculatorImpl(receiverAddress) + private var defaultMaker: Order = Order( + "BTC_USDT", + "order_1", + 1, + 0.01, + 0.01, + 0.000001, + 0.01, + "user_1", + "*", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 50_000.toBigDecimal().divide(0.01.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 50_000.toBigDecimal(), + 1.toBigDecimal(), + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.FILLED.code + ) + private var defaultTaker: Order = Order( + "BTC_USDT", + "order_2", + 2, + 0.01, + 0.01, + 0.000001, + 0.01, + "user_2", + "*", + OrderDirection.ASK, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 50_000.toBigDecimal().divide(0.01.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 50_000.toBigDecimal(), + 1.toBigDecimal(), + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.FILLED.code + ) + private var defaultTrade: TradeEvent = TradeEvent( + 1, + Pair("BTC", "USDT"), + "order_2", + "user_2", + 2, + OrderDirection.ASK, + (50_000 / 0.01).toLong(), + 0, + "order_1", + "user_1", + 1, + OrderDirection.BID, + (50_000 / 0.01).toLong(), + 0, + (1 / 0.000001).toLong() + ) @Test - fun test() = runBlocking { - val maker = Order( - "btc_usdt", - "order_1", - 1, - 0.01, - 0.01, - 0.00001, - 0.01, - "user_1", - "*", - OrderDirection.BID, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER, - 50_000, - 1000, - 0, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - OrderStatus.NEW.code - ) + fun givenTradeEventsAndOrders_whenFeeCalculated_feeActionsNotNull(): Unit = runBlocking { + val actions = feeCalculator.createFeeActions(defaultTrade, defaultMaker, defaultTaker, null, null) + assertThat(actions.makerFeeAction).isNotNull + assertThat(actions.takerFeeAction).isNotNull + } + + @Test + fun givenTradeEventsAndOrders_whenFeeCalculated_returnCorrectFees(): Unit = runBlocking { + val actions = feeCalculator.createFeeActions(defaultTrade, defaultMaker, defaultTaker, null, null) + with(actions.makerFeeAction) { + assertThat(amount.toDouble()).isEqualTo(0.01) // 1% of 1 BTC + assertThat(symbol).isEqualTo("BTC") + assertThat(sender).isEqualTo("user_1") + assertThat(pointer).isEqualTo("order_2") + assertThat(receiver).isEqualTo(receiverAddress) + } - val taker = Order( - "btc_usdt", - "order_2", - 2, - 0.01, - 0.01, - 0.00001, - 0.01, - "user_2", - "*", - OrderDirection.ASK, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER, - 50_000, - 1000, - 0, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - OrderStatus.NEW.code - ) - val trade = TradeEvent( - 1, - Pair("btc", "usdt"), - "order_2", - "user_2", - 2, - OrderDirection.ASK, - 50_000, - 0, - "order_1", - "user_1", - 1, - OrderDirection.BID, - 50_000, - 0, - 1000 - ) - val actions = feeCalculator.createFeeActions() + with(actions.takerFeeAction) { + assertThat(amount.toDouble()).isEqualTo(500.0) // 1% of 50,000 USDT + assertThat(symbol).isEqualTo("USDT") + assertThat(sender).isEqualTo("user_2") + assertThat(pointer).isEqualTo("order_1") + assertThat(receiver).isEqualTo(receiverAddress) + } } } \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt index c03c25330..ddb9a2e0f 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt @@ -1,6 +1,5 @@ package co.nilin.opex.accountant.core.service -import co.nilin.opex.accountant.core.api.FeeCalculator import co.nilin.opex.accountant.core.api.OrderManager import co.nilin.opex.accountant.core.api.TradeManager import co.nilin.opex.accountant.core.model.FinancialAction From 7286ec63da399ded88dc2ad4d4d8eb3f135b0ac1 Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 25 May 2022 12:30:16 +0430 Subject: [PATCH 03/18] Write test for fa job manager --- accountant/accountant-core/pom.xml | 4 ++ .../core/service/FAJobManagerImplTest.kt | 62 +++++++++++++++++++ .../core/service/FeeCalculatorImplTest.kt | 40 +++++++++--- .../core/service/OrderManagerImplTest.kt | 2 +- .../core/service/TradeManagerImplTest.kt | 1 - 5 files changed, 99 insertions(+), 10 deletions(-) create mode 100644 accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt diff --git a/accountant/accountant-core/pom.xml b/accountant/accountant-core/pom.xml index 769b1ff41..fb20af05c 100644 --- a/accountant/accountant-core/pom.xml +++ b/accountant/accountant-core/pom.xml @@ -53,6 +53,10 @@ org.mockito.kotlin mockito-kotlin + + io.mockk + mockk + org.jetbrains.kotlinx kotlinx-coroutines-core diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt new file mode 100644 index 000000000..4390326dd --- /dev/null +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt @@ -0,0 +1,62 @@ +package co.nilin.opex.accountant.core.service + +import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.accountant.core.spi.FinancialActionLoader +import co.nilin.opex.accountant.core.spi.FinancialActionPersister +import co.nilin.opex.accountant.core.spi.WalletProxy +import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test +import java.time.LocalDateTime + +class FAJobManagerImplTest { + + private val financialActionLoader = mockk() + private val financialActionPersister = mockk() + private val walletProxy = mockk() + + private val sut = FinancialActionJobManagerImpl(financialActionLoader, financialActionPersister, walletProxy) + + private fun stub() { + val fa = FinancialAction( + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + LocalDateTime.now() + ) + + coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(fa, fa) + coEvery { financialActionPersister.updateStatus(any(), any()) } returns Unit + } + + @Test + fun given2FALoaded_whenProcessing_thenVerifyThatTransferProxyCalled2Times() = runBlocking { + stub() + coEvery { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } returns Unit + sut.processFinancialActions(0, 2) + coVerify(exactly = 2) { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } + coVerify(exactly = 2) { financialActionPersister.updateStatus(any(), any()) } + } + + @Test + fun given2FALoaded_whenProcessingFailed_thenUpdateStatusCalledRegardless() = runBlocking { + stub() + coEvery { + walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) + } throws IllegalStateException() + + sut.processFinancialActions(0, 2) + coVerify(exactly = 2) { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } + coVerify(exactly = 2) { financialActionPersister.updateStatus(any(), any()) } + } + +} \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt index ec50eaf2c..923eb0aab 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt @@ -1,6 +1,7 @@ package co.nilin.opex.accountant.core.service import co.nilin.opex.accountant.core.inout.OrderStatus +import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent import co.nilin.opex.matching.engine.core.model.MatchConstraint @@ -11,6 +12,7 @@ import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import java.math.BigDecimal +import java.time.LocalDateTime internal class FeeCalculatorImplTest { @@ -20,10 +22,10 @@ internal class FeeCalculatorImplTest { "BTC_USDT", "order_1", 1, - 0.01, - 0.01, - 0.000001, - 0.01, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.000001.toBigDecimal(), + 0.01.toBigDecimal(), "user_1", "*", OrderDirection.BID, @@ -43,10 +45,10 @@ internal class FeeCalculatorImplTest { "BTC_USDT", "order_2", 2, - 0.01, - 0.01, - 0.000001, - 0.01, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.000001.toBigDecimal(), + 0.01.toBigDecimal(), "user_2", "*", OrderDirection.ASK, @@ -96,6 +98,7 @@ internal class FeeCalculatorImplTest { assertThat(sender).isEqualTo("user_1") assertThat(pointer).isEqualTo("order_2") assertThat(receiver).isEqualTo(receiverAddress) + assertThat(receiverWalletType).isEqualTo("exchange") } with(actions.takerFeeAction) { @@ -104,7 +107,28 @@ internal class FeeCalculatorImplTest { assertThat(sender).isEqualTo("user_2") assertThat(pointer).isEqualTo("order_1") assertThat(receiver).isEqualTo(receiverAddress) + assertThat(receiverWalletType).isEqualTo("exchange") } } + @Test + fun givenTradeEventsAndOrders_whenFAParentNotNull_thenFeeActionParentNotNull(): Unit = runBlocking { + val parentFA = FinancialAction( + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + LocalDateTime.now() + ) + + val actions = feeCalculator.createFeeActions(defaultTrade, defaultMaker, defaultTaker, parentFA, parentFA) + assertThat(actions.makerFeeAction.parent).isNotNull + assertThat(actions.takerFeeAction.parent).isNotNull + } + } \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt index 16bb649c3..c939fbff4 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt @@ -19,7 +19,7 @@ import org.mockito.MockitoAnnotations import java.math.BigDecimal import java.time.LocalDateTime -internal class OrderManagerImplTest() { +internal class OrderManagerImplTest { @Mock lateinit var financialActionPersister: FinancialActionPersister diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt index 2219e5677..add9d374b 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt @@ -1,6 +1,5 @@ package co.nilin.opex.accountant.core.service -import co.nilin.opex.accountant.core.api.FeeCalculator import co.nilin.opex.accountant.core.api.OrderManager import co.nilin.opex.accountant.core.api.TradeManager import co.nilin.opex.accountant.core.model.FinancialAction From 35b3c8824b6a61a99c3c5b136782308d435aa77b Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 25 May 2022 15:13:02 +0430 Subject: [PATCH 04/18] Replace mockito with mockk --- .../accountant/core/service/MockitoHelper.kt | 13 - .../core/service/OrderManagerImplTest.kt | 270 ++++++------- .../core/service/TradeManagerImplTest.kt | 358 ++++++++---------- 3 files changed, 283 insertions(+), 358 deletions(-) delete mode 100644 accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/MockitoHelper.kt diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/MockitoHelper.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/MockitoHelper.kt deleted file mode 100644 index b40a99504..000000000 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/MockitoHelper.kt +++ /dev/null @@ -1,13 +0,0 @@ -package co.nilin.opex.accountant.core.service - -import org.mockito.Mockito - -object MockitoHelper { - fun anyObject(): T { - Mockito.any() - return uninitialized() - } - - @Suppress("UNCHECKED_CAST") - fun uninitialized(): T = null as T -} \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt index c939fbff4..684e092b0 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt @@ -1,6 +1,5 @@ package co.nilin.opex.accountant.core.service -import co.nilin.opex.accountant.core.api.OrderManager import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.PairConfig import co.nilin.opex.accountant.core.model.PairFeeConfig @@ -9,168 +8,147 @@ import co.nilin.opex.matching.engine.core.eventh.events.SubmitOrderEvent import co.nilin.opex.matching.engine.core.model.MatchConstraint import co.nilin.opex.matching.engine.core.model.OrderDirection import co.nilin.opex.matching.engine.core.model.OrderType +import io.mockk.coEvery +import io.mockk.mockk import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Assertions.assertEquals +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import org.mockito.ArgumentMatchers.anyString -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.MockitoAnnotations +import org.mockito.kotlin.any import java.math.BigDecimal import java.time.LocalDateTime internal class OrderManagerImplTest { - @Mock - lateinit var financialActionPersister: FinancialActionPersister + private val financialActionPersister = mockk() + private val financialActionLoader = mockk() + private val orderPersister = mockk() + private val tempEventPersister = mockk() + private val pairConfigLoader = mockk() + private val richOrderPublisher = mockk() + private val orderManager = OrderManagerImpl( + pairConfigLoader, + financialActionPersister, + financialActionLoader, + orderPersister, + tempEventPersister, + richOrderPublisher + ) - @Mock - lateinit var financialActionLoader: FinancialActionLoader - - @Mock - lateinit var orderPersister: OrderPersister - - @Mock - lateinit var tempEventPersister: TempEventPersister - - @Mock - lateinit var pairConfigLoader: PairConfigLoader + init { + coEvery { tempEventPersister.loadTempEvents(any()) } returns emptyList() + coEvery { orderPersister.save(any()) } returns any() + } - @Mock - lateinit var richOrderPublisher: RichOrderPublisher + @Test + fun givenAskOrder_whenHandleRequestOrder_thenFAMatch(): Unit = runBlocking { + //given + val pair = co.nilin.opex.matching.engine.core.model.Pair("ETH", "BTC") + val pairConfig = PairConfig( + pair.toString(), + pair.leftSideName, + pair.rightSideName, + BigDecimal.valueOf(1.0), + BigDecimal.valueOf(0.001) + ) + val submitOrderEvent = SubmitOrderEvent( + "ouid", "uuid", null, pair, 30, 60, 0, OrderDirection.ASK, MatchConstraint.GTC, OrderType.LIMIT_ORDER + ) - private val orderManager: OrderManager + coEvery { + pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "") + } returns PairFeeConfig( + pairConfig, + submitOrderEvent.direction.toString(), + "", + BigDecimal.valueOf(0.1), + BigDecimal.valueOf(0.12) + ) - init { - MockitoAnnotations.openMocks(this) - orderManager = OrderManagerImpl( - pairConfigLoader, - financialActionPersister, - financialActionLoader, - orderPersister, - tempEventPersister, - richOrderPublisher + coEvery { financialActionPersister.persist(any()) } returnsArgument (0) + + //when + val financialActions = orderManager.handleRequestOrder(submitOrderEvent) + + //then + assertThat(financialActions.size).isEqualTo(1) + val expectedFinancialAction = FinancialAction( + null, + SubmitOrderEvent::class.simpleName!!, + submitOrderEvent.ouid, + pair.leftSideName, + pairConfig.leftSideFraction.multiply(submitOrderEvent.quantity.toBigDecimal()), + submitOrderEvent.uuid, + "main", + submitOrderEvent.uuid, + "exchange", + LocalDateTime.now() ) - runBlocking { - Mockito.`when`(tempEventPersister.loadTempEvents(anyString())).thenReturn(emptyList()) - } - } - @Test - fun givenAskOrder_whenHandleRequestOrder_thenFAMatch() { - runBlocking { - //given - val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") - val pairConfig = PairConfig( - pair.toString(), - pair.leftSideName, - pair.rightSideName, - BigDecimal.valueOf(1.0), - BigDecimal.valueOf(0.001) - ) - val submitOrderEvent = SubmitOrderEvent( - "ouid", "uuid", null, pair, 30, 60, 0, OrderDirection.ASK, MatchConstraint.GTC, OrderType.LIMIT_ORDER - ) - Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) - .thenReturn( - PairFeeConfig( - pairConfig, - submitOrderEvent.direction.toString(), - "", - BigDecimal.valueOf(0.1), - BigDecimal.valueOf(0.12) - ) - ) - Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) - .then { - return@then it.getArgument>(0) - } - - //when - val financialActions = orderManager.handleRequestOrder(submitOrderEvent) - - //then - assertEquals(1, financialActions.size) - val expectedFinancialAction = FinancialAction( - null, - SubmitOrderEvent::class.simpleName!!, - submitOrderEvent.ouid, - pair.leftSideName, - pairConfig.leftSideFraction.multiply(submitOrderEvent.quantity.toBigDecimal()), - submitOrderEvent.uuid, - "main", - submitOrderEvent.uuid, - "exchange", - LocalDateTime.now() - ) - assertEquals(expectedFinancialAction.eventType, financialActions[0].eventType) - assertEquals(expectedFinancialAction.symbol, financialActions[0].symbol) - assertEquals(expectedFinancialAction.amount, financialActions[0].amount) - assertEquals(expectedFinancialAction.sender, financialActions[0].sender) - assertEquals(expectedFinancialAction.senderWalletType, financialActions[0].senderWalletType) - assertEquals(expectedFinancialAction.receiver, financialActions[0].receiver) - assertEquals(expectedFinancialAction.receiverWalletType, financialActions[0].receiverWalletType) + with(expectedFinancialAction) { + assertThat(eventType).isEqualTo(financialActions[0].eventType) + assertThat(symbol).isEqualTo(financialActions[0].symbol) + assertThat(amount).isEqualTo(financialActions[0].amount) + assertThat(sender).isEqualTo(financialActions[0].sender) + assertThat(senderWalletType).isEqualTo(financialActions[0].senderWalletType) + assertThat(receiver).isEqualTo(financialActions[0].receiver) + assertThat(receiverWalletType).isEqualTo(financialActions[0].receiverWalletType) } } @Test - fun givenBidOrder_whenHandleRequestOrder_thenFAMatch() { - runBlocking { - //given - val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") - val pairConfig = PairConfig( - pair.toString(), - pair.leftSideName, - pair.rightSideName, - BigDecimal.valueOf(1.0), - BigDecimal.valueOf(0.001) - ) - val submitOrderEvent = SubmitOrderEvent( - "ouid", "uuid", null, pair, 35, 14, 0, OrderDirection.BID, MatchConstraint.GTC, OrderType.LIMIT_ORDER - ) - Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) - .thenReturn( - PairFeeConfig( - pairConfig, - submitOrderEvent.direction.toString(), - "", - BigDecimal.valueOf(0.08), - BigDecimal.valueOf(0.1) - ) - ) - Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) - .then { - return@then it.getArgument>(0) - } - - //when - val financialActions = runBlocking { - orderManager.handleRequestOrder(submitOrderEvent) - } - - //then - assertEquals(1, financialActions.size) - val expectedFinancialAction = FinancialAction( - null, - SubmitOrderEvent::class.simpleName!!, - submitOrderEvent.ouid, - pair.rightSideName, - pairConfig.leftSideFraction.multiply(submitOrderEvent.quantity.toBigDecimal()) - .multiply(pairConfig.rightSideFraction) - .multiply(submitOrderEvent.price.toBigDecimal()), - submitOrderEvent.uuid, - "main", - submitOrderEvent.uuid, - "exchange", - LocalDateTime.now() - ) - assertEquals(expectedFinancialAction.eventType, financialActions[0].eventType) - assertEquals(expectedFinancialAction.symbol, financialActions[0].symbol) - assertEquals(expectedFinancialAction.amount, financialActions[0].amount) - assertEquals(expectedFinancialAction.sender, financialActions[0].sender) - assertEquals(expectedFinancialAction.senderWalletType, financialActions[0].senderWalletType) - assertEquals(expectedFinancialAction.receiver, financialActions[0].receiver) - assertEquals(expectedFinancialAction.receiverWalletType, financialActions[0].receiverWalletType) + fun givenBidOrder_whenHandleRequestOrder_thenFAMatch(): Unit = runBlocking { + //given + val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") + val pairConfig = PairConfig( + pair.toString(), + pair.leftSideName, + pair.rightSideName, + BigDecimal.valueOf(1.0), + BigDecimal.valueOf(0.001) + ) + val submitOrderEvent = SubmitOrderEvent( + "ouid", "uuid", null, pair, 35, 14, 0, OrderDirection.BID, MatchConstraint.GTC, OrderType.LIMIT_ORDER + ) + + coEvery { + pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "") + } returns PairFeeConfig( + pairConfig, + submitOrderEvent.direction.toString(), + "", + BigDecimal.valueOf(0.08), + BigDecimal.valueOf(0.1) + ) + + coEvery { financialActionPersister.persist(any()) } returnsArgument (0) + + //when + val financialActions = orderManager.handleRequestOrder(submitOrderEvent) + + //then + assertThat(financialActions.size).isEqualTo(1) + val expectedFinancialAction = FinancialAction( + null, + SubmitOrderEvent::class.simpleName!!, + submitOrderEvent.ouid, + pair.rightSideName, + pairConfig.leftSideFraction.multiply(submitOrderEvent.quantity.toBigDecimal()) + .multiply(pairConfig.rightSideFraction) + .multiply(submitOrderEvent.price.toBigDecimal()), + submitOrderEvent.uuid, + "main", + submitOrderEvent.uuid, + "exchange", + LocalDateTime.now() + ) + with(expectedFinancialAction) { + assertThat(eventType).isEqualTo(financialActions[0].eventType) + assertThat(symbol).isEqualTo(financialActions[0].symbol) + assertThat(amount).isEqualTo(financialActions[0].amount) + assertThat(sender).isEqualTo(financialActions[0].sender) + assertThat(senderWalletType).isEqualTo(financialActions[0].senderWalletType) + assertThat(receiver).isEqualTo(financialActions[0].receiver) + assertThat(receiverWalletType).isEqualTo(financialActions[0].receiverWalletType) } } diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt index add9d374b..7febf327e 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt @@ -1,8 +1,5 @@ package co.nilin.opex.accountant.core.service -import co.nilin.opex.accountant.core.api.OrderManager -import co.nilin.opex.accountant.core.api.TradeManager -import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.accountant.core.model.PairConfig import co.nilin.opex.accountant.core.model.PairFeeConfig @@ -13,175 +10,145 @@ import co.nilin.opex.matching.engine.core.model.MatchConstraint import co.nilin.opex.matching.engine.core.model.OrderDirection import co.nilin.opex.matching.engine.core.model.OrderType import co.nilin.opex.matching.engine.core.model.Pair +import io.mockk.coEvery +import io.mockk.mockk import kotlinx.coroutines.runBlocking -import org.junit.jupiter.api.Assertions +import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import org.mockito.ArgumentMatchers -import org.mockito.Mock -import org.mockito.Mockito -import org.mockito.MockitoAnnotations import java.math.BigDecimal internal class TradeManagerImplTest { - @Mock - lateinit var financialActionPersister: FinancialActionPersister - - @Mock - lateinit var financeActionLoader: FinancialActionLoader - - @Mock - lateinit var orderPersister: OrderPersister - - @Mock - lateinit var pairConfigLoader: PairConfigLoader - - @Mock - lateinit var tempEventPersister: TempEventPersister - - @Mock - lateinit var tempEventRepublisher: TempEventRepublisher - - @Mock - lateinit var richOrderPublisher: RichOrderPublisher - - @Mock - lateinit var richTradePublisher: RichTradePublisher - - private val orderManager: OrderManager - private val tradeManager: TradeManager + private val financialActionPersister = mockk() + private val financeActionLoader = mockk() + private val orderPersister = mockk() + private val pairConfigLoader = mockk() + private val tempEventPersister = mockk() + private val richOrderPublisher = mockk() + private val richTradePublisher = mockk() + + private val orderManager = OrderManagerImpl( + pairConfigLoader, + financialActionPersister, + financeActionLoader, + orderPersister, + tempEventPersister, + richOrderPublisher + ) + private val tradeManager = TradeManagerImpl( + financialActionPersister, + financeActionLoader, + orderPersister, + tempEventPersister, + richTradePublisher, + richOrderPublisher, + FeeCalculatorImpl("0x0") + ) init { - MockitoAnnotations.openMocks(this) - - orderManager = OrderManagerImpl( - pairConfigLoader, - financialActionPersister, - financeActionLoader, - orderPersister, - tempEventPersister, - richOrderPublisher - ) - - tradeManager = TradeManagerImpl( - financialActionPersister, - financeActionLoader, - orderPersister, - tempEventPersister, - richTradePublisher, - richOrderPublisher, - FeeCalculatorImpl("0x0") - ) - - runBlocking { - Mockito.`when`(tempEventPersister.loadTempEvents(ArgumentMatchers.anyString())).thenReturn(emptyList()) - } + coEvery { tempEventPersister.loadTempEvents(any()) } returns emptyList() + coEvery { orderPersister.save(any()) } returnsArgument(0) + coEvery { financeActionLoader.findLast(any(),any()) } returns null + coEvery { richOrderPublisher.publish(any()) } returns Unit + coEvery { richTradePublisher.publish(any()) } returns Unit } @Test - fun givenSellOrder_WhenMatchBuyOrderCome_thenFAMatched() { - runBlocking { - //given - val pair = Pair("eth", "btc") - val pairConfig = PairConfig( - pair.toString(), - pair.leftSideName, - pair.rightSideName, - BigDecimal.valueOf(1.0), - BigDecimal.valueOf(0.01) - ) - val makerSubmitOrderEvent = SubmitOrderEvent( - "mouid", - "muuid", - null, - pair, - 60000, - 1, - 0, - OrderDirection.ASK, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER - ) - prepareOrder(pair, pairConfig, makerSubmitOrderEvent, BigDecimal.valueOf(0.1), BigDecimal.valueOf(0.12)) + fun givenSellOrder_WhenMatchBuyOrderCome_thenFAMatched(): Unit = runBlocking { + //given + val pair = Pair("eth", "btc") + val pairConfig = PairConfig( + pair.toString(), + pair.leftSideName, + pair.rightSideName, + BigDecimal.valueOf(1.0), + BigDecimal.valueOf(0.01) + ) + val makerSubmitOrderEvent = SubmitOrderEvent( + "mouid", + "muuid", + null, + pair, + 60000, + 1, + 0, + OrderDirection.ASK, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER + ) + prepareOrder(pair, pairConfig, makerSubmitOrderEvent, BigDecimal.valueOf(0.1), BigDecimal.valueOf(0.12)) - val takerSubmitOrderEvent = SubmitOrderEvent( - "touid", - "tuuid", - null, - pair, - 70000, - 1, - 0, - OrderDirection.BID, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER - ) + val takerSubmitOrderEvent = SubmitOrderEvent( + "touid", + "tuuid", + null, + pair, + 70000, + 1, + 0, + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER + ) - prepareOrder(pair, pairConfig, takerSubmitOrderEvent, BigDecimal.valueOf(0.08), BigDecimal.valueOf(0.1)) + prepareOrder(pair, pairConfig, takerSubmitOrderEvent, BigDecimal.valueOf(0.08), BigDecimal.valueOf(0.1)) - val tradeEvent = makeTradeEvent(pair, takerSubmitOrderEvent, makerSubmitOrderEvent) - //when - val tradeFinancialActions = tradeManager.handleTrade(tradeEvent) + val tradeEvent = makeTradeEvent(pair, takerSubmitOrderEvent, makerSubmitOrderEvent) + //when + val tradeFinancialActions = tradeManager.handleTrade(tradeEvent) - Assertions.assertEquals(4, tradeFinancialActions.size) - Assertions.assertEquals( - (makerSubmitOrderEvent.price.toBigDecimal() * pairConfig.rightSideFraction).stripTrailingZeros(), - tradeFinancialActions[0].amount.stripTrailingZeros() - ) - } + assertThat(tradeFinancialActions.size).isEqualTo(4) + assertThat((makerSubmitOrderEvent.price.toBigDecimal() * pairConfig.rightSideFraction).stripTrailingZeros()) + .isEqualTo(tradeFinancialActions[0].amount.stripTrailingZeros()) } @Test - fun givenBuyOrder_WhenMatchSellOrderCome_thenFAMatched() { - runBlocking { - //given - val pair = Pair("eth", "btc") - val pairConfig = PairConfig( - pair.toString(), - pair.leftSideName, - pair.rightSideName, - BigDecimal.valueOf(1.0), - BigDecimal.valueOf(0.001) - ) - val makerSubmitOrderEvent = SubmitOrderEvent( - "mouid", - "muuid", - null, - pair, - 70000, - 1, - 0, - OrderDirection.BID, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER - ) - prepareOrder(pair, pairConfig, makerSubmitOrderEvent, BigDecimal.valueOf(0.1), BigDecimal.valueOf(0.12)) + fun givenBuyOrder_WhenMatchSellOrderCome_thenFAMatched(): Unit = runBlocking { + //given + val pair = Pair("eth", "btc") + val pairConfig = PairConfig( + pair.toString(), + pair.leftSideName, + pair.rightSideName, + BigDecimal.valueOf(1.0), + BigDecimal.valueOf(0.001) + ) + val makerSubmitOrderEvent = SubmitOrderEvent( + "mouid", + "muuid", + null, + pair, + 70000, + 1, + 0, + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER + ) + prepareOrder(pair, pairConfig, makerSubmitOrderEvent, BigDecimal.valueOf(0.1), BigDecimal.valueOf(0.12)) - val takerSubmitOrderEvent = SubmitOrderEvent( - "touid", - "tuuid", - null, - pair, - 60000, - 1, - 0, - OrderDirection.ASK, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER - ) + val takerSubmitOrderEvent = SubmitOrderEvent( + "touid", + "tuuid", + null, + pair, + 60000, + 1, + 0, + OrderDirection.ASK, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER + ) - prepareOrder(pair, pairConfig, takerSubmitOrderEvent, BigDecimal.valueOf(0.08), BigDecimal.valueOf(0.1)) + prepareOrder(pair, pairConfig, takerSubmitOrderEvent, BigDecimal.valueOf(0.08), BigDecimal.valueOf(0.1)) - val tradeEvent = makeTradeEvent(pair, takerSubmitOrderEvent, makerSubmitOrderEvent) - //when - val tradeFinancialActions = tradeManager.handleTrade(tradeEvent) + val tradeEvent = makeTradeEvent(pair, takerSubmitOrderEvent, makerSubmitOrderEvent) + //when + val tradeFinancialActions = tradeManager.handleTrade(tradeEvent) - Assertions.assertEquals(4, tradeFinancialActions.size) - Assertions.assertEquals( - (makerSubmitOrderEvent.price.toBigDecimal() * pairConfig.rightSideFraction).stripTrailingZeros(), - tradeFinancialActions[1].amount.stripTrailingZeros() - ) - } + assertThat(tradeFinancialActions.size).isEqualTo(4) + assertThat((makerSubmitOrderEvent.price.toBigDecimal() * pairConfig.rightSideFraction).stripTrailingZeros()) + .isEqualTo(tradeFinancialActions[1].amount.stripTrailingZeros()) } private fun makeTradeEvent( @@ -208,60 +175,53 @@ internal class TradeManagerImplTest { ) } - private fun prepareOrder( + private suspend fun prepareOrder( pair: Pair, pairConfig: PairConfig, submitOrderEvent: SubmitOrderEvent, makerFee: BigDecimal, takerFee: BigDecimal ) { - runBlocking { - Mockito.`when`(pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "")) - .thenReturn( - PairFeeConfig( - pairConfig, - submitOrderEvent.direction.toString(), - "", - makerFee, - takerFee - ) - ) - Mockito.`when`(financialActionPersister.persist(MockitoHelper.anyObject())) - .then { - return@then it.getArgument>(0) - } - - val financialActions = orderManager.handleRequestOrder(submitOrderEvent) - - val orderPairFeeConfig = - pairConfigLoader.load(submitOrderEvent.pair.toString(), submitOrderEvent.direction, "") - val orderMakerFee = orderPairFeeConfig.makerFee * BigDecimal.ONE //user level formula - val orderTakerFee = orderPairFeeConfig.takerFee * BigDecimal.ONE //user level formula - Mockito.`when`(orderPersister.load(submitOrderEvent.ouid)).thenReturn( - Order( - submitOrderEvent.pair.toString(), - submitOrderEvent.ouid, - null, - orderMakerFee, - orderTakerFee, - orderPairFeeConfig.pairConfig.leftSideFraction, - orderPairFeeConfig.pairConfig.rightSideFraction, - submitOrderEvent.uuid, - "", - submitOrderEvent.direction, - submitOrderEvent.matchConstraint, - submitOrderEvent.orderType, - submitOrderEvent.price, - submitOrderEvent.quantity, - submitOrderEvent.quantity - submitOrderEvent.remainedQuantity, - submitOrderEvent.price.toBigDecimal(), - submitOrderEvent.quantity.toBigDecimal(), - (submitOrderEvent.quantity - submitOrderEvent.remainedQuantity).toBigDecimal(), - financialActions[0].amount, - financialActions[0].amount, - 0 - ) - ) - } + coEvery { + pairConfigLoader.load(pair.toString(), submitOrderEvent.direction, "") + } returns PairFeeConfig( + pairConfig, + submitOrderEvent.direction.toString(), + "", + makerFee, + takerFee + ) + coEvery { financialActionPersister.persist(any()) } returnsArgument (0) + + val financialActions = orderManager.handleRequestOrder(submitOrderEvent) + + val orderPairFeeConfig = + pairConfigLoader.load(submitOrderEvent.pair.toString(), submitOrderEvent.direction, "") + val orderMakerFee = orderPairFeeConfig.makerFee * BigDecimal.ONE //user level formula + val orderTakerFee = orderPairFeeConfig.takerFee * BigDecimal.ONE //user level formula + + coEvery { orderPersister.load(submitOrderEvent.ouid) } returns Order( + submitOrderEvent.pair.toString(), + submitOrderEvent.ouid, + null, + orderMakerFee, + orderTakerFee, + orderPairFeeConfig.pairConfig.leftSideFraction, + orderPairFeeConfig.pairConfig.rightSideFraction, + submitOrderEvent.uuid, + "", + submitOrderEvent.direction, + submitOrderEvent.matchConstraint, + submitOrderEvent.orderType, + submitOrderEvent.price, + submitOrderEvent.quantity, + submitOrderEvent.quantity - submitOrderEvent.remainedQuantity, + submitOrderEvent.price.toBigDecimal(), + submitOrderEvent.quantity.toBigDecimal(), + (submitOrderEvent.quantity - submitOrderEvent.remainedQuantity).toBigDecimal(), + financialActions[0].amount, + financialActions[0].amount, + 0 + ) } } \ No newline at end of file From cf9e1c42de8e88a2b73d562181bb5456acb631ac Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 25 May 2022 17:39:44 +0430 Subject: [PATCH 05/18] Added more test for order and trade manager --- .../core/service/OrderManagerImplTest.kt | 176 +++++++++++++++++- .../core/service/TradeManagerImplTest.kt | 1 + 2 files changed, 170 insertions(+), 7 deletions(-) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt index 684e092b0..1ff6165a3 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt @@ -1,14 +1,23 @@ package co.nilin.opex.accountant.core.service +import co.nilin.opex.accountant.core.inout.OrderStatus import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.accountant.core.model.PairConfig import co.nilin.opex.accountant.core.model.PairFeeConfig import co.nilin.opex.accountant.core.spi.* +import co.nilin.opex.matching.engine.core.eventh.events.CancelOrderEvent +import co.nilin.opex.matching.engine.core.eventh.events.CreateOrderEvent +import co.nilin.opex.matching.engine.core.eventh.events.RejectOrderEvent import co.nilin.opex.matching.engine.core.eventh.events.SubmitOrderEvent +import co.nilin.opex.matching.engine.core.inout.RejectReason +import co.nilin.opex.matching.engine.core.inout.RequestedOperation import co.nilin.opex.matching.engine.core.model.MatchConstraint import co.nilin.opex.matching.engine.core.model.OrderDirection import co.nilin.opex.matching.engine.core.model.OrderType +import co.nilin.opex.matching.engine.core.model.Pair import io.mockk.coEvery +import io.mockk.coVerify import io.mockk.mockk import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat @@ -25,6 +34,7 @@ internal class OrderManagerImplTest { private val tempEventPersister = mockk() private val pairConfigLoader = mockk() private val richOrderPublisher = mockk() + private val orderManager = OrderManagerImpl( pairConfigLoader, financialActionPersister, @@ -34,15 +44,43 @@ internal class OrderManagerImplTest { richOrderPublisher ) + private val order = Order( + "BTC_USDT", + "order_ouid", + null, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.000001.toBigDecimal(), + 0.01.toBigDecimal(), + "user_1", + "*", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 100000, + 1000, + 0, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + 100000.0.toBigDecimal(), + OrderStatus.NEW.code + ) + init { coEvery { tempEventPersister.loadTempEvents(any()) } returns emptyList() - coEvery { orderPersister.save(any()) } returns any() + coEvery { orderPersister.save(any()) } returnsArgument (0) + coEvery { richOrderPublisher.publish(any()) } returnsArgument (0) + coEvery { tempEventPersister.saveTempEvent(any(), any()) } returns any() + coEvery { financialActionLoader.findLast(any(), any()) } returns null + coEvery { financialActionPersister.persist(any()) } returnsArgument (0) } @Test fun givenAskOrder_whenHandleRequestOrder_thenFAMatch(): Unit = runBlocking { //given - val pair = co.nilin.opex.matching.engine.core.model.Pair("ETH", "BTC") + val pair = Pair("ETH", "BTC") val pairConfig = PairConfig( pair.toString(), pair.leftSideName, @@ -98,7 +136,7 @@ internal class OrderManagerImplTest { @Test fun givenBidOrder_whenHandleRequestOrder_thenFAMatch(): Unit = runBlocking { //given - val pair = co.nilin.opex.matching.engine.core.model.Pair("eth", "btc") + val pair = Pair("eth", "btc") val pairConfig = PairConfig( pair.toString(), pair.leftSideName, @@ -153,20 +191,144 @@ internal class OrderManagerImplTest { } @Test - fun handleNewOrder() { + fun givenNewOrderEventReceived_whenUpdatingOrder_matchingEngineIdMatch(): Unit = runBlocking { + val orderEvent = CreateOrderEvent( + "order_ouid", + "user_1", + 55, + Pair("BTC", "USDT"), + 100000, + 1000, + 0, + OrderDirection.BID + ) + + coEvery { orderPersister.load(any()) } returns order + + val fa = orderManager.handleNewOrder(orderEvent) + + assertThat(fa.size).isEqualTo(0) + assertThat(order.matchingEngineId).isEqualTo(55) + coVerify(exactly = 1) { richOrderPublisher.publish(any()) } } @Test - fun handleUpdateOrder() { + fun givenNewOrderEventReceived_whenLocalOrderNull_saveTempEvent(): Unit = runBlocking { + val orderEvent = CreateOrderEvent( + "order_ouid", + "user_1", + 55, + Pair("BTC", "USDT"), + 100000, + 1000, + 0, + OrderDirection.BID + ) + + coEvery { orderPersister.load(any()) } returns null + + val fa = orderManager.handleNewOrder(orderEvent) + + assertThat(fa.size).isEqualTo(0) + coVerify(exactly = 1) { tempEventPersister.saveTempEvent(any(), any()) } + } + + @Test + fun givenRejectOrderReceived_whenLocalOrderNull_saveTempEvent(): Unit = runBlocking { + val orderEvent = RejectOrderEvent( + "ouid", + "user_1", + 56, + Pair("BTC", "USDT"), + RequestedOperation.CANCEL_ORDER, + RejectReason.ORDER_NOT_FOUND + ) + + coEvery { orderPersister.load(any()) } returns null + + val fa = orderManager.handleRejectOrder(orderEvent) + + assertThat(fa.size).isEqualTo(0) + coVerify(exactly = 1) { tempEventPersister.saveTempEvent(any(), any()) } } @Test - fun handleRejectOrder() { + fun givenRejectOrderReceived_whenLocalFound_publishRichOrderUpdate(): Unit = runBlocking { + val orderEvent = RejectOrderEvent( + "ouid", + "user_1", + 56, + Pair("BTC", "USDT"), + 100000, + 1000, + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + RequestedOperation.CANCEL_ORDER, + RejectReason.ORDER_NOT_FOUND, + ) + coEvery { orderPersister.load(any()) } returns order + + val fa = orderManager.handleRejectOrder(orderEvent)[0] + + assertThat(fa.amount).isEqualTo(order.remainedTransferAmount) + assertThat(fa.symbol).isEqualTo(orderEvent.pair.rightSideName) + assertThat(order.status).isEqualTo(OrderStatus.REJECTED.code) + + coVerify(exactly = 1) { richOrderPublisher.publish(any()) } + coVerify(exactly = 1) { orderPersister.save(any()) } + } + + @Test + fun givenCancelOrderReceived_whenLocalOrderNull_saveTempEvent(): Unit = runBlocking { + val orderEvent = CancelOrderEvent( + "order_ouid", + "user_id", + 88, + Pair("BTC", "USDT"), + 100000, + 1000, + 500, + OrderDirection.BID + ) + + coEvery { orderPersister.load(any()) } returns null + + val fa = orderManager.handleCancelOrder(orderEvent) + + assertThat(fa.size).isEqualTo(0) + coVerify(exactly = 1) { tempEventPersister.saveTempEvent(any(), any()) } + } + + @Test + fun givenCancelOrderReceived_whenLocalFound_publishRichOrderUpdate(): Unit = runBlocking { + val orderEvent = CancelOrderEvent( + "order_ouid", + "user_id", + 88, + Pair("BTC", "USDT"), + 100000, + 1000, + 500, + OrderDirection.BID + ) + coEvery { orderPersister.load(any()) } returns order + + val fa = orderManager.handleCancelOrder(orderEvent)[0] + + assertThat(fa.amount).isEqualTo(order.remainedTransferAmount) + assertThat(fa.symbol).isEqualTo(orderEvent.pair.rightSideName) + assertThat(order.status).isEqualTo(OrderStatus.CANCELED.code) + + coVerify(exactly = 1) { richOrderPublisher.publish(any()) } + coVerify(exactly = 1) { orderPersister.save(any()) } } + //TODO @Test - fun handleCancelOrder() { + fun handleUpdateOrder() { } + } diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt index 7febf327e..34de594b0 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/TradeManagerImplTest.kt @@ -35,6 +35,7 @@ internal class TradeManagerImplTest { tempEventPersister, richOrderPublisher ) + private val tradeManager = TradeManagerImpl( financialActionPersister, financeActionLoader, From fcf870749274b810121189387996671d0102feb4 Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 25 May 2022 18:26:41 +0430 Subject: [PATCH 06/18] Refactor --- .../impl/FinancialActionLoaderImpl.kt | 13 +++---- .../postgres/impl/PairConfigLoaderImpl.kt | 16 +++++---- .../postgres/impl/TempEventPersisterImpl.kt | 34 ++++++++++--------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt index cc0e9cd63..79abb341c 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt @@ -21,17 +21,15 @@ class FinancialActionLoaderImpl(val financialActionRepository: FinancialActionRe return financialActionRepository.findByStatus( FinancialActionStatus.CREATED.name, PageRequest.of(offset.toInt(), size.toInt(), Sort.by(Sort.Direction.ASC, "createDate")) - ).map { fim -> - loadFinancialAction(fim.id)!! - }.toList() + ).map { loadFinancialAction(it.id)!! } + .toList() } override suspend fun findLast(uuid: String, ouid: String): FinancialAction? { return financialActionRepository.findByOuidAndUuid( ouid, uuid, PageRequest.of(0, 1, Sort.by(Sort.Direction.DESC, "createDate")) - ).map { fim -> - loadFinancialAction(fim.id) - }.firstOrNull() + ).map { loadFinancialAction(it.id) } + .firstOrNull() } private suspend fun loadFinancialAction(id: Long?): FinancialAction? { @@ -61,7 +59,6 @@ class FinancialActionLoaderImpl(val financialActionRepository: FinancialActionRe symbol, eventType, FinancialActionStatus.CREATED - ).awaitFirstOrElse { BigDecimal.ZERO } - .toLong() + ).awaitFirstOrElse { BigDecimal.ZERO }.toLong() } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/PairConfigLoaderImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/PairConfigLoaderImpl.kt index 9474c5559..89443d0e0 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/PairConfigLoaderImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/PairConfigLoaderImpl.kt @@ -39,11 +39,11 @@ class PairConfigLoaderImpl( } override suspend fun load(pair: String, direction: OrderDirection, userLevel: String): PairFeeConfig { - val pairConfig = pairConfigRepository - .findById(pair).awaitFirstOrElse { - val error = OpexError.InvalidPair - throw OpexException(error, String.format(error.message!!, pair)) - } + val pairConfig = pairConfigRepository.findById(pair).awaitFirstOrElse { + val error = OpexError.InvalidPair + throw OpexException(error, String.format(error.message!!, pair)) + } + var pairFeeConfig: PairFeeConfigModel? if (userLevel.isEmpty()) { pairFeeConfig = pairFeeConfigRepository @@ -73,7 +73,11 @@ class PairConfigLoaderImpl( pairConfig.rightSideWalletSymbol, pairConfig.leftSideFraction, pairConfig.rightSideFraction - ), pairFeeConfig!!.direction, pairFeeConfig.userLevel, pairFeeConfig.makerFee, pairFeeConfig.takerFee + ), + pairFeeConfig!!.direction, + pairFeeConfig.userLevel, + pairFeeConfig.makerFee, + pairFeeConfig.takerFee ) } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt index 2dbd04b47..d844017d3 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt @@ -21,8 +21,11 @@ class TempEventPersisterImpl(val tempEventRepository: TempEventRepository) : Tem override suspend fun saveTempEvent(ouid: String, event: CoreEvent) { tempEventRepository.save( TempEventModel( - null, ouid, event.javaClass.name, - Gson().toJson(event), LocalDateTime.now() + null, + ouid, + event.javaClass.name, + Gson().toJson(event), + LocalDateTime.now() ) ).awaitSingle() } @@ -30,9 +33,7 @@ class TempEventPersisterImpl(val tempEventRepository: TempEventRepository) : Tem override suspend fun loadTempEvents(ouid: String): List { return tempEventRepository .findByOuid(ouid) - .map { value: TempEventModel -> - Gson().fromJson(value.eventBody, Class.forName(value.eventType)) as CoreEvent - } + .map { Gson().fromJson(it.eventBody, Class.forName(it.eventType)) as CoreEvent } .toList() } @@ -41,25 +42,26 @@ class TempEventPersisterImpl(val tempEventRepository: TempEventRepository) : Tem } override suspend fun removeTempEvents(tempEvents: List) { - tempEventRepository.deleteAll(tempEvents.map { event -> + tempEventRepository.deleteAll(tempEvents.map { TempEventModel( - event.id, event.ouid, event.eventBody.javaClass.name, - "", event.eventDate + it.id, + it.ouid, + it.eventBody.javaClass.name, + "", + it.eventDate ) }).awaitFirstOrNull() } - override suspend fun fetchTempEvents( - offset: Long, - size: Long - ): List { + override suspend fun fetchTempEvents(offset: Long, size: Long): List { return tempEventRepository .findAll(PageRequest.of(offset.toInt(), size.toInt(), Sort.by(Sort.Direction.ASC, "eventDate"))) - .map { value: TempEventModel -> + .map { TempEvent( - value.id!!, value.ouid, Gson().fromJson(value.eventBody, Class.forName(value.eventType)) - as - CoreEvent, value.eventDate + it.id!!, + it.ouid, + Gson().fromJson(it.eventBody, Class.forName(it.eventType)) as CoreEvent, + it.eventDate ) } .toList() From 11552b872cb2faadcf00abd18d15cdfd274c312a Mon Sep 17 00:00:00 2001 From: Peyman Date: Sat, 28 May 2022 15:54:27 +0430 Subject: [PATCH 07/18] Refactor kafka consumers --- .../opex/accountant/app/config/AppConfig.kt | 8 +-- .../app/listener/AccountantEventListener.kt | 14 ++--- .../listener/AccountantTempEventListener.kt | 18 +++---- .../app/listener/AccountantTradeListener.kt | 5 +- .../accountant/app/listener/OrderListener.kt | 24 ++++----- .../accountant-eventlistener-kafka/pom.xml | 4 ++ .../kafka/listener/consumer/EventConsumer.kt | 31 +++++++++++ .../listener/consumer/EventKafkaListener.kt | 23 +------- .../listener/consumer/OrderKafkaListener.kt | 23 +------- .../consumer/TempEventKafkaListener.kt | 25 +-------- .../listener/consumer/TradeKafkaListener.kt | 23 +------- .../ports/kafka/listener/spi/EventListener.kt | 5 +- .../ports/kafka/listener/spi/Listener.kt | 9 ++++ .../spi/OrderSubmitRequestListener.kt | 5 +- .../kafka/listener/spi/TempEventListener.kt | 5 +- .../ports/kafka/listener/spi/TradeListener.kt | 5 +- .../ports/kafka/listener/ConsumerTest.kt | 52 +++++++++++++++++++ .../kafka/listener/consumer/ConsumerObject.kt | 3 ++ .../kafka/listener/consumer/ListenerObject.kt | 14 +++++ 19 files changed, 156 insertions(+), 140 deletions(-) create mode 100644 accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventConsumer.kt create mode 100644 accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/Listener.kt create mode 100644 accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/ConsumerTest.kt create mode 100644 accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ConsumerObject.kt create mode 100644 accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt index b944ed180..e4fe77f13 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/config/AppConfig.kt @@ -104,7 +104,7 @@ class AppConfig { @Autowired fun configureOrderListener(orderKafkaListener: OrderKafkaListener, orderListener: OrderListener) { - orderKafkaListener.addOrderListener(orderListener) + orderKafkaListener.addListener(orderListener) } @Autowired @@ -112,7 +112,7 @@ class AppConfig { tradeKafkaListener: TradeKafkaListener, accountantTradeListener: AccountantTradeListener ) { - tradeKafkaListener.addTradeListener(accountantTradeListener) + tradeKafkaListener.addListener(accountantTradeListener) } @Autowired @@ -120,7 +120,7 @@ class AppConfig { eventKafkaListener: EventKafkaListener, accountantEventListener: AccountantEventListener ) { - eventKafkaListener.addEventListener(accountantEventListener) + eventKafkaListener.addListener(accountantEventListener) } @Autowired @@ -128,7 +128,7 @@ class AppConfig { tempEventKafkaListener: TempEventKafkaListener, accountantTempEventListener: AccountantTempEventListener ) { - tempEventKafkaListener.addEventListener(accountantTempEventListener) + tempEventKafkaListener.addListener(accountantTempEventListener) } } \ No newline at end of file diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantEventListener.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantEventListener.kt index e1de3e767..80dd26f72 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantEventListener.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantEventListener.kt @@ -11,15 +11,15 @@ class AccountantEventListener(private val orderManager: OrderManager) : EventLis return "EventListener" } - override fun onEvent(coreEvent: CoreEvent, partition: Int, offset: Long, timestamp: Long) { + override fun onEvent(event: CoreEvent, partition: Int, offset: Long, timestamp: Long) { runBlocking { - when (coreEvent) { - is CreateOrderEvent -> orderManager.handleNewOrder(coreEvent) - is RejectOrderEvent -> orderManager.handleRejectOrder(coreEvent) - is UpdatedOrderEvent -> orderManager.handleUpdateOrder(coreEvent) - is CancelOrderEvent -> orderManager.handleCancelOrder(coreEvent) + when (event) { + is CreateOrderEvent -> orderManager.handleNewOrder(event) + is RejectOrderEvent -> orderManager.handleRejectOrder(event) + is UpdatedOrderEvent -> orderManager.handleUpdateOrder(event) + is CancelOrderEvent -> orderManager.handleCancelOrder(event) else -> { - println("Event is not accepted ${coreEvent::class.java}") + println("Event is not accepted ${event::class.java}") } } } diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTempEventListener.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTempEventListener.kt index c5056fcb7..21feb6b90 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTempEventListener.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTempEventListener.kt @@ -15,17 +15,17 @@ class AccountantTempEventListener( return "TempEventListener" } - override fun onEvent(coreEvent: CoreEvent, partition: Int, offset: Long, timestamp: Long) { - println("TempEvent $coreEvent") + override fun onEvent(event: CoreEvent, partition: Int, offset: Long, timestamp: Long) { + println("TempEvent $event") runBlocking { - when (coreEvent) { - is CreateOrderEvent -> orderManager.handleNewOrder(coreEvent) - is RejectOrderEvent -> orderManager.handleRejectOrder(coreEvent) - is UpdatedOrderEvent -> orderManager.handleUpdateOrder(coreEvent) - is CancelOrderEvent -> orderManager.handleCancelOrder(coreEvent) - is TradeEvent -> tradeManager.handleTrade(coreEvent) + when (event) { + is CreateOrderEvent -> orderManager.handleNewOrder(event) + is RejectOrderEvent -> orderManager.handleRejectOrder(event) + is UpdatedOrderEvent -> orderManager.handleUpdateOrder(event) + is CancelOrderEvent -> orderManager.handleCancelOrder(event) + is TradeEvent -> tradeManager.handleTrade(event) else -> { - throw IllegalArgumentException("Event is not accepted ${coreEvent::class.java}") + throw IllegalArgumentException("Event is not accepted ${event::class.java}") } } } diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTradeListener.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTradeListener.kt index 829e6c88d..024f9034a 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTradeListener.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/AccountantTradeListener.kt @@ -1,6 +1,7 @@ package co.nilin.opex.accountant.app.listener import co.nilin.opex.accountant.core.api.TradeManager +import co.nilin.opex.accountant.ports.kafka.listener.spi.Listener import co.nilin.opex.accountant.ports.kafka.listener.spi.TradeListener import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent import kotlinx.coroutines.runBlocking @@ -11,9 +12,9 @@ class AccountantTradeListener(private val tradeManager: TradeManager) : TradeLis return "TradeListener" } - override fun onTrade(tradeEvent: TradeEvent, partition: Int, offset: Long, timestamp: Long) { + override fun onEvent(event: TradeEvent, partition: Int, offset: Long, timestamp: Long) { runBlocking { - tradeManager.handleTrade(tradeEvent) + tradeManager.handleTrade(event) } } } \ No newline at end of file diff --git a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/OrderListener.kt b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/OrderListener.kt index ac0286ad4..456cd1a79 100644 --- a/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/OrderListener.kt +++ b/accountant/accountant-app/src/main/kotlin/co/nilin/opex/accountant/app/listener/OrderListener.kt @@ -15,22 +15,22 @@ class OrderListener(private val orderManager: OrderManager) : OrderSubmitRequest return "OrderListener" } - override fun onOrder(order: OrderSubmitRequest, partition: Int, offset: Long, timestamp: Long) { + override fun onEvent(event: OrderSubmitRequest, partition: Int, offset: Long, timestamp: Long) { runBlocking { - logger.info("Order submit event received ${order.ouid}") + logger.info("Order submit event received ${event.ouid}") orderManager.handleRequestOrder( SubmitOrderEvent( - order.ouid, - order.uuid, - order.orderId, - order.pair, - order.price, - order.quantity, - order.quantity, - order.direction, - order.matchConstraint, - order.orderType + event.ouid, + event.uuid, + event.orderId, + event.pair, + event.price, + event.quantity, + event.quantity, + event.direction, + event.matchConstraint, + event.orderType ) ) } diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml b/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml index 53582bc51..8bb43937e 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/pom.xml @@ -57,5 +57,9 @@ spring-kafka-test test + + io.mockk + mockk + diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventConsumer.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventConsumer.kt new file mode 100644 index 000000000..68ba4eec8 --- /dev/null +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventConsumer.kt @@ -0,0 +1,31 @@ +package co.nilin.opex.accountant.ports.kafka.listener.consumer + +import co.nilin.opex.accountant.ports.kafka.listener.spi.Listener +import org.apache.kafka.clients.consumer.ConsumerRecord +import org.springframework.kafka.listener.MessageListener + +abstract class EventConsumer, K, V> : MessageListener { + + protected val listeners = arrayListOf() + + override fun onMessage(data: ConsumerRecord) { + listeners.forEach { it.onEvent(data.value(), data.partition(), data.offset(), data.timestamp()) } + } + + fun getListener(id: String): L? { + return listeners.find { it.id() == id } + } + + fun countListeners(): Int { + return listeners.size + } + + fun addListener(listener: L) { + listeners.add(listener) + } + + fun removeListener(listener: L) { + listeners.removeIf { it.id() == listener.id() } + } + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventKafkaListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventKafkaListener.kt index 3c8a58bb3..02dc816aa 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventKafkaListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/EventKafkaListener.kt @@ -2,28 +2,7 @@ package co.nilin.opex.accountant.ports.kafka.listener.consumer import co.nilin.opex.accountant.ports.kafka.listener.spi.EventListener import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent -import org.apache.kafka.clients.consumer.ConsumerRecord -import org.springframework.kafka.listener.MessageListener import org.springframework.stereotype.Component @Component -class EventKafkaListener : MessageListener { - - val eventListeners = arrayListOf() - - override fun onMessage(data: ConsumerRecord) { - eventListeners.forEach { tl -> - tl.onEvent(data.value(), data.partition(), data.offset(), data.timestamp()) - } - } - - fun addEventListener(tl: EventListener) { - eventListeners.add(tl) - } - - fun removeEventListener(tl: EventListener) { - eventListeners.removeIf { item -> - item.id() == tl.id() - } - } -} \ No newline at end of file +class EventKafkaListener : EventConsumer() \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/OrderKafkaListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/OrderKafkaListener.kt index 1a6edd9db..08b3d7df5 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/OrderKafkaListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/OrderKafkaListener.kt @@ -2,28 +2,7 @@ package co.nilin.opex.accountant.ports.kafka.listener.consumer import co.nilin.opex.accountant.ports.kafka.listener.inout.OrderSubmitRequest import co.nilin.opex.accountant.ports.kafka.listener.spi.OrderSubmitRequestListener -import org.apache.kafka.clients.consumer.ConsumerRecord -import org.springframework.kafka.listener.MessageListener import org.springframework.stereotype.Component @Component -class OrderKafkaListener : MessageListener { - - val orderListeners = arrayListOf() - - override fun onMessage(data: ConsumerRecord) { - orderListeners.forEach { tl -> - tl.onOrder(data.value(), data.partition(), data.offset(), data.timestamp()) - } - } - - fun addOrderListener(tl: OrderSubmitRequestListener) { - orderListeners.add(tl) - } - - fun removeOrderListener(tl: OrderSubmitRequestListener) { - orderListeners.removeIf { item -> - item.id() == tl.id() - } - } -} \ No newline at end of file +class OrderKafkaListener : EventConsumer() \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TempEventKafkaListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TempEventKafkaListener.kt index 485f99a2b..6fb848219 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TempEventKafkaListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TempEventKafkaListener.kt @@ -1,31 +1,8 @@ package co.nilin.opex.accountant.ports.kafka.listener.consumer - import co.nilin.opex.accountant.ports.kafka.listener.spi.TempEventListener import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent -import org.apache.kafka.clients.consumer.ConsumerRecord -import org.springframework.kafka.listener.MessageListener import org.springframework.stereotype.Component @Component -class TempEventKafkaListener : MessageListener { - - val eventListeners = arrayListOf() - - override fun onMessage(data: ConsumerRecord) { - println("TempEvent onMessage") - eventListeners.forEach { tl -> - tl.onEvent(data.value(), data.partition(), data.offset(), data.timestamp()) - } - } - - fun addEventListener(tl: TempEventListener) { - eventListeners.add(tl) - } - - fun removeEventListener(tl: TempEventListener) { - eventListeners.removeIf { item -> - item.id() == tl.id() - } - } -} \ No newline at end of file +class TempEventKafkaListener : EventConsumer() \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TradeKafkaListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TradeKafkaListener.kt index 4f10f4b17..a048a6983 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TradeKafkaListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/TradeKafkaListener.kt @@ -2,28 +2,7 @@ package co.nilin.opex.accountant.ports.kafka.listener.consumer import co.nilin.opex.accountant.ports.kafka.listener.spi.TradeListener import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent -import org.apache.kafka.clients.consumer.ConsumerRecord -import org.springframework.kafka.listener.MessageListener import org.springframework.stereotype.Component @Component -class TradeKafkaListener : MessageListener { - - val tradeListeners = arrayListOf() - - override fun onMessage(data: ConsumerRecord) { - tradeListeners.forEach { tl -> - tl.onTrade(data.value(), data.partition(), data.offset(), data.timestamp()) - } - } - - fun addTradeListener(tl: TradeListener) { - tradeListeners.add(tl) - } - - fun removeTradeListener(tl: TradeListener) { - tradeListeners.removeIf { item -> - item.id() == tl.id() - } - } -} \ No newline at end of file +class TradeKafkaListener : EventConsumer() \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/EventListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/EventListener.kt index 50304b05d..8c2f020dc 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/EventListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/EventListener.kt @@ -2,7 +2,4 @@ package co.nilin.opex.accountant.ports.kafka.listener.spi import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent -interface EventListener { - fun id(): String - fun onEvent(coreEvent: CoreEvent, partition: Int, offset: Long, timestamp: Long) -} \ No newline at end of file +interface EventListener : Listener \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/Listener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/Listener.kt new file mode 100644 index 000000000..a5886d313 --- /dev/null +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/Listener.kt @@ -0,0 +1,9 @@ +package co.nilin.opex.accountant.ports.kafka.listener.spi + +interface Listener { + + fun id(): String + + fun onEvent(event: T, partition: Int, offset: Long, timestamp: Long) + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/OrderSubmitRequestListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/OrderSubmitRequestListener.kt index 71756af2c..ac9a24904 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/OrderSubmitRequestListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/OrderSubmitRequestListener.kt @@ -2,7 +2,4 @@ package co.nilin.opex.accountant.ports.kafka.listener.spi import co.nilin.opex.accountant.ports.kafka.listener.inout.OrderSubmitRequest -interface OrderSubmitRequestListener { - fun id(): String - fun onOrder(order: OrderSubmitRequest, partition: Int, offset: Long, timestamp: Long) -} \ No newline at end of file +interface OrderSubmitRequestListener : Listener \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TempEventListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TempEventListener.kt index 6d069c573..479df1a3b 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TempEventListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TempEventListener.kt @@ -2,7 +2,4 @@ package co.nilin.opex.accountant.ports.kafka.listener.spi import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent -interface TempEventListener { - fun id(): String - fun onEvent(coreEvent: CoreEvent, partition: Int, offset: Long, timestamp: Long) -} \ No newline at end of file +interface TempEventListener : Listener \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TradeListener.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TradeListener.kt index 1d277a953..46f14a0d8 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TradeListener.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/listener/spi/TradeListener.kt @@ -2,7 +2,4 @@ package co.nilin.opex.accountant.ports.kafka.listener.spi import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent -interface TradeListener { - fun id(): String - fun onTrade(tradeEvent: TradeEvent, partition: Int, offset: Long, timestamp: Long) -} \ No newline at end of file +interface TradeListener : Listener \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/ConsumerTest.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/ConsumerTest.kt new file mode 100644 index 000000000..ea5b998ab --- /dev/null +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/ConsumerTest.kt @@ -0,0 +1,52 @@ +package co.nilin.opex.accountant.ports.kafka.listener + +import co.nilin.opex.accountant.ports.kafka.listener.consumer.ConsumerObject +import co.nilin.opex.accountant.ports.kafka.listener.consumer.ListenerObject +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import org.apache.kafka.clients.consumer.ConsumerRecord +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test + +class ConsumerTest { + + private val consumer = ConsumerObject() + private val listener = mockk() + + init { + coEvery { listener.onEvent(any(), any(), any(), any()) } returns Unit + } + + @Test + fun givenEventConsumer_onMessage_callListener() { + consumer.addListener(listener) + consumer.onMessage(ConsumerRecord("topic", 1, 0, null, "value")) + + coVerify(exactly = consumer.countListeners()) { listener.onEvent(eq("value"), eq(1), eq(0), any()) } + } + + @Test + fun givenEventConsumer_onMessageWith2Listeners_callListener() { + consumer.addListener(listener) + consumer.addListener(listener) + consumer.onMessage(ConsumerRecord("topic", 1, 0, null, "value")) + + coVerify(exactly = 2) { listener.onEvent(eq("value"), eq(1), eq(0), any()) } + } + + @Test + fun givenEventConsumer_whenAdding1Listener_listenerCountIs1() { + consumer.addListener(listener) + assertThat(consumer.countListeners()).isEqualTo(1) + } + + @Test + fun givenEventConsumer_whenAdding1ListenerAndRemoving1_listenerCountIs0() { + consumer.addListener(listener) + coEvery { listener.id() } returns "L1" + consumer.removeListener(listener) + assertThat(consumer.countListeners()).isEqualTo(0) + } + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ConsumerObject.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ConsumerObject.kt new file mode 100644 index 000000000..6c9911c98 --- /dev/null +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ConsumerObject.kt @@ -0,0 +1,3 @@ +package co.nilin.opex.accountant.ports.kafka.listener.consumer + +class ConsumerObject : EventConsumer() \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt new file mode 100644 index 000000000..6d3f268af --- /dev/null +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt @@ -0,0 +1,14 @@ +package co.nilin.opex.accountant.ports.kafka.listener.consumer + +import co.nilin.opex.accountant.ports.kafka.listener.spi.Listener + +class ListenerObject : Listener { + + override fun id(): String { + return "AnyListener" + } + + override fun onEvent(event: Any, partition: Int, offset: Long, timestamp: Long) { + println("event called") + } +} \ No newline at end of file From 1544c7e6af458f9f7559d7be01f6269db865c0f4 Mon Sep 17 00:00:00 2001 From: Peyman Date: Sun, 29 May 2022 10:48:27 +0430 Subject: [PATCH 08/18] DB domain test --- .../postgres/dao/FinancialActionRepository.kt | 4 +- .../impl/FinancialActionLoaderImpl.kt | 18 ++++----- .../ports/postgres/FALoaderImplTest.kt | 12 ++++++ .../ports/postgres/FAPersisterImplTest.kt | 37 +++++++++++++++++++ accountant/pom.xml | 5 +++ 5 files changed, 66 insertions(+), 10 deletions(-) create mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt create mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt index 92b5a6138..bfb557411 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt @@ -16,7 +16,9 @@ interface FinancialActionRepository : ReactiveCrudRepository @Query("select count(1) from fi_actions fi where fi.sender = :uuid and fi.symbol = :symbol and fi.event_type = :eventType and fi.status = :status") diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt index 79abb341c..643a6f80e 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionLoaderImpl.kt @@ -32,6 +32,15 @@ class FinancialActionLoaderImpl(val financialActionRepository: FinancialActionRe .firstOrNull() } + override suspend fun countUnprocessed(uuid: String, symbol: String, eventType: String): Long { + return financialActionRepository.findByUuidAndSymbolAndEventTypeAndStatus( + uuid, + symbol, + eventType, + FinancialActionStatus.CREATED + ).awaitFirstOrElse { BigDecimal.ZERO }.toLong() + } + private suspend fun loadFinancialAction(id: Long?): FinancialAction? { if (id != null) { val fim = financialActionRepository.findById(id).awaitFirst() @@ -52,13 +61,4 @@ class FinancialActionLoaderImpl(val financialActionRepository: FinancialActionRe } return null } - - override suspend fun countUnprocessed(uuid: String, symbol: String, eventType: String): Long { - return financialActionRepository.findByUuidAndSymbolAndEventTypeAndStatus( - uuid, - symbol, - eventType, - FinancialActionStatus.CREATED - ).awaitFirstOrElse { BigDecimal.ZERO }.toLong() - } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt new file mode 100644 index 000000000..d2992d1a0 --- /dev/null +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt @@ -0,0 +1,12 @@ +package co.nilin.opex.accountant.ports.postgres + +import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository +import co.nilin.opex.accountant.ports.postgres.impl.FinancialActionLoaderImpl +import io.mockk.mockk + +class FALoaderImplTest { + + private val financialActionRepository = mockk() + private val faLoader = FinancialActionLoaderImpl(financialActionRepository) + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt new file mode 100644 index 000000000..3a7ce10b9 --- /dev/null +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt @@ -0,0 +1,37 @@ +package co.nilin.opex.accountant.ports.postgres + +import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository +import co.nilin.opex.accountant.ports.postgres.impl.FinancialActionPersisterImpl +import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent +import io.mockk.coEvery +import io.mockk.coVerify +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.junit.jupiter.api.Test +import reactor.core.publisher.Flux +import java.time.LocalDateTime + +class FAPersisterImplTest { + + private val financialActionRepository = mockk() + private val faPersister = FinancialActionPersisterImpl(financialActionRepository) + + private val fa = FinancialAction( + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + LocalDateTime.now() + ) + + init { + coEvery { financialActionRepository.saveAll(emptyList()) } returns Flux.empty() + } + +} \ No newline at end of file diff --git a/accountant/pom.xml b/accountant/pom.xml index 01387a319..0b62a1582 100644 --- a/accountant/pom.xml +++ b/accountant/pom.xml @@ -29,6 +29,11 @@ org.springframework.boot spring-boot-starter-test + + io.mockk + mockk + test + From 9cc3c40d2bd42c49463c725b6e5521b8427fef1e Mon Sep 17 00:00:00 2001 From: Peyman Date: Mon, 30 May 2022 15:36:16 +0430 Subject: [PATCH 09/18] Add more tests --- .../ports/postgres/impl/OrderPersisterImpl.kt | 2 +- .../opex/accountant/ports/postgres/DOC.kt | 95 +++++++++++++ .../ports/postgres/OrderPersisterImplTest.kt | 53 +++++++ .../ports/postgres/PairConfigLoaderTest.kt | 129 ++++++++++++++++++ 4 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt create mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt create mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/OrderPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/OrderPersisterImpl.kt index 3f6b177fe..7d70b9a9b 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/OrderPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/OrderPersisterImpl.kt @@ -9,7 +9,7 @@ import org.springframework.stereotype.Component import java.time.LocalDateTime @Component -class OrderPersisterImpl(val orderRepository: OrderRepository) : OrderPersister { +class OrderPersisterImpl(private val orderRepository: OrderRepository) : OrderPersister { override suspend fun load(ouid: String): Order? { val model = orderRepository.findByOuid(ouid).awaitFirstOrNull() ?: return null diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt new file mode 100644 index 000000000..7d8c0176f --- /dev/null +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt @@ -0,0 +1,95 @@ +package co.nilin.opex.accountant.ports.postgres + +import co.nilin.opex.accountant.core.inout.OrderStatus +import co.nilin.opex.accountant.core.model.Order +import co.nilin.opex.accountant.core.model.PairConfig +import co.nilin.opex.accountant.ports.postgres.model.OrderModel +import co.nilin.opex.accountant.ports.postgres.model.PairConfigModel +import co.nilin.opex.accountant.ports.postgres.model.PairFeeConfigModel +import co.nilin.opex.matching.engine.core.model.MatchConstraint +import co.nilin.opex.matching.engine.core.model.OrderDirection +import co.nilin.opex.matching.engine.core.model.OrderType +import java.math.BigDecimal +import java.time.LocalDateTime + +object DOC { + + val orderModel = OrderModel( + 1, + "order_1", + "user_1", + "BTC_USDT", + 1, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.00001.toBigDecimal(), + 0.01.toBigDecimal(), + "", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 5500000, + 100, + 100, + 55000.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.FILLED.code, + "", + "", + LocalDateTime.now() + ) + + val order = Order( + "BTC_USDT", + "order_1", + 1, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.00001.toBigDecimal(), + 0.01.toBigDecimal(), + "user_1", + "", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 5500000, + 100, + 100, + 55000.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.FILLED.code, + 1 + ) + + val pairConfigModel = PairConfigModel( + "BTC_USDT", + "BTC", + "USDT", + 0.000001.toBigDecimal(), + 0.01.toBigDecimal() + ) + + val pairConfig = PairConfig( + "BTC_USDT", + "BTC", + "USDT", + 0.000001.toBigDecimal(), + 0.01.toBigDecimal() + ) + + val pairFeeConfigModel = PairFeeConfigModel( + 1, + "BTC_USDT", + "BID", + "1", + 0.01.toBigDecimal(), + 0.01.toBigDecimal() + ) + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt new file mode 100644 index 000000000..93d6b0d7d --- /dev/null +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt @@ -0,0 +1,53 @@ +package co.nilin.opex.accountant.ports.postgres + +import co.nilin.opex.accountant.ports.postgres.dao.OrderRepository +import co.nilin.opex.accountant.ports.postgres.impl.OrderPersisterImpl +import io.mockk.coVerify +import io.mockk.every +import io.mockk.mockk +import kotlinx.coroutines.runBlocking +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import reactor.core.publisher.Mono + +class OrderPersisterImplTest { + + private val repository = mockk { + every { save(any()) } returns Mono.just(DOC.orderModel) + every { findByOuid(any()) } returns Mono.just(DOC.orderModel) + } + + private val persister = OrderPersisterImpl(repository) + + @Test + fun givenOUID_whenLoading_resultNotNull(): Unit = runBlocking { + val order = persister.load("") + assertThat(order).isNotNull + } + + @Test + fun givenOUID_whenLoading_resultIsValidOrder(): Unit = runBlocking { + val order = persister.load("")!! + coVerify { repository.findByOuid(any()) } + assertThat(order.status).isEqualTo(DOC.orderModel.status) + assertThat(order.matchingEngineId).isEqualTo(DOC.orderModel.matchingEngineId) + assertThat(order.direction).isEqualTo(DOC.orderModel.direction) + assertThat(order.filledQuantity).isEqualTo(DOC.orderModel.filledQuantity) + assertThat(order.ouid).isEqualTo(DOC.orderModel.ouid) + } + + @Test + fun givenNewOrder_whenSaving_saveAndReturnValidOrder(): Unit = runBlocking { + val newOrder = persister.save(DOC.order) + coVerify { repository.save(any()) } + with(DOC.order){ + assertThat(newOrder).isNotNull + assertThat(status).isEqualTo(DOC.orderModel.status) + assertThat(matchingEngineId).isEqualTo(DOC.orderModel.matchingEngineId) + assertThat(direction).isEqualTo(DOC.orderModel.direction) + assertThat(filledQuantity).isEqualTo(DOC.orderModel.filledQuantity) + assertThat(ouid).isEqualTo(DOC.orderModel.ouid) + } + } + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt new file mode 100644 index 000000000..954b8faf5 --- /dev/null +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt @@ -0,0 +1,129 @@ +package co.nilin.opex.accountant.ports.postgres + +import co.nilin.opex.accountant.ports.postgres.dao.PairConfigRepository +import co.nilin.opex.accountant.ports.postgres.dao.PairFeeConfigRepository +import co.nilin.opex.accountant.ports.postgres.impl.PairConfigLoaderImpl +import co.nilin.opex.matching.engine.core.model.OrderDirection +import co.nilin.opex.utility.error.data.OpexException +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.runBlocking +import org.assertj.core.api.Assertions.assertThat +import org.assertj.core.api.Assertions.assertThatThrownBy +import org.junit.jupiter.api.Test +import reactor.core.publisher.Flux +import reactor.core.publisher.Mono + +@Suppress("ReactiveStreamsUnusedPublisher") +class PairConfigLoaderTest { + + private val pairConfigRepository = mockk { + every { findAll() } returns Flux.just(DOC.pairConfigModel, DOC.pairConfigModel) + every { findById(any() as String) } returns Mono.just(DOC.pairConfigModel) + } + private val pairFeeConfigRepository = mockk { + every { findAll() } returns Flux.just(DOC.pairFeeConfigModel, DOC.pairFeeConfigModel) + every { findByPairAndDirectionAndUserLevel(any(), any(), any()) } returns Mono.just(DOC.pairFeeConfigModel) + } + private val pairConfigLoader = PairConfigLoaderImpl(pairConfigRepository, pairFeeConfigRepository) + + @Test + fun givenPairConfigs_whenListNotEmpty_resultIsNotEmptyAndValid(): Unit = runBlocking { + val configs = pairConfigLoader.loadPairConfigs() + assertThat(configs.size).isEqualTo(2) + with(configs[1]) { + assertThat(pair).isEqualTo(DOC.pairConfig.pair) + assertThat(leftSideWalletSymbol).isEqualTo(DOC.pairConfig.leftSideWalletSymbol) + assertThat(rightSideWalletSymbol).isEqualTo(DOC.pairConfig.rightSideWalletSymbol) + assertThat(leftSideFraction).isEqualTo(DOC.pairConfig.leftSideFraction) + assertThat(rightSideFraction).isEqualTo(DOC.pairConfig.rightSideFraction) + } + } + + @Test + fun givenPairFeeConfigs_whenListNotEmpty_resultIsNotEmptyAndValid(): Unit = runBlocking { + val configs = pairConfigLoader.loadPairFeeConfigs() + assertThat(configs.size).isEqualTo(2) + with(configs[1]) { + assertThat(pairConfig.pair).isEqualTo(DOC.pairConfig.pair) + assertThat(userLevel).isEqualTo(DOC.pairFeeConfigModel.userLevel) + assertThat(direction).isEqualTo(DOC.pairFeeConfigModel.direction) + assertThat(makerFee).isEqualTo(DOC.pairFeeConfigModel.makerFee) + assertThat(takerFee).isEqualTo(DOC.pairFeeConfigModel.takerFee) + } + } + + @Test + fun givenPairDirectionUserLevel_whenPairConfigNotFound_throwsException(): Unit = runBlocking { + every { pairConfigRepository.findById(any() as String) } returns Mono.empty() + assertThatThrownBy { + runBlocking { pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "*") } + }.isInstanceOf(OpexException::class.java) + } + + @Test + fun givenPairDirection_whenUserLevelEmpty_loadWithDefaultUserLevel(): Unit = runBlocking { + val pair = pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "") + assertThat(pair).isNotNull + verify(exactly = 1) { pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("*")) } + } + + @Test + fun givenPairDirection_whenPairFeeConfigNotFound_throwsException(): Unit = runBlocking { + every { + pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("*")) + } returns Mono.empty() + + assertThatThrownBy { + runBlocking { pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "") } + }.isInstanceOf(OpexException::class.java) + } + + @Test + fun givenPairDirectionUserLevel_whenPairFeeConfigNotFound_loadWithDefaultUserLevel(): Unit = runBlocking { + every { + pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("1")) + } returns Mono.empty() + + val pair = pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "1") + assertThat(pair).isNotNull + verify(exactly = 1) { pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("*")) } + } + + @Test + fun givenPairDirectionUserLevel_whenPairFeeConfigNotFoundWithActualAndDefaultUserLevel_throwsException(): Unit = + runBlocking { + every { + pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("1")) + } returns Mono.empty() + + every { + pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("*")) + } returns Mono.empty() + + assertThatThrownBy { + runBlocking { pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "1") } + }.isInstanceOf(OpexException::class.java) + } + + @Test + fun givenPairDirection_whenPairConfigNotFound_throwException(): Unit = runBlocking { + every { pairConfigRepository.findById(any() as String) } returns Mono.empty() + assertThatThrownBy { + runBlocking { pairConfigLoader.load("BTC_USDT", OrderDirection.BID) } + }.isInstanceOf(OpexException::class.java) + } + + @Test + fun givenPairDirection_whenConfigLoaded_returnValidPairConfig(): Unit = runBlocking { + with(pairConfigLoader.load("BTC_USDT", OrderDirection.BID)){ + assertThat(pair).isEqualTo(DOC.pairConfigModel.pair) + assertThat(leftSideWalletSymbol).isEqualTo(DOC.pairConfigModel.leftSideWalletSymbol) + assertThat(rightSideWalletSymbol).isEqualTo(DOC.pairConfigModel.rightSideWalletSymbol) + assertThat(rightSideFraction).isEqualTo(DOC.pairConfigModel.rightSideFraction) + assertThat(leftSideFraction).isEqualTo(DOC.pairConfigModel.leftSideFraction) + } + } + +} \ No newline at end of file From 71cb12b930404501a6b1a76224774f910314749f Mon Sep 17 00:00:00 2001 From: Peyman Date: Mon, 30 May 2022 17:08:37 +0430 Subject: [PATCH 10/18] Temp event test --- .../postgres/impl/TempEventPersisterImpl.kt | 6 +- .../opex/accountant/ports/postgres/DOC.kt | 24 ++++++++ .../ports/postgres/TempEventPersisterTest.kt | 55 +++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt index d844017d3..d07388817 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt @@ -9,14 +9,14 @@ import com.google.gson.Gson import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.toList import kotlinx.coroutines.reactive.awaitFirstOrNull -import kotlinx.coroutines.reactive.awaitSingle +import kotlinx.coroutines.reactor.awaitSingleOrNull import org.springframework.data.domain.PageRequest import org.springframework.data.domain.Sort import org.springframework.stereotype.Component import java.time.LocalDateTime @Component -class TempEventPersisterImpl(val tempEventRepository: TempEventRepository) : TempEventPersister { +class TempEventPersisterImpl(private val tempEventRepository: TempEventRepository) : TempEventPersister { override suspend fun saveTempEvent(ouid: String, event: CoreEvent) { tempEventRepository.save( @@ -27,7 +27,7 @@ class TempEventPersisterImpl(val tempEventRepository: TempEventRepository) : Tem Gson().toJson(event), LocalDateTime.now() ) - ).awaitSingle() + ).awaitSingleOrNull() } override suspend fun loadTempEvents(ouid: String): List { diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt index 7d8c0176f..8f5a3bb61 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt @@ -3,12 +3,16 @@ package co.nilin.opex.accountant.ports.postgres import co.nilin.opex.accountant.core.inout.OrderStatus import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.accountant.core.model.PairConfig +import co.nilin.opex.accountant.core.model.TempEvent import co.nilin.opex.accountant.ports.postgres.model.OrderModel import co.nilin.opex.accountant.ports.postgres.model.PairConfigModel import co.nilin.opex.accountant.ports.postgres.model.PairFeeConfigModel +import co.nilin.opex.accountant.ports.postgres.model.TempEventModel +import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent import co.nilin.opex.matching.engine.core.model.MatchConstraint import co.nilin.opex.matching.engine.core.model.OrderDirection import co.nilin.opex.matching.engine.core.model.OrderType +import co.nilin.opex.matching.engine.core.model.Pair import java.math.BigDecimal import java.time.LocalDateTime @@ -92,4 +96,24 @@ object DOC { 0.01.toBigDecimal() ) + class TestCoreEvent(val leftSidePair: String, val rightSidePair: String) : + CoreEvent(Pair(leftSidePair, rightSidePair), LocalDateTime.now()) + + val testEvent = TestCoreEvent("BTC","USDT") + + val tempEvent = TempEvent( + 1, + "event_1", + TestCoreEvent("BTC", "USDT"), + LocalDateTime.now() + ) + + val tempEventModel = TempEventModel( + 1, + "event_1", + TestCoreEvent::class.java.name, + "{\"leftSidePair\":\"BTC\",\"rightSidePair\":\"USDT\",\"pair\":{\"leftSideName\":\"BTC\",\"rightSideName\":\"USDT\"},\"eventDate\":{\"date\":{\"year\":2022,\"month\":5,\"day\":30},\"time\":{\"hour\":16,\"minute\":57,\"second\":44,\"nano\":809838600}}}", + LocalDateTime.now() + ) + } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt new file mode 100644 index 000000000..e16aa810c --- /dev/null +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt @@ -0,0 +1,55 @@ +package co.nilin.opex.accountant.ports.postgres + +import co.nilin.opex.accountant.ports.postgres.dao.TempEventRepository +import co.nilin.opex.accountant.ports.postgres.impl.TempEventPersisterImpl +import co.nilin.opex.accountant.ports.postgres.model.TempEventModel +import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.flow.flow +import kotlinx.coroutines.runBlocking +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import reactor.core.publisher.Mono + +@Suppress("ReactiveStreamsUnusedPublisher") +class TempEventPersisterTest { + + private val tempEventRepository = mockk { + every { save(any()) } returns Mono.empty() + every { findAll(any()) } returns flow { emit(DOC.tempEventModel) } + every { findByOuid(any()) } returns flow { emit(DOC.tempEventModel) } + every { delete(any()) } returns Mono.empty() + every { deleteAll(any() as Iterable) } returns Mono.empty() + every { deleteByOuid(any()) } returns Mono.empty() + } + + private val persister = TempEventPersisterImpl(tempEventRepository) + + @Test + fun givenOuidAndEvent_whenSaving_callRepoOnce(): Unit = runBlocking { + persister.saveTempEvent("event_1", DOC.testEvent) + verify(exactly = 1) { tempEventRepository.save(any()) } + } + + @Test + fun givenOUID_whenLoadingTempEvent_parseEventJSON(): Unit = runBlocking { + val events = persister.loadTempEvents("event_1") + + assertThat(events).isNotEmpty + + with(events[0]) { + assertThat(this).isInstanceOf(CoreEvent::class.java) + assertThat(pair.rightSideName).isEqualTo(DOC.testEvent.rightSidePair) + assertThat(pair.leftSideName).isEqualTo(DOC.testEvent.leftSidePair) + } + } + + @Test + fun givenOuid_whenDeletingByOUID_callRepoOnce(): Unit = runBlocking { + persister.removeTempEvents("event_1") + verify(exactly = 1) { tempEventRepository.deleteByOuid(any()) } + } + +} \ No newline at end of file From 09c8645bdb767e3ddda03337f1007125ad3e4922 Mon Sep 17 00:00:00 2001 From: Peyman Date: Mon, 30 May 2022 17:45:43 +0430 Subject: [PATCH 11/18] Refactor publishers --- .../ports/kafka/submitter/service/EventPublisher.kt | 5 +++++ .../kafka/submitter/service/RichOrderSubmitter.kt | 13 +++++++++---- .../kafka/submitter/service/RichTradeSubmitter.kt | 13 +++++++++---- .../kafka/submitter/service/TempEventSubmitter.kt | 12 +++++++++--- 4 files changed, 32 insertions(+), 11 deletions(-) create mode 100644 accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt new file mode 100644 index 000000000..0fbe3e4ca --- /dev/null +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt @@ -0,0 +1,5 @@ +package co.nilin.opex.accountant.ports.kafka.submitter.service + +interface EventPublisher { + fun topic(): String +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt index 0a93b1b2c..2d73b13d6 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt @@ -7,19 +7,20 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.kafka.core.KafkaTemplate import org.springframework.stereotype.Component import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine @Component -class RichOrderSubmitter(@Qualifier("richOrderKafkaTemplate") val kafkaTemplate: KafkaTemplate) : - RichOrderPublisher { +class RichOrderSubmitter( + @Qualifier("richOrderKafkaTemplate") + private val kafkaTemplate: KafkaTemplate +) : RichOrderPublisher, EventPublisher { private val logger = LoggerFactory.getLogger(RichOrderSubmitter::class.java) override suspend fun publish(order: RichOrderEvent): Unit = suspendCoroutine { cont -> logger.info("Submitting RichOrder") - val sendFuture = kafkaTemplate.send("richOrder", order) + val sendFuture = kafkaTemplate.send(topic(), order) sendFuture.addCallback({ cont.resume(Unit) }, { @@ -27,4 +28,8 @@ class RichOrderSubmitter(@Qualifier("richOrderKafkaTemplate") val kafkaTemplate: cont.resume(Unit) }) } + + override fun topic(): String { + return "richOrder" + } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt index c5f3641af..6ff682ea4 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt @@ -7,19 +7,20 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.kafka.core.KafkaTemplate import org.springframework.stereotype.Component import kotlin.coroutines.resume -import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine @Component -class RichTradeSubmitter(@Qualifier("richTradeKafkaTemplate") val kafkaTemplate: KafkaTemplate) : - RichTradePublisher { +class RichTradeSubmitter( + @Qualifier("richTradeKafkaTemplate") + private val kafkaTemplate: KafkaTemplate +) : RichTradePublisher,EventPublisher { private val logger = LoggerFactory.getLogger(RichTradeSubmitter::class.java) override suspend fun publish(trade: RichTrade): Unit = suspendCoroutine { cont -> logger.info("Submitting RichTrade event: id=${trade.id}") - val sendFuture = kafkaTemplate.send("richTrade", trade) + val sendFuture = kafkaTemplate.send(topic(), trade) sendFuture.addCallback({ cont.resume(Unit) }, { @@ -27,4 +28,8 @@ class RichTradeSubmitter(@Qualifier("richTradeKafkaTemplate") val kafkaTemplate: cont.resume(Unit) }) } + + override fun topic(): String { + return "richTrade" + } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt index 09c184248..5082b2b06 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt @@ -11,8 +11,10 @@ import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine @Component -class TempEventSubmitter(@Qualifier("accountantEventKafkaTemplate") val kafkaTemplate: KafkaTemplate) : - TempEventRepublisher { +class TempEventSubmitter( + @Qualifier("accountantEventKafkaTemplate") + private val kafkaTemplate: KafkaTemplate +) : TempEventRepublisher, EventPublisher { private val logger = LoggerFactory.getLogger(TempEventSubmitter::class.java) @@ -20,7 +22,7 @@ class TempEventSubmitter(@Qualifier("accountantEventKafkaTemplate") val kafkaTem logger.info("Submitting TempEvents") events.forEach { event -> - val sendFuture = kafkaTemplate.send("tempevents", event) + val sendFuture = kafkaTemplate.send(topic(), event) sendFuture.addCallback({ cont.resume(Unit) }, { @@ -29,4 +31,8 @@ class TempEventSubmitter(@Qualifier("accountantEventKafkaTemplate") val kafkaTem }) } } + + override fun topic(): String { + return "tempevents" + } } \ No newline at end of file From eaeeb7f695967c8163934c943a6e83353aa53f45 Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 1 Jun 2022 16:51:26 +0430 Subject: [PATCH 12/18] Add submitters test --- .../submitter/service/RichOrderSubmitter.kt | 3 +- .../submitter/service/RichTradeSubmitter.kt | 3 +- .../accountant/ports/kafka/submitter/DUC.kt | 50 ++++++++++ .../kafka/submitter/EventPublishersTest.kt | 98 +++++++++++++++++++ 4 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt create mode 100644 accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt index 2d73b13d6..e85424cd6 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.kafka.core.KafkaTemplate import org.springframework.stereotype.Component import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine @Component @@ -25,7 +26,7 @@ class RichOrderSubmitter( cont.resume(Unit) }, { logger.error("Error submitting RichOrder", it) - cont.resume(Unit) + cont.resumeWithException(it) }) } diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt index 6ff682ea4..5e69d69d0 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt @@ -7,6 +7,7 @@ import org.springframework.beans.factory.annotation.Qualifier import org.springframework.kafka.core.KafkaTemplate import org.springframework.stereotype.Component import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException import kotlin.coroutines.suspendCoroutine @Component @@ -25,7 +26,7 @@ class RichTradeSubmitter( cont.resume(Unit) }, { logger.error("RichTrade submitter error", it) - cont.resume(Unit) + cont.resumeWithException(it) }) } diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt new file mode 100644 index 000000000..898035ae5 --- /dev/null +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt @@ -0,0 +1,50 @@ +package co.nilin.opex.accountant.ports.kafka.submitter + +import co.nilin.opex.accountant.core.inout.RichOrderEvent +import co.nilin.opex.accountant.core.inout.RichTrade +import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent +import co.nilin.opex.matching.engine.core.model.OrderDirection +import co.nilin.opex.matching.engine.core.model.Pair +import org.springframework.kafka.support.SendResult +import org.springframework.util.concurrent.SettableListenableFuture +import java.time.LocalDateTime + +object DUC { + + class TestRichOrderEvent : RichOrderEvent + class TestCoreEvent : CoreEvent(Pair("BTC", "USDT")) + + val testRichOrder = TestRichOrderEvent() + val testCoreEvent = TestCoreEvent() + val richTrade = RichTrade( + 1, + "BTC_USDT", + "", + "", + 1, + OrderDirection.BID, + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + "", + "", + "", + 1, + OrderDirection.BID, + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + 1.0.toBigDecimal(), + "", + 1.0.toBigDecimal(), + LocalDateTime.now() + ) + + fun kafkaSendFuture() = SettableListenableFuture>().apply { + set(SendResult(null, null)) + } + +} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt new file mode 100644 index 000000000..47639a9bf --- /dev/null +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt @@ -0,0 +1,98 @@ +package co.nilin.opex.accountant.ports.kafka.submitter + +import co.nilin.opex.accountant.core.inout.RichOrderEvent +import co.nilin.opex.accountant.core.inout.RichTrade +import co.nilin.opex.accountant.ports.kafka.submitter.service.RichOrderSubmitter +import co.nilin.opex.accountant.ports.kafka.submitter.service.RichTradeSubmitter +import co.nilin.opex.accountant.ports.kafka.submitter.service.TempEventSubmitter +import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import kotlinx.coroutines.runBlocking +import org.assertj.core.api.Assertions +import org.assertj.core.api.Assertions.assertThat +import org.junit.jupiter.api.Test +import org.springframework.kafka.core.KafkaTemplate +import org.springframework.kafka.support.SendResult +import org.springframework.util.concurrent.SettableListenableFuture + +class EventPublishersTest { + + private val richOrderTemplate = mockk>() + private val richOrderSubmitter = RichOrderSubmitter(richOrderTemplate) + + private val richTradeTemplate = mockk>() + private val richTradeSubmitter = RichTradeSubmitter(richTradeTemplate) + + private val tempEventTemplate = mockk>() + private val tempEventSubmitter = TempEventSubmitter(tempEventTemplate) + + init { + every { richOrderTemplate.send(any(), any()) } returns DUC.kafkaSendFuture() + every { richTradeTemplate.send(any(), any()) } returns DUC.kafkaSendFuture() + every { tempEventTemplate.send(any(), any()) } returns DUC.kafkaSendFuture() + } + + @Test + fun givenSubmitters_validateTopics(): Unit = runBlocking { + assertThat(richOrderSubmitter.topic()).isEqualTo("richOrder") + assertThat(richTradeSubmitter.topic()).isEqualTo("richTrade") + assertThat(tempEventSubmitter.topic()).isEqualTo("tempevents") + } + + @Test + fun givenRichOrderSubmitter_whenKafkaFailsToSend_throwException(): Unit = runBlocking { + val future = SettableListenableFuture>() + every { richOrderTemplate.send(any(), any()) } returns future + + future.setException(IllegalStateException("mock")) + + Assertions.assertThatThrownBy { + runBlocking { richOrderSubmitter.publish(DUC.testRichOrder) } + }.isInstanceOfAny(Throwable::class.java) + } + + @Test + fun givenRichTradeSubmitter_whenKafkaFailsToSend_throwException(): Unit = runBlocking { + val future = SettableListenableFuture>() + every { richTradeTemplate.send(any(), any()) } returns future + + future.setException(IllegalStateException("mock")) + + Assertions.assertThatThrownBy { + runBlocking { richTradeSubmitter.publish(DUC.richTrade) } + }.isInstanceOfAny(Throwable::class.java) + } + + @Test + fun givenTempEventSubmitter_whenKafkaFailsToSend_throwException(): Unit = runBlocking { + val future = SettableListenableFuture>() + every { tempEventTemplate.send(any(), any()) } returns future + + future.setException(IllegalStateException("mock")) + + Assertions.assertThatThrownBy { + runBlocking { tempEventSubmitter.republish(listOf(DUC.testCoreEvent)) } + }.isInstanceOfAny(Throwable::class.java) + } + + @Test + fun givenRichOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { + richOrderSubmitter.publish(DUC.testRichOrder) + verify { richOrderTemplate.send(eq(richOrderSubmitter.topic()),any()) } + } + + @Test + fun givenTradeOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { + richTradeSubmitter.publish(DUC.richTrade) + verify { richTradeTemplate.send(eq(richTradeSubmitter.topic()),any()) } + } + + @Test + fun givenTempEventSubmitter_whenRepublish_callSendForEachEventWithCorrectTopic(): Unit = runBlocking { + tempEventSubmitter.republish(listOf(DUC.testCoreEvent,DUC.testCoreEvent)) + verify(exactly = 2) { tempEventTemplate.send(eq(tempEventSubmitter.topic()),any()) } + } + +} \ No newline at end of file From 5bd432099fac85c1791a178b3f651a8a7fc33854 Mon Sep 17 00:00:00 2001 From: Peyman Date: Wed, 1 Jun 2022 18:05:32 +0430 Subject: [PATCH 13/18] Refactor tests --- .../nilin/opex/accountant/core/service/DOC.kt | 22 ++++++++++++ .../core/service/FAJobManagerImplTest.kt | 22 ++---------- .../core/service/FeeCalculatorImplTest.kt | 6 ++-- .../postgres/dao/FinancialActionRepository.kt | 6 ++++ .../impl/FinancialActionPersisterImpl.kt | 33 +++--------------- .../opex/accountant/ports/postgres/DOC.kt | 17 ++++++++++ .../ports/postgres/FALoaderImplTest.kt | 12 ------- .../ports/postgres/FAPersisterImplTest.kt | 34 +++++++++---------- .../ports/kafka/submitter/{DUC.kt => DOC.kt} | 2 +- .../kafka/submitter/EventPublishersTest.kt | 18 +++++----- 10 files changed, 80 insertions(+), 92 deletions(-) create mode 100644 accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt delete mode 100644 accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt rename accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/{DUC.kt => DOC.kt} (95%) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt new file mode 100644 index 000000000..84e4c3495 --- /dev/null +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt @@ -0,0 +1,22 @@ +package co.nilin.opex.accountant.core.service + +import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent +import java.time.LocalDateTime + +object DOC { + + val fa = FinancialAction( + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + LocalDateTime.now() + ) + +} \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt index 4390326dd..1e7cf90e3 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt @@ -1,16 +1,13 @@ package co.nilin.opex.accountant.core.service -import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.spi.FinancialActionLoader import co.nilin.opex.accountant.core.spi.FinancialActionPersister import co.nilin.opex.accountant.core.spi.WalletProxy -import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent import io.mockk.coEvery import io.mockk.coVerify import io.mockk.mockk import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test -import java.time.LocalDateTime class FAJobManagerImplTest { @@ -20,27 +17,13 @@ class FAJobManagerImplTest { private val sut = FinancialActionJobManagerImpl(financialActionLoader, financialActionPersister, walletProxy) - private fun stub() { - val fa = FinancialAction( - null, - TradeEvent::class.java.name, - "trade_id", - "BTC_USDT", - 10000.0.toBigDecimal(), - "user_parent", - "main", - "system", - "main", - LocalDateTime.now() - ) - - coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(fa, fa) + init { + coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(DOC.fa, DOC.fa) coEvery { financialActionPersister.updateStatus(any(), any()) } returns Unit } @Test fun given2FALoaded_whenProcessing_thenVerifyThatTransferProxyCalled2Times() = runBlocking { - stub() coEvery { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } returns Unit sut.processFinancialActions(0, 2) coVerify(exactly = 2) { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } @@ -49,7 +32,6 @@ class FAJobManagerImplTest { @Test fun given2FALoaded_whenProcessingFailed_thenUpdateStatusCalledRegardless() = runBlocking { - stub() coEvery { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } throws IllegalStateException() diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt index 923eb0aab..cf28a48ee 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt @@ -18,7 +18,7 @@ internal class FeeCalculatorImplTest { private val receiverAddress = "0x0" private val feeCalculator = FeeCalculatorImpl(receiverAddress) - private var defaultMaker: Order = Order( + private var defaultMaker = Order( "BTC_USDT", "order_1", 1, @@ -41,7 +41,7 @@ internal class FeeCalculatorImplTest { BigDecimal.ZERO, OrderStatus.FILLED.code ) - private var defaultTaker: Order = Order( + private var defaultTaker = Order( "BTC_USDT", "order_2", 2, @@ -64,7 +64,7 @@ internal class FeeCalculatorImplTest { BigDecimal.ZERO, OrderStatus.FILLED.code ) - private var defaultTrade: TradeEvent = TradeEvent( + private var defaultTrade = TradeEvent( 1, Pair("BTC", "USDT"), "order_2", diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt index bfb557411..1090e0859 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/dao/FinancialActionRepository.kt @@ -31,4 +31,10 @@ interface FinancialActionRepository : ReactiveCrudRepository + + @Query("update fi_actions set status = :status where id = :id") + fun updateStatus(@Param("id") id: Long, @Param("status") status: FinancialActionStatus) + + @Query("update fi_actions set status = :status, retry_count = retry_count + 1 where id = :id") + fun updateStatusAndIncreaseRetry(@Param("id") id: Long, @Param("status") status: FinancialActionStatus): Mono } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt index 4f5fb4528..a8ec77beb 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt @@ -5,14 +5,11 @@ import co.nilin.opex.accountant.core.model.FinancialActionStatus import co.nilin.opex.accountant.core.spi.FinancialActionPersister import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository import co.nilin.opex.accountant.ports.postgres.model.FinancialActionModel -import kotlinx.coroutines.reactive.awaitFirst -import kotlinx.coroutines.reactive.awaitFirstOrElse -import kotlinx.coroutines.reactive.awaitLast +import kotlinx.coroutines.reactive.awaitFirstOrNull import org.springframework.stereotype.Component -import java.time.LocalDateTime @Component -class FinancialActionPersisterImpl(val financialActionRepository: FinancialActionRepository) : +class FinancialActionPersisterImpl(private val financialActionRepository: FinancialActionRepository) : FinancialActionPersister { override suspend fun persist(financialActions: List): List { @@ -32,33 +29,11 @@ class FinancialActionPersisterImpl(val financialActionRepository: FinancialActio "", it.createDate ) - }).awaitLast() + }).awaitFirstOrNull() return financialActions } override suspend fun updateStatus(financialAction: FinancialAction, status: FinancialActionStatus) { - val existing = financialActionRepository.findById(financialAction.id!!).awaitFirstOrElse { - throw IllegalArgumentException() - } - financialActionRepository.save( - FinancialActionModel( - existing.id, - existing.parentId, - existing.eventType, - existing.pointer, - existing.symbol, - existing.amount, - existing.sender, - existing.senderWalletType, - existing.receiver, - existing.receiverWalletType, - existing.agent, - existing.ip, - existing.createDate, - status, - 1 + existing.retryCount, - LocalDateTime.now() - ) - ).awaitFirst() + financialActionRepository.updateStatusAndIncreaseRetry(financialAction.id!!, status).awaitFirstOrNull() } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt index 8f5a3bb61..0e9c41ad8 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt @@ -1,6 +1,7 @@ package co.nilin.opex.accountant.ports.postgres import co.nilin.opex.accountant.core.inout.OrderStatus +import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.accountant.core.model.PairConfig import co.nilin.opex.accountant.core.model.TempEvent @@ -9,6 +10,7 @@ import co.nilin.opex.accountant.ports.postgres.model.PairConfigModel import co.nilin.opex.accountant.ports.postgres.model.PairFeeConfigModel import co.nilin.opex.accountant.ports.postgres.model.TempEventModel import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent +import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent import co.nilin.opex.matching.engine.core.model.MatchConstraint import co.nilin.opex.matching.engine.core.model.OrderDirection import co.nilin.opex.matching.engine.core.model.OrderType @@ -116,4 +118,19 @@ object DOC { LocalDateTime.now() ) + val fa = FinancialAction( + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + LocalDateTime.now(), + 1, + 1 + ) + } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt deleted file mode 100644 index d2992d1a0..000000000 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FALoaderImplTest.kt +++ /dev/null @@ -1,12 +0,0 @@ -package co.nilin.opex.accountant.ports.postgres - -import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository -import co.nilin.opex.accountant.ports.postgres.impl.FinancialActionLoaderImpl -import io.mockk.mockk - -class FALoaderImplTest { - - private val financialActionRepository = mockk() - private val faLoader = FinancialActionLoaderImpl(financialActionRepository) - -} \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt index 3a7ce10b9..eaa2b1a7e 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt @@ -1,37 +1,35 @@ package co.nilin.opex.accountant.ports.postgres -import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.accountant.core.model.FinancialActionStatus import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository import co.nilin.opex.accountant.ports.postgres.impl.FinancialActionPersisterImpl -import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent +import co.nilin.opex.accountant.ports.postgres.model.FinancialActionModel import io.mockk.coEvery import io.mockk.coVerify import io.mockk.mockk import kotlinx.coroutines.runBlocking import org.junit.jupiter.api.Test import reactor.core.publisher.Flux -import java.time.LocalDateTime +import reactor.core.publisher.Mono class FAPersisterImplTest { - private val financialActionRepository = mockk() + private val financialActionRepository = mockk { + coEvery { saveAll(emptyList()) } returns Flux.empty() + coEvery { updateStatusAndIncreaseRetry(any(), any()) } returns Mono.empty() + } private val faPersister = FinancialActionPersisterImpl(financialActionRepository) - private val fa = FinancialAction( - null, - TradeEvent::class.java.name, - "trade_id", - "BTC_USDT", - 10000.0.toBigDecimal(), - "user_parent", - "main", - "system", - "main", - LocalDateTime.now() - ) + @Test + fun givenListOfActions_whenSaving_callSaveAll(): Unit = runBlocking { + faPersister.persist(emptyList()) + coVerify { financialActionRepository.saveAll(any() as Iterable) } + } - init { - coEvery { financialActionRepository.saveAll(emptyList()) } returns Flux.empty() + @Test + fun givenFAAndStatus_whenUpdatingStatusAndFANotFound_throwException(): Unit = runBlocking { + faPersister.updateStatus(DOC.fa, FinancialActionStatus.CREATED) + coVerify { financialActionRepository.updateStatusAndIncreaseRetry(any(), any()) } } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DOC.kt similarity index 95% rename from accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt rename to accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DOC.kt index 898035ae5..7f434ae31 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DUC.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DOC.kt @@ -9,7 +9,7 @@ import org.springframework.kafka.support.SendResult import org.springframework.util.concurrent.SettableListenableFuture import java.time.LocalDateTime -object DUC { +object DOC { class TestRichOrderEvent : RichOrderEvent class TestCoreEvent : CoreEvent(Pair("BTC", "USDT")) diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt index 47639a9bf..beb66b33c 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt @@ -29,9 +29,9 @@ class EventPublishersTest { private val tempEventSubmitter = TempEventSubmitter(tempEventTemplate) init { - every { richOrderTemplate.send(any(), any()) } returns DUC.kafkaSendFuture() - every { richTradeTemplate.send(any(), any()) } returns DUC.kafkaSendFuture() - every { tempEventTemplate.send(any(), any()) } returns DUC.kafkaSendFuture() + every { richOrderTemplate.send(any(), any()) } returns DOC.kafkaSendFuture() + every { richTradeTemplate.send(any(), any()) } returns DOC.kafkaSendFuture() + every { tempEventTemplate.send(any(), any()) } returns DOC.kafkaSendFuture() } @Test @@ -49,7 +49,7 @@ class EventPublishersTest { future.setException(IllegalStateException("mock")) Assertions.assertThatThrownBy { - runBlocking { richOrderSubmitter.publish(DUC.testRichOrder) } + runBlocking { richOrderSubmitter.publish(DOC.testRichOrder) } }.isInstanceOfAny(Throwable::class.java) } @@ -61,7 +61,7 @@ class EventPublishersTest { future.setException(IllegalStateException("mock")) Assertions.assertThatThrownBy { - runBlocking { richTradeSubmitter.publish(DUC.richTrade) } + runBlocking { richTradeSubmitter.publish(DOC.richTrade) } }.isInstanceOfAny(Throwable::class.java) } @@ -73,25 +73,25 @@ class EventPublishersTest { future.setException(IllegalStateException("mock")) Assertions.assertThatThrownBy { - runBlocking { tempEventSubmitter.republish(listOf(DUC.testCoreEvent)) } + runBlocking { tempEventSubmitter.republish(listOf(DOC.testCoreEvent)) } }.isInstanceOfAny(Throwable::class.java) } @Test fun givenRichOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { - richOrderSubmitter.publish(DUC.testRichOrder) + richOrderSubmitter.publish(DOC.testRichOrder) verify { richOrderTemplate.send(eq(richOrderSubmitter.topic()),any()) } } @Test fun givenTradeOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { - richTradeSubmitter.publish(DUC.richTrade) + richTradeSubmitter.publish(DOC.richTrade) verify { richTradeTemplate.send(eq(richTradeSubmitter.topic()),any()) } } @Test fun givenTempEventSubmitter_whenRepublish_callSendForEachEventWithCorrectTopic(): Unit = runBlocking { - tempEventSubmitter.republish(listOf(DUC.testCoreEvent,DUC.testCoreEvent)) + tempEventSubmitter.republish(listOf(DOC.testCoreEvent,DOC.testCoreEvent)) verify(exactly = 2) { tempEventTemplate.send(eq(tempEventSubmitter.topic()),any()) } } From a0d2cff8711cf8ebdd06a25855969f9b561beaa1 Mon Sep 17 00:00:00 2001 From: Peyman Date: Mon, 6 Jun 2022 11:23:06 +0430 Subject: [PATCH 14/18] Refactor --- .../core/service/FAJobManagerImplTest.kt | 2 +- .../core/service/{DOC.kt => Valid.kt} | 2 +- .../ports/postgres/FAPersisterImplTest.kt | 2 +- .../ports/postgres/OrderPersisterImplTest.kt | 28 +++++++------- .../ports/postgres/PairConfigLoaderTest.kt | 38 +++++++++---------- .../ports/postgres/TempEventPersisterTest.kt | 10 ++--- .../ports/postgres/{DOC.kt => Valid.kt} | 2 +- .../kafka/submitter/EventPublishersTest.kt | 18 ++++----- .../kafka/submitter/{DOC.kt => Valid.kt} | 2 +- 9 files changed, 52 insertions(+), 52 deletions(-) rename accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/{DOC.kt => Valid.kt} (92%) rename accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/{DOC.kt => Valid.kt} (96%) rename accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/{DOC.kt => Valid.kt} (95%) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt index 1e7cf90e3..5825f3000 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt @@ -18,7 +18,7 @@ class FAJobManagerImplTest { private val sut = FinancialActionJobManagerImpl(financialActionLoader, financialActionPersister, walletProxy) init { - coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(DOC.fa, DOC.fa) + coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(Valid.fa, Valid.fa) coEvery { financialActionPersister.updateStatus(any(), any()) } returns Unit } diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt similarity index 92% rename from accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt rename to accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt index 84e4c3495..2baf7a88d 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/DOC.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt @@ -4,7 +4,7 @@ import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent import java.time.LocalDateTime -object DOC { +object Valid { val fa = FinancialAction( null, diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt index eaa2b1a7e..541d075c9 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt @@ -28,7 +28,7 @@ class FAPersisterImplTest { @Test fun givenFAAndStatus_whenUpdatingStatusAndFANotFound_throwException(): Unit = runBlocking { - faPersister.updateStatus(DOC.fa, FinancialActionStatus.CREATED) + faPersister.updateStatus(Valid.fa, FinancialActionStatus.CREATED) coVerify { financialActionRepository.updateStatusAndIncreaseRetry(any(), any()) } } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt index 93d6b0d7d..2c146557c 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt @@ -13,8 +13,8 @@ import reactor.core.publisher.Mono class OrderPersisterImplTest { private val repository = mockk { - every { save(any()) } returns Mono.just(DOC.orderModel) - every { findByOuid(any()) } returns Mono.just(DOC.orderModel) + every { save(any()) } returns Mono.just(Valid.orderModel) + every { findByOuid(any()) } returns Mono.just(Valid.orderModel) } private val persister = OrderPersisterImpl(repository) @@ -29,24 +29,24 @@ class OrderPersisterImplTest { fun givenOUID_whenLoading_resultIsValidOrder(): Unit = runBlocking { val order = persister.load("")!! coVerify { repository.findByOuid(any()) } - assertThat(order.status).isEqualTo(DOC.orderModel.status) - assertThat(order.matchingEngineId).isEqualTo(DOC.orderModel.matchingEngineId) - assertThat(order.direction).isEqualTo(DOC.orderModel.direction) - assertThat(order.filledQuantity).isEqualTo(DOC.orderModel.filledQuantity) - assertThat(order.ouid).isEqualTo(DOC.orderModel.ouid) + assertThat(order.status).isEqualTo(Valid.orderModel.status) + assertThat(order.matchingEngineId).isEqualTo(Valid.orderModel.matchingEngineId) + assertThat(order.direction).isEqualTo(Valid.orderModel.direction) + assertThat(order.filledQuantity).isEqualTo(Valid.orderModel.filledQuantity) + assertThat(order.ouid).isEqualTo(Valid.orderModel.ouid) } @Test fun givenNewOrder_whenSaving_saveAndReturnValidOrder(): Unit = runBlocking { - val newOrder = persister.save(DOC.order) + val newOrder = persister.save(Valid.order) coVerify { repository.save(any()) } - with(DOC.order){ + with(Valid.order){ assertThat(newOrder).isNotNull - assertThat(status).isEqualTo(DOC.orderModel.status) - assertThat(matchingEngineId).isEqualTo(DOC.orderModel.matchingEngineId) - assertThat(direction).isEqualTo(DOC.orderModel.direction) - assertThat(filledQuantity).isEqualTo(DOC.orderModel.filledQuantity) - assertThat(ouid).isEqualTo(DOC.orderModel.ouid) + assertThat(status).isEqualTo(Valid.orderModel.status) + assertThat(matchingEngineId).isEqualTo(Valid.orderModel.matchingEngineId) + assertThat(direction).isEqualTo(Valid.orderModel.direction) + assertThat(filledQuantity).isEqualTo(Valid.orderModel.filledQuantity) + assertThat(ouid).isEqualTo(Valid.orderModel.ouid) } } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt index 954b8faf5..87188040d 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt @@ -19,12 +19,12 @@ import reactor.core.publisher.Mono class PairConfigLoaderTest { private val pairConfigRepository = mockk { - every { findAll() } returns Flux.just(DOC.pairConfigModel, DOC.pairConfigModel) - every { findById(any() as String) } returns Mono.just(DOC.pairConfigModel) + every { findAll() } returns Flux.just(Valid.pairConfigModel, Valid.pairConfigModel) + every { findById(any() as String) } returns Mono.just(Valid.pairConfigModel) } private val pairFeeConfigRepository = mockk { - every { findAll() } returns Flux.just(DOC.pairFeeConfigModel, DOC.pairFeeConfigModel) - every { findByPairAndDirectionAndUserLevel(any(), any(), any()) } returns Mono.just(DOC.pairFeeConfigModel) + every { findAll() } returns Flux.just(Valid.pairFeeConfigModel, Valid.pairFeeConfigModel) + every { findByPairAndDirectionAndUserLevel(any(), any(), any()) } returns Mono.just(Valid.pairFeeConfigModel) } private val pairConfigLoader = PairConfigLoaderImpl(pairConfigRepository, pairFeeConfigRepository) @@ -33,11 +33,11 @@ class PairConfigLoaderTest { val configs = pairConfigLoader.loadPairConfigs() assertThat(configs.size).isEqualTo(2) with(configs[1]) { - assertThat(pair).isEqualTo(DOC.pairConfig.pair) - assertThat(leftSideWalletSymbol).isEqualTo(DOC.pairConfig.leftSideWalletSymbol) - assertThat(rightSideWalletSymbol).isEqualTo(DOC.pairConfig.rightSideWalletSymbol) - assertThat(leftSideFraction).isEqualTo(DOC.pairConfig.leftSideFraction) - assertThat(rightSideFraction).isEqualTo(DOC.pairConfig.rightSideFraction) + assertThat(pair).isEqualTo(Valid.pairConfig.pair) + assertThat(leftSideWalletSymbol).isEqualTo(Valid.pairConfig.leftSideWalletSymbol) + assertThat(rightSideWalletSymbol).isEqualTo(Valid.pairConfig.rightSideWalletSymbol) + assertThat(leftSideFraction).isEqualTo(Valid.pairConfig.leftSideFraction) + assertThat(rightSideFraction).isEqualTo(Valid.pairConfig.rightSideFraction) } } @@ -46,11 +46,11 @@ class PairConfigLoaderTest { val configs = pairConfigLoader.loadPairFeeConfigs() assertThat(configs.size).isEqualTo(2) with(configs[1]) { - assertThat(pairConfig.pair).isEqualTo(DOC.pairConfig.pair) - assertThat(userLevel).isEqualTo(DOC.pairFeeConfigModel.userLevel) - assertThat(direction).isEqualTo(DOC.pairFeeConfigModel.direction) - assertThat(makerFee).isEqualTo(DOC.pairFeeConfigModel.makerFee) - assertThat(takerFee).isEqualTo(DOC.pairFeeConfigModel.takerFee) + assertThat(pairConfig.pair).isEqualTo(Valid.pairConfig.pair) + assertThat(userLevel).isEqualTo(Valid.pairFeeConfigModel.userLevel) + assertThat(direction).isEqualTo(Valid.pairFeeConfigModel.direction) + assertThat(makerFee).isEqualTo(Valid.pairFeeConfigModel.makerFee) + assertThat(takerFee).isEqualTo(Valid.pairFeeConfigModel.takerFee) } } @@ -118,11 +118,11 @@ class PairConfigLoaderTest { @Test fun givenPairDirection_whenConfigLoaded_returnValidPairConfig(): Unit = runBlocking { with(pairConfigLoader.load("BTC_USDT", OrderDirection.BID)){ - assertThat(pair).isEqualTo(DOC.pairConfigModel.pair) - assertThat(leftSideWalletSymbol).isEqualTo(DOC.pairConfigModel.leftSideWalletSymbol) - assertThat(rightSideWalletSymbol).isEqualTo(DOC.pairConfigModel.rightSideWalletSymbol) - assertThat(rightSideFraction).isEqualTo(DOC.pairConfigModel.rightSideFraction) - assertThat(leftSideFraction).isEqualTo(DOC.pairConfigModel.leftSideFraction) + assertThat(pair).isEqualTo(Valid.pairConfigModel.pair) + assertThat(leftSideWalletSymbol).isEqualTo(Valid.pairConfigModel.leftSideWalletSymbol) + assertThat(rightSideWalletSymbol).isEqualTo(Valid.pairConfigModel.rightSideWalletSymbol) + assertThat(rightSideFraction).isEqualTo(Valid.pairConfigModel.rightSideFraction) + assertThat(leftSideFraction).isEqualTo(Valid.pairConfigModel.leftSideFraction) } } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt index e16aa810c..711193ed8 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt @@ -18,8 +18,8 @@ class TempEventPersisterTest { private val tempEventRepository = mockk { every { save(any()) } returns Mono.empty() - every { findAll(any()) } returns flow { emit(DOC.tempEventModel) } - every { findByOuid(any()) } returns flow { emit(DOC.tempEventModel) } + every { findAll(any()) } returns flow { emit(Valid.tempEventModel) } + every { findByOuid(any()) } returns flow { emit(Valid.tempEventModel) } every { delete(any()) } returns Mono.empty() every { deleteAll(any() as Iterable) } returns Mono.empty() every { deleteByOuid(any()) } returns Mono.empty() @@ -29,7 +29,7 @@ class TempEventPersisterTest { @Test fun givenOuidAndEvent_whenSaving_callRepoOnce(): Unit = runBlocking { - persister.saveTempEvent("event_1", DOC.testEvent) + persister.saveTempEvent("event_1", Valid.testEvent) verify(exactly = 1) { tempEventRepository.save(any()) } } @@ -41,8 +41,8 @@ class TempEventPersisterTest { with(events[0]) { assertThat(this).isInstanceOf(CoreEvent::class.java) - assertThat(pair.rightSideName).isEqualTo(DOC.testEvent.rightSidePair) - assertThat(pair.leftSideName).isEqualTo(DOC.testEvent.leftSidePair) + assertThat(pair.rightSideName).isEqualTo(Valid.testEvent.rightSidePair) + assertThat(pair.leftSideName).isEqualTo(Valid.testEvent.leftSidePair) } } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt similarity index 96% rename from accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt rename to accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt index 0e9c41ad8..4fc41ccfe 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/DOC.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt @@ -18,7 +18,7 @@ import co.nilin.opex.matching.engine.core.model.Pair import java.math.BigDecimal import java.time.LocalDateTime -object DOC { +object Valid { val orderModel = OrderModel( 1, diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt index beb66b33c..8c82f9875 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt @@ -29,9 +29,9 @@ class EventPublishersTest { private val tempEventSubmitter = TempEventSubmitter(tempEventTemplate) init { - every { richOrderTemplate.send(any(), any()) } returns DOC.kafkaSendFuture() - every { richTradeTemplate.send(any(), any()) } returns DOC.kafkaSendFuture() - every { tempEventTemplate.send(any(), any()) } returns DOC.kafkaSendFuture() + every { richOrderTemplate.send(any(), any()) } returns Valid.kafkaSendFuture() + every { richTradeTemplate.send(any(), any()) } returns Valid.kafkaSendFuture() + every { tempEventTemplate.send(any(), any()) } returns Valid.kafkaSendFuture() } @Test @@ -49,7 +49,7 @@ class EventPublishersTest { future.setException(IllegalStateException("mock")) Assertions.assertThatThrownBy { - runBlocking { richOrderSubmitter.publish(DOC.testRichOrder) } + runBlocking { richOrderSubmitter.publish(Valid.testRichOrder) } }.isInstanceOfAny(Throwable::class.java) } @@ -61,7 +61,7 @@ class EventPublishersTest { future.setException(IllegalStateException("mock")) Assertions.assertThatThrownBy { - runBlocking { richTradeSubmitter.publish(DOC.richTrade) } + runBlocking { richTradeSubmitter.publish(Valid.richTrade) } }.isInstanceOfAny(Throwable::class.java) } @@ -73,25 +73,25 @@ class EventPublishersTest { future.setException(IllegalStateException("mock")) Assertions.assertThatThrownBy { - runBlocking { tempEventSubmitter.republish(listOf(DOC.testCoreEvent)) } + runBlocking { tempEventSubmitter.republish(listOf(Valid.testCoreEvent)) } }.isInstanceOfAny(Throwable::class.java) } @Test fun givenRichOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { - richOrderSubmitter.publish(DOC.testRichOrder) + richOrderSubmitter.publish(Valid.testRichOrder) verify { richOrderTemplate.send(eq(richOrderSubmitter.topic()),any()) } } @Test fun givenTradeOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { - richTradeSubmitter.publish(DOC.richTrade) + richTradeSubmitter.publish(Valid.richTrade) verify { richTradeTemplate.send(eq(richTradeSubmitter.topic()),any()) } } @Test fun givenTempEventSubmitter_whenRepublish_callSendForEachEventWithCorrectTopic(): Unit = runBlocking { - tempEventSubmitter.republish(listOf(DOC.testCoreEvent,DOC.testCoreEvent)) + tempEventSubmitter.republish(listOf(Valid.testCoreEvent,Valid.testCoreEvent)) verify(exactly = 2) { tempEventTemplate.send(eq(tempEventSubmitter.topic()),any()) } } diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DOC.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt similarity index 95% rename from accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DOC.kt rename to accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt index 7f434ae31..e7cb17831 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/DOC.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt @@ -9,7 +9,7 @@ import org.springframework.kafka.support.SendResult import org.springframework.util.concurrent.SettableListenableFuture import java.time.LocalDateTime -object DOC { +object Valid { class TestRichOrderEvent : RichOrderEvent class TestCoreEvent : CoreEvent(Pair("BTC", "USDT")) From c7aa4f1802397875fbc709f3a4b21ea50c996a5b Mon Sep 17 00:00:00 2001 From: Peyman Date: Tue, 7 Jun 2022 15:52:14 +0430 Subject: [PATCH 15/18] Refactor --- .../nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt | 1 + .../opex/accountant/ports/postgres/OrderPersisterImplTest.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt index 541d075c9..398891cd1 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt @@ -12,6 +12,7 @@ import org.junit.jupiter.api.Test import reactor.core.publisher.Flux import reactor.core.publisher.Mono +@Suppress("ReactiveStreamsUnusedPublisher") class FAPersisterImplTest { private val financialActionRepository = mockk { diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt index 2c146557c..bfb9427c5 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt @@ -10,6 +10,7 @@ import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test import reactor.core.publisher.Mono +@Suppress("ReactiveStreamsUnusedPublisher") class OrderPersisterImplTest { private val repository = mockk { From 337e4ef17bea3ecd0d1afa0a0d6256ee3ff2c9e0 Mon Sep 17 00:00:00 2001 From: Peyman Date: Mon, 13 Jun 2022 13:08:56 +0430 Subject: [PATCH 16/18] Refactor and improvements --- .../core/service/FAJobManagerImplTest.kt | 76 +++++++++++- .../core/service/FeeCalculatorImplTest.kt | 84 ++----------- .../core/service/OrderManagerImplTest.kt | 41 ++----- .../opex/accountant/core/service/Valid.kt | 111 ++++++++++++++++++ .../kafka/listener/consumer/ListenerObject.kt | 5 +- .../impl/FinancialActionPersisterImpl.kt | 3 +- .../postgres/impl/TempEventPersisterImpl.kt | 10 +- .../postgres/model/FinancialActionModel.kt | 2 +- .../ports/postgres/model/OrderModel.kt | 2 +- .../postgres/model/PairFeeConfigModel.kt | 2 +- .../ports/postgres/FAPersisterImplTest.kt | 13 +- .../ports/postgres/OrderPersisterImplTest.kt | 8 +- .../ports/postgres/PairConfigLoaderTest.kt | 18 ++- .../ports/postgres/TempEventPersisterTest.kt | 4 +- .../opex/accountant/ports/postgres/Valid.kt | 23 +++- .../kafka/submitter/service/EventPublisher.kt | 4 +- .../submitter/service/RichOrderSubmitter.kt | 10 +- .../submitter/service/RichTradeSubmitter.kt | 9 +- .../submitter/service/TempEventSubmitter.kt | 8 +- .../kafka/submitter/EventPublishersTest.kt | 18 +-- 20 files changed, 283 insertions(+), 168 deletions(-) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt index 5825f3000..14df01b48 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt @@ -1,5 +1,6 @@ package co.nilin.opex.accountant.core.service +import co.nilin.opex.accountant.core.model.FinancialActionStatus import co.nilin.opex.accountant.core.spi.FinancialActionLoader import co.nilin.opex.accountant.core.spi.FinancialActionPersister import co.nilin.opex.accountant.core.spi.WalletProxy @@ -26,8 +27,26 @@ class FAJobManagerImplTest { fun given2FALoaded_whenProcessing_thenVerifyThatTransferProxyCalled2Times() = runBlocking { coEvery { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } returns Unit sut.processFinancialActions(0, 2) - coVerify(exactly = 2) { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } - coVerify(exactly = 2) { financialActionPersister.updateStatus(any(), any()) } + with(Valid.fa) { + coVerify(exactly = 2) { + walletProxy.transfer( + eq(symbol), + eq(senderWalletType), + eq(sender), + eq(receiverWalletType), + eq(receiver), + eq(amount), + eq(eventType + pointer), + any() + ) + } + coVerify(exactly = 2) { + financialActionPersister.updateStatus( + eq(this@with), + eq(FinancialActionStatus.PROCESSED) + ) + } + } } @Test @@ -37,8 +56,57 @@ class FAJobManagerImplTest { } throws IllegalStateException() sut.processFinancialActions(0, 2) - coVerify(exactly = 2) { walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) } - coVerify(exactly = 2) { financialActionPersister.updateStatus(any(), any()) } + with(Valid.fa){ + coVerify(exactly = 2) { + walletProxy.transfer( + eq(symbol), + eq(senderWalletType), + eq(sender), + eq(receiverWalletType), + eq(receiver), + eq(amount), + eq(eventType + pointer), + any() + ) + } + coVerify(exactly = 2) { + financialActionPersister.updateStatus( + eq(this@with), + eq(FinancialActionStatus.CREATED) + ) + } + } + } + + @Test + fun given2FALoaded_whenProcessingFailedAndRetryCountExceeded_thenUpdateStatusCalledRegardless() = runBlocking { + coEvery { + walletProxy.transfer(any(), any(), any(), any(), any(), any(), any(), any()) + } throws IllegalStateException() + + coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(Valid.faHighRetry) + + sut.processFinancialActions(0, 1) + with(Valid.faHighRetry){ + coVerify(exactly = 1) { + walletProxy.transfer( + eq(symbol), + eq(senderWalletType), + eq(sender), + eq(receiverWalletType), + eq(receiver), + eq(amount), + eq(eventType + pointer), + any() + ) + } + coVerify(exactly = 1) { + financialActionPersister.updateStatus( + eq(this@with), + eq(FinancialActionStatus.ERROR) + ) + } + } } } \ No newline at end of file diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt index cf28a48ee..6ba568e71 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt @@ -1,97 +1,29 @@ package co.nilin.opex.accountant.core.service -import co.nilin.opex.accountant.core.inout.OrderStatus import co.nilin.opex.accountant.core.model.FinancialAction -import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent -import co.nilin.opex.matching.engine.core.model.MatchConstraint -import co.nilin.opex.matching.engine.core.model.OrderDirection -import co.nilin.opex.matching.engine.core.model.OrderType -import co.nilin.opex.matching.engine.core.model.Pair import kotlinx.coroutines.runBlocking import org.assertj.core.api.Assertions.assertThat import org.junit.jupiter.api.Test -import java.math.BigDecimal import java.time.LocalDateTime internal class FeeCalculatorImplTest { private val receiverAddress = "0x0" private val feeCalculator = FeeCalculatorImpl(receiverAddress) - private var defaultMaker = Order( - "BTC_USDT", - "order_1", - 1, - 0.01.toBigDecimal(), - 0.01.toBigDecimal(), - 0.000001.toBigDecimal(), - 0.01.toBigDecimal(), - "user_1", - "*", - OrderDirection.BID, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER, - 50_000.toBigDecimal().divide(0.01.toBigDecimal()).longValueExact(), - 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), - 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), - 50_000.toBigDecimal(), - 1.toBigDecimal(), - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - OrderStatus.FILLED.code - ) - private var defaultTaker = Order( - "BTC_USDT", - "order_2", - 2, - 0.01.toBigDecimal(), - 0.01.toBigDecimal(), - 0.000001.toBigDecimal(), - 0.01.toBigDecimal(), - "user_2", - "*", - OrderDirection.ASK, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER, - 50_000.toBigDecimal().divide(0.01.toBigDecimal()).longValueExact(), - 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), - 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), - 50_000.toBigDecimal(), - 1.toBigDecimal(), - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - OrderStatus.FILLED.code - ) - private var defaultTrade = TradeEvent( - 1, - Pair("BTC", "USDT"), - "order_2", - "user_2", - 2, - OrderDirection.ASK, - (50_000 / 0.01).toLong(), - 0, - "order_1", - "user_1", - 1, - OrderDirection.BID, - (50_000 / 0.01).toLong(), - 0, - (1 / 0.000001).toLong() - ) @Test fun givenTradeEventsAndOrders_whenFeeCalculated_feeActionsNotNull(): Unit = runBlocking { - val actions = feeCalculator.createFeeActions(defaultTrade, defaultMaker, defaultTaker, null, null) + val actions = + feeCalculator.createFeeActions(Valid.tradeEvent, Valid.makerOrder, Valid.takerOrder, null, null) assertThat(actions.makerFeeAction).isNotNull assertThat(actions.takerFeeAction).isNotNull } @Test fun givenTradeEventsAndOrders_whenFeeCalculated_returnCorrectFees(): Unit = runBlocking { - val actions = feeCalculator.createFeeActions(defaultTrade, defaultMaker, defaultTaker, null, null) + val actions = + feeCalculator.createFeeActions(Valid.tradeEvent, Valid.makerOrder, Valid.takerOrder, null, null) with(actions.makerFeeAction) { assertThat(amount.toDouble()).isEqualTo(0.01) // 1% of 1 BTC assertThat(symbol).isEqualTo("BTC") @@ -126,7 +58,13 @@ internal class FeeCalculatorImplTest { LocalDateTime.now() ) - val actions = feeCalculator.createFeeActions(defaultTrade, defaultMaker, defaultTaker, parentFA, parentFA) + val actions = feeCalculator.createFeeActions( + Valid.tradeEvent, + Valid.makerOrder, + Valid.takerOrder, + parentFA, + parentFA + ) assertThat(actions.makerFeeAction.parent).isNotNull assertThat(actions.takerFeeAction.parent).isNotNull } diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt index 1ff6165a3..73934989e 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt @@ -2,7 +2,6 @@ package co.nilin.opex.accountant.core.service import co.nilin.opex.accountant.core.inout.OrderStatus import co.nilin.opex.accountant.core.model.FinancialAction -import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.accountant.core.model.PairConfig import co.nilin.opex.accountant.core.model.PairFeeConfig import co.nilin.opex.accountant.core.spi.* @@ -44,30 +43,6 @@ internal class OrderManagerImplTest { richOrderPublisher ) - private val order = Order( - "BTC_USDT", - "order_ouid", - null, - 0.01.toBigDecimal(), - 0.01.toBigDecimal(), - 0.000001.toBigDecimal(), - 0.01.toBigDecimal(), - "user_1", - "*", - OrderDirection.BID, - MatchConstraint.GTC, - OrderType.LIMIT_ORDER, - 100000, - 1000, - 0, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - BigDecimal.ZERO, - 100000.0.toBigDecimal(), - OrderStatus.NEW.code - ) - init { coEvery { tempEventPersister.loadTempEvents(any()) } returns emptyList() coEvery { orderPersister.save(any()) } returnsArgument (0) @@ -203,12 +178,12 @@ internal class OrderManagerImplTest { OrderDirection.BID ) - coEvery { orderPersister.load(any()) } returns order + coEvery { orderPersister.load(any()) } returns Valid.order val fa = orderManager.handleNewOrder(orderEvent) assertThat(fa.size).isEqualTo(0) - assertThat(order.matchingEngineId).isEqualTo(55) + assertThat(Valid.order.matchingEngineId).isEqualTo(55) coVerify(exactly = 1) { richOrderPublisher.publish(any()) } } @@ -267,13 +242,13 @@ internal class OrderManagerImplTest { RequestedOperation.CANCEL_ORDER, RejectReason.ORDER_NOT_FOUND, ) - coEvery { orderPersister.load(any()) } returns order + coEvery { orderPersister.load(any()) } returns Valid.order val fa = orderManager.handleRejectOrder(orderEvent)[0] - assertThat(fa.amount).isEqualTo(order.remainedTransferAmount) + assertThat(fa.amount).isEqualTo(Valid.order.remainedTransferAmount) assertThat(fa.symbol).isEqualTo(orderEvent.pair.rightSideName) - assertThat(order.status).isEqualTo(OrderStatus.REJECTED.code) + assertThat(Valid.order.status).isEqualTo(OrderStatus.REJECTED.code) coVerify(exactly = 1) { richOrderPublisher.publish(any()) } coVerify(exactly = 1) { orderPersister.save(any()) } @@ -312,13 +287,13 @@ internal class OrderManagerImplTest { 500, OrderDirection.BID ) - coEvery { orderPersister.load(any()) } returns order + coEvery { orderPersister.load(any()) } returns Valid.order val fa = orderManager.handleCancelOrder(orderEvent)[0] - assertThat(fa.amount).isEqualTo(order.remainedTransferAmount) + assertThat(fa.amount).isEqualTo(Valid.order.remainedTransferAmount) assertThat(fa.symbol).isEqualTo(orderEvent.pair.rightSideName) - assertThat(order.status).isEqualTo(OrderStatus.CANCELED.code) + assertThat(Valid.order.status).isEqualTo(OrderStatus.CANCELED.code) coVerify(exactly = 1) { richOrderPublisher.publish(any()) } coVerify(exactly = 1) { orderPersister.save(any()) } diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt index 2baf7a88d..9300e86e5 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt @@ -1,7 +1,14 @@ package co.nilin.opex.accountant.core.service +import co.nilin.opex.accountant.core.inout.OrderStatus import co.nilin.opex.accountant.core.model.FinancialAction +import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent +import co.nilin.opex.matching.engine.core.model.MatchConstraint +import co.nilin.opex.matching.engine.core.model.OrderDirection +import co.nilin.opex.matching.engine.core.model.OrderType +import co.nilin.opex.matching.engine.core.model.Pair +import java.math.BigDecimal import java.time.LocalDateTime object Valid { @@ -19,4 +26,108 @@ object Valid { LocalDateTime.now() ) + val faHighRetry = FinancialAction( + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + LocalDateTime.now(), + 15 + ) + + var makerOrder = Order( + "BTC_USDT", + "order_1", + 1, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.000001.toBigDecimal(), + 0.01.toBigDecimal(), + "user_1", + "*", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 50_000.toBigDecimal().divide(0.01.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 50_000.toBigDecimal(), + 1.toBigDecimal(), + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.FILLED.code + ) + + var takerOrder = Order( + "BTC_USDT", + "order_2", + 2, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.000001.toBigDecimal(), + 0.01.toBigDecimal(), + "user_2", + "*", + OrderDirection.ASK, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 50_000.toBigDecimal().divide(0.01.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 1.toBigDecimal().divide(0.000001.toBigDecimal()).longValueExact(), + 50_000.toBigDecimal(), + 1.toBigDecimal(), + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + OrderStatus.FILLED.code + ) + + var tradeEvent = TradeEvent( + 1, + Pair("BTC", "USDT"), + "order_2", + "user_2", + 2, + OrderDirection.ASK, + (50_000 / 0.01).toLong(), + 0, + "order_1", + "user_1", + 1, + OrderDirection.BID, + (50_000 / 0.01).toLong(), + 0, + (1 / 0.000001).toLong() + ) + + val order = Order( + "BTC_USDT", + "order_ouid", + null, + 0.01.toBigDecimal(), + 0.01.toBigDecimal(), + 0.000001.toBigDecimal(), + 0.01.toBigDecimal(), + "user_1", + "*", + OrderDirection.BID, + MatchConstraint.GTC, + OrderType.LIMIT_ORDER, + 100000, + 1000, + 0, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + BigDecimal.ZERO, + 100000.0.toBigDecimal(), + OrderStatus.NEW.code + ) + } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt index 6d3f268af..d99cb8469 100644 --- a/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt +++ b/accountant/accountant-ports/accountant-eventlistener-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/listener/consumer/ListenerObject.kt @@ -1,14 +1,17 @@ package co.nilin.opex.accountant.ports.kafka.listener.consumer import co.nilin.opex.accountant.ports.kafka.listener.spi.Listener +import org.slf4j.LoggerFactory class ListenerObject : Listener { + private val logger = LoggerFactory.getLogger(ListenerObject::class.java) + override fun id(): String { return "AnyListener" } override fun onEvent(event: Any, partition: Int, offset: Long, timestamp: Long) { - println("event called") + logger.info("event called") } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt index a8ec77beb..fb82e954d 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/FinancialActionPersisterImpl.kt @@ -6,6 +6,7 @@ import co.nilin.opex.accountant.core.spi.FinancialActionPersister import co.nilin.opex.accountant.ports.postgres.dao.FinancialActionRepository import co.nilin.opex.accountant.ports.postgres.model.FinancialActionModel import kotlinx.coroutines.reactive.awaitFirstOrNull +import kotlinx.coroutines.reactor.awaitSingle import org.springframework.stereotype.Component @Component @@ -29,7 +30,7 @@ class FinancialActionPersisterImpl(private val financialActionRepository: Financ "", it.createDate ) - }).awaitFirstOrNull() + }).collectList().awaitSingle() return financialActions } diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt index d07388817..bba689912 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/impl/TempEventPersisterImpl.kt @@ -42,15 +42,7 @@ class TempEventPersisterImpl(private val tempEventRepository: TempEventRepositor } override suspend fun removeTempEvents(tempEvents: List) { - tempEventRepository.deleteAll(tempEvents.map { - TempEventModel( - it.id, - it.ouid, - it.eventBody.javaClass.name, - "", - it.eventDate - ) - }).awaitFirstOrNull() + tempEventRepository.deleteAllById(tempEvents.map { it.id }).awaitFirstOrNull() } override suspend fun fetchTempEvents(offset: Long, size: Long): List { diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt index 734e4e660..e7f5ac076 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/FinancialActionModel.kt @@ -8,7 +8,7 @@ import java.math.BigDecimal import java.time.LocalDateTime @Table("fi_actions") -class FinancialActionModel( +data class FinancialActionModel( @Id var id: Long?, @Column("parent_id") var parentId: Long?, @Column("event_type") val eventType: String, diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/OrderModel.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/OrderModel.kt index 1274516d5..5858767ee 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/OrderModel.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/OrderModel.kt @@ -10,7 +10,7 @@ import java.math.BigDecimal import java.time.LocalDateTime @Table("orders") -class OrderModel( +data class OrderModel( @Id var id: Long?, val ouid: String, val uuid: String, diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/PairFeeConfigModel.kt b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/PairFeeConfigModel.kt index 346fd5336..cd46a2abc 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/PairFeeConfigModel.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/main/kotlin/co/nilin/opex/accountant/ports/postgres/model/PairFeeConfigModel.kt @@ -5,7 +5,7 @@ import org.springframework.data.relational.core.mapping.Table import java.math.BigDecimal @Table("pair_fee_config") -class PairFeeConfigModel( +data class PairFeeConfigModel( val id: Long?, @Column("pair_config_id") val pairConfigId: String, @Column("direction") val direction: String, diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt index 398891cd1..5813cb072 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/FAPersisterImplTest.kt @@ -16,21 +16,26 @@ import reactor.core.publisher.Mono class FAPersisterImplTest { private val financialActionRepository = mockk { - coEvery { saveAll(emptyList()) } returns Flux.empty() + coEvery { saveAll(any() as Iterable) } returns Flux.just(Valid.faModel) coEvery { updateStatusAndIncreaseRetry(any(), any()) } returns Mono.empty() } private val faPersister = FinancialActionPersisterImpl(financialActionRepository) @Test fun givenListOfActions_whenSaving_callSaveAll(): Unit = runBlocking { - faPersister.persist(emptyList()) - coVerify { financialActionRepository.saveAll(any() as Iterable) } + faPersister.persist(listOf(Valid.fa)) + coVerify { financialActionRepository.saveAll(eq(listOf(Valid.faModel))) } } @Test fun givenFAAndStatus_whenUpdatingStatusAndFANotFound_throwException(): Unit = runBlocking { faPersister.updateStatus(Valid.fa, FinancialActionStatus.CREATED) - coVerify { financialActionRepository.updateStatusAndIncreaseRetry(any(), any()) } + coVerify { + financialActionRepository.updateStatusAndIncreaseRetry( + eq(Valid.fa.id!!), + eq(FinancialActionStatus.CREATED) + ) + } } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt index bfb9427c5..52260d5d0 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/OrderPersisterImplTest.kt @@ -22,14 +22,14 @@ class OrderPersisterImplTest { @Test fun givenOUID_whenLoading_resultNotNull(): Unit = runBlocking { - val order = persister.load("") + val order = persister.load(Valid.orderModel.ouid) assertThat(order).isNotNull } @Test fun givenOUID_whenLoading_resultIsValidOrder(): Unit = runBlocking { - val order = persister.load("")!! - coVerify { repository.findByOuid(any()) } + val order = persister.load(Valid.orderModel.ouid)!! + coVerify { repository.findByOuid(eq(Valid.orderModel.ouid)) } assertThat(order.status).isEqualTo(Valid.orderModel.status) assertThat(order.matchingEngineId).isEqualTo(Valid.orderModel.matchingEngineId) assertThat(order.direction).isEqualTo(Valid.orderModel.direction) @@ -41,7 +41,7 @@ class OrderPersisterImplTest { fun givenNewOrder_whenSaving_saveAndReturnValidOrder(): Unit = runBlocking { val newOrder = persister.save(Valid.order) coVerify { repository.save(any()) } - with(Valid.order){ + with(Valid.order) { assertThat(newOrder).isNotNull assertThat(status).isEqualTo(Valid.orderModel.status) assertThat(matchingEngineId).isEqualTo(Valid.orderModel.matchingEngineId) diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt index 87188040d..73da00a7f 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/PairConfigLoaderTest.kt @@ -66,7 +66,13 @@ class PairConfigLoaderTest { fun givenPairDirection_whenUserLevelEmpty_loadWithDefaultUserLevel(): Unit = runBlocking { val pair = pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "") assertThat(pair).isNotNull - verify(exactly = 1) { pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("*")) } + verify(exactly = 1) { + pairFeeConfigRepository.findByPairAndDirectionAndUserLevel( + eq("BTC_USDT"), + eq(OrderDirection.BID), + eq("*") + ) + } } @Test @@ -88,7 +94,13 @@ class PairConfigLoaderTest { val pair = pairConfigLoader.load("BTC_USDT", OrderDirection.BID, "1") assertThat(pair).isNotNull - verify(exactly = 1) { pairFeeConfigRepository.findByPairAndDirectionAndUserLevel(any(), any(), eq("*")) } + verify(exactly = 1) { + pairFeeConfigRepository.findByPairAndDirectionAndUserLevel( + eq("BTC_USDT"), + eq(OrderDirection.BID), + eq("*") + ) + } } @Test @@ -117,7 +129,7 @@ class PairConfigLoaderTest { @Test fun givenPairDirection_whenConfigLoaded_returnValidPairConfig(): Unit = runBlocking { - with(pairConfigLoader.load("BTC_USDT", OrderDirection.BID)){ + with(pairConfigLoader.load("BTC_USDT", OrderDirection.BID)) { assertThat(pair).isEqualTo(Valid.pairConfigModel.pair) assertThat(leftSideWalletSymbol).isEqualTo(Valid.pairConfigModel.leftSideWalletSymbol) assertThat(rightSideWalletSymbol).isEqualTo(Valid.pairConfigModel.rightSideWalletSymbol) diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt index 711193ed8..d0933fdee 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/TempEventPersisterTest.kt @@ -48,8 +48,8 @@ class TempEventPersisterTest { @Test fun givenOuid_whenDeletingByOUID_callRepoOnce(): Unit = runBlocking { - persister.removeTempEvents("event_1") - verify(exactly = 1) { tempEventRepository.deleteByOuid(any()) } + persister.removeTempEvents(Valid.tempEvent.ouid) + verify(exactly = 1) { tempEventRepository.deleteByOuid(eq(Valid.tempEvent.ouid)) } } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt index 4fc41ccfe..302e78751 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt @@ -5,10 +5,7 @@ import co.nilin.opex.accountant.core.model.FinancialAction import co.nilin.opex.accountant.core.model.Order import co.nilin.opex.accountant.core.model.PairConfig import co.nilin.opex.accountant.core.model.TempEvent -import co.nilin.opex.accountant.ports.postgres.model.OrderModel -import co.nilin.opex.accountant.ports.postgres.model.PairConfigModel -import co.nilin.opex.accountant.ports.postgres.model.PairFeeConfigModel -import co.nilin.opex.accountant.ports.postgres.model.TempEventModel +import co.nilin.opex.accountant.ports.postgres.model.* import co.nilin.opex.matching.engine.core.eventh.events.CoreEvent import co.nilin.opex.matching.engine.core.eventh.events.TradeEvent import co.nilin.opex.matching.engine.core.model.MatchConstraint @@ -101,7 +98,7 @@ object Valid { class TestCoreEvent(val leftSidePair: String, val rightSidePair: String) : CoreEvent(Pair(leftSidePair, rightSidePair), LocalDateTime.now()) - val testEvent = TestCoreEvent("BTC","USDT") + val testEvent = TestCoreEvent("BTC", "USDT") val tempEvent = TempEvent( 1, @@ -133,4 +130,20 @@ object Valid { 1 ) + val faModel = FinancialActionModel( + null, + null, + TradeEvent::class.java.name, + "trade_id", + "BTC_USDT", + 10000.0.toBigDecimal(), + "user_parent", + "main", + "system", + "main", + "", + "", + LocalDateTime.now() + ) + } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt index 0fbe3e4ca..afd662665 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/EventPublisher.kt @@ -1,5 +1,7 @@ package co.nilin.opex.accountant.ports.kafka.submitter.service interface EventPublisher { - fun topic(): String + + val topic: String + } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt index e85424cd6..aaeabb34a 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichOrderSubmitter.kt @@ -13,15 +13,17 @@ import kotlin.coroutines.suspendCoroutine @Component class RichOrderSubmitter( @Qualifier("richOrderKafkaTemplate") - private val kafkaTemplate: KafkaTemplate + private val kafkaTemplate: KafkaTemplate, ) : RichOrderPublisher, EventPublisher { private val logger = LoggerFactory.getLogger(RichOrderSubmitter::class.java) + override val topic = "richOrder" + override suspend fun publish(order: RichOrderEvent): Unit = suspendCoroutine { cont -> logger.info("Submitting RichOrder") - val sendFuture = kafkaTemplate.send(topic(), order) + val sendFuture = kafkaTemplate.send(topic, order) sendFuture.addCallback({ cont.resume(Unit) }, { @@ -29,8 +31,4 @@ class RichOrderSubmitter( cont.resumeWithException(it) }) } - - override fun topic(): String { - return "richOrder" - } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt index 5e69d69d0..e3d7554db 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/RichTradeSubmitter.kt @@ -14,14 +14,16 @@ import kotlin.coroutines.suspendCoroutine class RichTradeSubmitter( @Qualifier("richTradeKafkaTemplate") private val kafkaTemplate: KafkaTemplate -) : RichTradePublisher,EventPublisher { +) : RichTradePublisher, EventPublisher { private val logger = LoggerFactory.getLogger(RichTradeSubmitter::class.java) + override val topic = "richTrade" + override suspend fun publish(trade: RichTrade): Unit = suspendCoroutine { cont -> logger.info("Submitting RichTrade event: id=${trade.id}") - val sendFuture = kafkaTemplate.send(topic(), trade) + val sendFuture = kafkaTemplate.send(topic, trade) sendFuture.addCallback({ cont.resume(Unit) }, { @@ -30,7 +32,4 @@ class RichTradeSubmitter( }) } - override fun topic(): String { - return "richTrade" - } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt index 5082b2b06..f2630016a 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/main/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/service/TempEventSubmitter.kt @@ -18,11 +18,13 @@ class TempEventSubmitter( private val logger = LoggerFactory.getLogger(TempEventSubmitter::class.java) + override val topic = "tempevents" + override suspend fun republish(events: List): Unit = suspendCoroutine { cont -> logger.info("Submitting TempEvents") events.forEach { event -> - val sendFuture = kafkaTemplate.send(topic(), event) + val sendFuture = kafkaTemplate.send(topic, event) sendFuture.addCallback({ cont.resume(Unit) }, { @@ -31,8 +33,4 @@ class TempEventSubmitter( }) } } - - override fun topic(): String { - return "tempevents" - } } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt index 8c82f9875..987550f39 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/EventPublishersTest.kt @@ -36,9 +36,9 @@ class EventPublishersTest { @Test fun givenSubmitters_validateTopics(): Unit = runBlocking { - assertThat(richOrderSubmitter.topic()).isEqualTo("richOrder") - assertThat(richTradeSubmitter.topic()).isEqualTo("richTrade") - assertThat(tempEventSubmitter.topic()).isEqualTo("tempevents") + assertThat(richOrderSubmitter.topic).isEqualTo("richOrder") + assertThat(richTradeSubmitter.topic).isEqualTo("richTrade") + assertThat(tempEventSubmitter.topic).isEqualTo("tempevents") } @Test @@ -78,21 +78,21 @@ class EventPublishersTest { } @Test - fun givenRichOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { + fun givenRichOrderSubmitter_whenPublish_callSendWithCorrectTopic(): Unit = runBlocking { richOrderSubmitter.publish(Valid.testRichOrder) - verify { richOrderTemplate.send(eq(richOrderSubmitter.topic()),any()) } + verify { richOrderTemplate.send(eq(richOrderSubmitter.topic), eq(Valid.testRichOrder)) } } @Test - fun givenTradeOrderSubmitter_whenPublish_callSendWithCorrectTopic():Unit = runBlocking { + fun givenTradeOrderSubmitter_whenPublish_callSendWithCorrectTopic(): Unit = runBlocking { richTradeSubmitter.publish(Valid.richTrade) - verify { richTradeTemplate.send(eq(richTradeSubmitter.topic()),any()) } + verify { richTradeTemplate.send(eq(richTradeSubmitter.topic), eq(Valid.richTrade)) } } @Test fun givenTempEventSubmitter_whenRepublish_callSendForEachEventWithCorrectTopic(): Unit = runBlocking { - tempEventSubmitter.republish(listOf(Valid.testCoreEvent,Valid.testCoreEvent)) - verify(exactly = 2) { tempEventTemplate.send(eq(tempEventSubmitter.topic()),any()) } + tempEventSubmitter.republish(listOf(Valid.testCoreEvent, Valid.testCoreEvent)) + verify(exactly = 2) { tempEventTemplate.send(eq(tempEventSubmitter.topic), eq(Valid.testCoreEvent)) } } } \ No newline at end of file From 97331b799f9520aeabbb42b02d7342ffa9aa2c23 Mon Sep 17 00:00:00 2001 From: Peyman Date: Mon, 13 Jun 2022 13:10:56 +0430 Subject: [PATCH 17/18] Refactor and improvements --- .../core/service/FAJobManagerImplTest.kt | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt index 14df01b48..3318eac7d 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FAJobManagerImplTest.kt @@ -56,18 +56,18 @@ class FAJobManagerImplTest { } throws IllegalStateException() sut.processFinancialActions(0, 2) - with(Valid.fa){ + with(Valid.fa) { coVerify(exactly = 2) { walletProxy.transfer( - eq(symbol), - eq(senderWalletType), - eq(sender), - eq(receiverWalletType), - eq(receiver), - eq(amount), - eq(eventType + pointer), - any() - ) + eq(symbol), + eq(senderWalletType), + eq(sender), + eq(receiverWalletType), + eq(receiver), + eq(amount), + eq(eventType + pointer), + any() + ) } coVerify(exactly = 2) { financialActionPersister.updateStatus( @@ -87,7 +87,7 @@ class FAJobManagerImplTest { coEvery { financialActionLoader.loadUnprocessed(any(), any()) } returns listOf(Valid.faHighRetry) sut.processFinancialActions(0, 1) - with(Valid.faHighRetry){ + with(Valid.faHighRetry) { coVerify(exactly = 1) { walletProxy.transfer( eq(symbol), From 30f9885d75d970e3a09f0faf9759acb61059dfcd Mon Sep 17 00:00:00 2001 From: Peyman Date: Tue, 14 Jun 2022 14:45:55 +0430 Subject: [PATCH 18/18] Removed dynamic time --- .../core/service/FeeCalculatorImplTest.kt | 2 +- .../core/service/OrderManagerImplTest.kt | 4 ++-- .../co/nilin/opex/accountant/core/service/Valid.kt | 6 ++++-- .../nilin/opex/accountant/ports/postgres/Valid.kt | 14 ++++++++------ .../opex/accountant/ports/kafka/submitter/Valid.kt | 4 +++- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt index 6ba568e71..15d1b20dd 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/FeeCalculatorImplTest.kt @@ -55,7 +55,7 @@ internal class FeeCalculatorImplTest { "main", "system", "main", - LocalDateTime.now() + Valid.currentTime ) val actions = feeCalculator.createFeeActions( diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt index 73934989e..66193ff06 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/OrderManagerImplTest.kt @@ -94,7 +94,7 @@ internal class OrderManagerImplTest { "main", submitOrderEvent.uuid, "exchange", - LocalDateTime.now() + Valid.currentTime ) with(expectedFinancialAction) { @@ -152,7 +152,7 @@ internal class OrderManagerImplTest { "main", submitOrderEvent.uuid, "exchange", - LocalDateTime.now() + Valid.currentTime ) with(expectedFinancialAction) { assertThat(eventType).isEqualTo(financialActions[0].eventType) diff --git a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt index 9300e86e5..d54b99029 100644 --- a/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt +++ b/accountant/accountant-core/src/test/kotlin/co/nilin/opex/accountant/core/service/Valid.kt @@ -13,6 +13,8 @@ import java.time.LocalDateTime object Valid { + val currentTime = LocalDateTime.now() + val fa = FinancialAction( null, TradeEvent::class.java.name, @@ -23,7 +25,7 @@ object Valid { "main", "system", "main", - LocalDateTime.now() + currentTime ) val faHighRetry = FinancialAction( @@ -36,7 +38,7 @@ object Valid { "main", "system", "main", - LocalDateTime.now(), + currentTime, 15 ) diff --git a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt index 302e78751..9931a14ff 100644 --- a/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt +++ b/accountant/accountant-ports/accountant-persister-postgres/src/test/kotlin/co/nilin/opex/accountant/ports/postgres/Valid.kt @@ -17,6 +17,8 @@ import java.time.LocalDateTime object Valid { + private val currentTime = LocalDateTime.now() + val orderModel = OrderModel( 1, "order_1", @@ -42,7 +44,7 @@ object Valid { OrderStatus.FILLED.code, "", "", - LocalDateTime.now() + currentTime ) val order = Order( @@ -96,7 +98,7 @@ object Valid { ) class TestCoreEvent(val leftSidePair: String, val rightSidePair: String) : - CoreEvent(Pair(leftSidePair, rightSidePair), LocalDateTime.now()) + CoreEvent(Pair(leftSidePair, rightSidePair), currentTime) val testEvent = TestCoreEvent("BTC", "USDT") @@ -104,7 +106,7 @@ object Valid { 1, "event_1", TestCoreEvent("BTC", "USDT"), - LocalDateTime.now() + currentTime ) val tempEventModel = TempEventModel( @@ -112,7 +114,7 @@ object Valid { "event_1", TestCoreEvent::class.java.name, "{\"leftSidePair\":\"BTC\",\"rightSidePair\":\"USDT\",\"pair\":{\"leftSideName\":\"BTC\",\"rightSideName\":\"USDT\"},\"eventDate\":{\"date\":{\"year\":2022,\"month\":5,\"day\":30},\"time\":{\"hour\":16,\"minute\":57,\"second\":44,\"nano\":809838600}}}", - LocalDateTime.now() + currentTime ) val fa = FinancialAction( @@ -125,7 +127,7 @@ object Valid { "main", "system", "main", - LocalDateTime.now(), + currentTime, 1, 1 ) @@ -143,7 +145,7 @@ object Valid { "main", "", "", - LocalDateTime.now() + currentTime ) } \ No newline at end of file diff --git a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt index e7cb17831..90356d53d 100644 --- a/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt +++ b/accountant/accountant-ports/accountant-submitter-kafka/src/test/kotlin/co/nilin/opex/accountant/ports/kafka/submitter/Valid.kt @@ -14,6 +14,8 @@ object Valid { class TestRichOrderEvent : RichOrderEvent class TestCoreEvent : CoreEvent(Pair("BTC", "USDT")) + val currentTime = LocalDateTime.now() + val testRichOrder = TestRichOrderEvent() val testCoreEvent = TestCoreEvent() val richTrade = RichTrade( @@ -40,7 +42,7 @@ object Valid { 1.0.toBigDecimal(), "", 1.0.toBigDecimal(), - LocalDateTime.now() + currentTime ) fun kafkaSendFuture() = SettableListenableFuture>().apply {