2016-03-17 12:03:07 +01:00
/*
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/>.
*/
2018-03-03 13:11:12 +01:00
#include <config.h>
2016-03-17 12:03:07 +01:00
#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>
2020-09-16 12:26:45 +02:00
#include <opm/common/OpmLog/KeywordLocation.hpp>
2016-03-17 12:03:07 +01:00
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 ) {
2020-09-16 14:21:50 +02:00
BOOST_CHECK_EQUAL ( "There is an error here? \n In file /path/to/file, line 100 \n " , Log :: fileMessage ( KeywordLocation ( "Keyword" , "/path/to/file" , 100 ) , "There is an error here?" ));
2016-03-17 12:03:07 +01:00
2017-07-31 15:39:31 +02:00
BOOST_CHECK_EQUAL ( " \n Error: This is the error" , Log :: prefixMessage ( Log :: MessageType :: Error , "This is the error" ));
BOOST_CHECK_EQUAL ( " \n Warning: This is the warning" , Log :: prefixMessage ( Log :: MessageType :: Warning , "This is the warning" ));
2016-06-08 13:40:19 +02:00
BOOST_CHECK_EQUAL ( "Info: This is the info" , Log :: prefixMessage ( Log :: MessageType :: Info , "This is the info" ));
2016-03-17 12:03:07 +01:00
}
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 );
2019-09-06 13:11:54 +02:00
BOOST_CHECK_THROW ( StreamLog ( "/non/existing/directory/logfile" , Log :: MessageType :: Warning ) , std :: runtime_error );
2016-03-17 12:03:07 +01:00
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 ));
2020-09-29 13:54:21 +02:00
BOOST_CHECK_EQUAL ( 0U , counter2 -> numMessages ( Log :: MessageType :: Info ));
2016-03-17 12:03:07 +01:00
}
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 ;
}
2016-10-19 15:08:46 +02:00
void addMessageUnconditionally ( int64_t messageType , const std :: string & /* message */ ) override
{
2016-03-17 12:03:07 +01:00
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" );
2016-06-08 10:55:38 +02:00
counter . addMessage ( Log :: MessageType :: Note , "This is a note" );
2016-03-17 12:03:07 +01:00
BOOST_CHECK_EQUAL ( 1U , counter . numMessages ( Log :: MessageType :: Error ));
BOOST_CHECK_EQUAL ( 1U , counter . numMessages ( Log :: MessageType :: Warning ));
2020-09-29 13:54:21 +02:00
BOOST_CHECK_EQUAL ( 0U , counter . numMessages ( Log :: MessageType :: Info ));
2016-06-08 09:00:24 +02:00
BOOST_CHECK_EQUAL ( 1U , counter . numMessages ( Log :: MessageType :: Note ));
2016-03-17 12:03:07 +01:00
{
int64_t not_enabled = 4096 ;
int64_t not_power2 = 4095 ;
2020-09-29 13:54:21 +02:00
BOOST_CHECK_EQUAL ( 0U , counter . numMessages ( not_enabled ));
2016-03-17 12:03:07 +01:00
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" );
2020-09-29 13:54:21 +02:00
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 ) );
2016-03-17 12:03:07 +01:00
}
BOOST_CHECK_EQUAL ( log_stream . str () , "Warning \n " );
}
2016-05-09 11:34:08 +02:00
2016-05-09 15:11:34 +02:00
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
2020-09-16 14:21:50 +02:00
BOOST_CHECK_EQUAL ( fileMessage ( KeywordLocation ( "Keyword" , "foo/bar" , 1 ), "message" ), "message \n In file foo/bar, line 1 \n " );
BOOST_CHECK_EQUAL ( fileMessage ( MessageType :: Error , KeywordLocation ( "Keyword" , "foo/bar" , 1 ), "message" ), " \n Error: message \n In file foo/bar, line 1 \n " );
2016-05-09 15:11:34 +02:00
// prefixMessage
2017-07-31 15:39:31 +02:00
BOOST_CHECK_EQUAL ( prefixMessage ( MessageType :: Error , "message" ), " \n Error: message" );
2016-06-08 13:40:19 +02:00
BOOST_CHECK_EQUAL ( prefixMessage ( MessageType :: Info , "message" ), "Info: message" );
BOOST_CHECK_EQUAL ( prefixMessage ( MessageType :: Note , "message" ), "Note: message" );
2016-05-09 15:11:34 +02:00
// colorCode Message
2016-05-25 13:56:33 +02:00
BOOST_CHECK_EQUAL ( colorCodeMessage ( MessageType :: Info , "message" ), "message" );
2016-06-06 15:29:09 +02:00
BOOST_CHECK_EQUAL ( colorCodeMessage ( MessageType :: Warning , "message" ), AnsiTerminalColors :: blue_strong + "message" + AnsiTerminalColors :: none );
2016-05-12 10:28:44 +02:00
BOOST_CHECK_EQUAL ( colorCodeMessage ( MessageType :: Error , "message" ), AnsiTerminalColors :: red_strong + "message" + AnsiTerminalColors :: none );
2016-05-09 15:11:34 +02:00
}
2016-05-09 11:34:08 +02:00
BOOST_AUTO_TEST_CASE ( TestOpmLogWithColors )
{
2016-05-12 10:29:48 +02:00
OpmLog :: removeAllBackends ();
2016-05-09 11:34:08 +02:00
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" ));
2016-05-18 22:22:10 +02:00
streamLog -> setMessageFormatter ( std :: make_shared < SimpleMessageFormatter > ( false , true ));
2016-05-09 11:34:08 +02:00
}
OpmLog :: warning ( "Warning" );
OpmLog :: error ( "Error" );
OpmLog :: info ( "Info" );
OpmLog :: bug ( "Bug" );
2016-06-08 15:30:52 +02:00
const std :: string expected = Log :: colorCodeMessage ( Log :: MessageType :: Warning , "Warning" ) + " \n "
+ Log :: colorCodeMessage ( Log :: MessageType :: Error , "Error" ) + " \n "
2016-05-09 11:34:08 +02:00
+ Log :: colorCodeMessage ( Log :: MessageType :: Info , "Info" ) + " \n "
2016-06-08 15:30:52 +02:00
+ Log :: colorCodeMessage ( Log :: MessageType :: Bug , "Bug" ) + " \n " ;
2016-05-09 11:34:08 +02:00
BOOST_CHECK_EQUAL ( log_stream . str (), expected );
{
auto counter = OpmLog :: getBackend < CounterLog > ( "COUNTER" );
2020-09-29 13:54:21 +02:00
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 ) );
2016-05-09 11:34:08 +02:00
}
2016-05-12 10:54:19 +02:00
std :: cout << log_stream . str () << std :: endl ;
2016-05-09 11:34:08 +02:00
}
2016-05-18 13:27:12 +02:00
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" ));
2016-05-18 22:22:10 +02:00
streamLog1 -> setMessageFormatter ( std :: make_shared < SimpleMessageFormatter > ( false , true ));
streamLog1 -> setMessageLimiter ( std :: make_shared < MessageLimiter > ( 2 ));
streamLog2 -> setMessageFormatter ( std :: make_shared < SimpleMessageFormatter > ( false , true ));
2016-10-19 15:08:46 +02:00
std :: shared_ptr < MessageLimiter > lim ( new MessageLimiter ( MessageLimiter :: NoLimit , {{ Log :: MessageType :: Warning , 2 }}));
streamLog2 -> setMessageLimiter ( lim ); // no tag limit, but a warning category limit
2016-05-18 13:27:12 +02:00
}
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" );
2016-06-08 15:30:52 +02:00
const std :: string expected1 = Log :: colorCodeMessage ( Log :: MessageType :: Warning , "Warning" ) + " \n "
+ Log :: colorCodeMessage ( Log :: MessageType :: Error , "Error" ) + " \n "
2016-05-18 13:27:12 +02:00
+ Log :: colorCodeMessage ( Log :: MessageType :: Info , "Info" ) + " \n "
2016-06-08 15:30:52 +02:00
+ 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 " ;
2016-05-18 13:27:12 +02:00
BOOST_CHECK_EQUAL ( log_stream1 . str (), expected1 );
2016-06-08 15:30:52 +02:00
const std :: string expected2 = Log :: colorCodeMessage ( Log :: MessageType :: Warning , "Warning" ) + " \n "
+ Log :: colorCodeMessage ( Log :: MessageType :: Error , "Error" ) + " \n "
2016-05-18 13:27:12 +02:00
+ Log :: colorCodeMessage ( Log :: MessageType :: Info , "Info" ) + " \n "
2016-06-08 15:30:52 +02:00
+ Log :: colorCodeMessage ( Log :: MessageType :: Bug , "Bug" ) + " \n "
+ Log :: colorCodeMessage ( Log :: MessageType :: Warning , "Warning" ) + " \n "
2017-07-31 15:39:31 +02:00
+ Log :: colorCodeMessage ( Log :: MessageType :: Warning , "Message limit reached for message category: \n Warning" ) + " \n " ;
2016-05-18 13:27:12 +02:00
BOOST_CHECK_EQUAL ( log_stream2 . str (), expected2 );
std :: cout << log_stream1 . str () << std :: endl ;
std :: cout << log_stream2 . str () << std :: endl ;
}
2016-05-23 15:01:50 +08:00
BOOST_AUTO_TEST_CASE ( TestsetupSimpleLog )
{
bool use_prefix = false ;
OpmLog :: setupSimpleDefaultLogging ( use_prefix );
2016-05-23 15:04:41 +08:00
BOOST_CHECK_EQUAL ( true , OpmLog :: hasBackend ( "SimpleDefaultLog" ));
2016-05-23 15:01:50 +08:00
}
2016-06-08 15:30:52 +02:00
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 );
}