cmdOptions) {
if (log.isDebugEnabled())
log.debug("cmd options {}", cmdOptions.toString());
+ if (cmdOptions.isEmpty())
+ throw new IllegalStateException("No command params specified.");
+
if (cmdOptions.contains("sudo")) {
log.error("", new IllegalStateException("'sudo' commands are prohibited."));
exit(1);
}
- if (cmdOptions == null)
- throw new IllegalStateException("No command params specified.");
-
this.cmdOptions = cmdOptions;
}
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
new file mode 100644
index 00000000000..d3626301436
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -0,0 +1,62 @@
+/*
+ * 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.apitest;
+
+import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+
+
+import bisq.apitest.config.ApiTestConfig;
+import bisq.apitest.method.BitcoinCliHelper;
+
+public class ApiTestCase {
+
+ // The gRPC service stubs are used by method & scenario tests, but not e2e tests.
+ protected static GrpcStubs grpcStubs;
+
+ protected static Scaffold scaffold;
+ protected static ApiTestConfig config;
+ protected static BitcoinCliHelper bitcoinCli;
+
+ public static void setUpScaffold(String supportingApps) {
+ // The supportingApps argument is a comma delimited string of supporting app
+ // names, e.g. "bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon"
+ scaffold = new Scaffold(supportingApps).setUp();
+ config = scaffold.config;
+ bitcoinCli = new BitcoinCliHelper((config));
+ grpcStubs = new GrpcStubs(alicedaemon, config).init();
+ }
+
+ public static void setUpScaffold() {
+ scaffold = new Scaffold(new String[]{}).setUp();
+ config = scaffold.config;
+ grpcStubs = new GrpcStubs(alicedaemon, config).init();
+ }
+
+ public static void tearDownScaffold() {
+ scaffold.tearDown();
+ }
+
+ protected void sleep(long ms) {
+ try {
+ MILLISECONDS.sleep(ms);
+ } catch (InterruptedException ignored) {
+ }
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/GrpcStubs.java b/apitest/src/test/java/bisq/apitest/GrpcStubs.java
new file mode 100644
index 00000000000..6279c61489f
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/GrpcStubs.java
@@ -0,0 +1,109 @@
+/*
+ * 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.apitest;
+
+import bisq.proto.grpc.GetVersionGrpc;
+import bisq.proto.grpc.OffersGrpc;
+import bisq.proto.grpc.PaymentAccountsGrpc;
+import bisq.proto.grpc.WalletsGrpc;
+
+import io.grpc.CallCredentials;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.Metadata;
+
+import java.util.concurrent.Executor;
+
+import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
+import static io.grpc.Status.UNAUTHENTICATED;
+import static java.lang.String.format;
+import static java.util.concurrent.TimeUnit.SECONDS;
+
+
+
+import bisq.apitest.config.ApiTestConfig;
+import bisq.apitest.config.BisqAppConfig;
+
+public class GrpcStubs {
+
+ public final CallCredentials credentials;
+ public final String host;
+ public final int port;
+
+ public GetVersionGrpc.GetVersionBlockingStub versionService;
+ public OffersGrpc.OffersBlockingStub offersService;
+ public PaymentAccountsGrpc.PaymentAccountsBlockingStub paymentAccountsService;
+ public WalletsGrpc.WalletsBlockingStub walletsService;
+
+ public GrpcStubs(BisqAppConfig bisqAppConfig, ApiTestConfig config) {
+ this.credentials = new PasswordCallCredentials(config.apiPassword);
+ this.host = "localhost";
+ this.port = bisqAppConfig.apiPort;
+ }
+
+ public GrpcStubs init() {
+ var channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build();
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ try {
+ channel.shutdown().awaitTermination(1, SECONDS);
+ } catch (InterruptedException ex) {
+ throw new IllegalStateException(ex);
+ }
+ }));
+
+ this.versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials);
+ this.offersService = OffersGrpc.newBlockingStub(channel).withCallCredentials(credentials);
+ this.paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
+ this.walletsService = WalletsGrpc.newBlockingStub(channel).withCallCredentials(credentials);
+
+ return this;
+ }
+
+ static class PasswordCallCredentials extends CallCredentials {
+
+ public static final String PASSWORD_KEY = "password";
+ private final String passwordValue;
+
+ public PasswordCallCredentials(String passwordValue) {
+ if (passwordValue == null)
+ throw new IllegalArgumentException(format("'%s' value must not be null", PASSWORD_KEY));
+ this.passwordValue = passwordValue;
+ }
+
+ @Override
+ public void applyRequestMetadata(RequestInfo requestInfo,
+ Executor appExecutor,
+ MetadataApplier metadataApplier) {
+ appExecutor.execute(() -> {
+ try {
+ var headers = new Metadata();
+ var passwordKey = Metadata.Key.of(PASSWORD_KEY, ASCII_STRING_MARSHALLER);
+ headers.put(passwordKey, passwordValue);
+ metadataApplier.apply(headers);
+ } catch (Throwable ex) {
+ metadataApplier.fail(UNAUTHENTICATED.withCause(ex));
+ }
+ });
+ }
+
+ @Override
+ public void thisUsesUnstableApi() {
+ // An experimental api. A noop but never called; tries to make it clearer to
+ // implementors that they may break in the future.
+ }
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/JUnitHelper.java b/apitest/src/test/java/bisq/apitest/JUnitHelper.java
new file mode 100644
index 00000000000..03f16ee6b11
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/JUnitHelper.java
@@ -0,0 +1,58 @@
+package bisq.apitest;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.runner.Description;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.notification.Failure;
+import org.junit.runner.notification.RunListener;
+
+import static java.lang.String.format;
+
+@Slf4j
+public class JUnitHelper {
+
+ private static boolean allPass;
+
+ public static void runTests(Class>... testClasses) {
+ JUnitCore jUnitCore = new JUnitCore();
+ jUnitCore.addListener(new RunListener() {
+ public void testStarted(Description description) {
+ log.info("{}", description);
+ }
+
+ public void testIgnored(Description description) {
+ log.info("Ignored {}", description);
+ }
+
+ public void testFailure(Failure failure) {
+ log.error("Failed {}", failure.getTrace());
+ }
+ });
+ Result result = jUnitCore.run(testClasses);
+ printTestResults(result);
+ }
+
+ public static void printTestResults(Result result) {
+ log.info("Total tests: {}, Failed: {}, Ignored: {}",
+ result.getRunCount(),
+ result.getFailureCount(),
+ result.getIgnoreCount());
+
+ if (result.wasSuccessful()) {
+ log.info("All {} tests passed", result.getRunCount());
+ allPass = true;
+ } else if (result.getFailureCount() > 0) {
+ log.error("{} test(s) failed", result.getFailureCount());
+ result.getFailures().iterator().forEachRemaining(f -> log.error(format("%s.%s()%n\t%s",
+ f.getDescription().getTestClass().getName(),
+ f.getDescription().getMethodName(),
+ f.getTrace())));
+ }
+ }
+
+ public static boolean allTestsPassed() {
+ return allPass;
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
new file mode 100644
index 00000000000..bed3477801a
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
@@ -0,0 +1,86 @@
+/*
+ * 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.apitest.method;
+
+import java.io.IOException;
+
+import static java.lang.String.format;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+
+
+import bisq.apitest.config.ApiTestConfig;
+import bisq.apitest.linux.BitcoinCli;
+
+public final class BitcoinCliHelper {
+
+ private final ApiTestConfig config;
+
+ public BitcoinCliHelper(ApiTestConfig config) {
+ this.config = config;
+ }
+
+ // Convenience methods for making bitcoin-cli calls.
+
+ public String getNewBtcAddress() {
+ try {
+ String newAddress = new BitcoinCli(config, "getnewaddress").run().getOutput();
+ assertNotNull(newAddress);
+ return newAddress;
+ } catch (IOException | InterruptedException ex) {
+ fail(ex.getMessage());
+ return null;
+ }
+ }
+
+ public String[] generateToAddress(int blocks, String address) {
+ try {
+ String generateToAddressCmd = format("generatetoaddress %d \"%s\"", blocks, address);
+ BitcoinCli generateToAddress = new BitcoinCli(config, generateToAddressCmd).run();
+ String[] txids = generateToAddress.getOutputValueAsStringArray();
+ assertNotNull(txids);
+ return txids;
+ } catch (IOException | InterruptedException ex) {
+ fail(ex.getMessage());
+ return null;
+ }
+ }
+
+ public void generateBlocks(int blocks) {
+ generateToAddress(blocks, getNewBtcAddress());
+ }
+
+ public String sendToAddress(String address, String amount) {
+ // sendtoaddress "address" amount \
+ // ( "comment" "comment_to" subtractfeefromamount \
+ // replaceable conf_target "estimate_mode" )
+ // returns a transaction id
+ try {
+ String sendToAddressCmd = format("sendtoaddress \"%s\" %s \"\" \"\" false",
+ address, amount);
+ BitcoinCli sendToAddress = new BitcoinCli(config, sendToAddressCmd).run();
+ String txid = sendToAddress.getOutput();
+ assertNotNull(txid);
+ return txid;
+ } catch (IOException | InterruptedException ex) {
+ fail(ex.getMessage());
+ return null;
+ }
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java b/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
new file mode 100644
index 00000000000..5dac0ca7d74
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
@@ -0,0 +1,66 @@
+/*
+ * 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.apitest.method;
+
+import bisq.proto.grpc.GetBalanceRequest;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
+import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+
+
+@Slf4j
+@TestMethodOrder(OrderAnnotation.class)
+public class GetBalanceTest extends MethodTest {
+
+ @BeforeAll
+ public static void setUp() {
+ try {
+ setUpScaffold("bitcoind,seednode,alicedaemon");
+
+ // Have to generate 1 regtest block for alice's wallet to show 10 BTC balance.
+ bitcoinCli.generateBlocks(1);
+
+ // Give the alicedaemon time to parse the new block.
+ MILLISECONDS.sleep(1500);
+ } catch (InterruptedException ex) {
+ fail(ex.getMessage());
+ }
+ }
+
+ @Test
+ @Order(1)
+ public void testGetBalance() {
+ var balance = grpcStubs.walletsService.getBalance(GetBalanceRequest.newBuilder().build()).getBalance();
+ assertEquals(1000000000, balance);
+ }
+
+ @AfterAll
+ public static void tearDown() {
+ tearDownScaffold();
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java b/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
new file mode 100644
index 00000000000..91305de8ba5
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
@@ -0,0 +1,56 @@
+/*
+ * 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.apitest.method;
+
+import bisq.proto.grpc.GetVersionRequest;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static bisq.common.app.Version.VERSION;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+
+
+@Slf4j
+@TestMethodOrder(OrderAnnotation.class)
+public class GetVersionTest extends MethodTest {
+
+ @BeforeAll
+ public static void setUp() {
+ setUpScaffold(alicedaemon.name());
+ }
+
+ @Test
+ @Order(1)
+ public void testGetVersion() {
+ var version = grpcStubs.versionService.getVersion(GetVersionRequest.newBuilder().build()).getVersion();
+ assertEquals(VERSION, version);
+ }
+
+ @AfterAll
+ public static void tearDown() {
+ tearDownScaffold();
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
new file mode 100644
index 00000000000..37dea63cdb9
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.apitest.method;
+
+import bisq.proto.grpc.GetBalanceRequest;
+import bisq.proto.grpc.GetFundingAddressesRequest;
+import bisq.proto.grpc.LockWalletRequest;
+import bisq.proto.grpc.RemoveWalletPasswordRequest;
+import bisq.proto.grpc.SetWalletPasswordRequest;
+import bisq.proto.grpc.UnlockWalletRequest;
+
+
+
+import bisq.apitest.ApiTestCase;
+
+public class MethodTest extends ApiTestCase {
+
+ // Convenience methods for building gRPC request objects
+
+ protected final GetBalanceRequest createBalanceRequest() {
+ return GetBalanceRequest.newBuilder().build();
+ }
+
+ protected final SetWalletPasswordRequest createSetWalletPasswordRequest(String password) {
+ return SetWalletPasswordRequest.newBuilder().setPassword(password).build();
+ }
+
+ protected final SetWalletPasswordRequest createSetWalletPasswordRequest(String oldPassword, String newPassword) {
+ return SetWalletPasswordRequest.newBuilder().setPassword(oldPassword).setNewPassword(newPassword).build();
+ }
+
+ protected final RemoveWalletPasswordRequest createRemoveWalletPasswordRequest(String password) {
+ return RemoveWalletPasswordRequest.newBuilder().setPassword(password).build();
+ }
+
+ protected final UnlockWalletRequest createUnlockWalletRequest(String password, long timeout) {
+ return UnlockWalletRequest.newBuilder().setPassword(password).setTimeout(timeout).build();
+ }
+
+ protected final LockWalletRequest createLockWalletRequest() {
+ return LockWalletRequest.newBuilder().build();
+ }
+
+ protected final GetFundingAddressesRequest createGetFundingAddressesRequest() {
+ return GetFundingAddressesRequest.newBuilder().build();
+ }
+
+ // Convenience methods for calling frequently used & thoroughly tested gRPC services.
+
+ protected final long getBalance() {
+ return grpcStubs.walletsService.getBalance(createBalanceRequest()).getBalance();
+ }
+
+ protected final void unlockWallet(String password, long timeout) {
+ //noinspection ResultOfMethodCallIgnored
+ grpcStubs.walletsService.unlockWallet(createUnlockWalletRequest(password, timeout));
+ }
+
+ protected final void lockWallet() {
+ //noinspection ResultOfMethodCallIgnored
+ grpcStubs.walletsService.lockWallet(createLockWalletRequest());
+ }
+
+ protected final String getUnusedBtcAddress() {
+ return grpcStubs.walletsService.getFundingAddresses(createGetFundingAddressesRequest())
+ .getAddressBalanceInfoList()
+ .stream()
+ .filter(a -> a.getBalance() == 0 && a.getNumConfirmations() == 0)
+ .findFirst()
+ .get()
+ .getAddress();
+
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
new file mode 100644
index 00000000000..388c667f084
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
@@ -0,0 +1,137 @@
+package bisq.apitest.method;
+
+import io.grpc.StatusRuntimeException;
+
+import java.util.concurrent.TimeUnit;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
+
+@SuppressWarnings("ResultOfMethodCallIgnored")
+@Slf4j
+@TestMethodOrder(OrderAnnotation.class)
+public class WalletProtectionTest extends MethodTest {
+
+ @BeforeAll
+ public static void setUp() {
+ setUpScaffold(alicedaemon.name());
+ try {
+ TimeUnit.MILLISECONDS.sleep(2000);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ }
+
+ @Test
+ @Order(1)
+ public void testSetWalletPassword() {
+ var request = createSetWalletPasswordRequest("first-password");
+ grpcStubs.walletsService.setWalletPassword(request);
+ }
+
+ @Test
+ @Order(2)
+ public void testGetBalanceOnEncryptedWalletShouldThrowException() {
+ Throwable exception = assertThrows(StatusRuntimeException.class, this::getBalance);
+ assertEquals("UNKNOWN: wallet is locked", exception.getMessage());
+ }
+
+ @Test
+ @Order(3)
+ public void testUnlockWalletFor4Seconds() {
+ var request = createUnlockWalletRequest("first-password", 4);
+ grpcStubs.walletsService.unlockWallet(request);
+ getBalance(); // should not throw 'wallet locked' exception
+
+ sleep(4500); // let unlock timeout expire
+ Throwable exception = assertThrows(StatusRuntimeException.class, this::getBalance);
+ assertEquals("UNKNOWN: wallet is locked", exception.getMessage());
+ }
+
+ @Test
+ @Order(4)
+ public void testGetBalanceAfterUnlockTimeExpiryShouldThrowException() {
+ var request = createUnlockWalletRequest("first-password", 3);
+ grpcStubs.walletsService.unlockWallet(request);
+ sleep(4000); // let unlock timeout expire
+ Throwable exception = assertThrows(StatusRuntimeException.class, this::getBalance);
+ assertEquals("UNKNOWN: wallet is locked", exception.getMessage());
+ }
+
+ @Test
+ @Order(5)
+ public void testLockWalletBeforeUnlockTimeoutExpiry() {
+ unlockWallet("first-password", 60);
+ var request = createLockWalletRequest();
+ grpcStubs.walletsService.lockWallet(request);
+
+ Throwable exception = assertThrows(StatusRuntimeException.class, this::getBalance);
+ assertEquals("UNKNOWN: wallet is locked", exception.getMessage());
+ }
+
+ @Test
+ @Order(6)
+ public void testLockWalletWhenWalletAlreadyLockedShouldThrowException() {
+ var request = createLockWalletRequest();
+
+ Throwable exception = assertThrows(StatusRuntimeException.class, () ->
+ grpcStubs.walletsService.lockWallet(request));
+ assertEquals("UNKNOWN: wallet is already locked", exception.getMessage());
+
+ }
+
+ @Test
+ @Order(7)
+ public void testUnlockWalletTimeoutOverride() {
+ unlockWallet("first-password", 2);
+ sleep(500); // override unlock timeout after 0.5s
+ unlockWallet("first-password", 6);
+ sleep(5000);
+ getBalance(); // getbalance 5s after resetting unlock timeout to 6s
+ }
+
+ @Test
+ @Order(8)
+ public void testSetNewWalletPassword() {
+ var request = createSetWalletPasswordRequest("first-password", "second-password");
+ grpcStubs.walletsService.setWalletPassword(request);
+
+ unlockWallet("second-password", 2);
+ getBalance();
+ sleep(2500); // allow time for wallet save
+ }
+
+ @Test
+ @Order(9)
+ public void testSetNewWalletPasswordWithIncorrectNewPasswordShouldThrowException() {
+ var request = createSetWalletPasswordRequest("bad old password", "irrelevant");
+
+ Throwable exception = assertThrows(StatusRuntimeException.class, () ->
+ grpcStubs.walletsService.setWalletPassword(request));
+ assertEquals("UNKNOWN: incorrect old password", exception.getMessage());
+ }
+
+ @Test
+ @Order(10)
+ public void testRemoveNewWalletPassword() {
+ var request = createRemoveWalletPasswordRequest("second-password");
+ grpcStubs.walletsService.removeWalletPassword(request);
+ getBalance(); // should not throw 'wallet locked' exception
+ }
+
+
+ @AfterAll
+ public static void tearDown() {
+ tearDownScaffold();
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
new file mode 100644
index 00000000000..64a01363569
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
@@ -0,0 +1,69 @@
+/*
+ * 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.apitest.scenario;
+
+import lombok.extern.slf4j.Slf4j;
+
+import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.MethodOrderer;
+import org.junit.jupiter.api.Order;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.TestMethodOrder;
+
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+
+@Slf4j
+@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
+public class FundWalletScenarioTest extends ScenarioTest {
+
+ @BeforeAll
+ public static void setUp() {
+ try {
+ setUpScaffold("bitcoind,seednode,alicedaemon");
+ bitcoinCli.generateBlocks(1);
+ MILLISECONDS.sleep(1500);
+ } catch (InterruptedException ex) {
+ fail(ex.getMessage());
+ }
+ }
+
+ @Test
+ @Order(1)
+ public void testFundWallet() {
+ long balance = getBalance(); // bisq wallet was initialized with 10 btc
+ assertEquals(1000000000, balance);
+
+ String unusedAddress = getUnusedBtcAddress();
+ bitcoinCli.sendToAddress(unusedAddress, "2.5");
+
+ bitcoinCli.generateBlocks(1);
+ sleep(1500);
+
+ balance = getBalance();
+ assertEquals(1250000000L, balance); // new balance is 12.5 btc
+ }
+
+ @AfterAll
+ public static void tearDown() {
+ tearDownScaffold();
+ }
+}
diff --git a/apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java b/apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java
new file mode 100644
index 00000000000..9750b2ed9d6
--- /dev/null
+++ b/apitest/src/test/java/bisq/apitest/scenario/ScenarioTest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.apitest.scenario;
+
+import lombok.extern.slf4j.Slf4j;
+
+
+
+import bisq.apitest.method.MethodTest;
+
+@Slf4j
+public class ScenarioTest extends MethodTest {
+}
diff --git a/build.gradle b/build.gradle
index ad902e11739..389f4a8bc17 100644
--- a/build.gradle
+++ b/build.gradle
@@ -579,6 +579,14 @@ configure(project(':apitest')) {
// ./gradlew :apitest:cleanDaoSetup -x test
apply from: 'dao-setup.gradle'
+ // We have to disable the :apitest 'test' task by default because we do not want
+ // to interfere with normal builds. To run JUnit tests in this subproject:
+ // Run a normal build and install dao-setup files:
+ // 'gradle clean build :apitest:installDaoSetup'
+ // Run apitest tests cases
+ // 'gradle :apitest:test' -Dforce=true
+ test.enabled = System.getProperty("force") == "true"
+
sourceSets {
main {
resources {
@@ -588,6 +596,13 @@ configure(project(':apitest')) {
}
}
+ test {
+ useJUnitPlatform()
+ testLogging {
+ events "passed", "skipped", "failed"
+ }
+ }
+
dependencies {
compile project(':proto')
compile project(':common')
@@ -609,10 +624,17 @@ configure(project(':apitest')) {
implementation "org.slf4j:slf4j-api:$slf4jVersion"
implementation "ch.qos.logback:logback-core:$logbackVersion"
implementation "ch.qos.logback:logback-classic:$logbackVersion"
- implementation "junit:junit:$junitVersion"
+
compileOnly "org.projectlombok:lombok:$lombokVersion"
compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
+
+ testCompile "org.junit.jupiter:junit-jupiter-api:5.6.2"
+ testCompile "org.junit.jupiter:junit-jupiter-params:5.6.2"
+ testAnnotationProcessor "org.projectlombok:lombok:$lombokVersion"
+ testCompileOnly "org.projectlombok:lombok:$lombokVersion"
+ testRuntime "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
+ testRuntime("org.junit.jupiter:junit-jupiter-engine:5.6.2")
}
}
From 591c8b295c6fb7968b6af86b579b75c6fd8353e4 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 20 Jul 2020 12:33:47 -0300
Subject: [PATCH 66/90] Change :apitest:test task system property name
The property name 'force' is changed 'runApiTests'.
To run the :apitest test task:
./gradlew :apitest:test -DrunApiTests=true
---
build.gradle | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/build.gradle b/build.gradle
index 389f4a8bc17..406c99e327a 100644
--- a/build.gradle
+++ b/build.gradle
@@ -571,7 +571,7 @@ configure(project(':apitest')) {
// https://github.com/bisq-network/bisq/raw/master/docs/dao-setup.zip
// These tasks are not run by the default build, but they can can be run during
// full or partial builds, or by themselves.
- // To run a full Bisq clean build, test, and install dao-setup files:
+ // To run the regular clean + build + test (non api), and install dao-setup files:
// ./gradlew clean build :apitest:installDaoSetup
// To install or re-install dao-setup file only:
// ./gradlew :apitest:installDaoSetup -x test
@@ -581,11 +581,9 @@ configure(project(':apitest')) {
// We have to disable the :apitest 'test' task by default because we do not want
// to interfere with normal builds. To run JUnit tests in this subproject:
- // Run a normal build and install dao-setup files:
- // 'gradle clean build :apitest:installDaoSetup'
- // Run apitest tests cases
- // 'gradle :apitest:test' -Dforce=true
- test.enabled = System.getProperty("force") == "true"
+ // Run a normal build and install dao-setup files first, then run:
+ // 'gradle :apitest:test -DrunApiTests=true'
+ test.enabled = System.getProperty("runApiTests") == "true"
sourceSets {
main {
From b4d3ea7e023c790ac07ad3c53fc8d6b991ddb1a0 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 20 Jul 2020 12:37:35 -0300
Subject: [PATCH 67/90] Add comment about Bisq DAO dev environment
Some explanation is needed about why Bob & Alice have non-zero
initial BTC and BSQ balances when tests run. The comments
also include links to more detailed information about the DAO/
regtest testing environment.
---
.../test/java/bisq/apitest/ApiTestCase.java | 25 +++++++++++++++++++
1 file changed, 25 insertions(+)
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
index d3626301436..2cc74883a9d 100644
--- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -25,6 +25,31 @@
import bisq.apitest.config.ApiTestConfig;
import bisq.apitest.method.BitcoinCliHelper;
+/**
+ * Base class for all test types: 'method', 'scenario' and 'e2e'.
+ *
+ * During scaffold setup, various combinations of bitcoind and bisq instances
+ * can be started in the background before test cases are run. Currently, this test
+ * harness supports only the "Bisq DAO development environment running against a
+ * local Bitcoin regtest network" as described in
+ * dev-setup.md
+ * and dao-setup.md.
+ *
+ * Those documents contain information about the configurations used by this test harness:
+ * bitcoin-core's bitcoin.conf and blocknotify values, bisq instance options, the DAO genesis
+ * transaction id, initial BSQ and BTC balances for Bob & Alice accounts, and default
+ * PerfectMoney dummy payment accounts (USD) for Bob and Alice.
+ *
+ * During a build, the
+ * dao-setup.zip
+ * file is downloaded and extracted if necessary. In each test case's @BeforeClass
+ * method, the DAO setup files are re-installed into the run time's data directories
+ * (each test case runs on a refreshed DAO/regtest environment setup).
+ *
+ * Initial Alice balances & accounts: 10.0 BTC, 1000000.00 BSQ, USD PerfectMoney dummy
+ *
+ * Initial Bob balances & accounts: 10.0 BTC, 1500000.00 BSQ, USD PerfectMoney dummy
+ */
public class ApiTestCase {
// The gRPC service stubs are used by method & scenario tests, but not e2e tests.
From 999e9ec93b6eea9d131b0255249acdfcec69fbb7 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 20 Jul 2020 14:53:00 -0300
Subject: [PATCH 68/90] Fix @BeforeClass error handling and use jupiter api
The Scaffold set up was calling System.exit(1) when it encountered a
configuration error, or a problem starting bitcoind & bisq instances.
This incorrect error handling was hiding errors from gradle, and
preventing tests that would otherwise successfully complete.
This change fixes the problem by throwing an IllegalStateException up
to the test case's @BeforeClass method -- to be caught and used in a
JUnit fail(ex) call. An 'initializationError' triggered in @BeforeClass
correctly bubbles up to gradle, and will not block execution of remaining
tests. A gradle Test Summary containing any initialization errors is also
produced in /apitest/build/reports/tests/test/index.html
This change also fixes many import statements and asserts to ensure
'org.junit.jupiter.api.*' is used in place of 'org.junit.*', for
proper gradle integration.
---
.../src/main/java/bisq/apitest/Scaffold.java | 34 ++++++-------------
.../src/main/java/bisq/apitest/SetupTask.java | 14 +++-----
.../apitest/linux/AbstractLinuxProcess.java | 9 +++--
.../java/bisq/apitest/linux/LinuxProcess.java | 4 +--
.../apitest/linux/SystemCommandExecutor.java | 8 ++---
.../test/java/bisq/apitest/ApiTestCase.java | 10 ++++--
.../bisq/apitest/method/BitcoinCliHelper.java | 10 +++---
.../bisq/apitest/method/GetBalanceTest.java | 6 ++--
.../bisq/apitest/method/GetVersionTest.java | 7 +++-
.../apitest/method/WalletProtectionTest.java | 12 +++----
.../scenario/FundWalletScenarioTest.java | 9 +++--
11 files changed, 59 insertions(+), 64 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java
index fe2b9a3e04e..ef905a9d3e8 100644
--- a/apitest/src/main/java/bisq/apitest/Scaffold.java
+++ b/apitest/src/main/java/bisq/apitest/Scaffold.java
@@ -42,7 +42,6 @@
import static bisq.apitest.config.BisqAppConfig.*;
import static java.lang.String.format;
-import static java.lang.System.err;
import static java.lang.System.exit;
import static java.lang.System.out;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
@@ -128,27 +127,19 @@ public Scaffold(ApiTestConfig config) {
}
- public Scaffold setUp() {
- try {
- installDaoSetupDirectories();
-
- // Start each background process from an executor, then add a shutdown hook.
- CountDownLatch countdownLatch = new CountDownLatch(config.supportingApps.size());
- startBackgroundProcesses(executor, countdownLatch);
- installShutdownHook();
+ public Scaffold setUp() throws IOException, InterruptedException, ExecutionException {
+ installDaoSetupDirectories();
- // Wait for all submitted startup tasks to decrement the count of the latch.
- Objects.requireNonNull(countdownLatch).await();
+ // Start each background process from an executor, then add a shutdown hook.
+ CountDownLatch countdownLatch = new CountDownLatch(config.supportingApps.size());
+ startBackgroundProcesses(executor, countdownLatch);
+ installShutdownHook();
- // Verify each startup task's future is done.
- verifyStartupCompleted();
+ // Wait for all submitted startup tasks to decrement the count of the latch.
+ Objects.requireNonNull(countdownLatch).await();
- } catch (Throwable ex) {
- err.println("Fault: An unexpected error occurred. " +
- "Please file a report at https://bisq.network/issues");
- ex.printStackTrace(err);
- exit(EXIT_FAILURE);
- }
+ // Verify each startup task's future is done.
+ verifyStartupCompleted();
return this;
}
@@ -336,10 +327,7 @@ private void startBisqApp(BisqAppConfig bisqAppConfig,
log.info("Giving {} ms for {} to initialize ...", config.bisqAppInitTime, bisqAppConfig.appName);
MILLISECONDS.sleep(config.bisqAppInitTime);
if (bisqApp.hasStartupExceptions()) {
- for (Throwable t : bisqApp.getStartupExceptions()) {
- log.error("", t);
- }
- exit(EXIT_FAILURE);
+ throw bisqApp.startupIllegalStateException(log);
}
}
diff --git a/apitest/src/main/java/bisq/apitest/SetupTask.java b/apitest/src/main/java/bisq/apitest/SetupTask.java
index 56f3af07140..d2d76cba50c 100644
--- a/apitest/src/main/java/bisq/apitest/SetupTask.java
+++ b/apitest/src/main/java/bisq/apitest/SetupTask.java
@@ -25,9 +25,7 @@
import lombok.extern.slf4j.Slf4j;
-import static bisq.apitest.Scaffold.EXIT_FAILURE;
import static java.lang.String.format;
-import static java.lang.System.exit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -50,16 +48,14 @@ public Status call() throws Exception {
try {
linuxProcess.start(); // always runs in background
MILLISECONDS.sleep(1000); // give 1s for bg process to init
- if (linuxProcess.hasStartupExceptions()) {
- for (Throwable t : linuxProcess.getStartupExceptions()) {
- log.error("", t);
- }
- exit(EXIT_FAILURE);
- }
-
} catch (InterruptedException ex) {
throw new IllegalStateException(format("Error starting %s", linuxProcess.getName()), ex);
}
+
+ if (linuxProcess.hasStartupExceptions()) {
+ throw linuxProcess.startupIllegalStateException(log);
+ }
+
Objects.requireNonNull(countdownLatch).countDown();
return new Status(linuxProcess.getName(), LocalDateTime.now());
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
index 5a9f5565508..a9b62c26be4 100644
--- a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
@@ -62,8 +62,13 @@ public boolean hasStartupExceptions() {
}
@Override
- public List getStartupExceptions() {
- return startupExceptions;
+ public IllegalStateException startupIllegalStateException(org.slf4j.Logger log) {
+ StringBuilder errorBuilder = new StringBuilder();
+ for (Throwable t : startupExceptions) {
+ log.error("", t);
+ errorBuilder.append(t.getMessage()).append("\n");
+ }
+ return new IllegalStateException(errorBuilder.toString().trim(), startupExceptions.get(0));
}
@SuppressWarnings("unused")
diff --git a/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java
index 5c453de0b10..8c19be66f12 100644
--- a/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java
@@ -19,8 +19,6 @@
import java.io.IOException;
-import java.util.List;
-
public interface LinuxProcess {
void start() throws InterruptedException, IOException;
@@ -30,7 +28,7 @@ public interface LinuxProcess {
boolean hasStartupExceptions();
- List getStartupExceptions();
+ IllegalStateException startupIllegalStateException(org.slf4j.Logger log);
void shutdown() throws IOException, InterruptedException;
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/SystemCommandExecutor.java b/apitest/src/main/java/bisq/apitest/linux/SystemCommandExecutor.java
index 25c0cf8fe0d..28c0fde235e 100644
--- a/apitest/src/main/java/bisq/apitest/linux/SystemCommandExecutor.java
+++ b/apitest/src/main/java/bisq/apitest/linux/SystemCommandExecutor.java
@@ -24,8 +24,6 @@
import lombok.extern.slf4j.Slf4j;
-import static java.lang.System.exit;
-
/**
* This class can be used to execute a system command from a Java application.
* See the documentation for the public methods of this class for more
@@ -65,10 +63,8 @@ public SystemCommandExecutor(final List cmdOptions) {
if (cmdOptions.isEmpty())
throw new IllegalStateException("No command params specified.");
- if (cmdOptions.contains("sudo")) {
- log.error("", new IllegalStateException("'sudo' commands are prohibited."));
- exit(1);
- }
+ if (cmdOptions.contains("sudo"))
+ throw new IllegalStateException("'sudo' commands are prohibited.");
this.cmdOptions = cmdOptions;
}
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
index 2cc74883a9d..e2301346c43 100644
--- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -17,6 +17,10 @@
package bisq.apitest;
+import java.io.IOException;
+
+import java.util.concurrent.ExecutionException;
+
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -59,7 +63,8 @@ public class ApiTestCase {
protected static ApiTestConfig config;
protected static BitcoinCliHelper bitcoinCli;
- public static void setUpScaffold(String supportingApps) {
+ public static void setUpScaffold(String supportingApps)
+ throws InterruptedException, ExecutionException, IOException {
// The supportingApps argument is a comma delimited string of supporting app
// names, e.g. "bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon"
scaffold = new Scaffold(supportingApps).setUp();
@@ -68,7 +73,8 @@ public static void setUpScaffold(String supportingApps) {
grpcStubs = new GrpcStubs(alicedaemon, config).init();
}
- public static void setUpScaffold() {
+ public static void setUpScaffold()
+ throws InterruptedException, ExecutionException, IOException {
scaffold = new Scaffold(new String[]{}).setUp();
config = scaffold.config;
grpcStubs = new GrpcStubs(alicedaemon, config).init();
diff --git a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
index bed3477801a..693da32966b 100644
--- a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
+++ b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
@@ -20,8 +20,8 @@
import java.io.IOException;
import static java.lang.String.format;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.fail;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+import static org.junit.jupiter.api.Assertions.fail;
@@ -44,7 +44,7 @@ public String getNewBtcAddress() {
assertNotNull(newAddress);
return newAddress;
} catch (IOException | InterruptedException ex) {
- fail(ex.getMessage());
+ fail(ex);
return null;
}
}
@@ -57,7 +57,7 @@ public String[] generateToAddress(int blocks, String address) {
assertNotNull(txids);
return txids;
} catch (IOException | InterruptedException ex) {
- fail(ex.getMessage());
+ fail(ex);
return null;
}
}
@@ -79,7 +79,7 @@ public String sendToAddress(String address, String amount) {
assertNotNull(txid);
return txid;
} catch (IOException | InterruptedException ex) {
- fail(ex.getMessage());
+ fail(ex);
return null;
}
}
diff --git a/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java b/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
index 5dac0ca7d74..2cf4e8ae1cd 100644
--- a/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/GetBalanceTest.java
@@ -47,14 +47,16 @@ public static void setUp() {
// Give the alicedaemon time to parse the new block.
MILLISECONDS.sleep(1500);
- } catch (InterruptedException ex) {
- fail(ex.getMessage());
+ } catch (Exception ex) {
+ fail(ex);
}
}
@Test
@Order(1)
public void testGetBalance() {
+ // All tests depend on the DAO / regtest environment, and Alice's wallet is
+ // initialized with 10 BTC during the scaffolding setup.
var balance = grpcStubs.walletsService.getBalance(GetBalanceRequest.newBuilder().build()).getBalance();
assertEquals(1000000000, balance);
}
diff --git a/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java b/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
index 91305de8ba5..22413cf9d3c 100644
--- a/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/GetVersionTest.java
@@ -30,6 +30,7 @@
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static bisq.common.app.Version.VERSION;
import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
@@ -39,7 +40,11 @@ public class GetVersionTest extends MethodTest {
@BeforeAll
public static void setUp() {
- setUpScaffold(alicedaemon.name());
+ try {
+ setUpScaffold(alicedaemon.name());
+ } catch (Exception ex) {
+ fail(ex);
+ }
}
@Test
diff --git a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
index 388c667f084..a00d5333c01 100644
--- a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
@@ -2,8 +2,6 @@
import io.grpc.StatusRuntimeException;
-import java.util.concurrent.TimeUnit;
-
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.AfterAll;
@@ -13,8 +11,10 @@
import org.junit.jupiter.api.TestMethodOrder;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.fail;
import static org.junit.jupiter.api.MethodOrderer.OrderAnnotation;
@SuppressWarnings("ResultOfMethodCallIgnored")
@@ -24,11 +24,11 @@ public class WalletProtectionTest extends MethodTest {
@BeforeAll
public static void setUp() {
- setUpScaffold(alicedaemon.name());
try {
- TimeUnit.MILLISECONDS.sleep(2000);
- } catch (InterruptedException e) {
- e.printStackTrace();
+ setUpScaffold(alicedaemon.name());
+ MILLISECONDS.sleep(2000);
+ } catch (Exception ex) {
+ fail(ex);
}
}
diff --git a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
index 64a01363569..e95e310eb58 100644
--- a/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
+++ b/apitest/src/test/java/bisq/apitest/scenario/FundWalletScenarioTest.java
@@ -27,9 +27,8 @@
import org.junit.jupiter.api.TestMethodOrder;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.fail;
-
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.fail;
@Slf4j
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
@@ -41,8 +40,8 @@ public static void setUp() {
setUpScaffold("bitcoind,seednode,alicedaemon");
bitcoinCli.generateBlocks(1);
MILLISECONDS.sleep(1500);
- } catch (InterruptedException ex) {
- fail(ex.getMessage());
+ } catch (Exception ex) {
+ fail(ex);
}
}
From 13a8396b4533f8d67578ac9db0129baed7f45be6 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 20 Jul 2020 15:05:10 -0300
Subject: [PATCH 69/90] Remove unnecessary curly braces
---
apitest/src/main/java/bisq/apitest/Scaffold.java | 3 +--
apitest/src/main/java/bisq/apitest/SetupTask.java | 3 +--
2 files changed, 2 insertions(+), 4 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java
index ef905a9d3e8..12bd79b9bd7 100644
--- a/apitest/src/main/java/bisq/apitest/Scaffold.java
+++ b/apitest/src/main/java/bisq/apitest/Scaffold.java
@@ -326,9 +326,8 @@ private void startBisqApp(BisqAppConfig bisqAppConfig,
}
log.info("Giving {} ms for {} to initialize ...", config.bisqAppInitTime, bisqAppConfig.appName);
MILLISECONDS.sleep(config.bisqAppInitTime);
- if (bisqApp.hasStartupExceptions()) {
+ if (bisqApp.hasStartupExceptions())
throw bisqApp.startupIllegalStateException(log);
- }
}
private BisqApp createBisqApp(BisqAppConfig bisqAppConfig)
diff --git a/apitest/src/main/java/bisq/apitest/SetupTask.java b/apitest/src/main/java/bisq/apitest/SetupTask.java
index d2d76cba50c..8818eee19ac 100644
--- a/apitest/src/main/java/bisq/apitest/SetupTask.java
+++ b/apitest/src/main/java/bisq/apitest/SetupTask.java
@@ -52,9 +52,8 @@ public Status call() throws Exception {
throw new IllegalStateException(format("Error starting %s", linuxProcess.getName()), ex);
}
- if (linuxProcess.hasStartupExceptions()) {
+ if (linuxProcess.hasStartupExceptions())
throw linuxProcess.startupIllegalStateException(log);
- }
Objects.requireNonNull(countdownLatch).countDown();
return new Status(linuxProcess.getName(), LocalDateTime.now());
From cf031e688390332863c183344e1e0441baa2454f Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 22 Jul 2020 10:58:20 -0300
Subject: [PATCH 70/90] Change 'missing bitcoind path' error msg
Since JUnit tests cannot take program arguments, change the
wording to instruct the user to configure the bitcoind path
in apitest.properties
---
.../src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
index a9b62c26be4..bcaf72ece60 100644
--- a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
@@ -95,8 +95,7 @@ public void verifyBitcoinPathsExist(boolean verbose) {
if (!bitcoindExecutable.exists() || !bitcoindExecutable.canExecute())
throw new IllegalStateException(format("'%s' cannot be found or executed.%n"
+ "A bitcoin-core v0.19.X installation is required, and" +
- " a '--bitcoinPath' option must be passed on the command line"
- + " or added to 'apitest.properties'",
+ " the 'bitcoinPath' must be configured in 'apitest.properties'",
bitcoindExecutable.getAbsolutePath()));
File bitcoindDatadir = new File(config.bitcoinDatadir);
From 27ee4b8974ba364a386e94bcf699b28c0072157a Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 27 Jul 2020 16:35:46 -0300
Subject: [PATCH 71/90] Do not leave orphaned processes after failed teardown
The test harness should not fail a test case's @AfterAll (teardown)
method on the first background instance shutdown exception. This
change makes the shutdown logic similar to the startup's: it caches
any exceptions that may have occurred during an instance shutdown,
logs them, then proceeds to shut down the next background instance.
An IllegalStateException (the 1st one) is passed up to @AfterAll method
only after the scaffolding teardown process is complete, to avoid leaving
any orphaned java or bitcoind processes running after a java system
exit.
---
.../src/main/java/bisq/apitest/Scaffold.java | 38 +++++++++++++++----
.../src/main/java/bisq/apitest/SetupTask.java | 4 --
.../apitest/linux/AbstractLinuxProcess.java | 25 ++++++++++--
.../main/java/bisq/apitest/linux/BisqApp.java | 20 ++++++----
.../bisq/apitest/linux/BitcoinDaemon.java | 33 ++++++++++------
.../java/bisq/apitest/linux/LinuxProcess.java | 12 +++++-
6 files changed, 96 insertions(+), 36 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java
index 12bd79b9bd7..9319226211f 100644
--- a/apitest/src/main/java/bisq/apitest/Scaffold.java
+++ b/apitest/src/main/java/bisq/apitest/Scaffold.java
@@ -30,6 +30,7 @@
import java.io.IOException;
import java.util.Objects;
+import java.util.Optional;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
@@ -56,6 +57,7 @@
import bisq.apitest.linux.BashCommand;
import bisq.apitest.linux.BisqApp;
import bisq.apitest.linux.BitcoinDaemon;
+import bisq.apitest.linux.LinuxProcess;
@Slf4j
public class Scaffold {
@@ -152,17 +154,30 @@ public void tearDown() {
SetupTask[] orderedTasks = new SetupTask[]{
bobNodeTask, aliceNodeTask, arbNodeTask, seedNodeTask, bitcoindTask};
+ final Optional[] firstShutdownException = new Optional[]{Optional.empty()};
stream(orderedTasks).filter(t -> t != null && t.getLinuxProcess() != null)
.forEachOrdered(t -> {
try {
- t.getLinuxProcess().shutdown();
+ LinuxProcess p = t.getLinuxProcess();
+ p.shutdown();
MILLISECONDS.sleep(1000);
- } catch (IOException | InterruptedException ex) {
- throw new IllegalStateException(ex);
+ if (p.hasShutdownExceptions()) {
+ // We log shutdown exceptions, but do not throw
+ // one from here until the rest of the background
+ // instances have been shut down.
+ p.logExceptions(p.getShutdownExceptions(), log);
+ firstShutdownException[0] = Optional.of(p.getShutdownExceptions().get(0));
+ }
+ } catch (InterruptedException ignored) {
}
});
- log.info("Teardown complete");
+ if (firstShutdownException[0].isPresent())
+ throw new IllegalStateException("There were errors shutting down one or more background instances.",
+ firstShutdownException[0].get());
+ else
+ log.info("Teardown complete");
+
} catch (Exception ex) {
throw new IllegalStateException(ex);
}
@@ -274,7 +289,14 @@ private void startBackgroundProcesses(ExecutorService executor,
bitcoinDaemon.verifyBitcoinPathsExist(true);
bitcoindTask = new SetupTask(bitcoinDaemon, countdownLatch);
bitcoindTaskFuture = executor.submit(bitcoindTask);
- MILLISECONDS.sleep(3500); // todo make configurable
+ MILLISECONDS.sleep(config.bisqAppInitTime);
+
+ LinuxProcess bitcoindProcess = bitcoindTask.getLinuxProcess();
+ if (bitcoindProcess.hasStartupExceptions()) {
+ bitcoindProcess.logExceptions(bitcoindProcess.getStartupExceptions(), log);
+ throw new IllegalStateException(bitcoindProcess.getStartupExceptions().get(0));
+ }
+
bitcoinDaemon.verifyBitcoindRunning();
}
@@ -326,8 +348,10 @@ private void startBisqApp(BisqAppConfig bisqAppConfig,
}
log.info("Giving {} ms for {} to initialize ...", config.bisqAppInitTime, bisqAppConfig.appName);
MILLISECONDS.sleep(config.bisqAppInitTime);
- if (bisqApp.hasStartupExceptions())
- throw bisqApp.startupIllegalStateException(log);
+ if (bisqApp.hasStartupExceptions()) {
+ bisqApp.logExceptions(bisqApp.getStartupExceptions(), log);
+ throw new IllegalStateException(bisqApp.getStartupExceptions().get(0));
+ }
}
private BisqApp createBisqApp(BisqAppConfig bisqAppConfig)
diff --git a/apitest/src/main/java/bisq/apitest/SetupTask.java b/apitest/src/main/java/bisq/apitest/SetupTask.java
index 8818eee19ac..7e519b65cec 100644
--- a/apitest/src/main/java/bisq/apitest/SetupTask.java
+++ b/apitest/src/main/java/bisq/apitest/SetupTask.java
@@ -51,10 +51,6 @@ public Status call() throws Exception {
} catch (InterruptedException ex) {
throw new IllegalStateException(format("Error starting %s", linuxProcess.getName()), ex);
}
-
- if (linuxProcess.hasStartupExceptions())
- throw linuxProcess.startupIllegalStateException(log);
-
Objects.requireNonNull(countdownLatch).countDown();
return new Status(linuxProcess.getName(), LocalDateTime.now());
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
index bcaf72ece60..4063272c686 100644
--- a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
@@ -39,16 +39,18 @@
abstract class AbstractLinuxProcess implements LinuxProcess {
protected final String name;
+ protected final ApiTestConfig config;
protected long pid;
- protected final ApiTestConfig config;
protected final List startupExceptions;
+ protected final List shutdownExceptions;
public AbstractLinuxProcess(String name, ApiTestConfig config) {
this.name = name;
this.config = config;
this.startupExceptions = new ArrayList<>();
+ this.shutdownExceptions = new ArrayList<>();
}
@Override
@@ -62,15 +64,30 @@ public boolean hasStartupExceptions() {
}
@Override
- public IllegalStateException startupIllegalStateException(org.slf4j.Logger log) {
+ public boolean hasShutdownExceptions() {
+ return !shutdownExceptions.isEmpty();
+ }
+
+ @Override
+ public void logExceptions(List exceptions, org.slf4j.Logger log) {
StringBuilder errorBuilder = new StringBuilder();
- for (Throwable t : startupExceptions) {
+ for (Throwable t : exceptions) {
log.error("", t);
errorBuilder.append(t.getMessage()).append("\n");
}
- return new IllegalStateException(errorBuilder.toString().trim(), startupExceptions.get(0));
}
+ @Override
+ public List getStartupExceptions() {
+ return startupExceptions;
+ }
+
+ @Override
+ public List getShutdownExceptions() {
+ return shutdownExceptions;
+ }
+
+
@SuppressWarnings("unused")
public void verifyBitcoinPathsExist() {
verifyBitcoinPathsExist(false);
diff --git a/apitest/src/main/java/bisq/apitest/linux/BisqApp.java b/apitest/src/main/java/bisq/apitest/linux/BisqApp.java
index a5d20a43a72..f449d0b98f1 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BisqApp.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BisqApp.java
@@ -90,12 +90,16 @@ public long getPid() {
public void shutdown() {
try {
log.info("Shutting down {} ...", bisqAppConfig.appName);
- if (!isAlive(pid))
- throw new IllegalStateException(format("%s already shut down", bisqAppConfig.appName));
+ if (!isAlive(pid)) {
+ this.shutdownExceptions.add(new IllegalStateException(format("%s already shut down", bisqAppConfig.appName)));
+ return;
+ }
String killCmd = "kill -15 " + pid;
- if (new BashCommand(killCmd).run().getExitStatus() != 0)
- throw new IllegalStateException(format("Could not shut down %s", bisqAppConfig.appName));
+ if (new BashCommand(killCmd).run().getExitStatus() != 0) {
+ this.shutdownExceptions.add(new IllegalStateException(format("Could not shut down %s", bisqAppConfig.appName)));
+ return;
+ }
// Be lenient about the time it takes for a java app to shut down.
for (int i = 0; i < 5; i++) {
@@ -106,11 +110,13 @@ public void shutdown() {
MILLISECONDS.sleep(2500);
}
- if (isAlive(pid))
- throw new IllegalStateException(format("%s shutdown did not work", bisqAppConfig.appName));
+ if (isAlive(pid)) {
+ this.shutdownExceptions.add(new IllegalStateException(format("%s shutdown did not work", bisqAppConfig.appName)));
+ return;
+ }
} catch (Exception e) {
- throw new IllegalStateException(format("Error shutting down %s", bisqAppConfig.appName), e);
+ this.shutdownExceptions.add(new IllegalStateException(format("Error shutting down %s", bisqAppConfig.appName), e));
}
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
index c752d7c8e9b..cdbba297704 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
@@ -83,23 +83,32 @@ public long getPid() {
}
@Override
- public void shutdown() throws IOException, InterruptedException {
+ public void shutdown() {
try {
log.info("Shutting down bitcoind daemon...");
- if (!isAlive(pid))
- throw new IllegalStateException("bitcoind already shut down");
- if (new BashCommand("kill -15 " + pid).run().getExitStatus() != 0)
- throw new IllegalStateException("Could not shut down bitcoind; probably already stopped.");
+ if (!isAlive(pid)) {
+ this.shutdownExceptions.add(new IllegalStateException("Bitcoind already shut down."));
+ return;
+ }
+
+ if (new BashCommand("kill -15 " + pid).run().getExitStatus() != 0) {
+ this.shutdownExceptions.add(new IllegalStateException("Could not shut down bitcoind; probably already stopped."));
+ return;
+ }
+
+ MILLISECONDS.sleep(2500); // allow it time to shutdown
+
+ if (isAlive(pid)) {
+ this.shutdownExceptions.add(new IllegalStateException(
+ format("Could not kill bitcoind process with pid %d.", pid)));
+ return;
+ }
- MILLISECONDS.sleep(2000); // allow it time to shutdown
log.info("Stopped");
- } catch (Exception e) {
- throw new IllegalStateException("Error shutting down bitcoind", e);
- } finally {
- if (isAlive(pid))
- //noinspection ThrowFromFinallyBlock
- throw new IllegalStateException("bitcoind shutdown did not work");
+ } catch (InterruptedException ignored) {
+ } catch (IOException e) {
+ this.shutdownExceptions.add(new IllegalStateException("Error shutting down bitcoind.", e));
}
}
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java
index 8c19be66f12..fff25c2976c 100644
--- a/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/LinuxProcess.java
@@ -19,6 +19,8 @@
import java.io.IOException;
+import java.util.List;
+
public interface LinuxProcess {
void start() throws InterruptedException, IOException;
@@ -28,7 +30,13 @@ public interface LinuxProcess {
boolean hasStartupExceptions();
- IllegalStateException startupIllegalStateException(org.slf4j.Logger log);
+ boolean hasShutdownExceptions();
+
+ void logExceptions(List exceptions, org.slf4j.Logger log);
+
+ List getStartupExceptions();
+
+ List getShutdownExceptions();
- void shutdown() throws IOException, InterruptedException;
+ void shutdown();
}
From e2f00b74172d32710d9721a8360acf8eb8b8e0cc Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 27 Jul 2020 16:43:43 -0300
Subject: [PATCH 72/90] Remove extra whiteline
---
.../src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
index 4063272c686..4687477e956 100644
--- a/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
+++ b/apitest/src/main/java/bisq/apitest/linux/AbstractLinuxProcess.java
@@ -87,7 +87,6 @@ public List getShutdownExceptions() {
return shutdownExceptions;
}
-
@SuppressWarnings("unused")
public void verifyBitcoinPathsExist() {
verifyBitcoinPathsExist(false);
From 8bb7e12f317faa5b44e561cbd87f99fd91e1e820 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 28 Jul 2020 12:33:25 -0300
Subject: [PATCH 73/90] Clarify scaffold tear down error handling
The Scaffold#tearDown() method was split into two methods. The
original tearDown() now passes the background process/task array
to a new shutDownAll() method. This new method loops through the
tasks in a more readable way, plainly expressing the intent to log
all shutdown exceptions for each process being shut down, but not
throwing an exception while processes are being shut down.
The new shutDownAll() method returns the first shutdown exception
encountered, which in turn is passed up to the test case's @AfterAll
method.
---
.../src/main/java/bisq/apitest/Scaffold.java | 54 +++++++++++--------
1 file changed, 32 insertions(+), 22 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java
index 9319226211f..5f9e013c5cc 100644
--- a/apitest/src/main/java/bisq/apitest/Scaffold.java
+++ b/apitest/src/main/java/bisq/apitest/Scaffold.java
@@ -46,7 +46,6 @@
import static java.lang.System.exit;
import static java.lang.System.out;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
-import static java.util.Arrays.stream;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;
@@ -154,27 +153,12 @@ public void tearDown() {
SetupTask[] orderedTasks = new SetupTask[]{
bobNodeTask, aliceNodeTask, arbNodeTask, seedNodeTask, bitcoindTask};
- final Optional[] firstShutdownException = new Optional[]{Optional.empty()};
- stream(orderedTasks).filter(t -> t != null && t.getLinuxProcess() != null)
- .forEachOrdered(t -> {
- try {
- LinuxProcess p = t.getLinuxProcess();
- p.shutdown();
- MILLISECONDS.sleep(1000);
- if (p.hasShutdownExceptions()) {
- // We log shutdown exceptions, but do not throw
- // one from here until the rest of the background
- // instances have been shut down.
- p.logExceptions(p.getShutdownExceptions(), log);
- firstShutdownException[0] = Optional.of(p.getShutdownExceptions().get(0));
- }
- } catch (InterruptedException ignored) {
- }
- });
-
- if (firstShutdownException[0].isPresent())
- throw new IllegalStateException("There were errors shutting down one or more background instances.",
- firstShutdownException[0].get());
+ Optional firstException = shutDownAll(orderedTasks);
+
+ if (firstException.isPresent())
+ throw new IllegalStateException(
+ "There were errors shutting down one or more background instances.",
+ firstException.get());
else
log.info("Teardown complete");
@@ -184,6 +168,32 @@ public void tearDown() {
}
}
+ private Optional shutDownAll(SetupTask[] orderedTasks) {
+ Optional firstException = Optional.empty();
+ for (SetupTask t : orderedTasks) {
+ if (t != null && t.getLinuxProcess() != null) {
+ try {
+ LinuxProcess p = t.getLinuxProcess();
+ p.shutdown();
+ MILLISECONDS.sleep(1000);
+ if (p.hasShutdownExceptions()) {
+ // We log shutdown exceptions, but do not throw any from here
+ // because all of the background instances must be shut down.
+ p.logExceptions(p.getShutdownExceptions(), log);
+
+ // We cache only the 1st shutdown exception and move on to the
+ // next process to be shutdown. This cached exception will be the
+ // one thrown to the calling test case (the @AfterAll method).
+ if (!firstException.isPresent())
+ firstException = Optional.of(p.getShutdownExceptions().get(0));
+ }
+ } catch (InterruptedException ignored) {
+ }
+ }
+ }
+ return firstException;
+ }
+
public void installDaoSetupDirectories() {
cleanDaoSetupDirectories();
From 685839d3481e0cb0624673865c90f4503e41ab4f Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 12 Aug 2020 16:47:12 -0300
Subject: [PATCH 74/90] Add fallbackfee param to bitcoind start cmd
This commit adds a -fallbackfee=0.0002 parameter to the start 'bitcoind'
command to keep bitcoin-core v0.20.1 working as v0.19.1 does -- with the
'fallbackfee' enabled.
Bitcoin v0.20.0 contains a fix for inconsistent behaviour related
to this fallbackfee configuration. Prior to v0.20, fallbackfee
was disabled (0) by default for the mainnet chain, but enabled
(0.0002) for the testnet and regtest chains.
A test case with bitcoin-core v0.20.1 was breaking on
the bitcoin-cli 'sendtoaddress' command, which was returning an
error message instead of a tx-id:
error code: -4
error message:
Fee estimation failed. Fallbackfee is disabled. \
Wait a few blocks or enable -fallbackfee.
Bitcoin-core v0.20.0 release notes contain info about this change:
https://bitcoin.org/en/release/v0.20.0#updated-rpcs-1
The Bitcoin-core PR is https://github.com/bitcoin/bitcoin/pull/16524
---
apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
index cdbba297704..24d694a22d8 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
@@ -55,6 +55,7 @@ public void start() throws InterruptedException, IOException {
+ " -txindex=1"
+ " -peerbloomfilters=1"
+ " -debug=net"
+ + " -fallbackfee=0.0002"
+ " -rpcuser=" + config.bitcoinRpcUser
+ " -rpcpassword=" + config.bitcoinRpcPassword
+ " -blocknotify=" + config.bitcoinDatadir + "/blocknotify";
From 176f0b2ad811462f6104520ca6563d75b3e9ea3c Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 13 Aug 2020 13:32:58 -0300
Subject: [PATCH 75/90] Fix BitcoinCli wrapper error handling
This change checks the system call exit status of bitcoin-cli
commands, and populates a new error message accessor if the
system exist status != 0.
---
.../java/bisq/apitest/linux/BitcoinCli.java | 19 ++++++++++++--
.../bisq/apitest/method/BitcoinCliHelper.java | 26 ++++++++++++-------
2 files changed, 33 insertions(+), 12 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java b/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java
index 169dfd5da1a..0bf49aa3602 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java
@@ -33,11 +33,13 @@ public class BitcoinCli extends AbstractLinuxProcess implements LinuxProcess {
private String commandWithOptions;
private String output;
private boolean error;
+ private String errorMessage;
public BitcoinCli(ApiTestConfig config, String command) {
super("bitcoin-cli", config);
this.command = command;
this.error = false;
+ this.errorMessage = null;
}
public BitcoinCli run() throws IOException, InterruptedException {
@@ -138,6 +140,10 @@ public boolean isError() {
return error;
}
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+
@Override
public void start() throws InterruptedException, IOException {
verifyBitcoinPathsExist(false);
@@ -146,8 +152,17 @@ public void start() throws InterruptedException, IOException {
+ " -rpcuser=" + config.bitcoinRpcUser
+ " -rpcpassword=" + config.bitcoinRpcPassword
+ " " + command;
- output = new BashCommand(commandWithOptions).run().getOutput();
- error = output.startsWith("error");
+ BashCommand bashCommand = new BashCommand(commandWithOptions).run();
+
+ error = bashCommand.getExitStatus() != 0;
+ if (error) {
+ errorMessage = bashCommand.getError();
+ if (errorMessage == null || errorMessage.isEmpty())
+ throw new IllegalStateException("bitcoin-cli returned an error without a message");
+
+ } else {
+ output = bashCommand.getOutput();
+ }
}
@Override
diff --git a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
index 693da32966b..45edf415794 100644
--- a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
+++ b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
@@ -20,7 +20,6 @@
import java.io.IOException;
import static java.lang.String.format;
-import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.fail;
@@ -40,9 +39,12 @@ public BitcoinCliHelper(ApiTestConfig config) {
public String getNewBtcAddress() {
try {
- String newAddress = new BitcoinCli(config, "getnewaddress").run().getOutput();
- assertNotNull(newAddress);
- return newAddress;
+ BitcoinCli newAddress = new BitcoinCli(config, "getnewaddress").run();
+
+ if (newAddress.isError())
+ fail(format("Could generate new bitcoin address:%n%s", newAddress.getErrorMessage()));
+
+ return newAddress.getOutput();
} catch (IOException | InterruptedException ex) {
fail(ex);
return null;
@@ -53,9 +55,11 @@ public String[] generateToAddress(int blocks, String address) {
try {
String generateToAddressCmd = format("generatetoaddress %d \"%s\"", blocks, address);
BitcoinCli generateToAddress = new BitcoinCli(config, generateToAddressCmd).run();
- String[] txids = generateToAddress.getOutputValueAsStringArray();
- assertNotNull(txids);
- return txids;
+
+ if (generateToAddress.isError())
+ fail(format("Could not generate bitcoin block(s):%n%s", generateToAddress.getErrorMessage()));
+
+ return generateToAddress.getOutputValueAsStringArray();
} catch (IOException | InterruptedException ex) {
fail(ex);
return null;
@@ -75,9 +79,11 @@ public String sendToAddress(String address, String amount) {
String sendToAddressCmd = format("sendtoaddress \"%s\" %s \"\" \"\" false",
address, amount);
BitcoinCli sendToAddress = new BitcoinCli(config, sendToAddressCmd).run();
- String txid = sendToAddress.getOutput();
- assertNotNull(txid);
- return txid;
+
+ if (sendToAddress.isError())
+ fail(format("Could not send BTC to address:%n%s", sendToAddress.getErrorMessage()));
+
+ return sendToAddress.getOutput();
} catch (IOException | InterruptedException ex) {
fail(ex);
return null;
From 9637cc09437c9aef8c90d3eeea01b296f1f91ddc Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Thu, 13 Aug 2020 14:19:02 -0300
Subject: [PATCH 76/90] Fix test fail() msg
---
apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
index 45edf415794..6e5b52080f3 100644
--- a/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
+++ b/apitest/src/test/java/bisq/apitest/method/BitcoinCliHelper.java
@@ -42,7 +42,7 @@ public String getNewBtcAddress() {
BitcoinCli newAddress = new BitcoinCli(config, "getnewaddress").run();
if (newAddress.isError())
- fail(format("Could generate new bitcoin address:%n%s", newAddress.getErrorMessage()));
+ fail(format("Could not generate new bitcoin address:%n%s", newAddress.getErrorMessage()));
return newAddress.getOutput();
} catch (IOException | InterruptedException ex) {
From 72ff4dca2b241a55be17a1c9c15946abb20818ca Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 15 Aug 2020 12:20:25 -0300
Subject: [PATCH 77/90] Use non-default regtest bitcoind -rpcport
The default bitcoind / bitcoin-cli rpcport option has been changed
from 18443 to 19443, to help avoid rpcport conflicts between apitest's
bitcoind instances and other bitcoind and/or bitcion-qt instances
which are probably using the bitcoin-core default (regtest) rpcport
18443.
However, this commit cannot include other changes for avoiding bind
address:port conflicts between apitest bitcoind instances and other
regtest bitcoin-core instances because bitcoinj's bind port is hardcoded
in RegTestParams.java as 18444.
In order to avoid bitcoin-core regtest mode bind address conflicts,
you must start or restart your bitcoind or bitcoin-qt instance with a
non-default bind port argument, e.g.
bitcoin-qt -regtest -port=20444
---
apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java | 4 ++--
apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java | 1 +
apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java | 1 +
3 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
index 22ae67fccee..027d046b265 100644
--- a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
+++ b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
@@ -173,9 +173,9 @@ public ApiTestConfig(String... args) {
.ofType(String.class).defaultsTo("localhost");
ArgumentAcceptingOptionSpec bitcoinRpcPortOpt =
- parser.accepts(BITCOIN_RPC_PORT, "Bitcoin Core rpc port")
+ parser.accepts(BITCOIN_RPC_PORT, "Bitcoin Core rpc port (non-default)")
.withRequiredArg()
- .ofType(Integer.class).defaultsTo(18443);
+ .ofType(Integer.class).defaultsTo(19443);
ArgumentAcceptingOptionSpec bitcoinRpcUserOpt =
parser.accepts(BITCOIN_RPC_USER, "Bitcoin rpc user")
diff --git a/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java b/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java
index 0bf49aa3602..2367443b0c4 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BitcoinCli.java
@@ -149,6 +149,7 @@ public void start() throws InterruptedException, IOException {
verifyBitcoinPathsExist(false);
verifyBitcoindRunning();
commandWithOptions = config.bitcoinPath + "/bitcoin-cli -regtest "
+ + " -rpcport=" + config.bitcoinRpcPort
+ " -rpcuser=" + config.bitcoinRpcUser
+ " -rpcpassword=" + config.bitcoinRpcPassword
+ " " + command;
diff --git a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
index 24d694a22d8..e61f1317438 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
@@ -56,6 +56,7 @@ public void start() throws InterruptedException, IOException {
+ " -peerbloomfilters=1"
+ " -debug=net"
+ " -fallbackfee=0.0002"
+ + " -rpcport=" + config.bitcoinRpcPort
+ " -rpcuser=" + config.bitcoinRpcUser
+ " -rpcpassword=" + config.bitcoinRpcPassword
+ " -blocknotify=" + config.bitcoinDatadir + "/blocknotify";
From e88bdb9f8ac2cc003ccbd3374c865c6997a36244 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 15 Aug 2020 12:46:38 -0300
Subject: [PATCH 78/90] Add regtest-port-conflicts.md doc
---
apitest/docs/regtest-port-conflicts.md | 12 ++++++++++++
1 file changed, 12 insertions(+)
create mode 100644 apitest/docs/regtest-port-conflicts.md
diff --git a/apitest/docs/regtest-port-conflicts.md b/apitest/docs/regtest-port-conflicts.md
new file mode 100644
index 00000000000..601871218e2
--- /dev/null
+++ b/apitest/docs/regtest-port-conflicts.md
@@ -0,0 +1,12 @@
+# Avoiding bitcoin-core regtest port conflicts
+
+Some developers may already be running a `bitcoind` or `bitcoin-qt` instance in regtest mode when they try to run API
+test cases. If a `bitcoin-qt` instance is bound to the default regtest port 18443, `apitest` will not be able to start
+its own bitcoind instances.
+
+Though it would be preferable for `apitest` to change the bind port for Bisq's `bitcoinj` module at runtime, this is
+not currently possible because `bitcoinj` hardcodes the default regtest mode bind port in `RegTestParams`.
+
+To avoid the bind address:port conflict, pass a port option to your bitcoin-core instance:
+
+ bitcoin-qt -regtest -port=20444
From 12d52e869cd2f88470a056f3fd4a07c2a737d33d Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Sat, 15 Aug 2020 13:22:32 -0300
Subject: [PATCH 79/90] Fix port number typo
---
apitest/docs/regtest-port-conflicts.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apitest/docs/regtest-port-conflicts.md b/apitest/docs/regtest-port-conflicts.md
index 601871218e2..7ec3e6bf45a 100644
--- a/apitest/docs/regtest-port-conflicts.md
+++ b/apitest/docs/regtest-port-conflicts.md
@@ -1,7 +1,7 @@
# Avoiding bitcoin-core regtest port conflicts
Some developers may already be running a `bitcoind` or `bitcoin-qt` instance in regtest mode when they try to run API
-test cases. If a `bitcoin-qt` instance is bound to the default regtest port 18443, `apitest` will not be able to start
+test cases. If a `bitcoin-qt` instance is bound to the default regtest port 18444, `apitest` will not be able to start
its own bitcoind instances.
Though it would be preferable for `apitest` to change the bind port for Bisq's `bitcoinj` module at runtime, this is
From fc541257aed194feb1831b9e4feed1cb75a69376 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 17 Aug 2020 15:57:54 -0300
Subject: [PATCH 80/90] Add build / run / test categories docs
---
apitest/docs/README.md | 5 +++
apitest/docs/build-run.md | 61 +++++++++++++++++++++++++++++++++
apitest/docs/test-categories.md | 35 +++++++++++++++++++
3 files changed, 101 insertions(+)
create mode 100644 apitest/docs/README.md
create mode 100644 apitest/docs/build-run.md
create mode 100644 apitest/docs/test-categories.md
diff --git a/apitest/docs/README.md b/apitest/docs/README.md
new file mode 100644
index 00000000000..4430b6f84e3
--- /dev/null
+++ b/apitest/docs/README.md
@@ -0,0 +1,5 @@
+# Bisq apitest docs
+
+ - [build-run.md](build-run.md): Build and run API tests at the command line and from Intellij
+ - [test-categories.md](test-categories.md): Learn about the Bisq testing process and how you can contribute.
+ - [regtest-port-conflicts.md](regtest-port-conflicts.md): (deprecated) Set up a complete Bisq DAO development environment
diff --git a/apitest/docs/build-run.md b/apitest/docs/build-run.md
new file mode 100644
index 00000000000..73bd0f96a54
--- /dev/null
+++ b/apitest/docs/build-run.md
@@ -0,0 +1,61 @@
+# Build and Run API Test Harness
+
+## Linux & OSX
+
+The API test harness uses the GNU Bourne-Again SHell `bash`, and is not supported on Windows.
+
+## Predefined DAO / Regtest Setup
+
+The API test harness depends on the contents of https://github.com/bisq-network/bisq/raw/master/docs/dao-setup.zip.
+The files contained in dao-setup.zip include a bitcoin-core wallet, a regtest genesis tx and chain of 111 blocks, plus
+data directories for Bob and Alice Bisq instances. Bob & Alice wallets are pre-configured with 10 BTC each, and the
+equivalent of 2.5 BTC in BSQ distributed among Bob & Alice's BSQ wallets.
+
+See https://github.com/bisq-network/bisq/blob/master/docs/dao-setup.md for details.
+
+## Install DAO / Regtest Setup Files
+
+Bisq's gradle build file defines a task for downloading dao-setup.zip and extracting its contents to the
+`apitest/src/main/resources` folder, and the test harness will install a fresh set of data files to the
+`apitest/build/resources/main` folder during a test case's scaffold setup phase -- normally a static `@BeforeAll` method.
+
+The dao-setup files can be downloaded during a normal build:
+
+ $ ./gradlew clean build :apitest:installDaoSetup
+
+Or by running a single task:
+
+ $ ./gradlew :apitest:installDaoSetup
+
+The `:apitest:installDaoSetup` task does not need to be run again until after the next time you run the gradle `clean` task.
+
+## Run API Tests
+
+The API test harness supports narrow & broad functional and full end to end test cases requiring
+long setup and teardown times -- for example, to start a bitcoind instance, seednode, arbnode, plus Bob & Alice
+Bisq instances, then shut everything down in proper order. For this reason, API test cases do not run during a normal
+gradle build.
+
+To run API test cases, pass system property`-DrunApiTests=true`.
+
+To run all existing test cases:
+
+ $ ./gradlew :apitest:test -DrunApiTests=true
+
+To run all test cases in a package:
+
+ $ ./gradlew :apitest:test --tests "bisq.apitest.method.*" -DrunApiTests=true
+
+To run a single test case:
+
+ $ ./gradlew :apitest:test --tests "bisq.apitest.method.GetBalanceTest" -DrunApiTests=true
+
+## Gradle Test Reports
+
+To see detailed test results, logs, and full stack traces for test failures, open
+`apitest/build/reports/tests/test/index.html` in a browser.
+
+## See also
+
+ - [test-categories.md](test-categories.md)
+
diff --git a/apitest/docs/test-categories.md b/apitest/docs/test-categories.md
new file mode 100644
index 00000000000..ba1c095dc04
--- /dev/null
+++ b/apitest/docs/test-categories.md
@@ -0,0 +1,35 @@
+# API Test Categories
+
+This guide describes the categorization of tests.
+
+## Method Tests
+
+A `method` test is the `apitest` analog of a unit test. It tests a single API method such as `getbalance`, but is not
+considered a unit test because the code execution path traverses so many layers: from `gRPC` client -> `gRPC` server
+side service -> one or more Bisq `core` services, and back to the client.
+
+Method tests have direct access to `gRPC` client stubs, and test asserts are made directly on `gRPC` return values --
+Java Objects.
+
+All `method` tests are part of the `bisq.apitest.method` package.
+
+## Scenario Tests
+
+A `scenario` test is a narrow or broad functional test case covering a simple use case such as funding a wallet to a
+complex series of trades. Generally, a scenario test case requires multiple `gRPC` method calls.
+
+Scenario tests have direct access to `gRPC` client stubs, and test asserts are made directly on `gRPC` return values --
+Java Objects.
+
+All `scenario` tests are part of the `bisq.apitest.scenario` package.
+
+## End to End Tests
+
+An end to end (`e2e`) test can cover a narrow or broad use case, and all client calls go through the `CLI` shell script
+`bisq-cli`. End to end tests do not have access to `gRPC` client stubs, and test asserts are made on what the end
+user sees on the console -- what`gRPC CLI` prints to `STDOUT`.
+
+As test coverage grows, stable scenario test cases should be migrated to `e2e` test cases.
+
+All `e2e` tests are part of the `bisq.apitest.e2e` package.
+
From f85ae2bb4d1bc4605d13864967710daa4580909a Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:11:31 -0300
Subject: [PATCH 81/90] Explain how to run test cases from Intellij
---
apitest/docs/build-run.md | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/apitest/docs/build-run.md b/apitest/docs/build-run.md
index 73bd0f96a54..99cee6e328e 100644
--- a/apitest/docs/build-run.md
+++ b/apitest/docs/build-run.md
@@ -50,6 +50,13 @@ To run a single test case:
$ ./gradlew :apitest:test --tests "bisq.apitest.method.GetBalanceTest" -DrunApiTests=true
+To run test cases from an Intellij, add two JVM arguments to your JUnit launchers:
+
+ -DrunApiTests=true -Dlogback.configurationFile=apitest/build/resources/main/logback.xml
+
+The `-Dlogback.configurationFile` property will prevent `logback` from printing warnings about multiple `logback.xml`
+files it will find in Bisq jars `cli.jar`, `daemon.jar`, and `seednode.jar`.
+
## Gradle Test Reports
To see detailed test results, logs, and full stack traces for test failures, open
From af7252ec47987da7b7cf3a5546ba5e217e8220b5 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:14:37 -0300
Subject: [PATCH 82/90] Fix typo
---
apitest/docs/build-run.md | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/apitest/docs/build-run.md b/apitest/docs/build-run.md
index 99cee6e328e..308fe02cf66 100644
--- a/apitest/docs/build-run.md
+++ b/apitest/docs/build-run.md
@@ -50,7 +50,7 @@ To run a single test case:
$ ./gradlew :apitest:test --tests "bisq.apitest.method.GetBalanceTest" -DrunApiTests=true
-To run test cases from an Intellij, add two JVM arguments to your JUnit launchers:
+To run test cases from Intellij, add two JVM arguments to your JUnit launchers:
-DrunApiTests=true -Dlogback.configurationFile=apitest/build/resources/main/logback.xml
From 8b081ad5f257aa644309ffa1c6625935943c5892 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 17 Aug 2020 16:18:08 -0300
Subject: [PATCH 83/90] Update README
---
apitest/docs/README.md | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apitest/docs/README.md b/apitest/docs/README.md
index 4430b6f84e3..2072899d468 100644
--- a/apitest/docs/README.md
+++ b/apitest/docs/README.md
@@ -1,5 +1,5 @@
# Bisq apitest docs
- [build-run.md](build-run.md): Build and run API tests at the command line and from Intellij
- - [test-categories.md](test-categories.md): Learn about the Bisq testing process and how you can contribute.
- - [regtest-port-conflicts.md](regtest-port-conflicts.md): (deprecated) Set up a complete Bisq DAO development environment
+ - [test-categories.md](test-categories.md): Learn about method, scenario and end to end tests
+ - [regtest-port-conflicts.md](regtest-port-conflicts.md): Avoid port conflicts when running multiple bitcoin-core apps in regtest mode
From c3abd4e533b9f673ed805efa9ac6e92a81e843f1 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Tue, 18 Aug 2020 10:38:26 -0300
Subject: [PATCH 84/90] Remove white lines
---
apitest/src/test/java/bisq/apitest/method/MethodTest.java | 1 -
.../src/test/java/bisq/apitest/method/WalletProtectionTest.java | 2 --
2 files changed, 3 deletions(-)
diff --git a/apitest/src/test/java/bisq/apitest/method/MethodTest.java b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
index 37dea63cdb9..694aa6806e3 100644
--- a/apitest/src/test/java/bisq/apitest/method/MethodTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/MethodTest.java
@@ -84,6 +84,5 @@ protected final String getUnusedBtcAddress() {
.findFirst()
.get()
.getAddress();
-
}
}
diff --git a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
index a00d5333c01..450fb58e010 100644
--- a/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
+++ b/apitest/src/test/java/bisq/apitest/method/WalletProtectionTest.java
@@ -87,7 +87,6 @@ public void testLockWalletWhenWalletAlreadyLockedShouldThrowException() {
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs.walletsService.lockWallet(request));
assertEquals("UNKNOWN: wallet is already locked", exception.getMessage());
-
}
@Test
@@ -129,7 +128,6 @@ public void testRemoveNewWalletPassword() {
getBalance(); // should not throw 'wallet locked' exception
}
-
@AfterAll
public static void tearDown() {
tearDownScaffold();
From fa11dab28be39625946313b6c9e5ea9a4cd3e1c3 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 19 Aug 2020 11:04:21 -0300
Subject: [PATCH 85/90] Add punctuation & re-phrase sentence in README
A new commit was needed to force a codacy check after changes were
made to codacy rules.
---
apitest/docs/README.md | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/apitest/docs/README.md b/apitest/docs/README.md
index 2072899d468..625dadddc9f 100644
--- a/apitest/docs/README.md
+++ b/apitest/docs/README.md
@@ -1,5 +1,5 @@
# Bisq apitest docs
- - [build-run.md](build-run.md): Build and run API tests at the command line and from Intellij
- - [test-categories.md](test-categories.md): Learn about method, scenario and end to end tests
- - [regtest-port-conflicts.md](regtest-port-conflicts.md): Avoid port conflicts when running multiple bitcoin-core apps in regtest mode
+ - [build-run.md](build-run.md): Build and run API tests at the command line and from Intellij.
+ - [test-categories.md](test-categories.md): How to categorize a test case as `method`, `scenario` or `e2e`.
+ - [regtest-port-conflicts.md](regtest-port-conflicts.md): Avoid port conflicts when running multiple bitcoin-core apps in regtest mode.
From 2ba0ee9d5d6960a1e81984c3530dc42a8876b303 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 19 Aug 2020 11:14:33 -0300
Subject: [PATCH 86/90] Change access modifer
This commit is for forcing a codacy check. The previous
change to an .md doc did not force a codacy check.
---
apitest/src/test/java/bisq/apitest/JUnitHelper.java | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/apitest/src/test/java/bisq/apitest/JUnitHelper.java b/apitest/src/test/java/bisq/apitest/JUnitHelper.java
index 03f16ee6b11..8ea80ad0d5e 100644
--- a/apitest/src/test/java/bisq/apitest/JUnitHelper.java
+++ b/apitest/src/test/java/bisq/apitest/JUnitHelper.java
@@ -34,7 +34,11 @@ public void testFailure(Failure failure) {
printTestResults(result);
}
- public static void printTestResults(Result result) {
+ public static boolean allTestsPassed() {
+ return allPass;
+ }
+
+ private static void printTestResults(Result result) {
log.info("Total tests: {}, Failed: {}, Ignored: {}",
result.getRunCount(),
result.getFailureCount(),
@@ -51,8 +55,4 @@ public static void printTestResults(Result result) {
f.getTrace())));
}
}
-
- public static boolean allTestsPassed() {
- return allPass;
- }
}
From ba8b9ccf54c9e87bb00694e4ee667ca33c00258d Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 19 Aug 2020 11:49:21 -0300
Subject: [PATCH 87/90] Put 'empty' comments inside ignored catch blocks
Follow codacy rule against empty blocks.
---
apitest/src/main/java/bisq/apitest/Scaffold.java | 1 +
apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java | 1 +
.../src/main/java/bisq/apitest/linux/ThreadedStreamHandler.java | 1 +
apitest/src/test/java/bisq/apitest/ApiTestCase.java | 1 +
4 files changed, 4 insertions(+)
diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java
index 5f9e013c5cc..bf0e4c771dd 100644
--- a/apitest/src/main/java/bisq/apitest/Scaffold.java
+++ b/apitest/src/main/java/bisq/apitest/Scaffold.java
@@ -188,6 +188,7 @@ private Optional shutDownAll(SetupTask[] orderedTasks) {
firstException = Optional.of(p.getShutdownExceptions().get(0));
}
} catch (InterruptedException ignored) {
+ // empty
}
}
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
index e61f1317438..cc2e4952005 100644
--- a/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
+++ b/apitest/src/main/java/bisq/apitest/linux/BitcoinDaemon.java
@@ -109,6 +109,7 @@ public void shutdown() {
log.info("Stopped");
} catch (InterruptedException ignored) {
+ // empty
} catch (IOException e) {
this.shutdownExceptions.add(new IllegalStateException("Error shutting down bitcoind.", e));
}
diff --git a/apitest/src/main/java/bisq/apitest/linux/ThreadedStreamHandler.java b/apitest/src/main/java/bisq/apitest/linux/ThreadedStreamHandler.java
index 88ae539b0d0..540b1361009 100644
--- a/apitest/src/main/java/bisq/apitest/linux/ThreadedStreamHandler.java
+++ b/apitest/src/main/java/bisq/apitest/linux/ThreadedStreamHandler.java
@@ -80,6 +80,7 @@ private void doSleep(long millis) {
try {
Thread.sleep(millis);
} catch (InterruptedException ignored) {
+ // empty
}
}
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
index e2301346c43..286e7f8c206 100644
--- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -88,6 +88,7 @@ protected void sleep(long ms) {
try {
MILLISECONDS.sleep(ms);
} catch (InterruptedException ignored) {
+ // empty
}
}
}
From a1e6433dc23d2fafab8ac5441dcd5ad28760a227 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 19 Aug 2020 15:34:14 -0300
Subject: [PATCH 88/90] Move gRPC boilerplate from :core to :daemon
This change moves gRPC boilerplate classes from the :core.grpc pkg
into a new :daemon.grpc pkg.
* The :core.grpc pkg was renamed :core.api, and no longer has any
dependencies on gRPC libraries.
* All core service classes in the :core.api pkg are now package
protected, excepting CoreApi, making CoreApi the only possible
entry point for all Grpc*Service -> -Core*Service calls.
* All grpc service classes in the :daemon.grpc pkg are now package
protected, excepting GrpcServer; the only class depending on
Grpc*Service class is GrpcServer.
* gRPC dependencies were moved from the gradle.build file's :core
subproject to :daemon.
---
build.gradle | 18 +++++-------------
.../java/bisq/core/{grpc => api}/CoreApi.java | 4 ++--
.../core/{grpc => api}/CoreOffersService.java | 4 ++--
.../CorePaymentAccountsService.java | 4 ++--
.../core/{grpc => api}/CoreWalletsService.java | 4 ++--
.../model/AddressBalanceInfo.java | 2 +-
.../core/{grpc => api}/model/OfferInfo.java | 2 +-
.../java/bisq/daemon/app/BisqDaemonMain.java | 7 +++++--
.../bisq/daemon}/grpc/GrpcOffersService.java | 5 +++--
.../grpc/GrpcPaymentAccountsService.java | 5 +++--
.../java/bisq/daemon}/grpc/GrpcServer.java | 3 ++-
.../bisq/daemon}/grpc/GrpcWalletsService.java | 5 +++--
.../daemon}/grpc/PasswordAuthInterceptor.java | 2 +-
13 files changed, 32 insertions(+), 33 deletions(-)
rename core/src/main/java/bisq/core/{grpc => api}/CoreApi.java (98%)
rename core/src/main/java/bisq/core/{grpc => api}/CoreOffersService.java (98%)
rename core/src/main/java/bisq/core/{grpc => api}/CorePaymentAccountsService.java (97%)
rename core/src/main/java/bisq/core/{grpc => api}/CoreWalletsService.java (99%)
rename core/src/main/java/bisq/core/{grpc => api}/model/AddressBalanceInfo.java (98%)
rename core/src/main/java/bisq/core/{grpc => api}/model/OfferInfo.java (99%)
rename {core/src/main/java/bisq/core => daemon/src/main/java/bisq/daemon}/grpc/GrpcOffersService.java (97%)
rename {core/src/main/java/bisq/core => daemon/src/main/java/bisq/daemon}/grpc/GrpcPaymentAccountsService.java (93%)
rename {core/src/main/java/bisq/core => daemon/src/main/java/bisq/daemon}/grpc/GrpcServer.java (98%)
rename {core/src/main/java/bisq/core => daemon/src/main/java/bisq/daemon}/grpc/GrpcWalletsService.java (98%)
rename {core/src/main/java/bisq/core => daemon/src/main/java/bisq/daemon}/grpc/PasswordAuthInterceptor.java (98%)
diff --git a/build.gradle b/build.gradle
index 406c99e327a..f6c059691c9 100644
--- a/build.gradle
+++ b/build.gradle
@@ -328,19 +328,6 @@ configure(project(':core')) {
exclude(module: 'jackson-annotations')
}
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
- implementation("io.grpc:grpc-protobuf:$grpcVersion") {
- exclude(module: 'guava')
- exclude(module: 'animal-sniffer-annotations')
- }
- implementation("io.grpc:grpc-stub:$grpcVersion") {
- exclude(module: 'guava')
- exclude(module: 'animal-sniffer-annotations')
- }
- compileOnly "javax.annotation:javax.annotation-api:$javaxAnnotationVersion"
- runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
- exclude(module: 'guava')
- exclude(module: 'animal-sniffer-annotations')
- }
compileOnly "org.projectlombok:lombok:$lombokVersion"
annotationProcessor "org.projectlombok:lombok:$lombokVersion"
@@ -543,6 +530,7 @@ configure(project(':daemon')) {
mainClassName = 'bisq.daemon.app.BisqDaemonMain'
dependencies {
+ compile project(':proto')
compile project(':core')
implementation "com.google.guava:guava:$guavaVersion"
implementation "com.google.protobuf:protobuf-java:$protobufVersion"
@@ -554,6 +542,10 @@ configure(project(':daemon')) {
exclude(module: 'guava')
exclude(module: 'animal-sniffer-annotations')
}
+ runtimeOnly("io.grpc:grpc-netty-shaded:$grpcVersion") {
+ exclude(module: 'guava')
+ exclude(module: 'animal-sniffer-annotations')
+ }
implementation "org.slf4j:slf4j-api:$slf4jVersion"
implementation "ch.qos.logback:logback-core:$logbackVersion"
implementation "ch.qos.logback:logback-classic:$logbackVersion"
diff --git a/core/src/main/java/bisq/core/grpc/CoreApi.java b/core/src/main/java/bisq/core/api/CoreApi.java
similarity index 98%
rename from core/src/main/java/bisq/core/grpc/CoreApi.java
rename to core/src/main/java/bisq/core/api/CoreApi.java
index 88302a82d2a..7041404ce51 100644
--- a/core/src/main/java/bisq/core/grpc/CoreApi.java
+++ b/core/src/main/java/bisq/core/api/CoreApi.java
@@ -15,9 +15,9 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.core.api;
-import bisq.core.grpc.model.AddressBalanceInfo;
+import bisq.core.api.model.AddressBalanceInfo;
import bisq.core.monetary.Price;
import bisq.core.offer.Offer;
import bisq.core.offer.OfferPayload;
diff --git a/core/src/main/java/bisq/core/grpc/CoreOffersService.java b/core/src/main/java/bisq/core/api/CoreOffersService.java
similarity index 98%
rename from core/src/main/java/bisq/core/grpc/CoreOffersService.java
rename to core/src/main/java/bisq/core/api/CoreOffersService.java
index 35136ec1c5f..c5fac7442af 100644
--- a/core/src/main/java/bisq/core/grpc/CoreOffersService.java
+++ b/core/src/main/java/bisq/core/api/CoreOffersService.java
@@ -15,7 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.core.api;
import bisq.core.monetary.Price;
import bisq.core.offer.CreateOfferService;
@@ -40,7 +40,7 @@
import static bisq.core.offer.OfferPayload.Direction.BUY;
@Slf4j
-public class CoreOffersService {
+class CoreOffersService {
private final CreateOfferService createOfferService;
private final OfferBookService offerBookService;
diff --git a/core/src/main/java/bisq/core/grpc/CorePaymentAccountsService.java b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java
similarity index 97%
rename from core/src/main/java/bisq/core/grpc/CorePaymentAccountsService.java
rename to core/src/main/java/bisq/core/api/CorePaymentAccountsService.java
index 9a7183d21ab..f40c56c20d7 100644
--- a/core/src/main/java/bisq/core/grpc/CorePaymentAccountsService.java
+++ b/core/src/main/java/bisq/core/api/CorePaymentAccountsService.java
@@ -15,7 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.core.api;
import bisq.core.account.witness.AccountAgeWitnessService;
import bisq.core.locale.FiatCurrency;
@@ -34,7 +34,7 @@
import lombok.extern.slf4j.Slf4j;
@Slf4j
-public class CorePaymentAccountsService {
+class CorePaymentAccountsService {
private final Config config;
private final AccountAgeWitnessService accountAgeWitnessService;
diff --git a/core/src/main/java/bisq/core/grpc/CoreWalletsService.java b/core/src/main/java/bisq/core/api/CoreWalletsService.java
similarity index 99%
rename from core/src/main/java/bisq/core/grpc/CoreWalletsService.java
rename to core/src/main/java/bisq/core/api/CoreWalletsService.java
index 1d3719558b7..10feea5b8e6 100644
--- a/core/src/main/java/bisq/core/grpc/CoreWalletsService.java
+++ b/core/src/main/java/bisq/core/api/CoreWalletsService.java
@@ -15,13 +15,13 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.core.api;
+import bisq.core.api.model.AddressBalanceInfo;
import bisq.core.btc.Balances;
import bisq.core.btc.model.AddressEntry;
import bisq.core.btc.wallet.BtcWalletService;
import bisq.core.btc.wallet.WalletsManager;
-import bisq.core.grpc.model.AddressBalanceInfo;
import org.bitcoinj.core.Address;
import org.bitcoinj.core.TransactionConfidence;
diff --git a/core/src/main/java/bisq/core/grpc/model/AddressBalanceInfo.java b/core/src/main/java/bisq/core/api/model/AddressBalanceInfo.java
similarity index 98%
rename from core/src/main/java/bisq/core/grpc/model/AddressBalanceInfo.java
rename to core/src/main/java/bisq/core/api/model/AddressBalanceInfo.java
index dd9ed19f90e..a9da82a917f 100644
--- a/core/src/main/java/bisq/core/grpc/model/AddressBalanceInfo.java
+++ b/core/src/main/java/bisq/core/api/model/AddressBalanceInfo.java
@@ -15,7 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc.model;
+package bisq.core.api.model;
import bisq.common.Payload;
diff --git a/core/src/main/java/bisq/core/grpc/model/OfferInfo.java b/core/src/main/java/bisq/core/api/model/OfferInfo.java
similarity index 99%
rename from core/src/main/java/bisq/core/grpc/model/OfferInfo.java
rename to core/src/main/java/bisq/core/api/model/OfferInfo.java
index 0b2dc5fe0cd..fa6f0c95ea6 100644
--- a/core/src/main/java/bisq/core/grpc/model/OfferInfo.java
+++ b/core/src/main/java/bisq/core/api/model/OfferInfo.java
@@ -15,7 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc.model;
+package bisq.core.api.model;
import bisq.common.Payload;
diff --git a/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java b/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java
index 64b5bcfc331..3fcb6aa2576 100644
--- a/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java
+++ b/daemon/src/main/java/bisq/daemon/app/BisqDaemonMain.java
@@ -20,7 +20,6 @@
import bisq.core.app.BisqHeadlessAppMain;
import bisq.core.app.BisqSetup;
import bisq.core.app.CoreModule;
-import bisq.core.grpc.GrpcServer;
import bisq.common.UserThread;
import bisq.common.app.AppModule;
@@ -33,10 +32,14 @@
import lombok.extern.slf4j.Slf4j;
+
+
+import bisq.daemon.grpc.GrpcServer;
+
@Slf4j
public class BisqDaemonMain extends BisqHeadlessAppMain implements BisqSetup.BisqSetupListener {
- public static void main(String[] args) {
+ public static void main(String[] args) {
new BisqDaemonMain().execute(args);
}
diff --git a/core/src/main/java/bisq/core/grpc/GrpcOffersService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
similarity index 97%
rename from core/src/main/java/bisq/core/grpc/GrpcOffersService.java
rename to daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
index c0f90a8abb9..8a3fa548d92 100644
--- a/core/src/main/java/bisq/core/grpc/GrpcOffersService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcOffersService.java
@@ -15,9 +15,10 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.daemon.grpc;
-import bisq.core.grpc.model.OfferInfo;
+import bisq.core.api.CoreApi;
+import bisq.core.api.model.OfferInfo;
import bisq.core.trade.handlers.TransactionResultHandler;
import bisq.proto.grpc.CreateOfferReply;
diff --git a/core/src/main/java/bisq/core/grpc/GrpcPaymentAccountsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java
similarity index 93%
rename from core/src/main/java/bisq/core/grpc/GrpcPaymentAccountsService.java
rename to daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java
index 8388b85e3bc..e630b30fc50 100644
--- a/core/src/main/java/bisq/core/grpc/GrpcPaymentAccountsService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcPaymentAccountsService.java
@@ -15,8 +15,9 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.daemon.grpc;
+import bisq.core.api.CoreApi;
import bisq.core.payment.PaymentAccount;
import bisq.proto.grpc.CreatePaymentAccountReply;
@@ -32,7 +33,7 @@
import java.util.stream.Collectors;
-public class GrpcPaymentAccountsService extends PaymentAccountsGrpc.PaymentAccountsImplBase {
+class GrpcPaymentAccountsService extends PaymentAccountsGrpc.PaymentAccountsImplBase {
private final CoreApi coreApi;
diff --git a/core/src/main/java/bisq/core/grpc/GrpcServer.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
similarity index 98%
rename from core/src/main/java/bisq/core/grpc/GrpcServer.java
rename to daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
index 4b5d195a2e1..a1293dfa0ac 100644
--- a/core/src/main/java/bisq/core/grpc/GrpcServer.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcServer.java
@@ -15,8 +15,9 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.daemon.grpc;
+import bisq.core.api.CoreApi;
import bisq.core.trade.statistics.TradeStatistics2;
import bisq.common.config.Config;
diff --git a/core/src/main/java/bisq/core/grpc/GrpcWalletsService.java b/daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java
similarity index 98%
rename from core/src/main/java/bisq/core/grpc/GrpcWalletsService.java
rename to daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java
index f57cb69afb7..04dd3460234 100644
--- a/core/src/main/java/bisq/core/grpc/GrpcWalletsService.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/GrpcWalletsService.java
@@ -15,9 +15,10 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.daemon.grpc;
-import bisq.core.grpc.model.AddressBalanceInfo;
+import bisq.core.api.CoreApi;
+import bisq.core.api.model.AddressBalanceInfo;
import bisq.proto.grpc.GetAddressBalanceReply;
import bisq.proto.grpc.GetAddressBalanceRequest;
diff --git a/core/src/main/java/bisq/core/grpc/PasswordAuthInterceptor.java b/daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java
similarity index 98%
rename from core/src/main/java/bisq/core/grpc/PasswordAuthInterceptor.java
rename to daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java
index 291c09c5944..7798857dd2a 100644
--- a/core/src/main/java/bisq/core/grpc/PasswordAuthInterceptor.java
+++ b/daemon/src/main/java/bisq/daemon/grpc/PasswordAuthInterceptor.java
@@ -15,7 +15,7 @@
* along with Bisq. If not, see .
*/
-package bisq.core.grpc;
+package bisq.daemon.grpc;
import io.grpc.Metadata;
import io.grpc.ServerCall;
From 42ea59278ce0865dab588c349d491ce6c771b9aa Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Wed, 19 Aug 2020 20:29:16 -0300
Subject: [PATCH 89/90] Remove duplicate CompositeOptionSet class
Changed the access modifier of bisq.common.config.CompositeOptionSet
to make visible to bisq.apitest.config.ApiTestConfig, and removed the
bisq.apitest.config.CompositeOptionSet class.
---
.../bisq/apitest/config/ApiTestConfig.java | 2 +
.../apitest/config/CompositeOptionSet.java | 61 -------------------
.../common/config/CompositeOptionSet.java | 2 +-
3 files changed, 3 insertions(+), 62 deletions(-)
delete mode 100644 apitest/src/main/java/bisq/apitest/config/CompositeOptionSet.java
diff --git a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
index 027d046b265..bdde1bebf72 100644
--- a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
+++ b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
@@ -17,6 +17,8 @@
package bisq.apitest.config;
+import bisq.common.config.CompositeOptionSet;
+
import joptsimple.AbstractOptionSpec;
import joptsimple.ArgumentAcceptingOptionSpec;
import joptsimple.HelpFormatter;
diff --git a/apitest/src/main/java/bisq/apitest/config/CompositeOptionSet.java b/apitest/src/main/java/bisq/apitest/config/CompositeOptionSet.java
deleted file mode 100644
index 341b1e01017..00000000000
--- a/apitest/src/main/java/bisq/apitest/config/CompositeOptionSet.java
+++ /dev/null
@@ -1,61 +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.apitest.config;
-
-import joptsimple.OptionSet;
-import joptsimple.OptionSpec;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Composes multiple JOptSimple {@link OptionSet} instances such that calls to
- * {@link #valueOf(OptionSpec)} and co will search all instances in the order they were
- * added and return any value explicitly set, otherwise returning the default value for
- * the given option or null if no default has been set. The API found here loosely
- * emulates the {@link OptionSet} API without going through the unnecessary work of
- * actually extending it. In practice, this class is used to compose options provided at
- * the command line with those provided via config file, such that those provided at the
- * command line take precedence over those provided in the config file.
- */
-class CompositeOptionSet {
-
- private final List optionSets = new ArrayList<>();
-
- public void addOptionSet(OptionSet optionSet) {
- optionSets.add(optionSet);
- }
-
- public boolean has(OptionSpec> option) {
- for (OptionSet optionSet : optionSets)
- if (optionSet.has(option))
- return true;
-
- return false;
- }
-
- public V valueOf(OptionSpec option) {
- for (OptionSet optionSet : optionSets)
- if (optionSet.has(option))
- return optionSet.valueOf(option);
-
- // None of the provided option sets specified the given option so fall back to
- // the default value (if any) provided by the first specified OptionSet
- return optionSets.get(0).valueOf(option);
- }
-}
diff --git a/common/src/main/java/bisq/common/config/CompositeOptionSet.java b/common/src/main/java/bisq/common/config/CompositeOptionSet.java
index 2fb2fa0668d..f6a28ee3a6b 100644
--- a/common/src/main/java/bisq/common/config/CompositeOptionSet.java
+++ b/common/src/main/java/bisq/common/config/CompositeOptionSet.java
@@ -17,7 +17,7 @@
* the command line with those provided via config file, such that those provided at the
* command line take precedence over those provided in the config file.
*/
-class CompositeOptionSet {
+public class CompositeOptionSet {
private final List optionSets = new ArrayList<>();
From 0c3a1f561f8b293692c882ba64112204d3b58901 Mon Sep 17 00:00:00 2001
From: ghubstan <36207203+ghubstan@users.noreply.github.com>
Date: Mon, 24 Aug 2020 12:22:58 -0300
Subject: [PATCH 90/90] Add missing parameter to setUpScaffold method
This bugfix makes it possible to pass any combination of
ApiTestConfig options from a test case's @BeforeAll method
to the test harness.
---
apitest/src/test/java/bisq/apitest/ApiTestCase.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
index 286e7f8c206..b962a2f3aad 100644
--- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java
+++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java
@@ -73,9 +73,9 @@ public static void setUpScaffold(String supportingApps)
grpcStubs = new GrpcStubs(alicedaemon, config).init();
}
- public static void setUpScaffold()
+ public static void setUpScaffold(String[] params)
throws InterruptedException, ExecutionException, IOException {
- scaffold = new Scaffold(new String[]{}).setUp();
+ scaffold = new Scaffold(params).setUp();
config = scaffold.config;
grpcStubs = new GrpcStubs(alicedaemon, config).init();
}