Skip to content

Commit fea532a

Browse files
author
MarcoFalke
committed
Merge #16540: test: Add ASSERT_DEBUG_LOG to unit test framework
fa2c44c test: Add ASSERT_DEBUG_LOG to unit test framework (MarcoFalke) fa1936f logging: Add member for arbitrary print callbacks (MarcoFalke) Pull request description: Similar to `assert_debug_log` in the functional test framework Top commit has no ACKs. Tree-SHA512: aa9eaeca386b61d806867c04a33275f6eb4624fa5bf50f2928d16c83f5634bac96bcac46f9e8eda3b00b4251c5f12d7b01d6ffd84ba8e05c09eeec810cc31251
2 parents b05b281 + fa2c44c commit fea532a

File tree

9 files changed

+123
-26
lines changed

9 files changed

+123
-26
lines changed

src/Makefile.test.include

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,8 @@ GENERATED_TEST_FILES = $(JSON_TEST_FILES:.json=.json.h) $(RAW_TEST_FILES:.raw=.r
5959
BITCOIN_TEST_SUITE = \
6060
test/lib/blockfilter.cpp \
6161
test/lib/blockfilter.h \
62+
test/lib/logging.cpp \
63+
test/lib/logging.h \
6264
test/lib/transaction_utils.cpp \
6365
test/lib/transaction_utils.h \
6466
test/main.cpp \

src/logging.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ bool BCLog::Logger::StartLogging()
6767

6868
if (m_print_to_file) FileWriteStr(s, m_fileout);
6969
if (m_print_to_console) fwrite(s.data(), 1, s.size(), stdout);
70+
for (const auto& cb : m_print_callbacks) {
71+
cb(s);
72+
}
7073

7174
m_msgs_before_open.pop_front();
7275
}
@@ -81,6 +84,7 @@ void BCLog::Logger::DisconnectTestLogger()
8184
m_buffering = true;
8285
if (m_fileout != nullptr) fclose(m_fileout);
8386
m_fileout = nullptr;
87+
m_print_callbacks.clear();
8488
}
8589

8690
void BCLog::Logger::EnableCategory(BCLog::LogFlags flag)
@@ -270,6 +274,9 @@ void BCLog::Logger::LogPrintStr(const std::string& str)
270274
fwrite(str_prefixed.data(), 1, str_prefixed.size(), stdout);
271275
fflush(stdout);
272276
}
277+
for (const auto& cb : m_print_callbacks) {
278+
cb(str_prefixed);
279+
}
273280
if (m_print_to_file) {
274281
assert(m_fileout != nullptr);
275282

src/logging.h

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ namespace BCLog {
7777

7878
std::string LogTimestampStr(const std::string& str);
7979

80+
/** Slots that connect to the print signal */
81+
std::list<std::function<void(const std::string&)>> m_print_callbacks /* GUARDED_BY(m_cs) */ {};
82+
8083
public:
8184
bool m_print_to_console = false;
8285
bool m_print_to_file = false;
@@ -95,7 +98,22 @@ namespace BCLog {
9598
bool Enabled() const
9699
{
97100
std::lock_guard<std::mutex> scoped_lock(m_cs);
98-
return m_buffering || m_print_to_console || m_print_to_file;
101+
return m_buffering || m_print_to_console || m_print_to_file || !m_print_callbacks.empty();
102+
}
103+
104+
/** Connect a slot to the print signal and return the connection */
105+
std::list<std::function<void(const std::string&)>>::iterator PushBackCallback(std::function<void(const std::string&)> fun)
106+
{
107+
std::lock_guard<std::mutex> scoped_lock(m_cs);
108+
m_print_callbacks.push_back(std::move(fun));
109+
return --m_print_callbacks.end();
110+
}
111+
112+
/** Delete a connection */
113+
void DeleteCallback(std::list<std::function<void(const std::string&)>>::iterator it)
114+
{
115+
std::lock_guard<std::mutex> scoped_lock(m_cs);
116+
m_print_callbacks.erase(it);
99117
}
100118

101119
/** Start logging (and flush all buffered messages) */

src/noui.cpp

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -66,28 +66,31 @@ void noui_connect()
6666
noui_InitMessageConn = uiInterface.InitMessage_connect(noui_InitMessage);
6767
}
6868

69-
bool noui_ThreadSafeMessageBoxSuppressed(const std::string& message, const std::string& caption, unsigned int style)
69+
bool noui_ThreadSafeMessageBoxRedirect(const std::string& message, const std::string& caption, unsigned int style)
7070
{
71+
LogPrintf("%s: %s\n", caption, message);
7172
return false;
7273
}
7374

74-
bool noui_ThreadSafeQuestionSuppressed(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
75+
bool noui_ThreadSafeQuestionRedirect(const std::string& /* ignored interactive message */, const std::string& message, const std::string& caption, unsigned int style)
7576
{
77+
LogPrintf("%s: %s\n", caption, message);
7678
return false;
7779
}
7880

79-
void noui_InitMessageSuppressed(const std::string& message)
81+
void noui_InitMessageRedirect(const std::string& message)
8082
{
83+
LogPrintf("init message: %s\n", message);
8184
}
8285

83-
void noui_suppress()
86+
void noui_test_redirect()
8487
{
8588
noui_ThreadSafeMessageBoxConn.disconnect();
8689
noui_ThreadSafeQuestionConn.disconnect();
8790
noui_InitMessageConn.disconnect();
88-
noui_ThreadSafeMessageBoxConn = uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBoxSuppressed);
89-
noui_ThreadSafeQuestionConn = uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestionSuppressed);
90-
noui_InitMessageConn = uiInterface.InitMessage_connect(noui_InitMessageSuppressed);
91+
noui_ThreadSafeMessageBoxConn = uiInterface.ThreadSafeMessageBox_connect(noui_ThreadSafeMessageBoxRedirect);
92+
noui_ThreadSafeQuestionConn = uiInterface.ThreadSafeQuestion_connect(noui_ThreadSafeQuestionRedirect);
93+
noui_InitMessageConn = uiInterface.InitMessage_connect(noui_InitMessageRedirect);
9194
}
9295

9396
void noui_reconnect()

src/noui.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ void noui_InitMessage(const std::string& message);
1717
/** Connect all bitcoind signal handlers */
1818
void noui_connect();
1919

20-
/** Suppress all bitcoind signal handlers. Used to suppress output during test runs that produce expected errors */
21-
void noui_suppress();
20+
/** Redirect all bitcoind signal handlers to LogPrintf. Used to check or suppress output during test runs that produce expected errors */
21+
void noui_test_redirect();
2222

23-
/** Reconnects the regular Non-GUI handlers after having used noui_suppress */
23+
/** Reconnects the regular Non-GUI handlers after having used noui_test_redirect */
2424
void noui_reconnect();
2525

2626
#endif // BITCOIN_NOUI_H

src/test/lib/logging.cpp

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Copyright (c) 2019 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 <test/lib/logging.h>
6+
7+
#include <logging.h>
8+
#include <noui.h>
9+
#include <tinyformat.h>
10+
#include <util/memory.h>
11+
12+
#include <stdexcept>
13+
14+
DebugLogHelper::DebugLogHelper(std::string message)
15+
: m_message{std::move(message)}
16+
{
17+
m_print_connection = LogInstance().PushBackCallback(
18+
[this](const std::string& s) {
19+
if (m_found) return;
20+
m_found = s.find(m_message) != std::string::npos;
21+
});
22+
noui_test_redirect();
23+
}
24+
25+
void DebugLogHelper::check_found()
26+
{
27+
noui_reconnect();
28+
LogInstance().DeleteCallback(m_print_connection);
29+
if (!m_found) {
30+
throw std::runtime_error(strprintf("'%s' not found in debug log\n", m_message));
31+
}
32+
}

src/test/lib/logging.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright (c) 2019 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+
#ifndef BITCOIN_TEST_LIB_LOGGING_H
6+
#define BITCOIN_TEST_LIB_LOGGING_H
7+
8+
#include <util/macros.h>
9+
10+
#include <functional>
11+
#include <list>
12+
#include <string>
13+
14+
class DebugLogHelper
15+
{
16+
const std::string m_message;
17+
bool m_found{false};
18+
std::list<std::function<void(const std::string&)>>::iterator m_print_connection;
19+
20+
void check_found();
21+
22+
public:
23+
DebugLogHelper(std::string message);
24+
~DebugLogHelper() { check_found(); }
25+
};
26+
27+
#define ASSERT_DEBUG_LOG(message) DebugLogHelper PASTE2(debugloghelper, __COUNTER__)(message)
28+
29+
#endif // BITCOIN_TEST_LIB_LOGGING_H

src/test/timedata_tests.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
#include <netaddress.h>
77
#include <noui.h>
8+
#include <test/lib/logging.h>
89
#include <test/setup_common.h>
910
#include <timedata.h>
1011
#include <warnings.h>
@@ -59,9 +60,10 @@ BOOST_AUTO_TEST_CASE(addtimedata)
5960
MultiAddTimeData(3, DEFAULT_MAX_TIME_ADJUSTMENT + 1);
6061
// Filter size is 1 + 3 = 4: It is always initialized with a single element (offset 0)
6162

62-
noui_suppress();
63-
MultiAddTimeData(1, DEFAULT_MAX_TIME_ADJUSTMENT + 1); //filter size 5
64-
noui_reconnect();
63+
{
64+
ASSERT_DEBUG_LOG("Please check that your computer's date and time are correct!");
65+
MultiAddTimeData(1, DEFAULT_MAX_TIME_ADJUSTMENT + 1); //filter size 5
66+
}
6567

6668
BOOST_CHECK(GetWarnings("gui").find("clock is wrong") != std::string::npos);
6769

src/wallet/test/init_tests.cpp

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include <boost/test/unit_test.hpp>
66

77
#include <noui.h>
8+
#include <test/lib/logging.h>
89
#include <test/setup_common.h>
910
#include <util/system.h>
1011
#include <wallet/test/init_test_fixture.h>
@@ -34,28 +35,31 @@ BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_custom)
3435
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_does_not_exist)
3536
{
3637
SetWalletDir(m_walletdir_path_cases["nonexistent"]);
37-
noui_suppress();
38-
bool result = m_chain_client->verify();
39-
noui_reconnect();
40-
BOOST_CHECK(result == false);
38+
{
39+
ASSERT_DEBUG_LOG("does not exist");
40+
bool result = m_chain_client->verify();
41+
BOOST_CHECK(result == false);
42+
}
4143
}
4244

4345
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_is_not_directory)
4446
{
4547
SetWalletDir(m_walletdir_path_cases["file"]);
46-
noui_suppress();
47-
bool result = m_chain_client->verify();
48-
noui_reconnect();
49-
BOOST_CHECK(result == false);
48+
{
49+
ASSERT_DEBUG_LOG("is not a directory");
50+
bool result = m_chain_client->verify();
51+
BOOST_CHECK(result == false);
52+
}
5053
}
5154

5255
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_is_not_relative)
5356
{
5457
SetWalletDir(m_walletdir_path_cases["relative"]);
55-
noui_suppress();
56-
bool result = m_chain_client->verify();
57-
noui_reconnect();
58-
BOOST_CHECK(result == false);
58+
{
59+
ASSERT_DEBUG_LOG("is a relative path");
60+
bool result = m_chain_client->verify();
61+
BOOST_CHECK(result == false);
62+
}
5963
}
6064

6165
BOOST_AUTO_TEST_CASE(walletinit_verify_walletdir_no_trailing)

0 commit comments

Comments
 (0)