1 // Copyright (c) 2018 The Bitcoin Core developers
2 // Distributed under the MIT software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <qt/test/apptests.h>
6
7 #include <chainparams.h>
8 #include <init.h>
9 #include <qt/bitcoin.h>
10 #include <qt/bitcoingui.h>
11 #include <qt/networkstyle.h>
12 #include <qt/rpcconsole.h>
13 #include <shutdown.h>
14 #include <validation.h>
15
16 #if defined(HAVE_CONFIG_H)
17 #include <config/bitcoin-config.h>
18 #endif
19 #ifdef ENABLE_WALLET
20 #include <wallet/db.h>
21 #endif
22
23 #include <QAction>
24 #include <QEventLoop>
25 #include <QLineEdit>
26 #include <QScopedPointer>
27 #include <QTest>
28 #include <QTextEdit>
29 #include <QtGlobal>
30 #include <QtTest/QtTestWidgets>
31 #include <QtTest/QtTestGui>
32 #include <new>
33 #include <string>
34 #include <univalue.h>
35
36 namespace {
37 //! Call getblockchaininfo RPC and check first field of JSON output.
TestRpcCommand(RPCConsole * console)38 void TestRpcCommand(RPCConsole* console)
39 {
40 QEventLoop loop;
41 QTextEdit* messagesWidget = console->findChild<QTextEdit*>("messagesWidget");
42 QObject::connect(messagesWidget, &QTextEdit::textChanged, &loop, &QEventLoop::quit);
43 QLineEdit* lineEdit = console->findChild<QLineEdit*>("lineEdit");
44 QTest::keyClicks(lineEdit, "getblockchaininfo");
45 QTest::keyClick(lineEdit, Qt::Key_Return);
46 loop.exec();
47 QString output = messagesWidget->toPlainText();
48 UniValue value;
49 value.read(output.right(output.size() - output.lastIndexOf(QChar::ObjectReplacementCharacter) - 1).toStdString());
50 QCOMPARE(value["chain"].get_str(), std::string("regtest"));
51 }
52 } // namespace
53
54 //! Entry point for BitcoinApplication tests.
appTests()55 void AppTests::appTests()
56 {
57 #ifdef Q_OS_MAC
58 if (QApplication::platformName() == "minimal") {
59 // Disable for mac on "minimal" platform to avoid crashes inside the Qt
60 // framework when it tries to look up unimplemented cocoa functions,
61 // and fails to handle returned nulls
62 // (https://bugreports.qt.io/browse/QTBUG-49686).
63 QWARN("Skipping AppTests on mac build with 'minimal' platform set due to Qt bugs. To run AppTests, invoke "
64 "with 'test_litecoin-qt -platform cocoa' on mac, or else use a linux or windows build.");
65 return;
66 }
67 #endif
68
69 m_app.parameterSetup();
70 m_app.createOptionsModel(true /* reset settings */);
71 QScopedPointer<const NetworkStyle> style(
72 NetworkStyle::instantiate(QString::fromStdString(Params().NetworkIDString())));
73 m_app.setupPlatformStyle();
74 m_app.createWindow(style.data());
75 connect(&m_app, &BitcoinApplication::windowShown, this, &AppTests::guiTests);
76 expectCallback("guiTests");
77 m_app.baseInitialize();
78 m_app.requestInitialize();
79 m_app.exec();
80 m_app.requestShutdown();
81 m_app.exec();
82
83 // Reset global state to avoid interfering with later tests.
84 AbortShutdown();
85 UnloadBlockIndex();
86 }
87
88 //! Entry point for BitcoinGUI tests.
guiTests(BitcoinGUI * window)89 void AppTests::guiTests(BitcoinGUI* window)
90 {
91 HandleCallback callback{"guiTests", *this};
92 connect(window, &BitcoinGUI::consoleShown, this, &AppTests::consoleTests);
93 expectCallback("consoleTests");
94 QAction* action = window->findChild<QAction*>("openRPCConsoleAction");
95 action->activate(QAction::Trigger);
96 }
97
98 //! Entry point for RPCConsole tests.
consoleTests(RPCConsole * console)99 void AppTests::consoleTests(RPCConsole* console)
100 {
101 HandleCallback callback{"consoleTests", *this};
102 TestRpcCommand(console);
103 }
104
105 //! Destructor to shut down after the last expected callback completes.
~HandleCallback()106 AppTests::HandleCallback::~HandleCallback()
107 {
108 auto& callbacks = m_app_tests.m_callbacks;
109 auto it = callbacks.find(m_callback);
110 assert(it != callbacks.end());
111 callbacks.erase(it);
112 if (callbacks.empty()) {
113 m_app_tests.m_app.quit();
114 }
115 }
116