logger.cpp 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * Copyright (C) 2014 Pavel Kirienko <pavel.kirienko@gmail.com>
  3. */
  4. #include <gtest/gtest.h>
  5. #include <uavcan/protocol/logger.hpp>
  6. #include "helpers.hpp"
  7. struct LogSink : public uavcan::ILogSink
  8. {
  9. std::queue<uavcan::protocol::debug::LogMessage> msgs;
  10. LogLevel level;
  11. LogSink()
  12. : level(uavcan::protocol::debug::LogLevel::ERROR)
  13. { }
  14. LogLevel getLogLevel() const { return level; }
  15. void log(const uavcan::protocol::debug::LogMessage& message)
  16. {
  17. msgs.push(message);
  18. std::cout << message << std::endl;
  19. }
  20. uavcan::protocol::debug::LogMessage pop()
  21. {
  22. if (msgs.empty())
  23. {
  24. std::cout << "LogSink is empty" << std::endl;
  25. std::abort();
  26. }
  27. const uavcan::protocol::debug::LogMessage m = msgs.front();
  28. msgs.pop();
  29. return m;
  30. }
  31. bool popMatchByLevelAndText(int level, const std::string& source, const std::string& text)
  32. {
  33. if (msgs.empty())
  34. {
  35. std::cout << "LogSink is empty" << std::endl;
  36. return false;
  37. }
  38. const uavcan::protocol::debug::LogMessage m = pop();
  39. return
  40. level == m.level.value &&
  41. source == m.source &&
  42. text == m.text;
  43. }
  44. };
  45. TEST(Logger, Basic)
  46. {
  47. InterlinkedTestNodesWithSysClock nodes;
  48. uavcan::Logger logger(nodes.a);
  49. ASSERT_EQ(uavcan::protocol::debug::LogLevel::ERROR, logger.getLevel());
  50. LogSink sink;
  51. // Will fail - types are not registered
  52. uavcan::GlobalDataTypeRegistry::instance().reset();
  53. ASSERT_GT(0, logger.logError("foo", "Error (fail - type is not registered)"));
  54. ASSERT_EQ(0, logger.logDebug("foo", "Debug (ignored - low logging level)"));
  55. ASSERT_FALSE(logger.getExternalSink());
  56. logger.setExternalSink(&sink);
  57. ASSERT_EQ(&sink, logger.getExternalSink());
  58. uavcan::GlobalDataTypeRegistry::instance().reset();
  59. uavcan::DefaultDataTypeRegistrator<uavcan::protocol::debug::LogMessage> _reg1;
  60. SubscriberWithCollector<uavcan::protocol::debug::LogMessage> log_sub(nodes.b);
  61. ASSERT_LE(0, log_sub.start());
  62. // Sink test
  63. ASSERT_EQ(0, logger.logDebug("foo", "Debug (ignored due to low logging level)"));
  64. ASSERT_TRUE(sink.msgs.empty());
  65. sink.level = uavcan::protocol::debug::LogLevel::DEBUG;
  66. ASSERT_EQ(0, logger.logDebug("foo", "Debug (sink only)"));
  67. ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::DEBUG, "foo", "Debug (sink only)"));
  68. ASSERT_LE(0, logger.logError("foo", "Error"));
  69. nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
  70. ASSERT_TRUE(log_sub.collector.msg.get());
  71. ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::ERROR);
  72. ASSERT_EQ(log_sub.collector.msg->source, "foo");
  73. ASSERT_EQ(log_sub.collector.msg->text, "Error");
  74. logger.setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
  75. ASSERT_LE(0, logger.logWarning("foo", "Warning"));
  76. nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
  77. ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::WARNING);
  78. ASSERT_EQ(log_sub.collector.msg->source, "foo");
  79. ASSERT_EQ(log_sub.collector.msg->text, "Warning");
  80. ASSERT_LE(0, logger.logInfo("foo", "Info"));
  81. nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
  82. ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::INFO);
  83. ASSERT_EQ(log_sub.collector.msg->source, "foo");
  84. ASSERT_EQ(log_sub.collector.msg->text, "Info");
  85. ASSERT_LE(0, logger.logDebug("foo", "Debug"));
  86. nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
  87. ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::DEBUG);
  88. ASSERT_EQ(log_sub.collector.msg->source, "foo");
  89. ASSERT_EQ(log_sub.collector.msg->text, "Debug");
  90. ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::ERROR, "foo", "Error"));
  91. ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::WARNING, "foo", "Warning"));
  92. ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::INFO, "foo", "Info"));
  93. ASSERT_TRUE(sink.popMatchByLevelAndText(uavcan::protocol::debug::LogLevel::DEBUG, "foo", "Debug"));
  94. }
  95. #if !defined(UAVCAN_CPP_VERSION) || !defined(UAVCAN_CPP11)
  96. # error UAVCAN_CPP_VERSION
  97. #endif
  98. #if UAVCAN_CPP_VERSION >= UAVCAN_CPP11
  99. TEST(Logger, Cpp11Formatting)
  100. {
  101. InterlinkedTestNodesWithSysClock nodes;
  102. uavcan::Logger logger(nodes.a);
  103. logger.setLevel(uavcan::protocol::debug::LogLevel::DEBUG);
  104. SubscriberWithCollector<uavcan::protocol::debug::LogMessage> log_sub(nodes.b);
  105. ASSERT_LE(0, log_sub.start());
  106. ASSERT_LE(0, logger.logWarning("foo", "char='%*', %* is %*", '$', "double", 12.34));
  107. nodes.spinBoth(uavcan::MonotonicDuration::fromMSec(10));
  108. ASSERT_TRUE(log_sub.collector.msg.get());
  109. ASSERT_EQ(log_sub.collector.msg->level.value, uavcan::protocol::debug::LogLevel::WARNING);
  110. ASSERT_EQ(log_sub.collector.msg->source, "foo");
  111. ASSERT_EQ(log_sub.collector.msg->text, "char='$', double is 12.34");
  112. }
  113. #endif