| /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */ |
| /** |
| * Copyright (c) 2014 Regents of the University of California, |
| * Arizona Board of Regents, |
| * Colorado State University, |
| * University Pierre & Marie Curie, Sorbonne University, |
| * Washington University in St. Louis, |
| * Beijing Institute of Technology |
| * |
| * This file is part of NFD (Named Data Networking Forwarding Daemon). |
| * See AUTHORS.md for complete list of NFD authors and contributors. |
| * |
| * NFD is free software: you can redistribute it and/or modify it under the terms |
| * of the GNU General Public License as published by the Free Software Foundation, |
| * either version 3 of the License, or (at your option) any later version. |
| * |
| * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
| * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
| * PURPOSE. See the GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License along with |
| * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>. |
| **/ |
| |
| #include "core/logger.hpp" |
| |
| #include "tests/test-common.hpp" |
| |
| #include <boost/algorithm/string.hpp> |
| #include <boost/algorithm/string/classification.hpp> |
| |
| namespace nfd { |
| namespace tests { |
| |
| BOOST_FIXTURE_TEST_SUITE(CoreLogger, BaseFixture) |
| |
| class LoggerFixture : protected BaseFixture |
| { |
| public: |
| LoggerFixture() |
| : m_savedBuf(std::clog.rdbuf()) |
| , m_savedLevel(LoggerFactory::getInstance().getDefaultLevel()) |
| { |
| std::clog.rdbuf(m_buffer.rdbuf()); |
| } |
| |
| ~LoggerFixture() |
| { |
| std::clog.rdbuf(m_savedBuf); |
| LoggerFactory::getInstance().setDefaultLevel(m_savedLevel); |
| } |
| |
| std::stringstream m_buffer; |
| std::streambuf* m_savedBuf; |
| LogLevel m_savedLevel; |
| |
| }; |
| |
| BOOST_FIXTURE_TEST_CASE(Basic, LoggerFixture) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| NFD_LOG_INIT("BasicTests"); |
| g_logger.setLogLevel(LOG_ALL); |
| |
| const string EXPECTED[] = |
| { |
| "TRACE:", "[BasicTests]", "trace-message-JHGFDSR^1\n", |
| "DEBUG:", "[BasicTests]", "debug-message-IGg2474fdksd-fo-151617\n", |
| "WARNING:", "[BasicTests]", "warning-message-XXXhdhd111x\n", |
| "INFO:", "[BasicTests]", "info-message-Jjxjshj13\n", |
| "ERROR:", "[BasicTests]", "error-message-!#$&^%$#@\n", |
| "FATAL:", "[BasicTests]", "fatal-message-JJSjaamcng\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string); |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| NFD_LOG_TRACE("trace-message-JHGFDSR^1"); |
| NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17); |
| NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x"); |
| NFD_LOG_INFO("info-message-Jjxjshj13"); |
| NFD_LOG_ERROR("error-message-!#$&^%$#@"); |
| NFD_LOG_FATAL("fatal-message-JJSjaamcng"); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // std::cout << components.size() << " for " << moduleName << std::endl; |
| // for (size_t i = 0; i < components.size(); ++i) |
| // { |
| // std::cout << "-> " << components[i] << std::endl; |
| // } |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| |
| } |
| |
| |
| BOOST_FIXTURE_TEST_CASE(ConfigureFactory, LoggerFixture) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| NFD_LOG_INIT("ConfigureFactoryTests"); |
| |
| const string LOG_CONFIG = |
| "log\n" |
| "{\n" |
| " default_level INFO\n" |
| "}\n"; |
| |
| LoggerFactory::getInstance().setDefaultLevel(LOG_ALL); |
| |
| ConfigFile config; |
| LoggerFactory::getInstance().setConfigFile(config); |
| |
| config.parse(LOG_CONFIG, false, "LOG_CONFIG"); |
| |
| BOOST_REQUIRE_EQUAL(LoggerFactory::getInstance().getDefaultLevel(), LOG_INFO); |
| |
| const std::string EXPECTED[] = |
| { |
| "WARNING:", "[ConfigureFactoryTests]", "warning-message-XXXhdhd111x\n", |
| "INFO:", "[ConfigureFactoryTests]", "info-message-Jjxjshj13\n", |
| "ERROR:", "[ConfigureFactoryTests]", "error-message-!#$&^%$#@\n", |
| "FATAL:", "[ConfigureFactoryTests]", "fatal-message-JJSjaamcng\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(std::string); |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| NFD_LOG_TRACE("trace-message-JHGFDSR^1"); |
| NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17); |
| NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x"); |
| NFD_LOG_INFO("info-message-Jjxjshj13"); |
| NFD_LOG_ERROR("error-message-!#$&^%$#@"); |
| NFD_LOG_FATAL("fatal-message-JJSjaamcng"); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // std::cout << components.size() << " for " << moduleName << std::endl; |
| // for (size_t i = 0; i < components.size(); ++i) |
| // { |
| // std::cout << "-> " << components[i] << std::endl; |
| // } |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 4 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(TestNumberLevel, LoggerFixture) |
| { |
| const std::string LOG_CONFIG = |
| "log\n" |
| "{\n" |
| " default_level 2\n" // equivalent of WARN |
| "}\n"; |
| |
| LoggerFactory::getInstance().setDefaultLevel(LOG_ALL); |
| |
| ConfigFile config; |
| LoggerFactory::getInstance().setConfigFile(config); |
| |
| config.parse(LOG_CONFIG, false, "LOG_CONFIG"); |
| |
| BOOST_REQUIRE_EQUAL(LoggerFactory::getInstance().getDefaultLevel(), LOG_WARN); |
| } |
| |
| static void |
| testModuleBPrint() |
| { |
| NFD_LOG_INIT("TestModuleB"); |
| NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17); |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(LimitModules, LoggerFixture) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| NFD_LOG_INIT("TestModuleA"); |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| const std::string EXPECTED[] = |
| { |
| "WARNING:", "[TestModuleA]", "warning-message-XXXhdhd111x\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(std::string); |
| |
| const std::string LOG_CONFIG = |
| "log\n" |
| "{\n" |
| " default_level WARN\n" |
| "}\n"; |
| |
| ConfigFile config; |
| LoggerFactory::getInstance().setConfigFile(config); |
| |
| config.parse(LOG_CONFIG, false, "LOG_CONFIG"); |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| // this should print |
| NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 << "x"); |
| |
| // this should not because it's level is < WARN |
| testModuleBPrint(); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 1 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(ExplicitlySetModule, LoggerFixture) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| NFD_LOG_INIT("TestModuleA"); |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| const std::string LOG_CONFIG = |
| "log\n" |
| "{\n" |
| " default_level WARN\n" |
| " TestModuleB DEBUG\n" |
| "}\n"; |
| |
| ConfigFile config; |
| LoggerFactory::getInstance().setConfigFile(config); |
| |
| config.parse(LOG_CONFIG, false, "LOG_CONFIG"); |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| // this should print |
| NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 << "x"); |
| |
| // this too because its level is explicitly set to DEBUG |
| testModuleBPrint(); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const std::string EXPECTED[] = |
| { |
| "WARNING:", "[TestModuleA]", "warning-message-XXXhdhd111x\n", |
| "DEBUG:", "[TestModuleB]", "debug-message-IGg2474fdksd-fo-151617\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(std::string); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // for (size_t i = 0; i < components.size(); ++i) |
| // { |
| // std::cout << "-> " << components[i] << std::endl; |
| // } |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 2 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnknownModule, LoggerFixture) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| const std::string LOG_CONFIG = |
| "log\n" |
| "{\n" |
| " default_level DEBUG\n" |
| " TestMadeUpModule INFO\n" |
| "}\n"; |
| |
| ConfigFile config; |
| LoggerFactory::getInstance().setDefaultLevel(LOG_ALL); |
| LoggerFactory::getInstance().setConfigFile(config); |
| |
| const std::string EXPECTED = "DEBUG: [LoggerFactory] " |
| "Failed to configure logging level for module \"TestMadeUpModule\" (module not found)\n"; |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| config.parse(LOG_CONFIG, false, "LOG_CONFIG"); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string buffer = m_buffer.str(); |
| |
| const size_t firstSpace = buffer.find(" "); |
| BOOST_REQUIRE(firstSpace != string::npos); |
| |
| const string timestamp = buffer.substr(0, firstSpace); |
| const string message = buffer.substr(firstSpace + 1); |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| BOOST_CHECK_EQUAL(message, EXPECTED); |
| } |
| |
| static bool |
| checkError(const LoggerFactory::Error& error, const std::string& expected) |
| { |
| return error.what() == expected; |
| } |
| |
| BOOST_FIXTURE_TEST_CASE(UnknownLevelString, LoggerFixture) |
| { |
| const std::string LOG_CONFIG = |
| "log\n" |
| "{\n" |
| " default_level TestMadeUpLevel\n" |
| "}\n"; |
| |
| ConfigFile config; |
| LoggerFactory::getInstance().setConfigFile(config); |
| |
| BOOST_REQUIRE_EXCEPTION(config.parse(LOG_CONFIG, false, "LOG_CONFIG"), |
| LoggerFactory::Error, |
| bind(&checkError, |
| _1, |
| "Unsupported logging level \"TestMadeUpLevel\"")); |
| } |
| |
| class InClassLogger : public LoggerFixture |
| { |
| public: |
| |
| InClassLogger() |
| { |
| g_logger.setLogLevel(LOG_ALL); |
| } |
| |
| void |
| writeLogs() |
| { |
| NFD_LOG_TRACE("trace-message-JHGFDSR^1"); |
| NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17); |
| NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x"); |
| NFD_LOG_INFO("info-message-Jjxjshj13"); |
| NFD_LOG_ERROR("error-message-!#$&^%$#@"); |
| NFD_LOG_FATAL("fatal-message-JJSjaamcng"); |
| } |
| |
| private: |
| NFD_LOG_INCLASS_DECLARE(); |
| }; |
| |
| NFD_LOG_INCLASS_DEFINE(InClassLogger, "InClassLogger"); |
| |
| BOOST_FIXTURE_TEST_CASE(InClass, InClassLogger) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| writeLogs(); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string EXPECTED[] = |
| { |
| "TRACE:", "[InClassLogger]", "trace-message-JHGFDSR^1\n", |
| "DEBUG:", "[InClassLogger]", "debug-message-IGg2474fdksd-fo-151617\n", |
| "WARNING:", "[InClassLogger]", "warning-message-XXXhdhd111x\n", |
| "INFO:", "[InClassLogger]", "info-message-Jjxjshj13\n", |
| "ERROR:", "[InClassLogger]", "error-message-!#$&^%$#@\n", |
| "FATAL:", "[InClassLogger]", "fatal-message-JJSjaamcng\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| } |
| |
| |
| template<class T> |
| class InClassTemplateLogger : public LoggerFixture |
| { |
| public: |
| InClassTemplateLogger() |
| { |
| g_logger.setLogLevel(LOG_ALL); |
| } |
| |
| void |
| writeLogs() |
| { |
| NFD_LOG_TRACE("trace-message-JHGFDSR^1"); |
| NFD_LOG_DEBUG("debug-message-IGg2474fdksd-fo-" << 15 << 16 << 17); |
| NFD_LOG_WARN("warning-message-XXXhdhd11" << 1 <<"x"); |
| NFD_LOG_INFO("info-message-Jjxjshj13"); |
| NFD_LOG_ERROR("error-message-!#$&^%$#@"); |
| NFD_LOG_FATAL("fatal-message-JJSjaamcng"); |
| } |
| |
| private: |
| NFD_LOG_INCLASS_DECLARE(); |
| }; |
| |
| NFD_LOG_INCLASS_TEMPLATE_DEFINE(InClassTemplateLogger, "GenericInClassTemplateLogger"); |
| NFD_LOG_INCLASS_TEMPLATE_SPECIALIZATION_DEFINE(InClassTemplateLogger, int, "IntInClassLogger"); |
| |
| BOOST_FIXTURE_TEST_CASE(GenericInTemplatedClass, InClassTemplateLogger<bool>) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| writeLogs(); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string EXPECTED[] = |
| { |
| "TRACE:", "[GenericInClassTemplateLogger]", "trace-message-JHGFDSR^1\n", |
| "DEBUG:", "[GenericInClassTemplateLogger]", "debug-message-IGg2474fdksd-fo-151617\n", |
| "WARNING:", "[GenericInClassTemplateLogger]", "warning-message-XXXhdhd111x\n", |
| "INFO:", "[GenericInClassTemplateLogger]", "info-message-Jjxjshj13\n", |
| "ERROR:", "[GenericInClassTemplateLogger]", "error-message-!#$&^%$#@\n", |
| "FATAL:", "[GenericInClassTemplateLogger]", "fatal-message-JJSjaamcng\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before |
| // << " extracted=" << extractedTime |
| // << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| } |
| |
| |
| BOOST_FIXTURE_TEST_CASE(SpecializedInTemplatedClass, InClassTemplateLogger<int>) |
| { |
| using namespace ndn::time; |
| using std::string; |
| |
| const ndn::time::microseconds::rep ONE_SECOND = 1000000; |
| |
| microseconds::rep before = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| writeLogs(); |
| |
| microseconds::rep after = |
| duration_cast<microseconds>(system_clock::now().time_since_epoch()).count(); |
| |
| const string EXPECTED[] = |
| { |
| "TRACE:", "[IntInClassLogger]", "trace-message-JHGFDSR^1\n", |
| "DEBUG:", "[IntInClassLogger]", "debug-message-IGg2474fdksd-fo-151617\n", |
| "WARNING:", "[IntInClassLogger]", "warning-message-XXXhdhd111x\n", |
| "INFO:", "[IntInClassLogger]", "info-message-Jjxjshj13\n", |
| "ERROR:", "[IntInClassLogger]", "error-message-!#$&^%$#@\n", |
| "FATAL:", "[IntInClassLogger]", "fatal-message-JJSjaamcng\n", |
| }; |
| |
| const size_t N_EXPECTED = sizeof(EXPECTED) / sizeof(string); |
| |
| const string buffer = m_buffer.str(); |
| |
| std::vector<string> components; |
| boost::split(components, buffer, boost::is_any_of(" ,\n")); |
| |
| // expected + number of timestamps (one per log statement) + trailing newline of last statement |
| BOOST_REQUIRE_EQUAL(components.size(), N_EXPECTED + 6 + 1); |
| |
| std::vector<std::string>::const_iterator componentIter = components.begin(); |
| for (size_t i = 0; i < N_EXPECTED; ++i) |
| { |
| // timestamp LOG_LEVEL: [ModuleName] message\n |
| |
| const string& timestamp = *componentIter; |
| // std::cout << "timestamp = " << timestamp << std::endl; |
| ++componentIter; |
| |
| size_t timeDelimiterPosition = timestamp.find("."); |
| |
| BOOST_REQUIRE_NE(string::npos, timeDelimiterPosition); |
| |
| string secondsString = timestamp.substr(0, timeDelimiterPosition); |
| string usecondsString = timestamp.substr(timeDelimiterPosition + 1); |
| |
| microseconds::rep extractedTime = |
| ONE_SECOND * boost::lexical_cast<microseconds::rep>(secondsString) + |
| boost::lexical_cast<microseconds::rep>(usecondsString); |
| |
| // std::cout << "before=" << before << " extracted=" << extractedTime << " after=" << after << std::endl; |
| |
| BOOST_CHECK_LE(before, extractedTime); |
| BOOST_CHECK_LE(extractedTime, after); |
| |
| // LOG_LEVEL: |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| // [ModuleName] |
| BOOST_CHECK_EQUAL(*componentIter, EXPECTED[i]); |
| ++componentIter; |
| ++i; |
| |
| const string& message = *componentIter; |
| |
| // std::cout << "message = " << message << std::endl; |
| |
| // add back the newline that we split on |
| BOOST_CHECK_EQUAL(message + "\n", EXPECTED[i]); |
| ++componentIter; |
| } |
| } |
| |
| BOOST_AUTO_TEST_SUITE_END() |
| |
| } // namespace tests |
| } // namespace nfd |