Skip to content

Commit c3907b4

Browse files
committed
Add LogSink & LogMessage classes for a more robust sink solution.
Signed-off-by: Sean Luchen <[email protected]>
1 parent 282e0c3 commit c3907b4

File tree

5 files changed

+57
-14
lines changed

5 files changed

+57
-14
lines changed

.github/actions/setup-build-env/action.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ runs:
88
shell: bash
99
run: |
1010
sudo apt-get update
11-
sudo apt-get install gperf build-essential bison flex libfl-dev libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libbz2-dev libgtest-dev
11+
sudo apt-get install gperf build-essential bison flex libfl-dev libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev libbz2-dev libgtest-dev libgmock-dev
1212
1313
- name: Install macOS Dependencies
1414
if: runner.os == 'macOS'

kernel/log.cc

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@
3939
YOSYS_NAMESPACE_BEGIN
4040

4141
std::vector<FILE*> log_files;
42-
std::vector<std::ostream*> log_streams, log_warning_streams;
42+
std::vector<std::ostream*> log_streams;
43+
std::vector<LogSink*> log_sinks;
4344
std::vector<std::string> log_scratchpads;
4445
std::map<std::string, std::set<std::string>> log_hdump;
4546
std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;
@@ -156,10 +157,6 @@ static void logv_string(std::string_view format, std::string str, LogSeverity se
156157

157158
for (auto f : log_streams)
158159
*f << time_str;
159-
160-
if (severity >= LogSeverity::LOG_WARNING)
161-
for (auto f : log_warning_streams)
162-
*f << time_str;
163160
}
164161

165162
for (auto f : log_files)
@@ -168,11 +165,9 @@ static void logv_string(std::string_view format, std::string str, LogSeverity se
168165
for (auto f : log_streams)
169166
*f << str;
170167

171-
if (severity >= LogSeverity::LOG_WARNING)
172-
for (auto f : log_warning_streams) {
173-
*f << str;
174-
f->flush();
175-
}
168+
LogMessage log_msg(severity, str);
169+
for (LogSink* sink : log_sinks)
170+
sink->log(log_msg);
176171

177172
RTLIL::Design *design = yosys_get_design();
178173
if (design != nullptr)

kernel/log.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,9 +100,22 @@ enum LogSeverity {
100100
LOG_ERROR
101101
};
102102

103+
struct LogMessage {
104+
LogMessage(LogSeverity severity, std::string_view message) :
105+
severity(severity), timestamp(std::time(nullptr)), message(message) {}
106+
LogSeverity severity;
107+
std::time_t timestamp;
108+
std::string message;
109+
};
110+
111+
class LogSink {
112+
public:
113+
virtual void log(const LogMessage& message) = 0;
114+
};
115+
103116
extern std::vector<FILE*> log_files;
104117
extern std::vector<std::ostream*> log_streams;
105-
extern std::vector<std::ostream*> log_warning_streams;
118+
extern std::vector<LogSink*> log_sinks;
106119
extern std::vector<std::string> log_scratchpads;
107120
extern std::map<std::string, std::set<std::string>> log_hdump;
108121
extern std::vector<std::regex> log_warn_regexes, log_nowarn_regexes, log_werror_regexes;

tests/unit/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,10 @@ UNAME_S := $(shell uname -s)
44
GTEST_PREFIX := $(shell brew --prefix googletest 2>/dev/null)
55
ifeq ($(GTEST_PREFIX),)
66
GTEST_CXXFLAGS :=
7-
GTEST_LDFLAGS := -lgtest -lgtest_main
7+
GTEST_LDFLAGS := -lgtest -lgtest_main -lgmock
88
else
99
GTEST_CXXFLAGS := -I$(GTEST_PREFIX)/include
10-
GTEST_LDFLAGS := -L$(GTEST_PREFIX)/lib -lgtest -lgtest_main
10+
GTEST_LDFLAGS := -L$(GTEST_PREFIX)/lib -lgtest -lgtest_main -lgmock
1111
endif
1212

1313
ifeq ($(UNAME_S),Darwin)

tests/unit/kernel/logTest.cc

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
#include <gmock/gmock.h>
12
#include <gtest/gtest.h>
23

34
#include "kernel/yosys.h"
@@ -11,4 +12,38 @@ TEST(KernelLogTest, logvValidValues)
1112
EXPECT_EQ(7, 7);
1213
}
1314

15+
class TestSink : public LogSink {
16+
public:
17+
void log(const LogMessage& message) override {
18+
messages_.push_back(message);
19+
}
20+
std::vector<LogMessage> messages_;
21+
};
22+
23+
TEST(KernelLogTest, logToSink)
24+
{
25+
TestSink sink;
26+
log_sinks.push_back(&sink);
27+
log("test info log");
28+
log_warning("test warning log");
29+
30+
std::vector<LogMessage> expected{
31+
LogMessage(LogSeverity::LOG_INFO, "test info log"),
32+
LogMessage(LogSeverity::LOG_WARNING, "test warning log"),
33+
};
34+
// Certain calls to the log.h interface may prepend a string to
35+
// the provided string. We should ensure that the expected string
36+
// is a subset of the actual string. Additionally, we don't want to
37+
// compare timestamps. So, we use a custom comparator.
38+
for (const LogMessage& expected_msg : expected) {
39+
EXPECT_THAT(sink.messages_, ::testing::Contains(::testing::Truly(
40+
[&](const LogMessage& actual) {
41+
return actual.severity == expected_msg.severity &&
42+
actual.message.find(expected_msg.message) != std::string::npos;
43+
}
44+
)));
45+
}
46+
EXPECT_NE(sink.messages_[0].timestamp, 0);
47+
}
48+
1449
YOSYS_NAMESPACE_END

0 commit comments

Comments
 (0)