Merge #9974: Add basic Qt wallet test

9576b01 Enable xvfb in travis to allow running test_bitcoin-qt (Russell Yanofsky)
9e6817e Add new test_bitcoin-qt static library dependencies (Russell Yanofsky)
2754ef1 Add simple qt wallet test sending a transaction (Russell Yanofsky)
b61b34c Add braces to if statements in Qt test_main (Russell Yanofsky)
cc9503c Make qt test compatible with TestChain100Setup framework (Russell Yanofsky)
91e3035 Make test_bitcoin.cpp compatible with Qt Test framework (Russell Yanofsky)

Tree-SHA512: da491181848b8c39138e997ae5ff2df0b16eef2d9cdd0a965229b1a28d4fa862d5f1ef314a1736e5050e88858f329124d15c689659fc6e50fefde769ba24e523

remove line, testing

bitcoin -> dash, testing

bitcoin -> dash, testing

resolve name conflict, testing

bitcoin -> dash

re-add test fixture line

code review, fix tests

Signed-off-by: Pasta <Pasta@dash.org>

move ExceptionInitializer into test_dash_main.cpp

remove witness from nulldummy.py

Signed-off-by: Pasta <Pasta@dash.org>

change error text to match expected

Signed-off-by: Pasta <Pasta@dash.org>
This commit is contained in:
Jonas Schnelli 2017-03-17 14:30:48 +01:00 committed by Pasta
parent ae9ca8459d
commit aee4472ace
No known key found for this signature in database
GPG Key ID: 0B8EB7A31A44D9C6
12 changed files with 247 additions and 76 deletions

View File

@ -66,7 +66,7 @@ elif [ "$BUILD_TARGET" = "linux64" ]; then
export RUN_TESTS=true
elif [ "$BUILD_TARGET" = "linux64_nowallet" ]; then
export HOST=x86_64-unknown-linux-gnu
export PACKAGES="python3"
export PACKAGES="python3 xvfb"
export DEP_OPTS="NO_WALLET=1"
export BITCOIN_CONFIG="--enable-glibc-back-compat --enable-reduce-exports"
elif [ "$BUILD_TARGET" = "linux64_release" ]; then

View File

@ -19,6 +19,12 @@ export WINEDEBUG=fixme-all
export BOOST_TEST_LOG_LEVEL=test_suite
cd build-ci/dashcore-$BUILD_TARGET
if [ "$RUN_TESTS" = "true" -a "${DEP_OPTS#*NO_QT=1}" = "$DEP_OPTS" ]; then
export DISPLAY=:99.0;
/sbin/start-stop-daemon --start --pidfile /tmp/custom_xvfb_99.pid --make-pidfile --background --exec /usr/bin/Xvfb -- :99 -ac;
fi
if [ "$DIRECT_WINE_EXEC_TESTS" = "true" ]; then
# Inside Docker, binfmt isn't working so we can't trust in make invoking windows binaries correctly
wine ./src/test/test_dash.exe

View File

@ -100,7 +100,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
return tx
def block_submit(self, node, txs, witness = False, accept = False):
def block_submit(self, node, txs, accept = False):
dip4_activated = self.lastblockheight + 1 >= 432
block = create_block(self.tip, create_coinbase(self.lastblockheight + 1, dip4_activated=dip4_activated), self.lastblocktime + 1)
block.nVersion = 4

View File

@ -110,7 +110,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"]
# This will raise an exception due to min relay fee not being met
assert_raises_jsonrpc(-26, "66: min relay fee not met", self.nodes[0].sendrawtransaction, tx2_hex)
assert_raises_jsonrpc(-26, "66: insufficient priority", self.nodes[0].sendrawtransaction, tx2_hex)
assert(tx2_id not in self.nodes[0].getrawmempool())
# This is a less than 1000-byte transaction, so just set the fee

View File

@ -13,7 +13,9 @@ TEST_QT_MOC_CPP = \
qt/test/moc_uritests.cpp
if ENABLE_WALLET
TEST_QT_MOC_CPP += qt/test/moc_paymentservertests.cpp
TEST_QT_MOC_CPP += \
qt/test/moc_paymentservertests.cpp \
qt/test/moc_wallettests.cpp
endif
TEST_QT_H = \
@ -22,7 +24,16 @@ TEST_QT_H = \
qt/test/uritests.h \
qt/test/paymentrequestdata.h \
qt/test/paymentservertests.h \
qt/test/trafficgraphdatatests.h
qt/test/trafficgraphdatatests.h \
qt/test/wallettests.h
TEST_BITCOIN_CPP = \
test/test_dash.cpp \
test/testutil.cpp
TEST_BITCOIN_H = \
test/test_dash.h \
test/testutil.h
qt_test_test_dash_qt_CPPFLAGS = $(AM_CPPFLAGS) $(BITCOIN_INCLUDES) $(BITCOIN_QT_INCLUDES) \
$(QT_INCLUDES) $(QT_TEST_INCLUDES) $(PROTOBUF_CFLAGS)
@ -33,10 +44,13 @@ qt_test_test_dash_qt_SOURCES = \
qt/test/test_main.cpp \
qt/test/uritests.cpp \
qt/test/trafficgraphdatatests.cpp \
$(TEST_QT_H)
$(TEST_QT_H) \
$(TEST_BITCOIN_CPP) \
$(TEST_BITCOIN_H)
if ENABLE_WALLET
qt_test_test_dash_qt_SOURCES += \
qt/test/paymentservertests.cpp
qt/test/paymentservertests.cpp \
qt/test/wallettests.cpp
endif
nodist_qt_test_test_dash_qt_SOURCES = $(TEST_QT_MOC_CPP)

View File

@ -129,6 +129,7 @@ BITCOIN_TESTS =\
test/subsidy_tests.cpp \
test/test_dash.cpp \
test/test_dash.h \
test/test_dash_main.cpp \
test/test_random.h \
test/testutil.cpp \
test/testutil.h \

View File

@ -155,11 +155,15 @@ void RPCNestedTests::rpcNestedTests()
QVERIFY_EXCEPTION_THROWN(RPCConsole::RPCExecuteCommandLine(result, "rpcNestedTest(abc,,)"), std::runtime_error); //don't tollerate empty arguments when using ,
#endif
UnloadBlockIndex();
delete pcoinsTip;
pcoinsTip = nullptr;
llmq::DestroyLLMQSystem();
delete deterministicMNManager;
delete pcoinsdbview;
pcoinsdbview = nullptr;
delete pblocktree;
pblocktree = nullptr;
delete evoDb;
boost::filesystem::remove_all(boost::filesystem::path(path));

View File

@ -8,7 +8,6 @@
#endif
#include "chainparams.h"
#include "key.h"
#include "rpcnestedtests.h"
#include "util.h"
#include "uritests.h"
@ -17,20 +16,31 @@
#ifdef ENABLE_WALLET
#include "paymentservertests.h"
#include "wallettests.h"
#endif
#include <QCoreApplication>
#include <QApplication>
#include <QObject>
#include <QTest>
#include <openssl/ssl.h>
#if defined(QT_STATICPLUGIN) && QT_VERSION < 0x050000
#if defined(QT_STATICPLUGIN)
#include <QtPlugin>
#if QT_VERSION < 0x050000
Q_IMPORT_PLUGIN(qcncodecs)
Q_IMPORT_PLUGIN(qjpcodecs)
Q_IMPORT_PLUGIN(qtwcodecs)
Q_IMPORT_PLUGIN(qkrcodecs)
#else
#if defined(QT_QPA_PLATFORM_XCB)
Q_IMPORT_PLUGIN(QXcbIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_WINDOWS)
Q_IMPORT_PLUGIN(QWindowsIntegrationPlugin);
#elif defined(QT_QPA_PLATFORM_COCOA)
Q_IMPORT_PLUGIN(QCocoaIntegrationPlugin);
#endif
#endif
#endif
extern void noui_connect();
@ -38,7 +48,6 @@ extern void noui_connect();
// This is all you need to run all the tests
int main(int argc, char *argv[])
{
ECC_Start();
SetupEnvironment();
SetupNetworking();
SelectParams(CBaseChainParams::MAIN);
@ -47,31 +56,39 @@ int main(int argc, char *argv[])
bool fInvalid = false;
// Don't remove this, it's needed to access
// QCoreApplication:: in the tests
QCoreApplication app(argc, argv);
// QApplication:: and QCoreApplication:: in the tests
QApplication app(argc, argv);
app.setApplicationName("Dash-Qt-test");
SSL_library_init();
URITests test1;
if (QTest::qExec(&test1) != 0)
if (QTest::qExec(&test1) != 0) {
fInvalid = true;
}
#ifdef ENABLE_WALLET
PaymentServerTests test2;
if (QTest::qExec(&test2) != 0)
if (QTest::qExec(&test2) != 0) {
fInvalid = true;
}
#endif
RPCNestedTests test3;
if (QTest::qExec(&test3) != 0)
if (QTest::qExec(&test3) != 0) {
fInvalid = true;
}
CompatTests test4;
if (QTest::qExec(&test4) != 0)
if (QTest::qExec(&test4) != 0) {
fInvalid = true;
}
#ifdef ENABLE_WALLET
WalletTests test5;
if (QTest::qExec(&test5) != 0) {
fInvalid = true;
}
#endif
TrafficGraphDataTests test5;
if (QTest::qExec(&test5) != 0)
TrafficGraphDataTests test6;
if (QTest::qExec(&test6) != 0)
fInvalid = true;
ECC_Stop();
return fInvalid;
}

104
src/qt/test/wallettests.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "wallettests.h"
#include "qt/bitcoinamountfield.h"
#include "qt/optionsmodel.h"
#include "qt/platformstyle.h"
#include "qt/qvalidatedlineedit.h"
#include "qt/sendcoinsdialog.h"
#include "qt/sendcoinsentry.h"
#include "qt/transactiontablemodel.h"
#include "qt/walletmodel.h"
#include "test/test_dash.h"
#include "validation.h"
#include "wallet/wallet.h"
#include <QAbstractButton>
#include <QApplication>
#include <QTimer>
#include <QVBoxLayout>
namespace
{
//! Press "Yes" button in modal send confirmation dialog.
void ConfirmSend()
{
QTimer::singleShot(0, Qt::PreciseTimer, []() {
for (QWidget* widget : QApplication::topLevelWidgets()) {
if (widget->inherits("SendConfirmationDialog")) {
SendConfirmationDialog* dialog = qobject_cast<SendConfirmationDialog*>(widget);
QAbstractButton* button = dialog->button(QMessageBox::Yes);
button->setEnabled(true);
button->click();
}
}
});
}
//! Send coins to address and return txid.
uint256 SendCoins(CWallet& wallet, SendCoinsDialog& sendCoinsDialog, const CBitcoinAddress& address, CAmount amount)
{
QVBoxLayout* entries = sendCoinsDialog.findChild<QVBoxLayout*>("entries");
SendCoinsEntry* entry = qobject_cast<SendCoinsEntry*>(entries->itemAt(0)->widget());
entry->findChild<QValidatedLineEdit*>("payTo")->setText(QString::fromStdString(address.ToString()));
entry->findChild<BitcoinAmountField*>("payAmount")->setValue(amount);
uint256 txid;
boost::signals2::scoped_connection c = wallet.NotifyTransactionChanged.connect([&txid](CWallet*, const uint256& hash, ChangeType status) {
if (status == CT_NEW) txid = hash;
});
ConfirmSend();
QMetaObject::invokeMethod(&sendCoinsDialog, "on_sendButton_clicked");
return txid;
}
//! Find index of txid in transaction list.
QModelIndex FindTx(const QAbstractItemModel& model, const uint256& txid)
{
QString hash = QString::fromStdString(txid.ToString());
int rows = model.rowCount({});
for (int row = 0; row < rows; ++row) {
QModelIndex index = model.index(row, 0, {});
if (model.data(index, TransactionTableModel::TxHashRole) == hash) {
return index;
}
}
return {};
}
}
//! Simple qt wallet tests.
void WalletTests::walletTests()
{
// Set up wallet and chain with 101 blocks (1 mature block for spending).
TestChain100Setup test;
test.CreateAndProcessBlock({}, GetScriptForRawPubKey(test.coinbaseKey.GetPubKey()));
bitdb.MakeMock();
CWallet wallet("wallet_test.dat");
bool firstRun;
wallet.LoadWallet(firstRun);
{
LOCK(wallet.cs_wallet);
wallet.SetAddressBook(test.coinbaseKey.GetPubKey().GetID(), "", "receive");
wallet.AddKeyPubKey(test.coinbaseKey, test.coinbaseKey.GetPubKey());
}
wallet.ScanForWalletTransactions(chainActive.Genesis(), true);
wallet.SetBroadcastTransactions(true);
// Create widgets for sending coins and listing transactions.
std::unique_ptr<const PlatformStyle> platformStyle(PlatformStyle::instantiate("other"));
SendCoinsDialog sendCoinsDialog(platformStyle.get());
OptionsModel optionsModel;
WalletModel walletModel(platformStyle.get(), &wallet, &optionsModel);
sendCoinsDialog.setModel(&walletModel);
// Send two transactions, and verify they are added to transaction list.
TransactionTableModel* transactionTableModel = walletModel.getTransactionTableModel();
QCOMPARE(transactionTableModel->rowCount({}), 101);
uint256 txid1 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 5 * COIN);
uint256 txid2 = SendCoins(wallet, sendCoinsDialog, CBitcoinAddress(CKeyID()), 10 * COIN);
QCOMPARE(transactionTableModel->rowCount({}), 103);
QVERIFY(FindTx(*transactionTableModel, txid1).isValid());
QVERIFY(FindTx(*transactionTableModel, txid2).isValid());
bitdb.Flush(true);
bitdb.Reset();
}

15
src/qt/test/wallettests.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef BITCOIN_QT_TEST_WALLETTESTS_H
#define BITCOIN_QT_TEST_WALLETTESTS_H
#include <QObject>
#include <QTest>
class WalletTests : public QObject
{
Q_OBJECT
private Q_SLOTS:
void walletTests();
};
#endif // BITCOIN_QT_TEST_WALLETTESTS_H

View File

@ -2,8 +2,6 @@
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#define BOOST_TEST_MODULE Dash Test Suite
#include "test_dash.h"
#include "chainparams.h"
@ -21,7 +19,6 @@
#include "rpc/server.h"
#include "rpc/register.h"
#include "script/sigcache.h"
#include "stacktraces.h"
#include "test/testutil.h"
@ -33,11 +30,8 @@
#include <memory>
#include <boost/filesystem.hpp>
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_monitor.hpp>
#include <boost/thread.hpp>
std::unique_ptr<CConnman> g_connman;
FastRandomContext insecure_rand_ctx(true);
extern bool fPrintToConsole;
@ -84,11 +78,14 @@ TestingSetup::TestingSetup(const std::string& chainName) : BasicTestingSetup(cha
pcoinsdbview = new CCoinsViewDB(1 << 23, true);
llmq::InitLLMQSystem(*evoDb, nullptr, true);
pcoinsTip = new CCoinsViewCache(pcoinsdbview);
BOOST_REQUIRE(InitBlockIndex(chainparams));
if (!InitBlockIndex(chainparams)) {
throw std::runtime_error("InitBlockIndex failed.");
}
{
CValidationState state;
bool ok = ActivateBestChain(state, chainparams);
BOOST_REQUIRE(ok);
if (!ActivateBestChain(state, chainparams)) {
throw std::runtime_error("ActivateBestChain failed.");
}
}
nScriptCheckThreads = 3;
for (int i=0; i < nScriptCheckThreads-1; i++)
@ -215,48 +212,3 @@ CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn) {
return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, nHeight,
spendsCoinbase, sigOpCount, lp);
}
void Shutdown(void* parg)
{
exit(EXIT_SUCCESS);
}
void StartShutdown()
{
exit(EXIT_SUCCESS);
}
bool ShutdownRequested()
{
return false;
}
template<typename T>
void translate_exception(const T &e)
{
std::cerr << GetPrettyExceptionStr(std::current_exception()) << std::endl;
throw;
}
template<typename T>
void register_exception_translator()
{
boost::unit_test::unit_test_monitor.register_exception_translator<T>(&translate_exception<T>);
}
struct ExceptionInitializer {
ExceptionInitializer()
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();
register_exception_translator<std::exception>();
register_exception_translator<std::string>();
register_exception_translator<const char*>();
}
~ExceptionInitializer()
{
}
};
BOOST_GLOBAL_FIXTURE( ExceptionInitializer );

View File

@ -0,0 +1,58 @@
// Copyright (c) 2011-2016 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#define BOOST_TEST_MODULE Bitcoin Test Suite
#include "net.h"
#include "stacktraces.h"
#include <boost/test/unit_test.hpp>
#include <boost/test/unit_test_monitor.hpp>
std::unique_ptr<CConnman> g_connman;
void Shutdown(void* parg)
{
exit(EXIT_SUCCESS);
}
void StartShutdown()
{
exit(EXIT_SUCCESS);
}
bool ShutdownRequested()
{
return false;
}
template<typename T>
void translate_exception(const T &e)
{
std::cerr << GetPrettyExceptionStr(std::current_exception()) << std::endl;
throw;
}
template<typename T>
void register_exception_translator()
{
boost::unit_test::unit_test_monitor.register_exception_translator<T>(&translate_exception<T>);
}
struct ExceptionInitializer {
ExceptionInitializer()
{
RegisterPrettyTerminateHander();
RegisterPrettySignalHandlers();
register_exception_translator<std::exception>();
register_exception_translator<std::string>();
register_exception_translator<const char*>();
}
~ExceptionInitializer()
{
}
};
BOOST_GLOBAL_FIXTURE(ExceptionInitializer);