From f958efbf8c2a5f0c6f7393da1561f82ba6dd896b Mon Sep 17 00:00:00 2001 From: Alva Swanson Date: Sat, 22 Oct 2022 11:56:34 +0200 Subject: [PATCH] Use one global bitcoind instance for all integration tests At the moment, each test class starts its own Bitcoin Core instance. This causes slow CI tests and high resource usage. --- ...neInitialRegtestBlocksIntegrationTest.java | 17 +++++++- ...itcoindSendAndListTxsIntegrationTests.java | 3 -- ...indSendAndListUnspentIntegrationTests.java | 2 +- .../BitcoindSendIntegrationTests.java | 2 +- ...oindSendUnconfirmedTxIntegrationTests.java | 2 +- .../BitcoindStartupIntegrationTests.java | 33 ---------------- ...WalletCreationAndListIntegrationTests.java | 30 +++++++++++--- .../bitcoind/regtest/BitcoindExtension.java | 39 +++++++++++++++---- .../regtest/bitcoind/RemoteBitcoind.java | 4 +- 9 files changed, 77 insertions(+), 55 deletions(-) delete mode 100644 wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindStartupIntegrationTests.java diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindMineInitialRegtestBlocksIntegrationTest.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindMineInitialRegtestBlocksIntegrationTest.java index fa6b7fbe02..ef579bc75a 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindMineInitialRegtestBlocksIntegrationTest.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindMineInitialRegtestBlocksIntegrationTest.java @@ -22,6 +22,7 @@ import bisq.wallets.bitcoind.rpc.BitcoindWallet; import bisq.wallets.core.model.AddressType; import bisq.wallets.regtest.bitcoind.BitcoindRegtestSetup; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; @@ -38,12 +39,19 @@ public class BitcoindMineInitialRegtestBlocksIntegrationTest { private final BitcoindDaemon daemon; private final BitcoindWallet minerWallet; + private double startBalance; + public BitcoindMineInitialRegtestBlocksIntegrationTest(BitcoindRegtestSetup regtestSetup) { this.regtestSetup = regtestSetup; this.daemon = regtestSetup.getDaemon(); this.minerWallet = regtestSetup.getMinerWallet(); } + @BeforeEach + void setUp() { + startBalance = minerWallet.getBalance(); + } + @Test public void mineInitialRegtestBlocks() throws InterruptedException { String address = minerWallet.getNewAddress(AddressType.BECH32, ""); @@ -53,7 +61,12 @@ public void mineInitialRegtestBlocks() throws InterruptedException { boolean allBlocksMined = nBlocksMinedLatch.await(1, TimeUnit.MINUTES); assertThat(allBlocksMined).isTrue(); - assertThat(minerWallet.getBalance()) - .isEqualTo(50); + // Other tests could've mined some blocks already. + assertThat(getMinerBalance()) + .isGreaterThanOrEqualTo(50); + } + + private double getMinerBalance() { + return minerWallet.getBalance() - startBalance; } } diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListTxsIntegrationTests.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListTxsIntegrationTests.java index dc2f39c41c..a3a1b530d7 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListTxsIntegrationTests.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListTxsIntegrationTests.java @@ -66,7 +66,6 @@ public void sendBtcAndListTxs() throws MalformedURLException, InterruptedExcepti assertEquals("receive", firstTx.getCategory()); assertEquals(1, firstTx.getAmount()); assertEquals(1, firstTx.getConfirmations()); - assertEquals(102, firstTx.getBlockheight()); assertEquals(0, firstTx.getWalletconflicts().length); assertEquals("no", firstTx.getBip125Replaceable()); @@ -75,7 +74,6 @@ public void sendBtcAndListTxs() throws MalformedURLException, InterruptedExcepti assertEquals("receive", secondTx.getCategory()); assertEquals(1, secondTx.getAmount()); assertEquals(1, secondTx.getConfirmations()); - assertEquals(102, secondTx.getBlockheight()); assertEquals(0, secondTx.getWalletconflicts().length); assertEquals("no", secondTx.getBip125Replaceable()); @@ -84,7 +82,6 @@ public void sendBtcAndListTxs() throws MalformedURLException, InterruptedExcepti assertEquals("receive", thirdTx.getCategory()); assertEquals(1, thirdTx.getAmount()); assertEquals(1, thirdTx.getConfirmations()); - assertEquals(102, thirdTx.getBlockheight()); assertEquals(0, thirdTx.getWalletconflicts().length); assertEquals("no", thirdTx.getBip125Replaceable()); } diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListUnspentIntegrationTests.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListUnspentIntegrationTests.java index d6d6482569..fc2984a202 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListUnspentIntegrationTests.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendAndListUnspentIntegrationTests.java @@ -45,7 +45,7 @@ public void listUnspent() throws MalformedURLException, InterruptedException { regtestSetup.mineInitialRegtestBlocks(); BitcoindWallet minerWallet = regtestSetup.getMinerWallet(); - BitcoindWallet receiverBackend = regtestSetup.createAndInitializeNewWallet("receiver_wallet"); + BitcoindWallet receiverBackend = regtestSetup.createAndInitializeNewWallet("receiver_wallet_list_unspent"); String firstTxReceiverAddress = regtestSetup.sendBtcAndMineOneBlock(minerWallet, receiverBackend, 1); String secondTxReceiverAddress = regtestSetup.sendBtcAndMineOneBlock(minerWallet, receiverBackend, 1); diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendIntegrationTests.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendIntegrationTests.java index af547c4c3f..79f9162929 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendIntegrationTests.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendIntegrationTests.java @@ -43,7 +43,7 @@ public BitcoindSendIntegrationTests(BitcoindRegtestSetup regtestSetup) { @Test public void sendOneBtcToAddress() throws MalformedURLException, InterruptedException { regtestSetup.mineInitialRegtestBlocks(); - BitcoindWallet receiverBackend = regtestSetup.createAndInitializeNewWallet("receiver_wallet"); + BitcoindWallet receiverBackend = regtestSetup.createAndInitializeNewWallet("receiver_wallet_send_one_btc"); String receiverAddress = receiverBackend.getNewAddress(AddressType.BECH32, ""); minerWallet.sendToAddress(Optional.of(BitcoindRegtestSetup.WALLET_PASSPHRASE), receiverAddress, 1); diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendUnconfirmedTxIntegrationTests.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendUnconfirmedTxIntegrationTests.java index 4d2bcbf83c..a9e30e6b5e 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendUnconfirmedTxIntegrationTests.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindSendUnconfirmedTxIntegrationTests.java @@ -53,7 +53,7 @@ public BitcoindSendUnconfirmedTxIntegrationTests(BitcoindRegtestSetup regtestSet @BeforeAll public void start() throws IOException, InterruptedException { regtestSetup.mineInitialRegtestBlocks(); - receiverWallet = regtestSetup.createAndInitializeNewWallet("receiver_wallet"); + receiverWallet = regtestSetup.createAndInitializeNewWallet("receiver_wallet_send_check_unconfirmed_balance"); } @Test diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindStartupIntegrationTests.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindStartupIntegrationTests.java deleted file mode 100644 index abff1d7fa9..0000000000 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindStartupIntegrationTests.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * This file is part of Bisq. - * - * Bisq is free software: you can redistribute it and/or modify it - * under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or (at - * your option) any later version. - * - * Bisq is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public - * License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with Bisq. If not, see . - */ - -package bisq.wallets.bitcoind; - -import bisq.wallets.bitcoind.rpc.BitcoindWallet; -import bisq.wallets.regtest.AbstractRegtestSetup; -import bisq.wallets.regtest.WalletStartupTests; -import bisq.wallets.regtest.bitcoind.BitcoindRegtestSetup; -import bisq.wallets.regtest.process.MultiProcessCoordinator; - -import java.io.IOException; - -public class BitcoindStartupIntegrationTests extends WalletStartupTests { - @Override - public AbstractRegtestSetup createRegtestSetup() throws IOException { - return new BitcoindRegtestSetup(); - } -} diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindWalletCreationAndListIntegrationTests.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindWalletCreationAndListIntegrationTests.java index 693a2603c5..76d3d8e0db 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindWalletCreationAndListIntegrationTests.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/BitcoindWalletCreationAndListIntegrationTests.java @@ -20,38 +20,55 @@ import bisq.wallets.bitcoind.regtest.BitcoindExtension; import bisq.wallets.bitcoind.rpc.BitcoindDaemon; import bisq.wallets.bitcoind.rpc.BitcoindWallet; +import bisq.wallets.core.RpcConfig; import bisq.wallets.regtest.bitcoind.BitcoindRegtestSetup; +import bisq.wallets.regtest.bitcoind.RemoteBitcoind; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import java.net.MalformedURLException; import java.nio.file.Path; import java.util.List; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.assertEquals; @ExtendWith(BitcoindExtension.class) public class BitcoindWalletCreationAndListIntegrationTests { private final Path dataDir; + private final RpcConfig rpcConfig; private final BitcoindDaemon daemon; private final BitcoindWallet minerWallet; public BitcoindWalletCreationAndListIntegrationTests(BitcoindRegtestSetup regtestSetup) { this.dataDir = regtestSetup.getDataDir(); + this.rpcConfig = regtestSetup.getRpcConfig(); this.daemon = regtestSetup.getDaemon(); this.minerWallet = regtestSetup.getMinerWallet(); } @Test public void createFreshWallet() { - assertEquals(0, minerWallet.getBalance()); + String walletName = "fresh_wallet"; + + Path walletFilePath = dataDir.resolve("regtest") + .resolve("wallets") + .resolve(walletName) + .resolve("wallet.dat"); + assertThat(walletFilePath).doesNotExist(); + + // Create Wallet + daemon.createOrLoadWallet(walletName, Optional.of(BitcoindRegtestSetup.WALLET_PASSPHRASE)); + assertThat(walletFilePath).exists(); + + // Unload and reload existing wallet + daemon.unloadWallet(walletName); } @Test - public void loadWalletIfExisting() { - String walletName = "wallet"; + public void loadWalletIfExisting() throws MalformedURLException { + String walletName = "wallet_load_if_existing"; Path walletFilePath = dataDir.resolve("regtest") .resolve("wallets") @@ -67,7 +84,8 @@ public void loadWalletIfExisting() { daemon.unloadWallet(walletName); daemon.createOrLoadWallet(walletName, Optional.of(BitcoindRegtestSetup.WALLET_PASSPHRASE)); - assertThat(minerWallet.getBalance()) + var testWallet = new BitcoindWallet(daemon, rpcConfig, walletName); + assertThat(testWallet.getBalance()) .isZero(); // Cleanup, otherwise other tests don't start on a clean state. @@ -77,6 +95,6 @@ public void loadWalletIfExisting() { @Test void listWallets() { List results = daemon.listWallets(); - assertThat(results).hasSize(1); + assertThat(results).contains(RemoteBitcoind.MINER_WALLET_NAME); } } diff --git a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/regtest/BitcoindExtension.java b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/regtest/BitcoindExtension.java index fae8fb4e32..60ae05003d 100644 --- a/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/regtest/BitcoindExtension.java +++ b/wallets/bitcoind/src/test/java/bisq/wallets/bitcoind/regtest/BitcoindExtension.java @@ -18,25 +18,50 @@ package bisq.wallets.bitcoind.regtest; import bisq.wallets.regtest.bitcoind.BitcoindRegtestSetup; -import org.junit.jupiter.api.extension.*; +import org.junit.jupiter.api.extension.BeforeAllCallback; +import org.junit.jupiter.api.extension.ExtensionContext; +import org.junit.jupiter.api.extension.ParameterContext; +import org.junit.jupiter.api.extension.ParameterResolver; import java.io.IOException; -public class BitcoindExtension implements BeforeAllCallback, AfterAllCallback, ParameterResolver { +import static org.junit.jupiter.api.extension.ExtensionContext.Namespace.GLOBAL; - private final BitcoindRegtestSetup regtestSetup = new BitcoindRegtestSetup(); +public class BitcoindExtension implements BeforeAllCallback, ExtensionContext.Store.CloseableResource, ParameterResolver { + + private static boolean isRunning; + private static final BitcoindRegtestSetup regtestSetup; + + static { + try { + regtestSetup = new BitcoindRegtestSetup(); + } catch (IOException e) { + throw new RuntimeException(e); + } + } public BitcoindExtension() throws IOException { } @Override - public void beforeAll(ExtensionContext context) throws Exception{ - regtestSetup.start(); + public synchronized void beforeAll(ExtensionContext context) throws Exception { + if (!isRunning) { + regtestSetup.start(); + isRunning = true; + + // Register close hook + context.getRoot() + .getStore(GLOBAL) + .put("register_close_hook", this); + } } @Override - public void afterAll(ExtensionContext context) { - regtestSetup.shutdown(); + public synchronized void close() { + if (isRunning) { + regtestSetup.shutdown(); + isRunning = false; + } } @Override diff --git a/wallets/regtest/src/main/java/bisq/wallets/regtest/bitcoind/RemoteBitcoind.java b/wallets/regtest/src/main/java/bisq/wallets/regtest/bitcoind/RemoteBitcoind.java index 19e4620713..e25dfaf0e7 100644 --- a/wallets/regtest/src/main/java/bisq/wallets/regtest/bitcoind/RemoteBitcoind.java +++ b/wallets/regtest/src/main/java/bisq/wallets/regtest/bitcoind/RemoteBitcoind.java @@ -41,6 +41,8 @@ public class RemoteBitcoind implements BisqProcess { + public static final String MINER_WALLET_NAME = "miner_wallet"; + private final RpcConfig rpcConfig; @Getter private final BitcoindDaemon daemon; @@ -58,7 +60,7 @@ public RemoteBitcoind(RpcConfig rpcConfig, this.rpcConfig = rpcConfig; this.daemon = createBitcoindDaemon(); this.doMineInitialRegtestBlocks = doMineInitialRegtestBlocks; - this.minerWallet = new BitcoindWallet(daemon, rpcConfig, "miner_wallet"); + this.minerWallet = new BitcoindWallet(daemon, rpcConfig, MINER_WALLET_NAME); this.blockMiner = new BitcoindRegtestBlockMiner(daemon, minerWallet, zmqListeners); }