Add first JUnit 'method' tests

These @Order-ed test cases should be run with OrderedRunner.

They are called 'method' tests because they are the closest
thing to an API 'unit' test.  Method tests are not end to end
tests;  they have access to gRPC service stubs and do asserts
on Java values.  We can write 'method' tests for the new
gRPC methods we need to implement (test driven development).

Some notes about the three API test categories...

The plan is to categorize some of the narrower functional tests
as 'scenario' tests.  Like 'method' tests, 'scenario' tests will
have  access to gRPC service stubs and do asserts on Java values,
but they will cover use cases requiring several gRPC and bitcoin-cli
method calls.  One example is funding a wallet:  using bitcoin-cli
and bisq-cli to generate new addresses, send BTC from bitcoin-core
to a Bisq wallet, generate a bitcoin block, and check the Bisq
wallet's balance.  Another example is wallet unlocking/locking
scenarios that are a bit more complex than 'unit' or 'method' tests.

The third category of tests will be end to end, and live in an
'e2e' package.  They will cover more complex use cases and
do asserts on the Bisq CLI's console output (stdout/stderr),
not return values from gRPC service stubs.

There may sometimes be a fine line between what is a 'scenario'
test and an 'e2e' test.  But what starts out as a 'scenario' test
during test driven development can migrate to an 'e2e' test after
thorough testing in the quicker 'scenario' dev/test cycle.
This commit is contained in:
ghubstan 2020-07-13 20:34:25 -03:00
parent 080952b1d7
commit 4f08ec3edc
No known key found for this signature in database
GPG key ID: E35592D6800A861E
4 changed files with 257 additions and 0 deletions

View file

@ -0,0 +1,74 @@
/*
* 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.GetBalanceRequest;
import java.io.IOException;
import lombok.extern.slf4j.Slf4j;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import static java.lang.String.format;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import bisq.apitest.OrderedRunner;
import bisq.apitest.annotation.Order;
import bisq.apitest.linux.BitcoinCli;
@Slf4j
@RunWith(OrderedRunner.class)
public class GetBalanceTest extends MethodTest {
@BeforeClass
public static void setUp() {
try {
setUpScaffold();
String newAddress = new BitcoinCli(config, "getnewaddress").run().getOutput();
String generateToAddressCmd = format("generatetoaddress %d \"%s\"", 1, newAddress);
BitcoinCli generateToAddress = new BitcoinCli(config, generateToAddressCmd).run();
log.info("{}\n{}", generateToAddress.getCommandWithOptions(), generateToAddress.getOutputValueAsStringArray());
MILLISECONDS.sleep(1500); // give bisq app time to parse block
} catch (IOException | InterruptedException ex) {
fail(ex.getMessage());
}
}
@Test
@Order(1)
public void testGetBalance() {
var balance = grpcStubs.walletsService.getBalance(GetBalanceRequest.newBuilder().build()).getBalance();
assertEquals(1000000000, balance);
}
@AfterClass
public static void tearDown() {
tearDownScaffold();
}
}

View file

@ -0,0 +1,57 @@
/*
* 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.GetVersionRequest;
import lombok.extern.slf4j.Slf4j;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import static bisq.common.app.Version.VERSION;
import static org.junit.Assert.assertEquals;
import bisq.apitest.OrderedRunner;
import bisq.apitest.annotation.Order;
@Slf4j
@RunWith(OrderedRunner.class)
public class GetVersionTest extends MethodTest {
@BeforeClass
public static void setUp() {
setUpScaffold();
}
@Test
@Order(1)
public void testGetVersion() {
var version = grpcStubs.versionService.getVersion(GetVersionRequest.newBuilder().build()).getVersion();
assertEquals(VERSION, version);
}
@AfterClass
public static void tearDown() {
tearDownScaffold();
}
}

View file

@ -0,0 +1,68 @@
/*
* 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.GetBalanceRequest;
import bisq.proto.grpc.RemoveWalletPasswordRequest;
import bisq.proto.grpc.SetWalletPasswordRequest;
import static bisq.apitest.config.BisqAppConfig.alicedaemon;
import bisq.apitest.ApiTestCase;
import bisq.apitest.GrpcStubs;
import bisq.apitest.Scaffold;
import bisq.apitest.config.ApiTestConfig;
public class MethodTest extends ApiTestCase {
static Scaffold scaffold;
static ApiTestConfig config;
static GrpcStubs grpcStubs;
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();
}
// 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 RemoveWalletPasswordRequest createRemoveWalletPasswordRequest(String password) {
return RemoveWalletPasswordRequest.newBuilder().setPassword("password").build();
}
// Convenience methods for calling frequently used & thoroughly tested gRPC services.
protected final long getBalance() {
return grpcStubs.walletsService.getBalance(createBalanceRequest()).getBalance();
}
}

View file

@ -0,0 +1,58 @@
package bisq.apitest.method;
import io.grpc.StatusRuntimeException;
import lombok.extern.slf4j.Slf4j;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;
import bisq.apitest.OrderedRunner;
import bisq.apitest.annotation.Order;
@Slf4j
@RunWith(OrderedRunner.class)
public class WalletProtectionTest extends MethodTest {
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
@BeforeClass
public static void setUp() {
setUpScaffold();
}
@Test
@Order(1)
public void testSetWalletPassword() {
var setPasswordRequest = createSetWalletPasswordRequest("password");
grpcStubs.walletsService.setWalletPassword(setPasswordRequest);
}
@Test
@Order(2)
public void testGetBalanceOnEncryptedWalletShouldThrowException() {
exceptionRule.expect(StatusRuntimeException.class);
exceptionRule.expectMessage("UNKNOWN: wallet is locked");
getBalance();
}
@Test
@Order(3)
public void testRemoveWalletPassword() {
var removePasswordRequest = createRemoveWalletPasswordRequest("password");
grpcStubs.walletsService.removeWalletPassword(removePasswordRequest);
getBalance(); // should not throw exception
}
@AfterClass
public static void tearDown() {
tearDownScaffold();
}
}