Skip to content

Commit

Permalink
Use one global bitcoind instance for all integration tests
Browse files Browse the repository at this point in the history
At the moment, each test class starts its own Bitcoin Core instance.
This causes slow CI tests and high resource usage.
  • Loading branch information
alvasw committed Oct 22, 2022
1 parent 796d5e4 commit f958efb
Show file tree
Hide file tree
Showing 9 changed files with 77 additions and 55 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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, "");
Expand All @@ -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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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());

Expand All @@ -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());

Expand All @@ -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());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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.
Expand All @@ -77,6 +95,6 @@ public void loadWalletIfExisting() {
@Test
void listWallets() {
List<String> results = daemon.listWallets();
assertThat(results).hasSize(1);
assertThat(results).contains(RemoteBitcoind.MINER_WALLET_NAME);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
}

Expand Down

0 comments on commit f958efb

Please sign in to comment.