1 | #include "includes.h" |
2 | #include "test_sink.h" |
3 | #include "spdlog/fmt/bin_to_hex.h" |
4 | |
5 | template<class T> |
6 | std::string log_info(const T &what, spdlog::level::level_enum logger_level = spdlog::level::info) |
7 | { |
8 | |
9 | std::ostringstream oss; |
10 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
11 | |
12 | spdlog::logger oss_logger("oss" , oss_sink); |
13 | oss_logger.set_level(logger_level); |
14 | oss_logger.set_pattern("%v" ); |
15 | oss_logger.info(what); |
16 | |
17 | return oss.str().substr(0, oss.str().length() - strlen(spdlog::details::os::default_eol)); |
18 | } |
19 | |
20 | TEST_CASE("basic_logging " , "[basic_logging]" ) |
21 | { |
22 | // const char |
23 | REQUIRE(log_info("Hello" ) == "Hello" ); |
24 | REQUIRE(log_info("" ).empty()); |
25 | |
26 | // std::string |
27 | REQUIRE(log_info(std::string("Hello" )) == "Hello" ); |
28 | REQUIRE(log_info(std::string()).empty()); |
29 | |
30 | // Numbers |
31 | REQUIRE(log_info(5) == "5" ); |
32 | REQUIRE(log_info(5.6) == "5.6" ); |
33 | |
34 | // User defined class |
35 | // REQUIRE(log_info(some_logged_class("some_val")) == "some_val"); |
36 | } |
37 | |
38 | TEST_CASE("log_levels" , "[log_levels]" ) |
39 | { |
40 | REQUIRE(log_info("Hello" , spdlog::level::err).empty()); |
41 | REQUIRE(log_info("Hello" , spdlog::level::critical).empty()); |
42 | REQUIRE(log_info("Hello" , spdlog::level::info) == "Hello" ); |
43 | REQUIRE(log_info("Hello" , spdlog::level::debug) == "Hello" ); |
44 | REQUIRE(log_info("Hello" , spdlog::level::trace) == "Hello" ); |
45 | } |
46 | |
47 | TEST_CASE("level_to_string_view" , "[convert_to_string_view" ) |
48 | { |
49 | REQUIRE(spdlog::level::to_string_view(spdlog::level::trace) == "trace" ); |
50 | REQUIRE(spdlog::level::to_string_view(spdlog::level::debug) == "debug" ); |
51 | REQUIRE(spdlog::level::to_string_view(spdlog::level::info) == "info" ); |
52 | REQUIRE(spdlog::level::to_string_view(spdlog::level::warn) == "warning" ); |
53 | REQUIRE(spdlog::level::to_string_view(spdlog::level::err) == "error" ); |
54 | REQUIRE(spdlog::level::to_string_view(spdlog::level::critical) == "critical" ); |
55 | REQUIRE(spdlog::level::to_string_view(spdlog::level::off) == "off" ); |
56 | } |
57 | |
58 | TEST_CASE("to_short_c_str" , "[convert_to_short_c_str]" ) |
59 | { |
60 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::trace)) == "T" ); |
61 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::debug)) == "D" ); |
62 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::info)) == "I" ); |
63 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::warn)) == "W" ); |
64 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::err)) == "E" ); |
65 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::critical)) == "C" ); |
66 | REQUIRE(std::string(spdlog::level::to_short_c_str(spdlog::level::off)) == "O" ); |
67 | } |
68 | |
69 | TEST_CASE("to_level_enum" , "[convert_to_level_enum]" ) |
70 | { |
71 | REQUIRE(spdlog::level::from_str("trace" ) == spdlog::level::trace); |
72 | REQUIRE(spdlog::level::from_str("debug" ) == spdlog::level::debug); |
73 | REQUIRE(spdlog::level::from_str("info" ) == spdlog::level::info); |
74 | REQUIRE(spdlog::level::from_str("warning" ) == spdlog::level::warn); |
75 | REQUIRE(spdlog::level::from_str("warn" ) == spdlog::level::warn); |
76 | REQUIRE(spdlog::level::from_str("error" ) == spdlog::level::err); |
77 | REQUIRE(spdlog::level::from_str("critical" ) == spdlog::level::critical); |
78 | REQUIRE(spdlog::level::from_str("off" ) == spdlog::level::off); |
79 | REQUIRE(spdlog::level::from_str("null" ) == spdlog::level::off); |
80 | } |
81 | |
82 | TEST_CASE("periodic flush" , "[periodic_flush]" ) |
83 | { |
84 | using spdlog::sinks::test_sink_mt; |
85 | auto logger = spdlog::create<test_sink_mt>("periodic_flush" ); |
86 | auto test_sink = std::static_pointer_cast<test_sink_mt>(logger->sinks()[0]); |
87 | |
88 | spdlog::flush_every(std::chrono::seconds(1)); |
89 | std::this_thread::sleep_for(std::chrono::milliseconds(1250)); |
90 | REQUIRE(test_sink->flush_counter() == 1); |
91 | spdlog::flush_every(std::chrono::seconds(0)); |
92 | spdlog::drop_all(); |
93 | } |
94 | |
95 | TEST_CASE("clone-logger" , "[clone]" ) |
96 | { |
97 | using spdlog::sinks::test_sink_mt; |
98 | auto test_sink = std::make_shared<test_sink_mt>(); |
99 | auto logger = std::make_shared<spdlog::logger>("orig" , test_sink); |
100 | logger->set_pattern("%v" ); |
101 | auto cloned = logger->clone("clone" ); |
102 | |
103 | REQUIRE(cloned->name() == "clone" ); |
104 | REQUIRE(logger->sinks() == cloned->sinks()); |
105 | REQUIRE(logger->level() == cloned->level()); |
106 | REQUIRE(logger->flush_level() == cloned->flush_level()); |
107 | logger->info("Some message 1" ); |
108 | cloned->info("Some message 2" ); |
109 | |
110 | REQUIRE(test_sink->lines().size() == 2); |
111 | REQUIRE(test_sink->lines()[0] == "Some message 1" ); |
112 | REQUIRE(test_sink->lines()[1] == "Some message 2" ); |
113 | |
114 | spdlog::drop_all(); |
115 | } |
116 | |
117 | TEST_CASE("clone async" , "[clone]" ) |
118 | { |
119 | using spdlog::sinks::test_sink_st; |
120 | spdlog::init_thread_pool(4, 1); |
121 | auto test_sink = std::make_shared<test_sink_st>(); |
122 | auto logger = std::make_shared<spdlog::async_logger>("orig" , test_sink, spdlog::thread_pool()); |
123 | logger->set_pattern("%v" ); |
124 | auto cloned = logger->clone("clone" ); |
125 | |
126 | REQUIRE(cloned->name() == "clone" ); |
127 | REQUIRE(logger->sinks() == cloned->sinks()); |
128 | REQUIRE(logger->level() == cloned->level()); |
129 | REQUIRE(logger->flush_level() == cloned->flush_level()); |
130 | |
131 | logger->info("Some message 1" ); |
132 | cloned->info("Some message 2" ); |
133 | |
134 | spdlog::details::os::sleep_for_millis(100); |
135 | |
136 | REQUIRE(test_sink->lines().size() == 2); |
137 | REQUIRE(test_sink->lines()[0] == "Some message 1" ); |
138 | REQUIRE(test_sink->lines()[1] == "Some message 2" ); |
139 | |
140 | spdlog::drop_all(); |
141 | } |
142 | |
143 | TEST_CASE("to_hex" , "[to_hex]" ) |
144 | { |
145 | std::ostringstream oss; |
146 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
147 | spdlog::logger oss_logger("oss" , oss_sink); |
148 | |
149 | std::vector<unsigned char> v{9, 0xa, 0xb, 0xc, 0xff, 0xff}; |
150 | oss_logger.info("{}" , spdlog::to_hex(v)); |
151 | |
152 | auto output = oss.str(); |
153 | REQUIRE(ends_with(output, "0000: 09 0a 0b 0c ff ff" + std::string(spdlog::details::os::default_eol))); |
154 | } |
155 | |
156 | TEST_CASE("to_hex_upper" , "[to_hex]" ) |
157 | { |
158 | std::ostringstream oss; |
159 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
160 | spdlog::logger oss_logger("oss" , oss_sink); |
161 | |
162 | std::vector<unsigned char> v{9, 0xa, 0xb, 0xc, 0xff, 0xff}; |
163 | oss_logger.info("{:X}" , spdlog::to_hex(v)); |
164 | |
165 | auto output = oss.str(); |
166 | REQUIRE(ends_with(output, "0000: 09 0A 0B 0C FF FF" + std::string(spdlog::details::os::default_eol))); |
167 | } |
168 | |
169 | TEST_CASE("to_hex_no_delimiter" , "[to_hex]" ) |
170 | { |
171 | std::ostringstream oss; |
172 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
173 | spdlog::logger oss_logger("oss" , oss_sink); |
174 | |
175 | std::vector<unsigned char> v{9, 0xa, 0xb, 0xc, 0xff, 0xff}; |
176 | oss_logger.info("{:sX}" , spdlog::to_hex(v)); |
177 | |
178 | auto output = oss.str(); |
179 | REQUIRE(ends_with(output, "0000: 090A0B0CFFFF" + std::string(spdlog::details::os::default_eol))); |
180 | } |
181 | |
182 | TEST_CASE("to_hex_show_ascii" , "[to_hex]" ) |
183 | { |
184 | std::ostringstream oss; |
185 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
186 | spdlog::logger oss_logger("oss" , oss_sink); |
187 | |
188 | std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff}; |
189 | oss_logger.info("{:Xsa}" , spdlog::to_hex(v, 8)); |
190 | |
191 | REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." + std::string(spdlog::details::os::default_eol))); |
192 | } |
193 | |
194 | TEST_CASE("to_hex_different_size_per_line" , "[to_hex]" ) |
195 | { |
196 | std::ostringstream oss; |
197 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
198 | spdlog::logger oss_logger("oss" , oss_sink); |
199 | |
200 | std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff}; |
201 | |
202 | oss_logger.info("{:Xsa}" , spdlog::to_hex(v, 10)); |
203 | REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF ...A.K.." + std::string(spdlog::details::os::default_eol))); |
204 | |
205 | oss_logger.info("{:Xs}" , spdlog::to_hex(v, 10)); |
206 | REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol))); |
207 | |
208 | oss_logger.info("{:Xsa}" , spdlog::to_hex(v, 6)); |
209 | REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B ...A.K" + std::string(spdlog::details::os::default_eol) + "0006: FFFF .." + |
210 | std::string(spdlog::details::os::default_eol))); |
211 | |
212 | oss_logger.info("{:Xs}" , spdlog::to_hex(v, 6)); |
213 | REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4B" + std::string(spdlog::details::os::default_eol) + "0006: FFFF" + |
214 | std::string(spdlog::details::os::default_eol))); |
215 | } |
216 | |
217 | TEST_CASE("to_hex_no_ascii" , "[to_hex]" ) |
218 | { |
219 | std::ostringstream oss; |
220 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
221 | spdlog::logger oss_logger("oss" , oss_sink); |
222 | |
223 | std::vector<unsigned char> v{9, 0xa, 0xb, 0x41, 0xc, 0x4b, 0xff, 0xff}; |
224 | oss_logger.info("{:Xs}" , spdlog::to_hex(v, 8)); |
225 | |
226 | REQUIRE(ends_with(oss.str(), "0000: 090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol))); |
227 | |
228 | oss_logger.info("{:Xsna}" , spdlog::to_hex(v, 8)); |
229 | |
230 | REQUIRE(ends_with(oss.str(), "090A0B410C4BFFFF" + std::string(spdlog::details::os::default_eol))); |
231 | } |
232 | |
233 | TEST_CASE("default logger API" , "[default logger]" ) |
234 | { |
235 | std::ostringstream oss; |
236 | auto oss_sink = std::make_shared<spdlog::sinks::ostream_sink_mt>(oss); |
237 | |
238 | spdlog::set_default_logger(std::make_shared<spdlog::logger>("oss" , oss_sink)); |
239 | spdlog::set_pattern("*** %v" ); |
240 | |
241 | spdlog::default_logger()->set_level(spdlog::level::trace); |
242 | spdlog::trace("hello trace" ); |
243 | REQUIRE(oss.str() == "*** hello trace" + std::string(spdlog::details::os::default_eol)); |
244 | |
245 | oss.str("" ); |
246 | spdlog::debug("hello debug" ); |
247 | REQUIRE(oss.str() == "*** hello debug" + std::string(spdlog::details::os::default_eol)); |
248 | |
249 | oss.str("" ); |
250 | spdlog::info("Hello" ); |
251 | REQUIRE(oss.str() == "*** Hello" + std::string(spdlog::details::os::default_eol)); |
252 | |
253 | oss.str("" ); |
254 | spdlog::warn("Hello again {}" , 2); |
255 | REQUIRE(oss.str() == "*** Hello again 2" + std::string(spdlog::details::os::default_eol)); |
256 | |
257 | oss.str("" ); |
258 | spdlog::error(123); |
259 | REQUIRE(oss.str() == "*** 123" + std::string(spdlog::details::os::default_eol)); |
260 | |
261 | oss.str("" ); |
262 | spdlog::critical(std::string("some string" )); |
263 | REQUIRE(oss.str() == "*** some string" + std::string(spdlog::details::os::default_eol)); |
264 | |
265 | oss.str("" ); |
266 | spdlog::set_level(spdlog::level::info); |
267 | spdlog::debug("should not be logged" ); |
268 | REQUIRE(oss.str().empty()); |
269 | spdlog::drop_all(); |
270 | spdlog::set_pattern("%v" ); |
271 | } |
272 | |