427 lines
16 KiB
C++
427 lines
16 KiB
C++
/*
|
|
Copyright 2013 Statoil ASA.
|
|
|
|
This file is part of the Open Porous Media project (OPM).
|
|
|
|
OPM 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.
|
|
|
|
OPM 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 OPM. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <config.h>
|
|
|
|
#define BOOST_TEST_MODULE LogTests
|
|
|
|
#include <opm/common/utility/platform_dependent/disable_warnings.h>
|
|
#include <boost/test/unit_test.hpp>
|
|
#include <opm/common/utility/platform_dependent/reenable_warnings.h>
|
|
|
|
#include <stdexcept>
|
|
#include <iostream>
|
|
#include <sstream>
|
|
|
|
|
|
#include <opm/common/OpmLog/OpmLog.hpp>
|
|
#include <opm/common/OpmLog/LogBackend.hpp>
|
|
#include <opm/common/OpmLog/CounterLog.hpp>
|
|
#include <opm/common/OpmLog/TimerLog.hpp>
|
|
#include <opm/common/OpmLog/StreamLog.hpp>
|
|
#include <opm/common/OpmLog/LogUtil.hpp>
|
|
#include <opm/common/OpmLog/KeywordLocation.hpp>
|
|
|
|
using namespace Opm;
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(DoLogging) {
|
|
OpmLog::addMessage(Log::MessageType::Warning , "Warning1");
|
|
OpmLog::addMessage(Log::MessageType::Warning , "Warning2");
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Test_Format) {
|
|
BOOST_CHECK_EQUAL( "There is an error here?\nIn file /path/to/file, line 100\n" , Log::fileMessage(KeywordLocation("Keyword", "/path/to/file" , 100) , "There is an error here?"));
|
|
|
|
BOOST_CHECK_EQUAL( "\nError: This is the error" , Log::prefixMessage(Log::MessageType::Error , "This is the error"));
|
|
BOOST_CHECK_EQUAL( "\nWarning: This is the warning" , Log::prefixMessage(Log::MessageType::Warning , "This is the warning"));
|
|
BOOST_CHECK_EQUAL( "Info: This is the info" , Log::prefixMessage(Log::MessageType::Info , "This is the info"));
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(Test_Logger) {
|
|
Logger logger;
|
|
std::ostringstream log_stream;
|
|
std::shared_ptr<CounterLog> counter = std::make_shared<CounterLog>();
|
|
std::shared_ptr<StreamLog> streamLog = std::make_shared<StreamLog>( log_stream , Log::MessageType::Warning );
|
|
BOOST_CHECK_THROW( StreamLog( "/non/existing/directory/logfile", Log::MessageType::Warning ) , std::runtime_error );
|
|
BOOST_CHECK_EQUAL( false , logger.hasBackend("NO"));
|
|
|
|
logger.addBackend("COUNTER" , counter);
|
|
logger.addBackend("STREAM" , streamLog);
|
|
BOOST_CHECK_EQUAL( true , logger.hasBackend("COUNTER"));
|
|
BOOST_CHECK_EQUAL( true , logger.hasBackend("STREAM"));
|
|
|
|
logger.addMessage( Log::MessageType::Error , "Error");
|
|
logger.addMessage( Log::MessageType::Warning , "Warning");
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Error) );
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Warning) );
|
|
BOOST_CHECK_EQUAL( 0U , counter->numMessages(Log::MessageType::Info) );
|
|
|
|
BOOST_CHECK_EQUAL( log_stream.str() , "Warning\n");
|
|
|
|
|
|
BOOST_CHECK_THROW( logger.getBackend<LogBackend>("No") , std::invalid_argument );
|
|
{
|
|
auto counter2 = logger.getBackend<CounterLog>("COUNTER");
|
|
BOOST_CHECK_EQUAL( 1U , counter2->numMessages( Log::MessageType::Warning));
|
|
BOOST_CHECK_EQUAL( 1U , counter2->numMessages( Log::MessageType::Error));
|
|
BOOST_CHECK_EQUAL( 0U , counter2->numMessages( Log::MessageType::Info));
|
|
}
|
|
|
|
BOOST_CHECK_EQUAL( false , logger.removeBackend("NO-not-found"));
|
|
BOOST_CHECK_EQUAL( true , logger.removeBackend("COUNTER"));
|
|
BOOST_CHECK_EQUAL( false , logger.hasBackend("COUNTER") );
|
|
|
|
{
|
|
auto stream2 = logger.popBackend<StreamLog>("STREAM");
|
|
BOOST_CHECK_EQUAL( false , logger.hasBackend("STREAM") );
|
|
BOOST_CHECK_THROW( logger.popBackend<StreamLog>("STREAM") , std::invalid_argument );
|
|
}
|
|
}
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(LoggerAddTypes_PowerOf2) {
|
|
Logger logger;
|
|
int64_t not_power_of2 = 13;
|
|
int64_t power_of2 = 4096;
|
|
|
|
BOOST_CHECK_THROW( logger.addMessageType( not_power_of2 , "Prefix") , std::invalid_argument);
|
|
BOOST_CHECK_THROW( logger.enabledMessageType( not_power_of2 ) , std::invalid_argument);
|
|
|
|
logger.addMessageType( power_of2 , "Prefix");
|
|
BOOST_CHECK( logger.enabledMessageType( power_of2 ));
|
|
BOOST_CHECK_EQUAL( false , logger.enabledMessageType( 2*power_of2 ));
|
|
}
|
|
|
|
|
|
class TestLog: public LogBackend {
|
|
public:
|
|
TestLog( int64_t messageMask ) : LogBackend( messageMask )
|
|
{
|
|
m_defaultMessages = 0;
|
|
m_specialMessages = 0;
|
|
}
|
|
|
|
void addMessageUnconditionally(int64_t messageType , const std::string& /* message */) override
|
|
{
|
|
if (messageType & Log::DefaultMessageTypes)
|
|
m_defaultMessages +=1;
|
|
else
|
|
m_specialMessages += 1;
|
|
}
|
|
|
|
int m_defaultMessages;
|
|
int m_specialMessages;
|
|
};
|
|
/*
|
|
Testing that the logger frontend does not let unknown message types
|
|
pass through; even though the backend has shown interest in the
|
|
phony 4096 messagetype.
|
|
*/
|
|
|
|
BOOST_AUTO_TEST_CASE(LoggerMasksTypes) {
|
|
Logger logger;
|
|
int64_t power_of2 = 4096;
|
|
|
|
std::shared_ptr<TestLog> testLog = std::make_shared<TestLog>(Log::DefaultMessageTypes + power_of2);
|
|
logger.addBackend("TEST" , testLog);
|
|
BOOST_CHECK_EQUAL( false , logger.enabledMessageType( power_of2 ));
|
|
|
|
logger.addMessage( Log::MessageType::Error , "Error");
|
|
logger.addMessage( Log::MessageType::Warning , "Warning");
|
|
logger.addMessage( Log::MessageType::Info , "Info");
|
|
|
|
BOOST_CHECK_THROW( logger.addMessage( power_of2 , "Blocked message") , std::invalid_argument );
|
|
BOOST_CHECK_EQUAL( testLog->m_defaultMessages , 3 );
|
|
BOOST_CHECK_EQUAL( testLog->m_specialMessages , 0 );
|
|
|
|
logger.addMessageType( power_of2 , "Phony");
|
|
logger.addMessage( power_of2 , "Passing through");
|
|
BOOST_CHECK_EQUAL( testLog->m_specialMessages , 1 );
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(LoggerDefaultTypesEnabled) {
|
|
Logger logger;
|
|
BOOST_CHECK_EQUAL( logger.enabledMessageTypes() , Log::DefaultMessageTypes);
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE( CounterLogTesting) {
|
|
CounterLog counter(Log::DefaultMessageTypes);
|
|
|
|
counter.addMessage( Log::MessageType::Error , "This is an error ...");
|
|
counter.addMessage( Log::MessageType::Warning , "This is a warning");
|
|
counter.addMessage( Log::MessageType::Note , "This is a note");
|
|
|
|
BOOST_CHECK_EQUAL(1U , counter.numMessages( Log::MessageType::Error ));
|
|
BOOST_CHECK_EQUAL(1U , counter.numMessages( Log::MessageType::Warning ));
|
|
BOOST_CHECK_EQUAL(0U , counter.numMessages( Log::MessageType::Info ));
|
|
BOOST_CHECK_EQUAL(1U , counter.numMessages( Log::MessageType::Note ));
|
|
|
|
{
|
|
int64_t not_enabled = 4096;
|
|
int64_t not_power2 = 4095;
|
|
|
|
BOOST_CHECK_EQUAL( 0U , counter.numMessages( not_enabled ));
|
|
BOOST_CHECK_THROW( counter.numMessages( not_power2 ) , std::invalid_argument);
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(TestTimerLog) {
|
|
Logger logger;
|
|
std::ostringstream sstream;
|
|
std::shared_ptr<TimerLog> timer = std::make_shared<TimerLog>(sstream);
|
|
logger.addBackend( "TIMER" , timer );
|
|
logger.addMessageType( TimerLog::StartTimer , "Start");
|
|
logger.addMessageType( TimerLog::StopTimer , "Stop");
|
|
|
|
logger.addMessage( TimerLog::StartTimer , "");
|
|
logger.addMessage( TimerLog::StopTimer , "This was fast");
|
|
std::cout << sstream.str() << std::endl;
|
|
}
|
|
|
|
|
|
/*****************************************************************/
|
|
void initLogger(std::ostringstream& log_stream);
|
|
|
|
void initLogger(std::ostringstream& log_stream) {
|
|
std::shared_ptr<CounterLog> counter = std::make_shared<CounterLog>();
|
|
std::shared_ptr<StreamLog> streamLog = std::make_shared<StreamLog>( log_stream , Log::MessageType::Warning );
|
|
|
|
BOOST_CHECK_EQUAL( false , OpmLog::hasBackend("NO"));
|
|
|
|
OpmLog::addBackend("COUNTER" , counter);
|
|
OpmLog::addBackend("STREAM" , streamLog);
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("COUNTER"));
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM"));
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(TestOpmLog) {
|
|
std::ostringstream log_stream;
|
|
|
|
initLogger(log_stream);
|
|
|
|
OpmLog::addMessage( Log::MessageType::Warning , "Warning");
|
|
OpmLog::addMessage( Log::MessageType::Error , "Error");
|
|
|
|
{
|
|
auto counter = OpmLog::getBackend<CounterLog>("COUNTER");
|
|
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Error) );
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Warning) );
|
|
BOOST_CHECK_EQUAL( 0U , counter->numMessages(Log::MessageType::Info) );
|
|
}
|
|
|
|
BOOST_CHECK_EQUAL( log_stream.str() , "Warning\n");
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(TestHelperFunctions)
|
|
{
|
|
using namespace Log;
|
|
|
|
// isPower2
|
|
BOOST_CHECK(!isPower2(0));
|
|
BOOST_CHECK(isPower2(1));
|
|
BOOST_CHECK(isPower2(1 << 3));
|
|
BOOST_CHECK(isPower2(1ul << 62));
|
|
|
|
// fileMessage
|
|
BOOST_CHECK_EQUAL(fileMessage(KeywordLocation("Keyword", "foo/bar", 1), "message"), "message\nIn file foo/bar, line 1\n");
|
|
BOOST_CHECK_EQUAL(fileMessage(MessageType::Error, KeywordLocation("Keyword", "foo/bar", 1), "message"), "\nError: message\nIn file foo/bar, line 1\n");
|
|
|
|
// prefixMessage
|
|
BOOST_CHECK_EQUAL(prefixMessage(MessageType::Error, "message"), "\nError: message");
|
|
BOOST_CHECK_EQUAL(prefixMessage(MessageType::Info, "message"), "Info: message");
|
|
BOOST_CHECK_EQUAL(prefixMessage(MessageType::Note, "message"), "Note: message");
|
|
|
|
// colorCode Message
|
|
BOOST_CHECK_EQUAL(colorCodeMessage(MessageType::Info, "message"), "message");
|
|
BOOST_CHECK_EQUAL(colorCodeMessage(MessageType::Warning, "message"), AnsiTerminalColors::blue_strong + "message" + AnsiTerminalColors::none);
|
|
BOOST_CHECK_EQUAL(colorCodeMessage(MessageType::Error, "message"), AnsiTerminalColors::red_strong + "message" + AnsiTerminalColors::none);
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(TestOpmLogWithColors)
|
|
{
|
|
OpmLog::removeAllBackends();
|
|
|
|
std::ostringstream log_stream;
|
|
|
|
{
|
|
std::shared_ptr<CounterLog> counter = std::make_shared<CounterLog>();
|
|
std::shared_ptr<StreamLog> streamLog = std::make_shared<StreamLog>(log_stream, Log::DefaultMessageTypes);
|
|
BOOST_CHECK_EQUAL( false , OpmLog::hasBackend("NO"));
|
|
OpmLog::addBackend("COUNTER" , counter);
|
|
OpmLog::addBackend("STREAM" , streamLog);
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("COUNTER"));
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM"));
|
|
|
|
streamLog->setMessageFormatter(std::make_shared<SimpleMessageFormatter>(false, true));
|
|
}
|
|
|
|
OpmLog::warning("Warning");
|
|
OpmLog::error("Error");
|
|
OpmLog::info("Info");
|
|
OpmLog::bug("Bug");
|
|
|
|
const std::string expected = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n";
|
|
|
|
BOOST_CHECK_EQUAL(log_stream.str(), expected);
|
|
|
|
{
|
|
auto counter = OpmLog::getBackend<CounterLog>("COUNTER");
|
|
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Error) );
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Warning) );
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Info) );
|
|
BOOST_CHECK_EQUAL( 1U , counter->numMessages(Log::MessageType::Bug) );
|
|
}
|
|
|
|
|
|
std::cout << log_stream.str() << std::endl;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(TestOpmLogWithLimits)
|
|
{
|
|
OpmLog::removeAllBackends();
|
|
|
|
std::ostringstream log_stream1;
|
|
std::ostringstream log_stream2;
|
|
|
|
{
|
|
std::shared_ptr<StreamLog> streamLog1 = std::make_shared<StreamLog>(log_stream1, Log::DefaultMessageTypes);
|
|
std::shared_ptr<StreamLog> streamLog2 = std::make_shared<StreamLog>(log_stream2, Log::DefaultMessageTypes);
|
|
OpmLog::addBackend("STREAM1" , streamLog1);
|
|
OpmLog::addBackend("STREAM2" , streamLog2);
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM1"));
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM2"));
|
|
|
|
streamLog1->setMessageFormatter(std::make_shared<SimpleMessageFormatter>(false, true));
|
|
streamLog1->setMessageLimiter(std::make_shared<MessageLimiter>(2));
|
|
streamLog2->setMessageFormatter(std::make_shared<SimpleMessageFormatter>(false, true));
|
|
std::shared_ptr<MessageLimiter> lim(new MessageLimiter(MessageLimiter::NoLimit, {{ Log::MessageType::Warning, 2 }}));
|
|
streamLog2->setMessageLimiter(lim); // no tag limit, but a warning category limit
|
|
}
|
|
|
|
const std::string tag = "ExampleTag";
|
|
OpmLog::warning(tag, "Warning");
|
|
OpmLog::error("Error");
|
|
OpmLog::info("Info");
|
|
OpmLog::bug("Bug");
|
|
OpmLog::warning(tag, "Warning");
|
|
OpmLog::warning(tag, "Warning");
|
|
OpmLog::warning(tag, "Warning");
|
|
|
|
const std::string expected1 = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Message limit reached for message tag: " + tag) + "\n";
|
|
|
|
BOOST_CHECK_EQUAL(log_stream1.str(), expected1);
|
|
|
|
const std::string expected2 = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Warning, "Message limit reached for message category: \nWarning") + "\n";
|
|
|
|
BOOST_CHECK_EQUAL(log_stream2.str(), expected2);
|
|
|
|
std::cout << log_stream1.str() << std::endl;
|
|
std::cout << log_stream2.str() << std::endl;
|
|
}
|
|
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(TestsetupSimpleLog)
|
|
{
|
|
bool use_prefix = false;
|
|
OpmLog::setupSimpleDefaultLogging(use_prefix);
|
|
BOOST_CHECK_EQUAL(true, OpmLog::hasBackend("SimpleDefaultLog"));
|
|
}
|
|
|
|
|
|
|
|
BOOST_AUTO_TEST_CASE(TestFormat)
|
|
{
|
|
OpmLog::removeAllBackends();
|
|
std::ostringstream log_stream1;
|
|
std::ostringstream log_stream2;
|
|
std::ostringstream log_stream3;
|
|
{
|
|
std::shared_ptr<StreamLog> streamLog1 = std::make_shared<StreamLog>(log_stream1, Log::DefaultMessageTypes);
|
|
std::shared_ptr<StreamLog> streamLog2 = std::make_shared<StreamLog>(log_stream2, Log::DefaultMessageTypes);
|
|
std::shared_ptr<StreamLog> streamLog3 = std::make_shared<StreamLog>(log_stream3, Log::DefaultMessageTypes);
|
|
OpmLog::addBackend("STREAM1" , streamLog1);
|
|
OpmLog::addBackend("STREAM2" , streamLog2);
|
|
OpmLog::addBackend("STREAM3" , streamLog3);
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM1"));
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM2"));
|
|
BOOST_CHECK_EQUAL( true , OpmLog::hasBackend("STREAM3"));
|
|
streamLog1->setMessageFormatter(std::make_shared<SimpleMessageFormatter>(false, true));
|
|
streamLog2->setMessageFormatter(std::make_shared<SimpleMessageFormatter>(Log::MessageType::Info, true));
|
|
streamLog3->setMessageFormatter(std::make_shared<SimpleMessageFormatter>(false));
|
|
}
|
|
|
|
OpmLog::warning("Warning");
|
|
OpmLog::error("Error");
|
|
OpmLog::info("Info");
|
|
OpmLog::bug("Bug");
|
|
|
|
const std::string expected1 = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n";
|
|
|
|
const std::string expected2 = Log::colorCodeMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Error, "Error") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Info, "Info: Info") + "\n"
|
|
+ Log::colorCodeMessage(Log::MessageType::Bug, "Bug") + "\n";
|
|
|
|
const std::string expected3 = Log::prefixMessage(Log::MessageType::Warning, "Warning") + "\n"
|
|
+ Log::prefixMessage(Log::MessageType::Error, "Error") + "\n"
|
|
+ "Info" + "\n"
|
|
+ Log::prefixMessage(Log::MessageType::Bug, "Bug") + "\n";
|
|
|
|
BOOST_CHECK_EQUAL(log_stream1.str(), expected1);
|
|
BOOST_CHECK_EQUAL(log_stream2.str(), expected2);
|
|
BOOST_CHECK_EQUAL(log_stream3.str(), expected3);
|
|
}
|