gem5 v24.0.0.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, WarnLoggerPrint)
162{
164 Logger &logger = Logger::getWarn();
165 gtestLogOutput.str("");
166 logger.print(Logger::Loc("File", 10), "message");
167 ASSERT_EQ(gtestLogOutput.str(), "File:10: warn: message\n");
168
169 // PANIC does not include WARN
171 gtestLogOutput.str("");
172 logger.print(Logger::Loc("File", 10), "message");
173 ASSERT_EQ(gtestLogOutput.str(), "");
174
176}
177
179TEST_F(LoggingFixture, InfoLoggerPrint)
180{
182 Logger &logger = Logger::getInfo();
183 gtestLogOutput.str("");
184 logger.print(Logger::Loc("File", 10), "message");
185 ASSERT_EQ(gtestLogOutput.str(), "File:10: info: message\n");
186
187 // PANIC does not include INFO
189 gtestLogOutput.str("");
190 logger.print(Logger::Loc("File", 10), "message");
191 ASSERT_EQ(gtestLogOutput.str(), "");
192
194}
195
197TEST_F(LoggingFixture, HackLoggerPrint)
198{
200 Logger &logger = Logger::getHack();
201 gtestLogOutput.str("");
202 logger.print(Logger::Loc("File", 10), "message");
203 ASSERT_EQ(gtestLogOutput.str(), "File:10: hack: message\n");
204
205 // PANIC does not include HACK
207 gtestLogOutput.str("");
208 logger.print(Logger::Loc("File", 10), "message");
209 ASSERT_EQ(gtestLogOutput.str(), "");
210
212}
213
215TEST_F(LoggingFixture, FatalLoggerPrint)
216{
217 Logger &logger = Logger::getFatal();
218
219 // The actual value of memory usage is not relevant
221 gtestLogOutput.str("");
222 logger.print(Logger::Loc("File", 10), "message");
223 ASSERT_THAT(gtestLogOutput.str(),
224 testing::HasSubstr("File:10: fatal: message\nMemory Usage:"));
225
226 // PANIC does not include FATAL
228 gtestLogOutput.str("");
229 logger.print(Logger::Loc("File", 10), "message");
230 ASSERT_EQ(gtestLogOutput.str(), "");
231
233}
234
236TEST_F(LoggingFixture, PanicLoggerPrint)
237{
238 // The actual value of memory usage is not relevant
240 Logger &logger = Logger::getPanic();
241 gtestLogOutput.str("");
242 logger.print(Logger::Loc("File", 10), "message");
243 ASSERT_THAT(gtestLogOutput.str(),
244 ::testing::HasSubstr("File:10: panic: message\nMemory Usage:"));
245
247}
248
251{
252 Logger logger("test: ");
253
254 // The logger will automatically add '\n' to the end of the message
255 // if it does not already have at least one.
256 gtestLogOutput.str("");
257 base_message(logger, "message");
258 ASSERT_THAT(gtestLogOutput.str(), ::testing::HasSubstr("test: message\n"));
259
260 gtestLogOutput.str("");
261 base_message(logger, "message\n");
262 ASSERT_THAT(gtestLogOutput.str(), ::testing::HasSubstr("test: message\n"));
263
264 gtestLogOutput.str("");
265 base_message(logger, "sample message\n\n");
266 ASSERT_THAT(gtestLogOutput.str(),
267 ::testing::HasSubstr("test: sample message\n\n"));
268
269 gtestLogOutput.str("");
270 base_message(logger, "sample message\nwith \n3 lines");
271 ASSERT_THAT(gtestLogOutput.str(),
272 ::testing::HasSubstr("test: sample message\nwith \n3 lines\n"));
273
274 gtestLogOutput.str("");
275 base_message(logger, "sample %s with %d arguments\n", "message", 2);
276 ASSERT_THAT(gtestLogOutput.str(),
277 ::testing::HasSubstr("test: sample message with 2 arguments\n"));
278}
279
281TEST_F(LoggingFixture, BaseMessageOnce)
282{
283 Logger logger("test: ");
284
285 for (int i = 0; i < 10; i++) {
286 gtestLogOutput.str("");
287 base_message_once(logger, "message\n");
288 if (i == 0) {
289 ASSERT_THAT(gtestLogOutput.str(),
290 ::testing::HasSubstr("test: message\n"));
291 } else {
292 ASSERT_EQ(gtestLogOutput.str(), "");
293 }
294 }
295}
296
299{
300 // The logger will automatically add '\n' to the end of the message
301 // if it does not already have at least one.
302 gtestLogOutput.str("");
303 warn("message");
304 ASSERT_THAT(gtestLogOutput.str(),
305 ::testing::HasSubstr("warn: message\n"));
306
307 gtestLogOutput.str("");
308 warn("message\n");
309 ASSERT_THAT(gtestLogOutput.str(),
310 ::testing::HasSubstr("warn: message\n"));
311
312 gtestLogOutput.str("");
313 warn("sample message\n\n");
314 ASSERT_THAT(gtestLogOutput.str(),
315 ::testing::HasSubstr("warn: sample message\n\n"));
316
317 gtestLogOutput.str("");
318 warn("sample message\nwith \n3 lines");
319 ASSERT_THAT(gtestLogOutput.str(),
320 ::testing::HasSubstr("warn: sample message\nwith \n3 lines\n"));
321
322 gtestLogOutput.str("");
323 warn("sample %s with %d arguments\n", "message", 2);
324 ASSERT_THAT(gtestLogOutput.str(),
325 ::testing::HasSubstr("warn: sample message with 2 arguments\n"));
326}
327
330{
331 // The logger will automatically add '\n' to the end of the message
332 // if it does not already have at least one.
333 gtestLogOutput.str("");
334 inform("message");
335 ASSERT_THAT(gtestLogOutput.str(),
336 ::testing::HasSubstr("info: message\n"));
337
338 gtestLogOutput.str("");
339 inform("message\n");
340 ASSERT_THAT(gtestLogOutput.str(),
341 ::testing::HasSubstr("info: message\n"));
342
343 gtestLogOutput.str("");
344 inform("sample message\n\n");
345 ASSERT_THAT(gtestLogOutput.str(),
346 ::testing::HasSubstr("info: sample message\n\n"));
347
348 gtestLogOutput.str("");
349 inform("sample message\nwith \n3 lines");
350 ASSERT_THAT(gtestLogOutput.str(),
351 ::testing::HasSubstr("info: sample message\nwith \n3 lines\n"));
352
353 gtestLogOutput.str("");
354 inform("sample %s with %d arguments\n", "message", 2);
355 ASSERT_THAT(gtestLogOutput.str(),
356 ::testing::HasSubstr("info: sample message with 2 arguments\n"));
357}
358
361{
362 // The logger will automatically add '\n' to the end of the message
363 // if it does not already have at least one.
364 gtestLogOutput.str("");
365 hack("message");
366 ASSERT_THAT(gtestLogOutput.str(),
367 ::testing::HasSubstr("hack: message\n"));
368
369 gtestLogOutput.str("");
370 hack("message\n");
371 ASSERT_THAT(gtestLogOutput.str(),
372 ::testing::HasSubstr("hack: message\n"));
373
374 gtestLogOutput.str("");
375 hack("sample message\n\n");
376 ASSERT_THAT(gtestLogOutput.str(),
377 ::testing::HasSubstr("hack: sample message\n\n"));
378
379 gtestLogOutput.str("");
380 hack("sample message\nwith \n3 lines");
381 ASSERT_THAT(gtestLogOutput.str(),
382 ::testing::HasSubstr("hack: sample message\nwith \n3 lines\n"));
383
384 gtestLogOutput.str("");
385 hack("sample %s with %d arguments\n", "message", 2);
386 ASSERT_THAT(gtestLogOutput.str(),
387 ::testing::HasSubstr("hack: sample message with 2 arguments\n"));
388}
389
392{
393 for (int i = 0; i < 10; i++) {
394 gtestLogOutput.str("");
395 warn_once("message\n");
396 if (i == 0) {
397 ASSERT_THAT(gtestLogOutput.str(),
398 ::testing::HasSubstr("warn: message\n"));
399 } else {
400 ASSERT_EQ(gtestLogOutput.str(), "");
401 }
402 }
403}
404
407{
408 for (int i = 0; i < 10; i++) {
409 gtestLogOutput.str("");
410 inform_once("message\n");
411 if (i == 0) {
412 ASSERT_THAT(gtestLogOutput.str(),
413 ::testing::HasSubstr("info: message\n"));
414 } else {
415 ASSERT_EQ(gtestLogOutput.str(), "");
416 }
417 }
418}
419
422{
423 for (int i = 0; i < 10; i++) {
424 gtestLogOutput.str("");
425 hack_once("message\n");
426 if (i == 0) {
427 ASSERT_THAT(gtestLogOutput.str(),
428 ::testing::HasSubstr("hack: message\n"));
429 } else {
430 ASSERT_EQ(gtestLogOutput.str(), "");
431 }
432 }
433}
434
437{
438 gtestLogOutput.str("");
439 warn_if(true, "message\n");
440 ASSERT_THAT(gtestLogOutput.str(),
441 ::testing::HasSubstr("warn: message\n"));
442
443 gtestLogOutput.str("");
444 warn_if(false, "message\n");
445 ASSERT_EQ(gtestLogOutput.str(), "");
446}
447
450{
451 for (int i = 0; i < 10; i++) {
452 gtestLogOutput.str("");
453 warn_if_once(i == 3, "message\n");
454 if (i == 3) {
455 ASSERT_THAT(gtestLogOutput.str(),
456 ::testing::HasSubstr("warn: message\n"));
457 } else {
458 ASSERT_EQ(gtestLogOutput.str(), "");
459 }
460 }
461}
462
464TEST(LoggingDeathTest, EmptyPrefix)
465{
466#ifdef NDEBUG
467 GTEST_SKIP() << "Skipping as assertions are "
468 "stripped out of fast builds";
469#endif
470 ASSERT_DEATH(Logger(nullptr), "");
471}
472
474TEST(LoggingDeathTest, ExitHelper)
475{
476 ASSERT_DEATH(Logger("test: ").exit_helper(), "");
477}
478
480TEST(LoggingDeathTest, WarnLoggerExitHelper)
481{
482 ASSERT_DEATH(Logger::getWarn().exit_helper(), "");
483}
484
486TEST(LoggingDeathTest, InfoLoggerExitHelper)
487{
488 ASSERT_DEATH(Logger::getInfo().exit_helper(), "");
489}
490
492TEST(LoggingDeathTest, HackLoggerExitHelper)
493{
494 ASSERT_DEATH(Logger::getHack().exit_helper(), "");
495}
496
498TEST(LoggingDeathTest, FatalLoggerExitHelper)
499{
500 ASSERT_DEATH(Logger::getFatal().exit_helper(), "");
501}
502
504TEST(LoggingDeathTest, PanicLoggerExitHelper)
505{
506 ASSERT_DEATH(Logger::getPanic().exit_helper(), "");
507}
508
510TEST(LoggingDeathTest, ExitMessage)
511{
512 Logger logger("test: ");
513 ASSERT_DEATH(exit_message(logger, "message\n"), "test: message\n");
514}
515
517TEST(LoggingDeathTest, Panic)
518{
519 ASSERT_DEATH(panic("message\n"),
520 ::testing::HasSubstr("panic: message\nMemory Usage:"));
521}
522
524TEST(LoggingDeathTest, Fatal)
525{
526 ASSERT_DEATH(fatal("message\n"),
527 ::testing::HasSubstr("fatal: message\nMemory Usage:"));
528}
529
531TEST(LoggingDeathTest, PanicIf)
532{
533 panic_if(false, "No death");
534 ASSERT_DEATH(panic_if(true, "message\n"), ::testing::HasSubstr(
535 "panic: panic condition true occurred: message\nMemory Usage:"));
536}
537
539TEST(LoggingDeathTest, FatalIf)
540{
541 fatal_if(false, "No death");
542 ASSERT_DEATH(fatal_if(true, "message\n"), ::testing::HasSubstr(
543 "fatal: fatal condition true occurred: message\nMemory Usage:"));
544}
545
547TEST(LoggingDeathTest, gem5Assert)
548{
549#ifdef NDEBUG
550 GTEST_SKIP() << "Skipping as assertions are "
551 "stripped out of fast builds";
552#endif
553 gem5_assert(true, "message\n");
554 ASSERT_DEATH(gem5_assert(false, "message\n"), ::testing::HasSubstr(
555 "panic: assert(false) failed: message\nMemory Usage:"));
556 ASSERT_DEATH(gem5_assert(false, "%s, %s!\n", "Hello", "World"),
557 ::testing::HasSubstr(
558 "panic: assert(false) failed: Hello, World!\nMemory Usage:"));
559 gem5_assert(true);
560 ASSERT_DEATH(gem5_assert(false), ::testing::HasSubstr(
561 "panic: assert(false) failed\nMemory Usage:"));
562}
Temporarily redirects cerr to gtestLogOutput.
void TearDown() override
void SetUp() override
std::streambuf * old
Used to restore cerr's streambuf.
static Logger & getWarn()
Logger(const char *prefix)
Definition logging.hh:90
static Logger & getInfo()
static Logger & getHack()
void print(const Loc &loc, const char *format, const Args &...args)
Definition logging.hh:98
static Logger & getPanic()
Get a Logger for the specified type of message.
static Logger & getFatal()
static void setLevel(LogLevel ll)
Definition logging.hh:74
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define gem5_assert(cond,...)
The assert macro will function like a normal assert, but will use panic instead of straight abort().
Definition logging.hh:317
#define warn_if_once(cond,...)
Definition logging.hh:290
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define hack_once(...)
Definition logging.hh:264
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition logging.hh:214
#define hack(...)
Definition logging.hh:258
#define warn(...)
Definition logging.hh:256
#define base_message_once(logger,...)
Definition logging.hh:154
#define exit_message(logger,...)
Definition logging.hh:170
#define base_message(logger,...)
Definition logging.hh:141
#define warn_once(...)
Definition logging.hh:260
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition logging.hh:283
#define inform(...)
Definition logging.hh:257
#define inform_once(...)
Definition logging.hh:262
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 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
thread_local GTestLogOutput gtestLogOutput
Definition logging.cc:33

Generated on Tue Jun 18 2024 16:24:00 for gem5 by doxygen 1.11.0