From 925581d338e48b8a3ade45ab92640d838c15a369 Mon Sep 17 00:00:00 2001 From: Kjell Hedstrom Date: Wed, 16 Nov 2011 22:23:47 +0100 Subject: [PATCH] Updated for better unit-testing. Unit testing does not abort but throws a std::runtime_error if FATAL --- g2log/CMakeLists.txt | 8 +-- g2log/src/crashhandler.h | 2 +- g2log/src/crashhandler_unix.cpp | 4 +- g2log/src/g2log.cpp | 57 +++++++++++++----- g2log/src/g2log.h | 17 ++++-- g2log/src/{logworker.cpp => g2logworker.cpp} | 58 ++++++++----------- g2log/src/{logworker.h => g2logworker.h} | 20 +++---- g2log/src/main.cpp | 61 +++----------------- g2log/test/main_threaded_mean.cpp | 4 +- g2log/test/main_threaded_worst.cpp | 6 +- g2log/test/performance.h | 2 +- g2log/test/test_io.cpp | 27 ++++----- 12 files changed, 123 insertions(+), 143 deletions(-) rename g2log/src/{logworker.cpp => g2logworker.cpp} (70%) rename g2log/src/{logworker.h => g2logworker.h} (67%) diff --git a/g2log/CMakeLists.txt b/g2log/CMakeLists.txt index af40c4a..2caa2fd 100644 --- a/g2log/CMakeLists.txt +++ b/g2log/CMakeLists.txt @@ -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) diff --git a/g2log/src/crashhandler.h b/g2log/src/crashhandler.h index 1569155..d77e901 100644 --- a/g2log/src/crashhandler.h +++ b/g2log/src/crashhandler.h @@ -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 diff --git a/g2log/src/crashhandler_unix.cpp b/g2log/src/crashhandler_unix.cpp index 9fc1abd..58d4075 100644 --- a/g2log/src/crashhandler_unix.cpp +++ b/g2log/src/crashhandler_unix.cpp @@ -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) diff --git a/g2log/src/g2log.cpp b/g2log/src/g2log.cpp index 31a4707..a56ba9f 100644 --- a/g2log/src/g2log.cpp +++ b/g2log/src/g2log.cpp @@ -21,7 +21,7 @@ #include #include -#include "logworker.h" +#include "g2logworker.h" #include "crashhandler.h" #include @@ -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 lock(internal::g_logging_init_mutex); @@ -68,20 +68,50 @@ void initializeLogging(LogWorker *bgworker) } } -LogWorker* shutDownLogging() +g2LogWorker* shutDownLogging() { std::lock_guard 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 } diff --git a/g2log/src/g2log.h b/g2log/src/g2log.h index 855bdcc..d1416b5 100644 --- a/g2log/src/g2log.h +++ b/g2log/src/g2log.h @@ -21,7 +21,7 @@ #include #include -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 > millisecond; typedef std::chrono::duration > 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) */ diff --git a/g2log/src/logworker.cpp b/g2log/src/g2logworker.cpp similarity index 70% rename from g2log/src/logworker.cpp rename to g2log/src/g2logworker.cpp index 628857c..4d6ca55 100644 --- a/g2log/src/logworker.cpp +++ b/g2log/src/g2logworker.cpp @@ -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 #include @@ -17,10 +17,6 @@ #include #include - #if defined(YALLA) -#include // 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_; } diff --git a/g2log/src/logworker.h b/g2log/src/g2logworker.h similarity index 67% rename from g2log/src/logworker.h rename to g2log/src/g2logworker.h index 19af1fc..02c95e6 100644 --- a/g2log/src/logworker.h +++ b/g2log/src/g2logworker.h @@ -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 #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 pimpl_; + std::unique_ptr 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; }; diff --git a/g2log/src/main.cpp b/g2log/src/main.cpp index cab7c63..1bf85a9 100644 --- a/g2log/src/main.cpp +++ b/g2log/src/main.cpp @@ -5,9 +5,8 @@ * PUBLIC DOMAIN and Not copy-writed * ********************************************* */ -#include "logworker.h" +#include "g2logworker.h" #include "g2log.h" -#include "logworker.h" #include 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; - 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; + 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 at the end of the log, and will exit this example"; } diff --git a/g2log/test/main_threaded_mean.cpp b/g2log/test/main_threaded_mean.cpp index 31e1765..effcdff 100644 --- a/g2log/test/main_threaded_mean.cpp +++ b/g2log/test/main_threaded_mean.cpp @@ -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(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; diff --git a/g2log/test/main_threaded_worst.cpp b/g2log/test/main_threaded_worst.cpp index 0f99a1d..5d6c2a9 100644 --- a/g2log/test/main_threaded_worst.cpp +++ b/g2log/test/main_threaded_worst.cpp @@ -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]); diff --git a/g2log/test/performance.h b/g2log/test/performance.h index fb1b7c9..47d3b20 100644 --- a/g2log/test/performance.h +++ b/g2log/test/performance.h @@ -22,7 +22,7 @@ #if defined(G2LOG_PERFORMANCE) #include "g2log.h" -#include "logworker.h" +#include "g2logworker.h" #elif defined(GOOGLE_GLOG_PERFORMANCE) #include #else diff --git a/g2log/test/test_io.cpp b/g2log/test/test_io.cpp index bd8b0f8..dc758d1 100644 --- a/g2log/test/test_io.cpp +++ b/g2log/test/test_io.cpp @@ -7,7 +7,7 @@ #include #include "g2log.h" -#include "logworker.h" +#include "g2logworker.h" #include #include #include @@ -50,16 +50,17 @@ struct RestoreLogger void reset(); std::string readFileToText(); - std::unique_ptr logger_; + std::unique_ptr 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)) {