Updated for better unit-testing. Unit testing does not abort but throws a std::runtime_error if FATAL

This commit is contained in:
Kjell Hedstrom 2011-11-16 22:23:47 +01:00
parent b3b5335b90
commit 925581d338
12 changed files with 123 additions and 143 deletions

View File

@ -54,7 +54,7 @@ IF(UNIX)
MESSAGE("")
set(PLATFORM_LINK_LIBRIES justthread rt)
set(CMAKE_CXX_FLAGS "-Wall -Wunused -std=c++0x ${CMAKE_CXX_FLAGS_DEBUG} -pthread -I/usr/include/justthread")
set(G2_LOG_FILES ${LOG_SRC}/logworker.h ${LOG_SRC}/logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
set(G2_LOG_FILES ${LOG_SRC}/g2logworker.h ${LOG_SRC}/g2logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
include_directories("/usr/include/justthread")
# SETUP for GTEST
@ -73,7 +73,7 @@ IF(WIN32)
MESSAGE("then run 'Debug\\g2log-example.exe' or whatever performance test you feel like trying")
MESSAGE("")
set(PLATFORM_LINK_LIBRIES $ENV{PROGRAMFILES}/JustSoftwareSolutions/JustThread/lib/justthread_vc10_mdd.lib)
set(G2_LOG_FILES ${LOG_SRC}/logworker.h ${LOG_SRC}/logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_win.cpp)
set(G2_LOG_FILES ${LOG_SRC}/g2logworker.h ${LOG_SRC}/g2logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_win.cpp)
include_directories("$ENV{PROGRAMFILES}/JustSoftwareSolutions/JustThread/include")
ENDIF(WIN32)
@ -136,12 +136,10 @@ IF(UNIX)
# create the the TEST executable
add_executable(g2log-unit_test ../test_main/test_main.cpp test/test_io.cpp)
add_library(lib_test_logger ${LOG_SRC}/logworker.h ${LOG_SRC}/logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
add_library(lib_test_logger ${LOG_SRC}/g2logworker.h ${LOG_SRC}/g2logworker.cpp ${LOG_SRC}/g2log.h ${LOG_SRC}/g2log.cpp ${LOG_SRC}/crashhandler.h ${LOG_SRC}/crashhandler_unix.cpp)
set_target_properties(lib_test_logger PROPERTIES LINKER_LANGUAGE CXX)
set_target_properties(lib_test_logger PROPERTIES COMPILE_DEFINITIONS "YALLA=1")
target_link_libraries(lib_test_logger lib_activeobject)
# For unit-test only, dont 'crash' by signals, instead just throw a std::runtime_error
set_target_properties(g2log-unit_test PROPERTIES COMPILE_DEFINITIONS "YALLA=1")
target_link_libraries(g2log-unit_test lib_activeobject lib_test_logger gtest_160_lib justthread rt)
ENDIF(UNIX)

View File

@ -15,7 +15,7 @@ std::string signalName(int signal_number);
/** Re-"throw" a fatal signal, previously caught. This will exit the application
* This is an internal only function. Do not use it elsewhere. It is triggered
* from g2log, LogWorker after flushing messages to file */
* from g2log, g2LogWorker after flushing messages to file */
void exitWithDefaultSignalHandler(int signal_number);
} // end g2::interal

View File

@ -46,7 +46,7 @@ void crashHandler(int signal_number, siginfo_t *info, void *unused_context)
FatalMessage fatal_message(fatal_stream.str(),FatalMessage::kReasonOS_FATAL_SIGNAL, signal_number);
FatalTrigger trigger(fatal_message); std::ostringstream oss;
std::cerr << fatal_message.message_ << std::endl << std::flush;
} // message sent to LogWorker
} // message sent to g2LogWorker
// wait to die -- will be inside the FatalTrigger
}
} // end anonymous namespace
@ -86,7 +86,7 @@ default:
}
}
// Triggered by g2log::LogWorker after receiving a FATAL trigger
// Triggered by g2log->g2LogWorker after receiving a FATAL trigger
// which is LOG(FATAL), CHECK(false) or a fatal signal our signalhandler caught.
// --- If LOG(FATAL) or CHECK(false) the signal_number will be SIGABRT
void exitWithDefaultSignalHandler(int signal_number)

View File

@ -21,7 +21,7 @@
#include <cassert>
#include <mutex>
#include "logworker.h"
#include "g2logworker.h"
#include "crashhandler.h"
#include <signal.h>
@ -34,7 +34,7 @@ const std::string kTruncatedWarningText = "[...truncated...]";
}
namespace internal
{
static LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
static g2LogWorker* g_logger_instance = nullptr; // instantiated and OWNED somewhere else (main)
static std::mutex g_logging_init_mutex;
bool isLoggingInitialized(){return g_logger_instance != nullptr; }
@ -53,7 +53,7 @@ std::string splitFileName(const std::string& str)
} // end namespace g2::internal
void initializeLogging(LogWorker *bgworker)
void initializeLogging(g2LogWorker *bgworker)
{
static bool once_only_signalhandler = false;
std::lock_guard<std::mutex> lock(internal::g_logging_init_mutex);
@ -68,20 +68,50 @@ void initializeLogging(LogWorker *bgworker)
}
}
LogWorker* shutDownLogging()
g2LogWorker* shutDownLogging()
{
std::lock_guard<std::mutex> lock(internal::g_logging_init_mutex);
CHECK(internal::isLoggingInitialized());
LogWorker *backup = internal::g_logger_instance;
g2LogWorker *backup = internal::g_logger_instance;
internal::g_logger_instance = nullptr;
return backup;
}
namespace internal
{
// The default, initial, handling to send a 'fatal' event to g2logworker
// the caller will stay here, eternally, until the software is aborted
void callFatalInitial(FatalMessage message)
{
internal::g_logger_instance->fatal(message);
}
// By default this function pointer goes to \ref callFatalInitial;
void (*g_fatal_to_g2logworker_function_ptr)(FatalMessage) = callFatalInitial;
// Replaces the g2log.cpp/g_fatal_to_g2logworker_function_ptr through
// g2log::changeFatalInitHandler
void unitTestFatalInitHandler(g2::internal::FatalMessage fatal_message)
{
assert(internal::g_logger_instance != nullptr);
internal::g_logger_instance->save(fatal_message.message_); // calling 'save' instead of 'fatal'
throw std::runtime_error(fatal_message.message_);
}
// In case of unit-testing - a replacement 'fatal function' can be called
void changeFatalInitHandlerForUnitTesting()
{
g_fatal_to_g2logworker_function_ptr = unitTestFatalInitHandler;
}
LogContractMessage::LogContractMessage(const std::string &file, const int line,
const std::string& function, const std::string &boolean_expression)
: LogMessage(file, line, function, "FATAL")
@ -130,9 +160,9 @@ LogMessage::~LogMessage()
if(!isLoggingInitialized() )
{
std::cerr << "Did you forget to call g2::InitializeLogging(LogWorker*) in your main.cpp?" << std::endl;
std::cerr << "Did you forget to call g2::InitializeLogging(g2LogWorker*) in your main.cpp?" << std::endl;
std::cerr << log_entry_ << std::endl << std::flush;
throw std::runtime_error("Logger not initialized with g2::InitializeLogging(LogWorker*) for msg:\n" + log_entry_);
throw std::runtime_error("Logger not initialized with g2::InitializeLogging(g2LogWorker*) for msg:\n" + log_entry_);
}
@ -155,18 +185,17 @@ FatalMessage::FatalMessage(std::string message, FatalType type, int signal_id)
, type_(type)
, signal_id_(signal_id){}
// used to RAII trigger fatal message sending to LogWorker
// used to RAII trigger fatal message sending to g2LogWorker
FatalTrigger::FatalTrigger(const FatalMessage &message)
: message_(message){}
// at destruction, flushes fatal message to LogWorker
// at destruction, flushes fatal message to g2LogWorker
FatalTrigger::~FatalTrigger()
{
internal::g_logger_instance->fatal(message_);
#if !defined(YALLA) // don't sleep if unit-testing
// wait to die
// either we will stay here eternally, or it's in unit-test mode
// then we throw a std::runtime_error (and never hit sleep)
g_fatal_to_g2logworker_function_ptr(message_);
while(true){std::this_thread::sleep_for(std::chrono::seconds(1));}
#endif
}

View File

@ -21,7 +21,7 @@
#include <cstdarg>
#include <chrono>
class LogWorker;
class g2LogWorker;
#if !(defined(__PRETTY_FUNCTION__))
#define __PRETTY_FUNCTION__ __FUNCTION__
@ -141,15 +141,15 @@ And here is possible output
* --- Thanks for a great 2011 and good luck with 'g2' --- KjellKod */
namespace g2
{
/** Should be called at very first startup of the software with \ref LogWorker pointer. Ownership of the \ref LogWorker is
/** Should be called at very first startup of the software with \ref g2LogWorker pointer. Ownership of the \ref g2LogWorker is
* the responsibilkity of the caller */
void initializeLogging(LogWorker *logger);
void initializeLogging(g2LogWorker *logger);
/** Shutdown the logging by making the pointer to the background logger to nullptr
* The \ref pointer to the LogWorker is owned by the instantniater \ref initializeLogging
* The \ref pointer to the g2LogWorker is owned by the instantniater \ref initializeLogging
* and is not deleted. By restoring the ptr to nullptr we can re-initialize it later again. This is
* kept for test reasons and should normally not be used */
LogWorker* shutDownLogging();
g2LogWorker* shutDownLogging();
// defined here but should't not have to be used outside the g2log
@ -160,6 +160,13 @@ typedef std::chrono::duration<long,std::ratio<1, 1000> > millisecond;
typedef std::chrono::duration<long long,std::ratio<1, 1000000> > microsecond;
typedef const std::string& LogEntry;
/** By default the g2log will call g2LogWorker::fatal(...) which will abort() the system after flushing
* the logs to file. This makes unit test of FATAL level cumbersome. A work around is to change the 'fatal call'
* which can be done here */
void changeFatalInitHandlerForUnitTesting();
/** Trigger for flushing the message queue and exiting the applicaition
A thread that causes a FatalMessage will sleep forever until the
application has exited (after message flush) */

View File

@ -1,11 +1,11 @@
/* *************************************************
* Filename:logworker.cpp Framework for Logging and Design By Contract
* Filename:g2LogWorker.cpp Framework for Logging and Design By Contract
* Created: 2011 by Kjell Hedström
*
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
* ********************************************* */
#include "logworker.h"
#include "g2logworker.h"
#include <iostream>
#include <functional>
@ -17,10 +17,6 @@
#include <iomanip>
#include <ctime>
#if defined(YALLA)
#include <stdexcept> // exceptions
#endif
#include "active.h"
#include "g2log.h"
#include "crashhandler.h"
@ -54,13 +50,13 @@ struct LogTime
/** The actual background worker, while LogWorker gives the
* asynchronous API to put job in the background the LogWorkerImpl
/** The actual background worker, while g2LogWorker gives the
* asynchronous API to put job in the background the g2LogWorkerImpl
* does the actual background thread work */
struct LogWorkerImpl
struct g2LogWorkerImpl
{
LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory);
~LogWorkerImpl();
g2LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory);
~g2LogWorkerImpl();
void backgroundFileWrite(g2::internal::LogEntry message);
void backgroundExitFatal(g2::internal::FatalMessage fatal_message);
@ -71,15 +67,15 @@ struct LogWorkerImpl
g2::internal::time_point start_time_;
private:
LogWorkerImpl& operator=(const LogWorkerImpl&); // c++11 feature not yet in vs2010 = delete;
LogWorkerImpl(const LogWorkerImpl& other); // c++11 feature not yet in vs2010 = delete;
g2LogWorkerImpl& operator=(const g2LogWorkerImpl&); // c++11 feature not yet in vs2010 = delete;
g2LogWorkerImpl(const g2LogWorkerImpl& other); // c++11 feature not yet in vs2010 = delete;
};
//
// Private API implementation : LogWorkerImpl
LogWorkerImpl::LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory)
// Private API implementation : g2LogWorkerImpl
g2LogWorkerImpl::g2LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory)
: log_file_with_path_(log_directory)
, bg_(kjellkod::Active::createActive())
, start_time_(std::chrono::steady_clock::now())
@ -115,7 +111,7 @@ LogWorkerImpl::LogWorkerImpl(const std::string& log_prefix, const std::string& l
out.fill('0');
}
LogWorkerImpl::~LogWorkerImpl()
g2LogWorkerImpl::~g2LogWorkerImpl()
{
std::ostringstream ss_exit;
time_t exit_time;
@ -125,7 +121,7 @@ LogWorkerImpl::~LogWorkerImpl()
out << ss_exit.str() << std::flush;
}
void LogWorkerImpl::backgroundFileWrite(LogEntry message)
void g2LogWorkerImpl::backgroundFileWrite(LogEntry message)
{
using namespace std;
LogTime t;
@ -136,17 +132,9 @@ void LogWorkerImpl::backgroundFileWrite(LogEntry message)
out << "\t" << message << std::flush;
}
void LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message)
void g2LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message)
{
backgroundFileWrite(fatal_message.message_);
#if defined(YALLA)
// If running unit test - we simplify matters by not sending the signal, but
// by just throwing an exception
throw std::runtime_error(fatal_message.message_);
return;
#endif
out.close();
exitWithDefaultSignalHandler(fatal_message.signal_id_);
perror("g2log exited after receiving FATAL trigger. Flush message status: "); // should never reach this point
@ -154,31 +142,31 @@ void LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message)
// BELOW LogWorker
// BELOW g2LogWorker
// Public API implementation
LogWorker::LogWorker(const std::string& log_prefix, const std::string& log_directory)
: pimpl_(new LogWorkerImpl(log_prefix, log_directory))
g2LogWorker::g2LogWorker(const std::string& log_prefix, const std::string& log_directory)
: pimpl_(new g2LogWorkerImpl(log_prefix, log_directory))
, log_file_with_path_(pimpl_->log_file_with_path_)
{
}
LogWorker::~LogWorker()
g2LogWorker::~g2LogWorker()
{
pimpl_.reset();
std::cout << "\nExiting, log location: " << log_file_with_path_ << std::endl << std::flush;
}
void LogWorker::save(g2::internal::LogEntry msg)
void g2LogWorker::save(g2::internal::LogEntry msg)
{
pimpl_->bg_->send(std::tr1::bind(&LogWorkerImpl::backgroundFileWrite, pimpl_.get(), msg));
pimpl_->bg_->send(std::tr1::bind(&g2LogWorkerImpl::backgroundFileWrite, pimpl_.get(), msg));
}
void LogWorker::fatal(g2::internal::FatalMessage fatal_message)
void g2LogWorker::fatal(g2::internal::FatalMessage fatal_message)
{
pimpl_->bg_->send(std::tr1::bind(&LogWorkerImpl::backgroundExitFatal, pimpl_.get(), fatal_message));
pimpl_->bg_->send(std::tr1::bind(&g2LogWorkerImpl::backgroundExitFatal, pimpl_.get(), fatal_message));
}
std::string LogWorker::logFileName() const
std::string g2LogWorker::logFileName() const
{
return log_file_with_path_;
}

View File

@ -1,8 +1,8 @@
#ifndef LOG_WORKER_H_
#define LOG_WORKER_H_
#ifndef G2_LOG_WORKER_H_
#define G2_LOG_WORKER_H_
/* *************************************************
* Filename:logworker.h Framework for Logging and Design By Contract
* Filename:g2logworker.h Framework for Logging and Design By Contract
* Created: 2011 by Kjell Hedström
*
* PUBLIC DOMAIN and Not copywrited. First published at KjellKod.cc
@ -10,16 +10,16 @@
#include <memory>
#include "g2log.h"
class LogWorkerImpl;
class g2LogWorkerImpl;
/**
* \param log_prefix is the 'name' of the binary, this give the log name 'LOG-'name'-...
* \param log_directory gives the directory to put the log files */
class LogWorker
class g2LogWorker
{
public:
LogWorker(const std::string& log_prefix, const std::string& log_directory);
virtual ~LogWorker();
g2LogWorker(const std::string& log_prefix, const std::string& log_directory);
virtual ~g2LogWorker();
/// pushes in background thread (asynchronously) input messages to log file
void save(g2::internal::LogEntry entry);
@ -33,11 +33,11 @@ public:
std::string logFileName() const;
private:
std::unique_ptr<LogWorkerImpl> pimpl_;
std::unique_ptr<g2LogWorkerImpl> pimpl_;
const std::string log_file_with_path_;
LogWorker(const LogWorker&); // c++11 feature not yet in vs2010 = delete;
LogWorker& operator=(const LogWorker&); // c++11 feature not yet in vs2010 = delete;
g2LogWorker(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
g2LogWorker& operator=(const g2LogWorker&); // c++11 feature not yet in vs2010 = delete;
};

View File

@ -5,9 +5,8 @@
* PUBLIC DOMAIN and Not copy-writed
* ********************************************* */
#include "logworker.h"
#include "g2logworker.h"
#include "g2log.h"
#include "logworker.h"
#include <iomanip>
namespace
@ -25,14 +24,9 @@ int main(int argc, char** argv)
float pi_f = 3.1415926535897932384626433832795f;
LogWorker logger(argv[0], path_to_log_file);
g2LogWorker logger(argv[0], path_to_log_file);
g2::initializeLogging(&logger);
std::cout << "****** A NUMBER of 'runtime exceptions' will be printed on this screen" << std::endl;
std::cout << "****** that's all good and part of the 'example'. " << std::endl;
std::cout << "****** please see g2log/src/main.cpp and he finished log file to " << std::endl;
std::cout << "****** follow what is done in this example\n\n" << std::endl;
LOGF(INFO, "Hi log %d", 123);
LOG(INFO) << "Test SLOG INFO";
LOG(DEBUG) << "Test SLOG DEBUG";
@ -51,15 +45,6 @@ int main(int argc, char** argv)
//LOG(UNKNOWN_LEVEL) << "This log attempt will cause a compiler error";
LOG(INFO) << "Simple to use with streaming syntax, easy as abc or " << 123;
LOGF(WARNING, "Printf-style syntax is also %s", "available");
// ....
try
{
LOGF(FATAL, "FATAL has a special meaning. This %s will throw an exception", "message");
}
catch(...)
{
std::cout << "\n **** All good expected the 'FATAL has a special meaning' runtime exception\n\n\n" << std::endl;
}
LOG_IF(INFO, (1 < 2)) << "If true this text will be logged";
LOGF_IF(INFO, (1<2), "if %d<%d : then this text will be logged", 1,2);
LOG_IF(FATAL, (2>3)) << "This message should NOT throw";
@ -68,42 +53,14 @@ int main(int argc, char** argv)
{
const std::string logging = "logging";
// OK --- this WILL get a compiler warning
LOGF(DEBUG, "Printf-type %s is the number 1 for many %s", logging.c_str());
}
CHECK(1 != 2); // true: won't throw
try
{
CHECK(1 > 2) << "CHECK(false) will put this message to the throw exception message and our log";
}
catch(...)
{
std::cout << "\n **** All good expected the 'CHECK(false) will put ...' runtime exception\n\n\n" << std::endl;
}
//
// END: LOG Entris that were in the article
//
try
{
const std::string arg = "CHECK_F";
CHECK_F(1 > 2, "This is a test to see if %s works", arg.c_str());
}
catch(...)
{
std::cout << "\n **** All good expected the 'CHECK(1>2) This is a test ...' runtime exception\n\n\n" << std::endl;
LOGF(DEBUG, "ILLEGAL PRINTF_SYNTAX EXAMPLE. WILL GENERATE compiler warning.\n\nbadly formatted message:[Printf-type %s is the number 1 for many %s]", logging.c_str());
}
try
{
std::cout << "\n\n***** Be ready the example will show a 'runtime exception' " << std::endl;
std::cout << "\n\n***** Be ready this last example will 'abort' " << std::endl;
std::cout << "***** please theck the logfile for all the LOGS and compare them to this example" << std::endl;
std::cout << "***** this file is g2log/src/main.cpp. The log file is: " << logger.logFileName() << std::endl;
std::cout << "************************************************************\n\n" << std::endl;
CHECK(1<2) << "SHOULD NOT SEE THIS MESSAGE";
CHECK(1>2) << "Test to see if contract works: onetwothree: " << 123 << ". This should be inside an exception";
}
catch(...)
{
std::cout << "\n***** All good, the 'exception' was part of the example\n\n\n" << std::endl;
return 0;
}
std::cerr << "Unexpected ending, expected an exception" << std::endl << std::flush;
return 1;
CHECK(1>2) << "Test to see if contract works: onetwothree: " << 123 << ". This should be at the end of the log, and will exit this example";
}

View File

@ -49,7 +49,7 @@ int main(int argc, char** argv)
oss.str(""); // clear the stream
#if defined(G2LOG_PERFORMANCE)
LogWorker* logger = new LogWorker(g_prefix_log_name, g_path);
g2LogWorker* logger = new g2LogWorker(g_prefix_log_name, g_path);
g2::initializeLogging(logger);
#elif defined(GOOGLE_GLOG_PERFORMANCE)
google::InitGoogleLogging(argv[0]);
@ -85,7 +85,7 @@ int main(int argc, char** argv)
auto total_time_us = std::chrono::duration_cast<microsecond>(worker_end_time - start_time).count();
oss << "\n" << g_iterations << " log entries took: [" << total_time_us / 1000000 << " s] to write to disk"<< std::endl;
oss << "[Application(2threads):\t\t:" << application_time_us/1000 << " ms]" << std::endl;
oss << "[Application(" << number_of_threads << "):\t\t:" << application_time_us/1000 << " ms]" << std::endl;
oss << "[Background thread to finish\t:" << total_time_us/1000 << " ms]" << std::endl;
oss << "\nAverage time per log entry:" << std::endl;
oss << "[Application: " << application_time_us/(number_of_threads*g_iterations) << " us]" << std::endl;

View File

@ -26,6 +26,10 @@ const std::string g_path = "/tmp/";
using namespace g2_test;
//
// OK: The code below isn't pretty but it works. Lots and lots of log entries
// to keep track of!
//
int main(int argc, char** argv)
{
size_t number_of_threads =0;
@ -57,7 +61,7 @@ int main(int argc, char** argv)
oss.str(""); // clear the stream
#if defined(G2LOG_PERFORMANCE)
LogWorker* logger = new LogWorker(g_prefix_log_name, g_path);
g2LogWorker* logger = new g2LogWorker(g_prefix_log_name, g_path);
g2::initializeLogging(logger);
#elif defined(GOOGLE_GLOG_PERFORMANCE)
google::InitGoogleLogging(argv[0]);

View File

@ -22,7 +22,7 @@
#if defined(G2LOG_PERFORMANCE)
#include "g2log.h"
#include "logworker.h"
#include "g2logworker.h"
#elif defined(GOOGLE_GLOG_PERFORMANCE)
#include <glog/logging.h>
#else

View File

@ -7,7 +7,7 @@
#include <gtest/gtest.h>
#include "g2log.h"
#include "logworker.h"
#include "g2logworker.h"
#include <memory>
#include <string>
#include <fstream>
@ -50,16 +50,17 @@ struct RestoreLogger
void reset();
std::string readFileToText();
std::unique_ptr<LogWorker> logger_;
std::unique_ptr<g2LogWorker> logger_;
const std::string log_file_;
};
RestoreLogger::RestoreLogger()
: logger_(new LogWorker("UNIT_TEST_LOGGER", "./"))
: logger_(new g2LogWorker("UNIT_TEST_LOGGER", "./"))
, log_file_(logger_->logFileName())
{
g2::initializeLogging(logger_.get());
g2::internal::changeFatalInitHandlerForUnitTesting();
}
RestoreLogger::~RestoreLogger()
@ -175,13 +176,13 @@ TEST(LogTest, LOGF__FATAL)
try
{
LOGF(FATAL, "This message should throw %d",0);
sleep(k_wait_time);
}
catch (std::exception const &e)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
std::cerr << file_content << std::endl << std::flush;
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL") &&
verifyContent(file_content, "This message should throw"))
{
@ -203,13 +204,12 @@ TEST(LogTest, LOG_FATAL)
try
{
LOG(FATAL) << "This message should throw";
sleep(k_wait_time);
}
catch (std::exception const &e)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL") &&
verifyContent(file_content, "This message should throw"))
{
@ -231,13 +231,12 @@ TEST(LogTest, LOGF_IF__FATAL)
try
{
LOGF_IF(FATAL, (2<3), "This message%sshould throw"," ");
sleep(k_wait_time);
}
catch (std::exception const &e)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL") &&
verifyContent(file_content, "This message should throw"))
{
@ -260,13 +259,12 @@ TEST(LogTest, LOG_IF__FATAL)
{
LOG_IF(WARNING, (0 != t_info.compare(t_info))) << "This message should NOT be written";
LOG_IF(FATAL, (0 != t_info.compare(t_info2))) << "This message should throw";
sleep(k_wait_time);
}
catch (std::exception const &e)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL") &&
verifyContent(file_content, "This message should throw") &&
(false == verifyContent(file_content, "This message should NOT be written")))
@ -311,7 +309,7 @@ TEST(CheckTest, CHECK_F__thisWILL_PrintErrorMsg)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL"))
{
SUCCEED();
@ -332,13 +330,12 @@ TEST(CHECK_F_Test, CHECK_F__thisWILL_PrintErrorMsg)
try
{
CHECK_F(1 >= 2, msg.c_str(), arg1.c_str(), arg2.c_str());
sleep(k_wait_time);
}
catch (std::exception const &e)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL") &&
verifyContent(file_content, msg2))
{
@ -364,7 +361,7 @@ TEST(CHECK_Test, CHECK__thisWILL_PrintErrorMsg)
{
logger.reset();
std::string file_content = readFileToText(logger.log_file_);
if(verifyContent(e.what(), "RUNTIME EXCEPTION") &&
if(verifyContent(e.what(), "EXIT trigger caused by ") &&
verifyContent(file_content, "FATAL") &&
verifyContent(file_content, msg2))
{