gem5  v21.1.0.2
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 
35 using namespace gem5;
36 
38 class 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 
50 TEST_F(LoggingFixture, BasicPrint)
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 
78 TEST_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 
95 TEST_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 
111 TEST_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 
127 TEST_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 
143 TEST_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 
161 TEST_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 
179 TEST_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 
197 TEST_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 
215 TEST_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 
236 TEST_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 
250 TEST_F(LoggingFixture, BaseMessage)
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 
281 TEST_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 
406 TEST_F(LoggingFixture, InformOnce)
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 
449 TEST_F(LoggingFixture, WarnIfOnce)
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 
464 TEST(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 
474 TEST(LoggingDeathTest, ExitHelper)
475 {
476  ASSERT_DEATH(Logger("test: ").exit_helper(), "");
477 }
478 
480 TEST(LoggingDeathTest, WarnLoggerExitHelper)
481 {
482  ASSERT_DEATH(Logger::getWarn().exit_helper(), "");
483 }
484 
486 TEST(LoggingDeathTest, InfoLoggerExitHelper)
487 {
488  ASSERT_DEATH(Logger::getInfo().exit_helper(), "");
489 }
490 
492 TEST(LoggingDeathTest, HackLoggerExitHelper)
493 {
494  ASSERT_DEATH(Logger::getHack().exit_helper(), "");
495 }
496 
498 TEST(LoggingDeathTest, FatalLoggerExitHelper)
499 {
500  ASSERT_DEATH(Logger::getFatal().exit_helper(), "");
501 }
502 
504 TEST(LoggingDeathTest, PanicLoggerExitHelper)
505 {
506  ASSERT_DEATH(Logger::getPanic().exit_helper(), "");
507 }
508 
510 TEST(LoggingDeathTest, ExitMessage)
511 {
512  Logger logger("test: ");
513  ASSERT_DEATH(exit_message(logger, "message\n"), "test: message\n");
514 }
515 
517 TEST(LoggingDeathTest, Panic)
518 {
519  ASSERT_DEATH(panic("message\n"),
520  ::testing::HasSubstr("panic: message\nMemory Usage:"));
521 }
522 
524 TEST(LoggingDeathTest, Fatal)
525 {
526  ASSERT_DEATH(fatal("message\n"),
527  ::testing::HasSubstr("fatal: message\nMemory Usage:"));
528 }
529 
531 TEST(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 
539 TEST(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 
547 TEST(LoggingDeathTest, ChattyAssert)
548 {
549 #ifdef NDEBUG
550  GTEST_SKIP() << "Skipping as assertions are "
551  "stripped out of fast builds";
552 #endif
553  chatty_assert(true, "message\n");
554  ASSERT_DEATH(chatty_assert(false, "message\n"), ::testing::HasSubstr(
555  "panic: assert(false) failed: message\nMemory Usage:"));
556 }
gem5::Logger::NUM_LOG_LEVELS
@ NUM_LOG_LEVELS
Definition: logging.hh:70
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::Logger
Definition: logging.hh:54
gem5::Logger::getPanic
static Logger & getPanic()
Get a Logger for the specified type of message.
Definition: logging_mock.cc:86
warn
#define warn(...)
Definition: logging.hh:245
hack_once
#define hack_once(...)
Definition: logging.hh:253
gem5::Logger::PANIC
@ PANIC
Definition: logging.hh:69
base_message_once
#define base_message_once(...)
Definition: logging.hh:153
warn_once
#define warn_once(...)
Definition: logging.hh:249
TEST
TEST(LoggingDeathTest, EmptyPrefix)
Test that a logger cannot be created with an empty prefix.
Definition: logging.test.cc:464
logging.hh
inform_once
#define inform_once(...)
Definition: logging.hh:251
warn_if_once
#define warn_if_once(cond,...)
Definition: logging.hh:278
LoggingFixture
Temporarily redirects cerr to gtestLogOutput.
Definition: logging.test.cc:38
gem5::Logger::getHack
static Logger & getHack()
Definition: logging_mock.cc:110
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
hack
#define hack(...)
Definition: logging.hh:247
gem5::Logger::INFO
@ INFO
Definition: logging.hh:69
base_message
#define base_message(logger,...)
Definition: logging.hh:142
gem5::Logger::getInfo
static Logger & getInfo()
Definition: logging_mock.cc:104
LoggingFixture::old
std::streambuf * old
Used to restore cerr's streambuf.
Definition: logging.test.cc:46
gem5::Logger::Loc
Definition: logging.hh:83
chatty_assert
#define chatty_assert(cond,...)
The chatty assert macro will function like a normal assert, but will allow the specification of addit...
Definition: logging.hh:301
gem5::Logger::getFatal
static Logger & getFatal()
Definition: logging_mock.cc:92
gem5::Logger::HACK
@ HACK
Definition: logging.hh:69
gem5::Logger::getWarn
static Logger & getWarn()
Definition: logging_mock.cc:98
TEST_F
TEST_F(LoggingFixture, BasicPrint)
Test the most basic print.
Definition: logging.test.cc:50
gem5::statistics::enabled
bool enabled()
Definition: statistics.cc:280
LoggingFixture::SetUp
void SetUp() override
Definition: logging.test.cc:41
warn_if
#define warn_if(cond,...)
Conditional warning macro that checks the supplied condition and only prints a warning if the conditi...
Definition: logging.hh:272
panic_if
#define panic_if(cond,...)
Conditional panic macro that checks the supplied condition and only panics if the condition is true a...
Definition: logging.hh:203
inform
#define inform(...)
Definition: logging.hh:246
gem5::Logger::FATAL
@ FATAL
Definition: logging.hh:69
exit_message
#define exit_message(logger,...)
Definition: logging.hh:161
logging.hh
gem5::Logger::setLevel
static void setLevel(LogLevel ll)
Definition: logging.hh:74
gem5::gtestLogOutput
thread_local GTestLogOutput gtestLogOutput
Definition: logging.cc:33
gem5::Logger::WARN
@ WARN
Definition: logging.hh:69
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:225
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
LoggingFixture::TearDown
void TearDown() override
Definition: logging.test.cc:42
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::Logger::print
void print(const Loc &loc, const char *format, const Args &...args)
Definition: logging.hh:98

Generated on Tue Sep 21 2021 12:24:57 for gem5 by doxygen 1.8.17