gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
logging.test.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2021 Daniel R. Carvalho
3 * All rights reserved
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met: redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer;
9 * redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution;
12 * neither the name of the copyright holders nor the names of its
13 * contributors may be used to endorse or promote products derived from
14 * this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29#include <gmock/gmock.h>
30#include <gtest/gtest.h>
31
32#include "base/gtest/logging.hh"
33#include "base/logging.hh"
34
35using namespace gem5;
36
38class LoggingFixture : public ::testing::Test
39{
40 public:
41 void SetUp() override { old = std::cerr.rdbuf(gtestLogOutput.rdbuf()); }
42 void TearDown() override { std::cerr.rdbuf(old); }
43
44 private:
46 std::streambuf *old;
47};
48
51{
52 Logger logger("test: ");
53
54 // Tests that the logger will automatically add '\n' to the end of the
55 // message if it does not already have '\n' in the end
56 gtestLogOutput.str("");
57 logger.print(Logger::Loc("File", 10), "message");
58 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: message\n");
59
60 // Tests that the logger won't add '\n' if it already has '\n' in the end
61 gtestLogOutput.str("");
62 logger.print(Logger::Loc("File", 10), "message\n");
63 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: message\n");
64
65 // Tests that the logger won't remove '\n's if multiple are provided
66 gtestLogOutput.str("");
67 logger.print(Logger::Loc("File", 10), "sample message\n\n");
68 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: sample message\n\n");
69
70 // A more complete/complex test case
71 gtestLogOutput.str("");
72 logger.print(Logger::Loc("File", 10), "sample message\nwith \n3 lines");
73 ASSERT_EQ(gtestLogOutput.str(),
74 "File:10: test: sample message\nwith \n3 lines\n");
75}
76
78TEST_F(LoggingFixture, VariadicCharPrint)
79{
80 Logger logger("test: ");
81
82 gtestLogOutput.str("");
83 logger.print(Logger::Loc("File", 10), (const char *)"%s message",
84 "sample");
85 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: sample message\n");
86
87 gtestLogOutput.str("");
88 logger.print(Logger::Loc("File", 10),
89 (const char *)"sample %s with %d arguments\n", "message", 2);
90 ASSERT_EQ(gtestLogOutput.str(),
91 "File:10: test: sample message with 2 arguments\n");
92}
93
95TEST_F(LoggingFixture, VariadicStringPrint)
96{
97 Logger logger("test: ");
98
99 gtestLogOutput.str("");
100 logger.print(Logger::Loc("File", 10), std::string("%s message"), "sample");
101 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: sample message\n");
102
103 gtestLogOutput.str("");
104 logger.print(Logger::Loc("File", 10),
105 std::string("sample %s with %d arguments\n"), "message", 2);
106 ASSERT_EQ(gtestLogOutput.str(),
107 "File:10: test: sample message with 2 arguments\n");
108}
109
111TEST_F(LoggingFixture, VariadicCharMissingPrint)
112{
113 Logger logger("test: ");
114
115 gtestLogOutput.str("");
116 logger.print(Logger::Loc("File", 10), (const char *)"%s message");
117 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: <extra arg>% message\n");
118
119 gtestLogOutput.str("");
120 logger.print(Logger::Loc("File", 10), (const char *)"%s mes%ca%cge",
121 "sample", 's');
122 ASSERT_EQ(gtestLogOutput.str(),
123 "File:10: test: sample messa<extra arg>%ge\n");
124}
125
127TEST_F(LoggingFixture, VariadicStringMissingPrint)
128{
129 Logger logger("test: ");
130
131 gtestLogOutput.str("");
132 logger.print(Logger::Loc("File", 10), std::string("%s message"));
133 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: <extra arg>% message\n");
134
135 gtestLogOutput.str("");
136 logger.print(Logger::Loc("File", 10), std::string("%s mes%ca%cge"),
137 "sample", 's');
138 ASSERT_EQ(gtestLogOutput.str(),
139 "File:10: test: sample messa<extra arg>%ge\n");
140}
141
143TEST_F(LoggingFixture, DisabledPrint)
144{
145 class DisabledLogger : public Logger
146 {
147 public:
148 DisabledLogger(const char *prefix)
149 : Logger(prefix)
150 {
151 enabled = false;
152 }
153 } logger("test: ");
154
155 gtestLogOutput.str("");
156 logger.print(Logger::Loc("File", 10), "message");
157 ASSERT_EQ(gtestLogOutput.str(), "");
158}
159
161TEST_F(LoggingFixture, PrintWithExtraLogs)
162{
163 Logger logger("test: ");
164
165 logger.registerExtraLog([]() { return "Extra log 1\n"; });
166
167 gtestLogOutput.str("");
168 logger.print(Logger::Loc("File", 10), "message");
169 ASSERT_EQ(gtestLogOutput.str(), "File:10: test: message\nExtra log 1\n");
170
171 logger.registerExtraLog([]() { return "Extra log 2"; });
172 logger.registerExtraLog([]() { return "Extra log 3"; });
173
174 gtestLogOutput.str("");
175 logger.print(Logger::Loc("File", 10), "message");
176 ASSERT_EQ(
177 gtestLogOutput.str(),
178 "File:10: test: message\nExtra log 1\nExtra log 2\nExtra log 3\n");
179}
180
182TEST_F(LoggingFixture, WarnLoggerPrint)
183{
185 Logger &logger = Logger::getWarn();
186 gtestLogOutput.str("");
187 logger.print(Logger::Loc("File", 10), "message");
188 ASSERT_EQ(gtestLogOutput.str(), "File:10: warn: message\n");
189
190 // PANIC does not include WARN
192 gtestLogOutput.str("");
193 logger.print(Logger::Loc("File", 10), "message");
194 ASSERT_EQ(gtestLogOutput.str(), "");
195
197}
198
200TEST_F(LoggingFixture, InfoLoggerPrint)
201{
203 Logger &logger = Logger::getInfo();
204 gtestLogOutput.str("");
205 logger.print(Logger::Loc("File", 10), "message");
206 ASSERT_EQ(gtestLogOutput.str(), "File:10: info: message\n");
207
208 // PANIC does not include INFO
210 gtestLogOutput.str("");
211 logger.print(Logger::Loc("File", 10), "message");
212 ASSERT_EQ(gtestLogOutput.str(), "");
213
215}
216
218TEST_F(LoggingFixture, HackLoggerPrint)
219{
221 Logger &logger = Logger::getHack();
222 gtestLogOutput.str("");
223 logger.print(Logger::Loc("File", 10), "message");
224 ASSERT_EQ(gtestLogOutput.str(), "File:10: hack: message\n");
225
226 // PANIC does not include HACK
228 gtestLogOutput.str("");
229 logger.print(Logger::Loc("File", 10), "message");
230 ASSERT_EQ(gtestLogOutput.str(), "");
231
233}
234
236TEST_F(LoggingFixture, FatalLoggerPrint)
237{
238 Logger &logger = Logger::getFatal();
239
240 // The actual value of memory usage is not relevant
242 gtestLogOutput.str("");
243 logger.print(Logger::Loc("File", 10), "message");
244 ASSERT_THAT(gtestLogOutput.str(),
245 testing::HasSubstr("File:10: fatal: message\nMemory Usage:"));
246
247 // PANIC does not include FATAL
249 gtestLogOutput.str("");
250 logger.print(Logger::Loc("File", 10), "message");
251 ASSERT_EQ(gtestLogOutput.str(), "");
252
254}
255
257TEST_F(LoggingFixture, PanicLoggerPrint)
258{
259 // The actual value of memory usage is not relevant
261 Logger &logger = Logger::getPanic();
262 gtestLogOutput.str("");
263 logger.print(Logger::Loc("File", 10), "message");
264 ASSERT_THAT(gtestLogOutput.str(),
265 ::testing::HasSubstr("File:10: panic: message\nMemory Usage:"));
266
268}
269
272{
273 Logger logger("test: ");
274
275 // The logger will automatically add '\n' to the end of the message
276 // if it does not already have at least one.
277 gtestLogOutput.str("");
278 base_message(logger, "message");
279 ASSERT_THAT(gtestLogOutput.str(), ::testing::HasSubstr("test: message\n"));
280
281 gtestLogOutput.str("");
282 base_message(logger, "message\n");
283 ASSERT_THAT(gtestLogOutput.str(), ::testing::HasSubstr("test: message\n"));
284
285 gtestLogOutput.str("");
286 base_message(logger, "sample message\n\n");
287 ASSERT_THAT(gtestLogOutput.str(),
288 ::testing::HasSubstr("test: sample message\n\n"));
289
290 gtestLogOutput.str("");
291 base_message(logger, "sample message\nwith \n3 lines");
292 ASSERT_THAT(gtestLogOutput.str(),
293 ::testing::HasSubstr("test: sample message\nwith \n3 lines\n"));
294
295 gtestLogOutput.str("");
296 base_message(logger, "sample %s with %d arguments\n", "message", 2);
297 ASSERT_THAT(gtestLogOutput.str(),
298 ::testing::HasSubstr("test: sample message with 2 arguments\n"));
299}
300
302TEST_F(LoggingFixture, BaseMessageOnce)
303{
304 Logger logger("test: ");
305
306 for (int i = 0; i < 10; i++) {
307 gtestLogOutput.str("");
308 base_message_once(logger, "message\n");
309 if (i == 0) {
310 ASSERT_THAT(gtestLogOutput.str(),
311 ::testing::HasSubstr("test: message\n"));
312 } else {
313 ASSERT_EQ(gtestLogOutput.str(), "");
314 }
315 }
316}
317
320{
321 // The logger will automatically add '\n' to the end of the message
322 // if it does not already have at least one.
323 gtestLogOutput.str("");
324 warn("message");
325 ASSERT_THAT(gtestLogOutput.str(),
326 ::testing::HasSubstr("warn: message\n"));
327
328 gtestLogOutput.str("");
329 warn("message\n");
330 ASSERT_THAT(gtestLogOutput.str(),
331 ::testing::HasSubstr("warn: message\n"));
332
333 gtestLogOutput.str("");
334 warn("sample message\n\n");
335 ASSERT_THAT(gtestLogOutput.str(),
336 ::testing::HasSubstr("warn: sample message\n\n"));
337
338 gtestLogOutput.str("");
339 warn("sample message\nwith \n3 lines");
340 ASSERT_THAT(gtestLogOutput.str(),
341 ::testing::HasSubstr("warn: sample message\nwith \n3 lines\n"));
342
343 gtestLogOutput.str("");
344 warn("sample %s with %d arguments\n", "message", 2);
345 ASSERT_THAT(gtestLogOutput.str(),
346 ::testing::HasSubstr("warn: sample message with 2 arguments\n"));
347}
348
351{
352 // The logger will automatically add '\n' to the end of the message
353 // if it does not already have at least one.
354 gtestLogOutput.str("");
355 inform("message");
356 ASSERT_THAT(gtestLogOutput.str(),
357 ::testing::HasSubstr("info: message\n"));
358
359 gtestLogOutput.str("");
360 inform("message\n");
361 ASSERT_THAT(gtestLogOutput.str(),
362 ::testing::HasSubstr("info: message\n"));
363
364 gtestLogOutput.str("");
365 inform("sample message\n\n");
366 ASSERT_THAT(gtestLogOutput.str(),
367 ::testing::HasSubstr("info: sample message\n\n"));
368
369 gtestLogOutput.str("");
370 inform("sample message\nwith \n3 lines");
371 ASSERT_THAT(gtestLogOutput.str(),
372 ::testing::HasSubstr("info: sample message\nwith \n3 lines\n"));
373
374 gtestLogOutput.str("");
375 inform("sample %s with %d arguments\n", "message", 2);
376 ASSERT_THAT(gtestLogOutput.str(),
377 ::testing::HasSubstr("info: sample message with 2 arguments\n"));
378}
379
382{
383 // The logger will automatically add '\n' to the end of the message
384 // if it does not already have at least one.
385 gtestLogOutput.str("");
386 hack("message");
387 ASSERT_THAT(gtestLogOutput.str(),
388 ::testing::HasSubstr("hack: message\n"));
389
390 gtestLogOutput.str("");
391 hack("message\n");
392 ASSERT_THAT(gtestLogOutput.str(),
393 ::testing::HasSubstr("hack: message\n"));
394
395 gtestLogOutput.str("");
396 hack("sample message\n\n");
397 ASSERT_THAT(gtestLogOutput.str(),
398 ::testing::HasSubstr("hack: sample message\n\n"));
399
400 gtestLogOutput.str("");
401 hack("sample message\nwith \n3 lines");
402 ASSERT_THAT(gtestLogOutput.str(),
403 ::testing::HasSubstr("hack: sample message\nwith \n3 lines\n"));
404
405 gtestLogOutput.str("");
406 hack("sample %s with %d arguments\n", "message", 2);
407 ASSERT_THAT(gtestLogOutput.str(),
408 ::testing::HasSubstr("hack: sample message with 2 arguments\n"));
409}
410
413{
414 for (int i = 0; i < 10; i++) {
415 gtestLogOutput.str("");
416 warn_once("message\n");
417 if (i == 0) {
418 ASSERT_THAT(gtestLogOutput.str(),
419 ::testing::HasSubstr("warn: message\n"));
420 } else {
421 ASSERT_EQ(gtestLogOutput.str(), "");
422 }
423 }
424}
425
428{
429 for (int i = 0; i < 10; i++) {
430 gtestLogOutput.str("");
431 inform_once("message\n");
432 if (i == 0) {
433 ASSERT_THAT(gtestLogOutput.str(),
434 ::testing::HasSubstr("info: message\n"));
435 } else {
436 ASSERT_EQ(gtestLogOutput.str(), "");
437 }
438 }
439}
440
443{
444 for (int i = 0; i < 10; i++) {
445 gtestLogOutput.str("");
446 hack_once("message\n");
447 if (i == 0) {
448 ASSERT_THAT(gtestLogOutput.str(),
449 ::testing::HasSubstr("hack: message\n"));
450 } else {
451 ASSERT_EQ(gtestLogOutput.str(), "");
452 }
453 }
454}
455
458{
459 gtestLogOutput.str("");
460 warn_if(true, "message\n");
461 ASSERT_THAT(gtestLogOutput.str(),
462 ::testing::HasSubstr("warn: message\n"));
463
464 gtestLogOutput.str("");
465 warn_if(false, "message\n");
466 ASSERT_EQ(gtestLogOutput.str(), "");
467}
468
471{
472 for (int i = 0; i < 10; i++) {
473 gtestLogOutput.str("");
474 warn_if_once(i == 3, "message\n");
475 if (i == 3) {
476 ASSERT_THAT(gtestLogOutput.str(),
477 ::testing::HasSubstr("warn: message\n"));
478 } else {
479 ASSERT_EQ(gtestLogOutput.str(), "");
480 }
481 }
482}
483
485TEST(LoggingDeathTest, EmptyPrefix)
486{
487#ifdef NDEBUG
488 GTEST_SKIP() << "Skipping as assertions are "
489 "stripped out of fast builds";
490#endif
491 ASSERT_DEATH(Logger(nullptr), "");
492}
493
495TEST(LoggingDeathTest, ExitHelper)
496{
497 ASSERT_DEATH(Logger("test: ").exit_helper(), "");
498}
499
501TEST(LoggingDeathTest, WarnLoggerExitHelper)
502{
503 ASSERT_DEATH(Logger::getWarn().exit_helper(), "");
504}
505
507TEST(LoggingDeathTest, InfoLoggerExitHelper)
508{
509 ASSERT_DEATH(Logger::getInfo().exit_helper(), "");
510}
511
513TEST(LoggingDeathTest, HackLoggerExitHelper)
514{
515 ASSERT_DEATH(Logger::getHack().exit_helper(), "");
516}
517
519TEST(LoggingDeathTest, FatalLoggerExitHelper)
520{
521 ASSERT_DEATH(Logger::getFatal().exit_helper(), "");
522}
523
525TEST(LoggingDeathTest, PanicLoggerExitHelper)
526{
527 ASSERT_DEATH(Logger::getPanic().exit_helper(), "");
528}
529
531TEST(LoggingDeathTest, ExitMessage)
532{
533 Logger logger("test: ");
534 ASSERT_DEATH(exit_message(logger, "message\n"), "test: message\n");
535}
536
538TEST(LoggingDeathTest, Panic)
539{
540 ASSERT_DEATH(panic("message\n"),
541 ::testing::HasSubstr("panic: message\nMemory Usage:"));
542}
543
545TEST(LoggingDeathTest, Fatal)
546{
547 ASSERT_DEATH(fatal("message\n"),
548 ::testing::HasSubstr("fatal: message\nMemory Usage:"));
549}
550
552TEST(LoggingDeathTest, PanicIf)
553{
554 panic_if(false, "No death");
555 ASSERT_DEATH(panic_if(true, "message\n"), ::testing::HasSubstr(
556 "panic: panic condition true occurred: message\nMemory Usage:"));
557}
558
560TEST(LoggingDeathTest, FatalIf)
561{
562 fatal_if(false, "No death");
563 ASSERT_DEATH(fatal_if(true, "message\n"), ::testing::HasSubstr(
564 "fatal: fatal condition true occurred: message\nMemory Usage:"));
565}
566
568TEST(LoggingDeathTest, gem5Assert)
569{
570#ifdef NDEBUG
571 GTEST_SKIP() << "Skipping as assertions are "
572 "stripped out of fast builds";
573#endif
574 gem5_assert(true, "message\n");
575 ASSERT_DEATH(gem5_assert(false, "message\n"), ::testing::HasSubstr(
576 "panic: assert(false) failed: message\nMemory Usage:"));
577 ASSERT_DEATH(gem5_assert(false, "%s, %s!\n", "Hello", "World"),
578 ::testing::HasSubstr(
579 "panic: assert(false) failed: Hello, World!\nMemory Usage:"));
580 gem5_assert(true);
581 ASSERT_DEATH(gem5_assert(false), ::testing::HasSubstr(
582 "panic: assert(false) failed\nMemory Usage:"));
583}
Temporarily redirects cerr to gtestLogOutput.
void TearDown() override
void SetUp() override
std::streambuf * old
Used to restore cerr's streambuf.
static Logger & getWarn()
void registerExtraLog(std::function< std::string()> cb)
Register callback to generate extra log.
Definition logging.hh:131
Logger(const char *prefix)
Definition logging.hh:93
static Logger & getInfo()
static Logger & getHack()
void print(const Loc &loc, const char *format, const Args &...args)
Definition logging.hh:101
static Logger & getPanic()
Get a Logger for the specified type of message.
static Logger & getFatal()
static void setLevel(LogLevel ll)
Definition logging.hh:77
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
Definition logging.hh:349
#define warn_if_once(cond,...)
Definition logging.hh:322
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
#define hack_once(...)
Definition logging.hh:296
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:246
#define hack(...)
Definition logging.hh:290
#define warn(...)
Definition logging.hh:288
#define base_message_once(logger,...)
Definition logging.hh:186
#define exit_message(logger,...)
Definition logging.hh:202
#define base_message(logger,...)
Definition logging.hh:173
#define warn_once(...)
Definition logging.hh:292
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition logging.hh:315
#define inform(...)
Definition logging.hh:289
#define inform_once(...)
Definition logging.hh:294
TEST_F(LoggingFixture, BasicPrint)
Test the most basic print.
TEST(LoggingDeathTest, EmptyPrefix)
Test that a logger cannot be created with an empty prefix.
Bitfield< 7 > i
Definition misc_types.hh:67
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
thread_local GTestLogOutput gtestLogOutput
Definition logging.cc:33

Generated on Mon May 26 2025 09:19:07 for gem5 by doxygen 1.13.2