From ac3c6e07f054e57190abd872c5ec6dd9c83e5895 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Tue, 25 Aug 2020 11:29:27 -0300 Subject: [PATCH 1/5] Fix setUpScaffold() signature Adds the missing String[] params to the method signature, so test cases can pass any needed combination of options to the scaffolding setup from a @BeforeAll method. --- 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(); } From 2c803ef8119ca4ba0ec98ad5de927b9c3cea0143 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Tue, 25 Aug 2020 11:42:09 -0300 Subject: [PATCH 2/5] Move :cli test.sh to :apitest mainnet-test.sh * The bats test script was moved to the apitest subproject and renamed. * Version tests were updated for release 1.3.7. * The duplicated "test getoffers buy eur check return status" was replaced by a new "test getoffers sell eur check return status" test. * The bats dependency was switched to bats-core because development has halted on https://github.com/sstephenson/bats/tree/master. The new bats repository is https://github.com/bats-core/bats-core/tree/master --- cli/test.sh => apitest/scripts/mainnet-test.sh | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) rename cli/test.sh => apitest/scripts/mainnet-test.sh (94%) diff --git a/cli/test.sh b/apitest/scripts/mainnet-test.sh similarity index 94% rename from cli/test.sh rename to apitest/scripts/mainnet-test.sh index 9878d93fd02..ae3afd73d2d 100755 --- a/cli/test.sh +++ b/apitest/scripts/mainnet-test.sh @@ -1,11 +1,11 @@ #!/usr/bin/env bats # -# Integration tests for bisq-cli running against a live bisq-daemon +# Smoke tests for bisq-cli running against a live bisq-daemon (on mainnet) # # Prerequisites: # -# - bats v0.4.0 must be installed (brew install bats on macOS) -# see https://github.com/sstephenson/bats/tree/v0.4.0 +# - bats-core 1.2.0+ must be installed (brew install bats-core on macOS) +# see https://github.com/bats-core/bats-core # # - Run `./bisq-daemon --apiPassword=xyz --appDataDir=$TESTDIR` where $TESTDIR # is empty or otherwise contains an unencrypted wallet with a 0 BTC balance @@ -48,14 +48,14 @@ run ./bisq-cli --password="xyz" getversion [ "$status" -eq 0 ] echo "actual output: $output" >&2 - [ "$output" = "1.3.5" ] + [ "$output" = "1.3.7" ] } @test "test getversion" { run ./bisq-cli --password=xyz getversion [ "$status" -eq 0 ] echo "actual output: $output" >&2 - [ "$output" = "1.3.5" ] + [ "$output" = "1.3.7" ] } @test "test setwalletpassword \"a b c\"" { @@ -190,8 +190,8 @@ [ "$output" = "Error: incorrect parameter count, expecting direction (buy|sell), currency code" ] } -@test "test getoffers buy eur check return status" { - run ./bisq-cli --password=xyz getoffers buy eur +@test "test getoffers sell eur check return status" { + run ./bisq-cli --password=xyz getoffers sell eur [ "$status" -eq 0 ] } From cb6166c65f4b03a2efcdeb29c31764906971616c Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Tue, 25 Aug 2020 12:01:29 -0300 Subject: [PATCH 3/5] Remove duplicated grpc stub creation logic The :apitest GrpcStubs class was removed and recreated in the :cli subproject, to be used by both :cli and :apitest. CliMain was changed to use the new GrpcStubs. --- .../test/java/bisq/apitest/ApiTestCase.java | 9 +- .../src/test/java/bisq/apitest/GrpcStubs.java | 109 ------------------ cli/src/main/java/bisq/cli/CliMain.java | 20 +--- cli/src/main/java/bisq/cli/GrpcStubs.java | 54 +++++++++ 4 files changed, 64 insertions(+), 128 deletions(-) delete mode 100644 apitest/src/test/java/bisq/apitest/GrpcStubs.java create mode 100644 cli/src/main/java/bisq/cli/GrpcStubs.java diff --git a/apitest/src/test/java/bisq/apitest/ApiTestCase.java b/apitest/src/test/java/bisq/apitest/ApiTestCase.java index b962a2f3aad..f9100bee96c 100644 --- a/apitest/src/test/java/bisq/apitest/ApiTestCase.java +++ b/apitest/src/test/java/bisq/apitest/ApiTestCase.java @@ -28,6 +28,7 @@ import bisq.apitest.config.ApiTestConfig; import bisq.apitest.method.BitcoinCliHelper; +import bisq.cli.GrpcStubs; /** * Base class for all test types: 'method', 'scenario' and 'e2e'. @@ -65,19 +66,19 @@ public class ApiTestCase { 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(); config = scaffold.config; bitcoinCli = new BitcoinCliHelper((config)); - grpcStubs = new GrpcStubs(alicedaemon, config).init(); + // For now, all grpc requests are sent to the alicedaemon, but this will need to + // be made configurable for new test cases that call arb or bob node daemons. + grpcStubs = new GrpcStubs("localhost", alicedaemon.apiPort, config.apiPassword); } public static void setUpScaffold(String[] params) throws InterruptedException, ExecutionException, IOException { scaffold = new Scaffold(params).setUp(); config = scaffold.config; - grpcStubs = new GrpcStubs(alicedaemon, config).init(); + grpcStubs = new GrpcStubs("localhost", alicedaemon.apiPort, config.apiPassword); } public static void tearDownScaffold() { diff --git a/apitest/src/test/java/bisq/apitest/GrpcStubs.java b/apitest/src/test/java/bisq/apitest/GrpcStubs.java deleted file mode 100644 index 6279c61489f..00000000000 --- a/apitest/src/test/java/bisq/apitest/GrpcStubs.java +++ /dev/null @@ -1,109 +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; - -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/cli/src/main/java/bisq/cli/CliMain.java b/cli/src/main/java/bisq/cli/CliMain.java index 37dbe3f52d6..46dfee10726 100644 --- a/cli/src/main/java/bisq/cli/CliMain.java +++ b/cli/src/main/java/bisq/cli/CliMain.java @@ -133,21 +133,11 @@ public static void run(String[] args) { if (password == null) throw new IllegalArgumentException("missing required 'password' option"); - var credentials = new PasswordCallCredentials(password); - - var channel = ManagedChannelBuilder.forAddress(host, port).usePlaintext().build(); - Runtime.getRuntime().addShutdownHook(new Thread(() -> { - try { - channel.shutdown().awaitTermination(1, TimeUnit.SECONDS); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - })); - - var versionService = GetVersionGrpc.newBlockingStub(channel).withCallCredentials(credentials); - var offersService = OffersGrpc.newBlockingStub(channel).withCallCredentials(credentials); - var paymentAccountsService = PaymentAccountsGrpc.newBlockingStub(channel).withCallCredentials(credentials); - var walletsService = WalletsGrpc.newBlockingStub(channel).withCallCredentials(credentials); + GrpcStubs grpcStubs = new GrpcStubs(host, port, password); + var versionService = grpcStubs.versionService; + var offersService = grpcStubs.offersService; + var paymentAccountsService = grpcStubs.paymentAccountsService; + var walletsService = grpcStubs.walletsService; try { switch (method) { diff --git a/cli/src/main/java/bisq/cli/GrpcStubs.java b/cli/src/main/java/bisq/cli/GrpcStubs.java new file mode 100644 index 00000000000..e12a6efa7c7 --- /dev/null +++ b/cli/src/main/java/bisq/cli/GrpcStubs.java @@ -0,0 +1,54 @@ +/* + * 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.cli; + +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 static java.util.concurrent.TimeUnit.SECONDS; + +public class GrpcStubs { + + public final GetVersionGrpc.GetVersionBlockingStub versionService; + public final OffersGrpc.OffersBlockingStub offersService; + public final PaymentAccountsGrpc.PaymentAccountsBlockingStub paymentAccountsService; + public final WalletsGrpc.WalletsBlockingStub walletsService; + + public GrpcStubs(String apiHost, int apiPort, String apiPassword) { + CallCredentials credentials = new PasswordCallCredentials(apiPassword); + + var channel = ManagedChannelBuilder.forAddress(apiHost, apiPort).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); + } +} From b9c1feba9a6e49f9501fcdb4e8eb82cb146ff3f1 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Tue, 25 Aug 2020 12:35:57 -0300 Subject: [PATCH 4/5] Remove redundant ApiTestConfig options This change removes three options: runArbNodeAsDesktop, runAliceNodeAsDesktop, and runBobNodeAsDesktop, which should have been deleted when the supportingApps option was added. The comma delimited list of apps passed with the supportingApps option now determines whether arbitration / bob / alice nodes are started as desktops or daemons. --- .../src/main/java/bisq/apitest/Scaffold.java | 26 +++++++++------- .../bisq/apitest/config/ApiTestConfig.java | 30 ------------------- 2 files changed, 15 insertions(+), 41 deletions(-) diff --git a/apitest/src/main/java/bisq/apitest/Scaffold.java b/apitest/src/main/java/bisq/apitest/Scaffold.java index bf0e4c771dd..d195b787015 100644 --- a/apitest/src/main/java/bisq/apitest/Scaffold.java +++ b/apitest/src/main/java/bisq/apitest/Scaffold.java @@ -311,17 +311,25 @@ private void startBackgroundProcesses(ExecutorService executor, bitcoinDaemon.verifyBitcoindRunning(); } + // Start Bisq apps defined by the supportingApps option, in the in proper order. + if (config.hasSupportingApp(seednode.name())) startBisqApp(seednode, executor, countdownLatch); - if (config.hasSupportingApp(arbdaemon.name(), arbdesktop.name())) - startBisqApp(config.runArbNodeAsDesktop ? arbdesktop : arbdaemon, executor, countdownLatch); + if (config.hasSupportingApp(arbdaemon.name())) + startBisqApp(arbdaemon, executor, countdownLatch); + else if (config.hasSupportingApp(arbdesktop.name())) + startBisqApp(arbdesktop, executor, countdownLatch); - if (config.hasSupportingApp(alicedaemon.name(), alicedesktop.name())) - startBisqApp(config.runAliceNodeAsDesktop ? alicedesktop : alicedaemon, executor, countdownLatch); + if (config.hasSupportingApp(alicedaemon.name())) + startBisqApp(alicedaemon, executor, countdownLatch); + else if (config.hasSupportingApp(alicedesktop.name())) + startBisqApp(alicedesktop, executor, countdownLatch); - if (config.hasSupportingApp(bobdaemon.name(), bobdesktop.name())) - startBisqApp(config.runBobNodeAsDesktop ? bobdesktop : bobdaemon, executor, countdownLatch); + if (config.hasSupportingApp(bobdaemon.name())) + startBisqApp(bobdaemon, executor, countdownLatch); + else if (config.hasSupportingApp(bobdesktop.name())) + startBisqApp(bobdesktop, executor, countdownLatch); } private void startBisqApp(BisqAppConfig bisqAppConfig, @@ -329,28 +337,24 @@ private void startBisqApp(BisqAppConfig bisqAppConfig, CountDownLatch countdownLatch) throws IOException, InterruptedException { - BisqApp bisqApp; + BisqApp bisqApp = createBisqApp(bisqAppConfig); switch (bisqAppConfig) { case seednode: - bisqApp = createBisqApp(seednode); seedNodeTask = new SetupTask(bisqApp, countdownLatch); seedNodeTaskFuture = executor.submit(seedNodeTask); break; case arbdaemon: case arbdesktop: - bisqApp = createBisqApp(config.runArbNodeAsDesktop ? arbdesktop : arbdaemon); arbNodeTask = new SetupTask(bisqApp, countdownLatch); arbNodeTaskFuture = executor.submit(arbNodeTask); break; case alicedaemon: case alicedesktop: - bisqApp = createBisqApp(config.runAliceNodeAsDesktop ? alicedesktop : alicedaemon); aliceNodeTask = new SetupTask(bisqApp, countdownLatch); aliceNodeTaskFuture = executor.submit(aliceNodeTask); break; case bobdaemon: case bobdesktop: - bisqApp = createBisqApp(config.runBobNodeAsDesktop ? bobdesktop : bobdaemon); bobNodeTask = new SetupTask(bisqApp, countdownLatch); bobNodeTaskFuture = executor.submit(bobNodeTask); break; diff --git a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java index 6a9e9a6448b..d3c491c7421 100644 --- a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java +++ b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java @@ -65,9 +65,6 @@ public class ApiTestConfig { static final String ROOT_APP_DATA_DIR = "rootAppDataDir"; static final String API_PASSWORD = "apiPassword"; static final String RUN_SUBPROJECT_JARS = "runSubprojectJars"; - static final String RUN_ARB_NODE_AS_DESKTOP = "runArbNodeAsDesktop"; - static final String RUN_ALICE_NODE_AS_DESKTOP = "runAliceNodeAsDesktop"; - static final String RUN_BOB_NODE_AS_DESKTOP = "runBobNodeAsDesktop"; static final String BISQ_APP_INIT_TIME = "bisqAppInitTime"; static final String SKIP_TESTS = "skipTests"; static final String SHUTDOWN_AFTER_TESTS = "shutdownAfterTests"; @@ -98,9 +95,6 @@ public class ApiTestConfig { // Daemon instances can use same gRPC password, but each needs a different apiPort. public final String apiPassword; public final boolean runSubprojectJars; - public final boolean runArbNodeAsDesktop; - public final boolean runAliceNodeAsDesktop; - public final boolean runBobNodeAsDesktop; public final long bisqAppInitTime; public final boolean skipTests; public final boolean shutdownAfterTests; @@ -202,27 +196,6 @@ public ApiTestConfig(String... args) { .ofType(Boolean.class) .defaultsTo(false); - ArgumentAcceptingOptionSpec runArbNodeAsDesktopOpt = - parser.accepts(RUN_ARB_NODE_AS_DESKTOP, - "Run Arbitration node as desktop") - .withRequiredArg() - .ofType(Boolean.class) - .defaultsTo(false); // TODO how do I register mediator? - - ArgumentAcceptingOptionSpec runAliceNodeAsDesktopOpt = - parser.accepts(RUN_ALICE_NODE_AS_DESKTOP, - "Run Alice node as desktop") - .withRequiredArg() - .ofType(Boolean.class) - .defaultsTo(false); - - ArgumentAcceptingOptionSpec runBobNodeAsDesktopOpt = - parser.accepts(RUN_BOB_NODE_AS_DESKTOP, - "Run Bob node as desktop") - .withRequiredArg() - .ofType(Boolean.class) - .defaultsTo(false); - ArgumentAcceptingOptionSpec bisqAppInitTimeOpt = parser.accepts(BISQ_APP_INIT_TIME, "Amount of time (ms) to wait on a Bisq instance's initialization") @@ -302,9 +275,6 @@ public ApiTestConfig(String... args) { this.bitcoinRpcPassword = options.valueOf(bitcoinRpcPasswordOpt); this.apiPassword = options.valueOf(apiPasswordOpt); this.runSubprojectJars = options.valueOf(runSubprojectJarsOpt); - this.runArbNodeAsDesktop = options.valueOf(runArbNodeAsDesktopOpt); - this.runAliceNodeAsDesktop = options.valueOf(runAliceNodeAsDesktopOpt); - this.runBobNodeAsDesktop = options.valueOf(runBobNodeAsDesktopOpt); this.bisqAppInitTime = options.valueOf(bisqAppInitTimeOpt); this.skipTests = options.valueOf(skipTestsOpt); this.shutdownAfterTests = options.valueOf(shutdownAfterTestsOpt); From 4d12b8f3d3dfb985eaf1abc53f3850cb75c53719 Mon Sep 17 00:00:00 2001 From: ghubstan <36207203+ghubstan@users.noreply.github.com> Date: Tue, 25 Aug 2020 12:59:55 -0300 Subject: [PATCH 5/5] Allow remote debugging of background Bisq apps A unique hard coded debug listening port is assigned to the different Bisq app types in the BisqAppConfig enum, and background Bisq apps will be started with remote debug options if the scaffold-setup method is passed an --enableBisqDebugging=true option. * Added enableBisqDebugging (default=false) option to ApiTestConfig. * Added remoteDebugPort field to BisqAppConfig enum. * Added debugOpts field to BisqApp (using BisqAppConfig#remoteDebugPort). * Appends debugOpts to exported JAVA_OPTS environment variable if present. * Removed messy quotes from BisqAppConfig enum javaOpts values. * Removed redundant return statement from BisqApp#shutdown(). --- .../bisq/apitest/config/ApiTestConfig.java | 9 ++++ .../bisq/apitest/config/BisqAppConfig.java | 42 ++++++++++++------- .../main/java/bisq/apitest/linux/BisqApp.java | 7 +++- 3 files changed, 40 insertions(+), 18 deletions(-) diff --git a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java index d3c491c7421..5197a35634c 100644 --- a/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java +++ b/apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java @@ -69,6 +69,7 @@ public class ApiTestConfig { static final String SKIP_TESTS = "skipTests"; static final String SHUTDOWN_AFTER_TESTS = "shutdownAfterTests"; static final String SUPPORTING_APPS = "supportingApps"; + static final String ENABLE_BISQ_DEBUGGING = "enableBisqDebugging"; // Default values for certain options static final String DEFAULT_CONFIG_FILE_NAME = "apitest.properties"; @@ -99,6 +100,7 @@ public class ApiTestConfig { public final boolean skipTests; public final boolean shutdownAfterTests; public final List supportingApps; + public final boolean enableBisqDebugging; // Immutable system configurations set in the constructor. public final String bitcoinDatadir; @@ -224,6 +226,12 @@ public ApiTestConfig(String... args) { .ofType(String.class) .defaultsTo("bitcoind,seednode,arbdaemon,alicedaemon,bobdaemon"); + ArgumentAcceptingOptionSpec enableBisqDebuggingOpt = + parser.accepts(ENABLE_BISQ_DEBUGGING, + "Start Bisq apps with remote debug options") + .withRequiredArg() + .ofType(Boolean.class) + .defaultsTo(false); try { CompositeOptionSet options = new CompositeOptionSet(); @@ -279,6 +287,7 @@ public ApiTestConfig(String... args) { this.skipTests = options.valueOf(skipTestsOpt); this.shutdownAfterTests = options.valueOf(shutdownAfterTestsOpt); this.supportingApps = asList(options.valueOf(supportingAppsOpt).split(",")); + this.enableBisqDebugging = options.valueOf(enableBisqDebuggingOpt); // Assign values to special-case static fields. BASH_PATH_VALUE = bashPath; diff --git a/apitest/src/main/java/bisq/apitest/config/BisqAppConfig.java b/apitest/src/main/java/bisq/apitest/config/BisqAppConfig.java index 662956462ed..08a7531ca30 100644 --- a/apitest/src/main/java/bisq/apitest/config/BisqAppConfig.java +++ b/apitest/src/main/java/bisq/apitest/config/BisqAppConfig.java @@ -30,58 +30,64 @@ @see dev-setup.md @see dao-setup.md */ -@SuppressWarnings("unused") public enum BisqAppConfig { seednode("bisq-BTC_REGTEST_Seed_2002", "bisq-seednode", - "\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", SeedNodeMain.class.getName(), 2002, 5120, - -1), + -1, + 49996), arbdaemon("bisq-BTC_REGTEST_Arb_dao", "bisq-daemon", - "\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", BisqDaemonMain.class.getName(), 4444, 5121, - 9997), + 9997, + 49997), arbdesktop("bisq-BTC_REGTEST_Arb_dao", "bisq-desktop", - "\"-XX:MaxRAM=3g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=3g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", BisqAppMain.class.getName(), 4444, 5121, - -1), + -1, + 49997), alicedaemon("bisq-BTC_REGTEST_Alice_dao", "bisq-daemon", - "\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", BisqDaemonMain.class.getName(), 7777, 5122, - 9998), + 9998, + 49998), alicedesktop("bisq-BTC_REGTEST_Alice_dao", "bisq-desktop", - "\"-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", BisqAppMain.class.getName(), 7777, 5122, - -1), + -1, + 49998), bobdaemon("bisq-BTC_REGTEST_Bob_dao", "bisq-daemon", - "\"-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=2g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", BisqDaemonMain.class.getName(), 8888, 5123, - 9999), + 9999, + 49999), bobdesktop("bisq-BTC_REGTEST_Bob_dao", "bisq-desktop", - "\"-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml\"", + "-XX:MaxRAM=4g -Dlogback.configurationFile=apitest/build/resources/main/logback.xml", BisqAppMain.class.getName(), 8888, 5123, - -1); + -1, + 49999); public final String appName; public final String startupScript; @@ -91,6 +97,7 @@ public enum BisqAppConfig { public final int rpcBlockNotificationPort; // Daemons can use a global gRPC password, but each needs a unique apiPort. public final int apiPort; + public final int remoteDebugPort; BisqAppConfig(String appName, String startupScript, @@ -98,7 +105,8 @@ public enum BisqAppConfig { String mainClassName, int nodePort, int rpcBlockNotificationPort, - int apiPort) { + int apiPort, + int remoteDebugPort) { this.appName = appName; this.startupScript = startupScript; this.javaOpts = javaOpts; @@ -106,6 +114,7 @@ public enum BisqAppConfig { this.nodePort = nodePort; this.rpcBlockNotificationPort = rpcBlockNotificationPort; this.apiPort = apiPort; + this.remoteDebugPort = remoteDebugPort; } @Override @@ -118,6 +127,7 @@ public String toString() { ", nodePort=" + nodePort + "\n" + ", rpcBlockNotificationPort=" + rpcBlockNotificationPort + "\n" + ", apiPort=" + apiPort + "\n" + + ", remoteDebugPort=" + remoteDebugPort + "\n" + '}'; } } diff --git a/apitest/src/main/java/bisq/apitest/linux/BisqApp.java b/apitest/src/main/java/bisq/apitest/linux/BisqApp.java index f449d0b98f1..7c66746f3df 100644 --- a/apitest/src/main/java/bisq/apitest/linux/BisqApp.java +++ b/apitest/src/main/java/bisq/apitest/linux/BisqApp.java @@ -53,6 +53,7 @@ public class BisqApp extends AbstractLinuxProcess implements LinuxProcess { private final boolean useLocalhostForP2P; public final boolean useDevPrivilegeKeys; private final String findBisqPidScript; + private final String debugOpts; public BisqApp(BisqAppConfig bisqAppConfig, ApiTestConfig config) { super(bisqAppConfig.appName, config); @@ -67,6 +68,9 @@ public BisqApp(BisqAppConfig bisqAppConfig, ApiTestConfig config) { this.useDevPrivilegeKeys = true; this.findBisqPidScript = (config.isRunningTest ? "." : "./apitest") + "/scripts/get-bisq-pid.sh"; + this.debugOpts = config.enableBisqDebugging + ? " -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:" + bisqAppConfig.remoteDebugPort + : ""; } @Override @@ -112,7 +116,6 @@ public void shutdown() { if (isAlive(pid)) { this.shutdownExceptions.add(new IllegalStateException(format("%s shutdown did not work", bisqAppConfig.appName))); - return; } } catch (Exception e) { @@ -209,7 +212,7 @@ private long findBisqAppPid() throws IOException, InterruptedException { } private String getJavaOptsSpec() { - return "export JAVA_OPTS=" + bisqAppConfig.javaOpts + "; "; + return "export JAVA_OPTS=\"" + bisqAppConfig.javaOpts + debugOpts + "\"; "; } private List getOptsList() {