Skip to content

Commit

Permalink
Merge pull request #4525 from ghubstan/2-refactor-apitest-grpcstubs
Browse files Browse the repository at this point in the history
Refactor apitest for api calls to any daemon type
  • Loading branch information
sqrrm authored Sep 16, 2020
2 parents b812a26 + 3f0394f commit 6cf10c4
Show file tree
Hide file tree
Showing 9 changed files with 185 additions and 51 deletions.
4 changes: 2 additions & 2 deletions apitest/scripts/mainnet-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@
run ./bisq-cli --password="xyz" getversion
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "1.3.7" ]
[ "$output" = "1.3.8" ]
}

@test "test getversion" {
run ./bisq-cli --password=xyz getversion
[ "$status" -eq 0 ]
echo "actual output: $output" >&2
[ "$output" = "1.3.7" ]
[ "$output" = "1.3.8" ]
}

@test "test setwalletpassword \"a b c\"" {
Expand Down
4 changes: 3 additions & 1 deletion apitest/src/main/java/bisq/apitest/config/ApiTestConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
import joptsimple.OptionSet;
import joptsimple.OptionSpec;

import java.net.InetAddress;

import java.nio.file.Paths;

import java.io.File;
Expand Down Expand Up @@ -169,7 +171,7 @@ public ApiTestConfig(String... args) {
ArgumentAcceptingOptionSpec<String> bitcoinRegtestHostOpt =
parser.accepts(BITCOIN_REGTEST_HOST, "Bitcoin Core regtest host")
.withRequiredArg()
.ofType(String.class).defaultsTo("localhost");
.ofType(String.class).defaultsTo(InetAddress.getLoopbackAddress().getHostAddress());

ArgumentAcceptingOptionSpec<Integer> bitcoinRpcPortOpt =
parser.accepts(BITCOIN_RPC_PORT, "Bitcoin Core rpc port (non-default)")
Expand Down
27 changes: 19 additions & 8 deletions apitest/src/test/java/bisq/apitest/ApiTestCase.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,20 @@

package bisq.apitest;

import java.net.InetAddress;

import java.io.IOException;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;

import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import static java.util.concurrent.TimeUnit.MILLISECONDS;



import bisq.apitest.config.ApiTestConfig;
import bisq.apitest.config.BisqAppConfig;
import bisq.apitest.method.BitcoinCliHelper;
import bisq.cli.GrpcStubs;

Expand Down Expand Up @@ -57,34 +61,41 @@
*/
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;

// gRPC service stubs are used by method & scenario tests, but not e2e tests.
private static final Map<BisqAppConfig, GrpcStubs> grpcStubsCache = new HashMap<>();

public static void setUpScaffold(String supportingApps)
throws InterruptedException, ExecutionException, IOException {
scaffold = new Scaffold(supportingApps).setUp();
config = scaffold.config;
bitcoinCli = new BitcoinCliHelper((config));
// 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("localhost", alicedaemon.apiPort, config.apiPassword);
}

public static void tearDownScaffold() {
scaffold.tearDown();
}

protected static GrpcStubs grpcStubs(BisqAppConfig bisqAppConfig) {
if (grpcStubsCache.containsKey(bisqAppConfig)) {
return grpcStubsCache.get(bisqAppConfig);
} else {
GrpcStubs stubs = new GrpcStubs(InetAddress.getLoopbackAddress().getHostAddress(),
bisqAppConfig.apiPort, config.apiPassword);
grpcStubsCache.put(bisqAppConfig, stubs);
return stubs;
}
}

protected void sleep(long ms) {
try {
MILLISECONDS.sleep(ms);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.junit.jupiter.api.Test;
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.fail;
Expand Down Expand Up @@ -57,7 +58,8 @@ public static void setUp() {
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();
var balance = grpcStubs(alicedaemon).walletsService
.getBalance(GetBalanceRequest.newBuilder().build()).getBalance();
assertEquals(1000000000, balance);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,8 @@ public static void setUp() {
@Test
@Order(1)
public void testGetVersion() {
var version = grpcStubs.versionService.getVersion(GetVersionRequest.newBuilder().build()).getVersion();
var version = grpcStubs(alicedaemon).versionService
.getVersion(GetVersionRequest.newBuilder().build()).getVersion();
assertEquals(VERSION, version);
}

Expand Down
27 changes: 19 additions & 8 deletions apitest/src/test/java/bisq/apitest/method/MethodTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,17 @@
import bisq.proto.grpc.GetBalanceRequest;
import bisq.proto.grpc.GetFundingAddressesRequest;
import bisq.proto.grpc.LockWalletRequest;
import bisq.proto.grpc.RegisterDisputeAgentRequest;
import bisq.proto.grpc.RemoveWalletPasswordRequest;
import bisq.proto.grpc.SetWalletPasswordRequest;
import bisq.proto.grpc.UnlockWalletRequest;

import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;



import bisq.apitest.ApiTestCase;
import bisq.apitest.config.BisqAppConfig;

public class MethodTest extends ApiTestCase {

Expand Down Expand Up @@ -60,24 +64,31 @@ protected final GetFundingAddressesRequest createGetFundingAddressesRequest() {
return GetFundingAddressesRequest.newBuilder().build();
}

protected final RegisterDisputeAgentRequest createRegisterDisputeAgentRequest(String disputeAgentType) {
return RegisterDisputeAgentRequest.newBuilder()
.setDisputeAgentType(disputeAgentType)
.setRegistrationKey(DEV_PRIVILEGE_PRIV_KEY).build();
}

// Convenience methods for calling frequently used & thoroughly tested gRPC services.

protected final long getBalance() {
return grpcStubs.walletsService.getBalance(createBalanceRequest()).getBalance();
protected final long getBalance(BisqAppConfig bisqAppConfig) {
return grpcStubs(bisqAppConfig).walletsService.getBalance(createBalanceRequest()).getBalance();
}

protected final void unlockWallet(String password, long timeout) {
protected final void unlockWallet(BisqAppConfig bisqAppConfig, String password, long timeout) {
//noinspection ResultOfMethodCallIgnored
grpcStubs.walletsService.unlockWallet(createUnlockWalletRequest(password, timeout));
grpcStubs(bisqAppConfig).walletsService.unlockWallet(createUnlockWalletRequest(password, timeout));
}

protected final void lockWallet() {
protected final void lockWallet(BisqAppConfig bisqAppConfig) {
//noinspection ResultOfMethodCallIgnored
grpcStubs.walletsService.lockWallet(createLockWalletRequest());
grpcStubs(bisqAppConfig).walletsService.lockWallet(createLockWalletRequest());
}

protected final String getUnusedBtcAddress() {
return grpcStubs.walletsService.getFundingAddresses(createGetFundingAddressesRequest())
protected final String getUnusedBtcAddress(BisqAppConfig bisqAppConfig) {
//noinspection OptionalGetWithoutIsPresent
return grpcStubs(bisqAppConfig).walletsService.getFundingAddresses(createGetFundingAddressesRequest())
.getAddressBalanceInfoList()
.stream()
.filter(a -> a.getBalance() == 0 && a.getNumConfirmations() == 0)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* 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 <http://www.gnu.org/licenses/>.
*/

package bisq.apitest.method;

import bisq.proto.grpc.RegisterDisputeAgentRequest;

import io.grpc.StatusRuntimeException;

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.arbdaemon;
import static bisq.common.app.DevEnv.DEV_PRIVILEGE_PRIV_KEY;
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")
@Slf4j
@TestMethodOrder(OrderAnnotation.class)
public class RegisterDisputeAgentsTest extends MethodTest {

@BeforeAll
public static void setUp() {
try {
setUpScaffold("bitcoind,seednode,arbdaemon");
} catch (Exception ex) {
fail(ex);
}
}

@Test
@Order(1)
public void testRegisterArbitratorShouldThrowException() {
var req =
createRegisterDisputeAgentRequest("arbitrator");
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: arbitrators must be registered in a Bisq UI",
exception.getMessage());
}

@Test
@Order(2)
public void testInvalidDisputeAgentTypeArgShouldThrowException() {
var req =
createRegisterDisputeAgentRequest("badagent");
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: unknown dispute agent type badagent",
exception.getMessage());
}

@Test
@Order(3)
public void testInvalidRegistrationKeyArgShouldThrowException() {
var req = RegisterDisputeAgentRequest.newBuilder()
.setDisputeAgentType("refundagent")
.setRegistrationKey("invalid" + DEV_PRIVILEGE_PRIV_KEY).build();
Throwable exception = assertThrows(StatusRuntimeException.class, () ->
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req));
assertEquals("INVALID_ARGUMENT: invalid registration key",
exception.getMessage());
}

@Test
@Order(4)
public void testRegisterMediator() {
var req =
createRegisterDisputeAgentRequest("mediator");
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}

@Test
@Order(5)
public void testRegisterRefundAgent() {
var req =
createRegisterDisputeAgentRequest("refundagent");
grpcStubs(arbdaemon).disputeAgentsService.registerDisputeAgent(req);
}

@AfterAll
public static void tearDown() {
tearDownScaffold();
}
}
Loading

0 comments on commit 6cf10c4

Please sign in to comment.