diff --git a/g2log/CMakeLists.txt b/g2log/CMakeLists.txt index 3f6baf0..5eaf517 100644 --- a/g2log/CMakeLists.txt +++ b/g2log/CMakeLists.txt @@ -99,7 +99,7 @@ ENDIF(MSVC) # GENERIC STEPS - file(GLOB SRC_FILES ${LOG_SRC}/*.h ${LOG_SRC}/*.hpp ${LOG_SRC}/*.cpp ) + file(GLOB SRC_FILES ${LOG_SRC}/*.h ${LOG_SRC}/*.hpp ${LOG_SRC}/*.cpp) if(MSVC) list(REMOVE_ITEM SRC_FILES ${LOG_SRC}/crashhandler_unix.cpp) else() diff --git a/g2log/src/g2logworker.cpp b/g2log/src/g2logworker.cpp index f724d2f..01950fb 100644 --- a/g2log/src/g2logworker.cpp +++ b/g2log/src/g2logworker.cpp @@ -26,289 +26,73 @@ #include "crashhandler.h" #include "g2time.h" #include "g2future.h" +#include "g2filesink.h" +#include "std2_make_unique.hpp" using namespace g2; using namespace g2::internal; -namespace -{ -static const std::string date_formatted = "%Y/%m/%d"; -static const std::string time_formatted = "%H:%M:%S"; -static const std::string file_name_time_formatted = "%Y%m%d-%H%M%S"; - -// check for filename validity - filename should not be part of PATH -bool isValidFilename(const std::string prefix_filename) -{ - - std::string illegal_characters("/,|<>:#$%{}()[]\'\"^!?+* "); - size_t pos = prefix_filename.find_first_of(illegal_characters,0); - if(pos != std::string::npos) - { - std::cerr << "Illegal character [" << prefix_filename.at(pos) << "] in logname prefix: " << "[" << prefix_filename << "]" << std::endl; - return false; - } - else if (prefix_filename.empty()) - { - std::cerr << "Empty filename prefix is not allowed" << std::endl; - return false; - } - - return true; -} - - -// Clean up the path if put in by mistake in the prefix -std::string prefixSanityFix(std::string prefix) -{ - prefix.erase(std::remove_if(prefix.begin(), prefix.end(), ::isspace), prefix.end()); - prefix.erase(std::remove( prefix.begin(), prefix.end(), '/'), prefix.end()); // '/' - prefix.erase(std::remove( prefix.begin(), prefix.end(), '\\'), prefix.end()); // '\\' - prefix.erase(std::remove( prefix.begin(), prefix.end(), '.'), prefix.end()); // '.' - if(!isValidFilename(prefix)) - { - return ""; - } - return prefix; -} - - -std::string pathSanityFix(std::string path, std::string file_name) { - // Unify the delimeters,. maybe sketchy solution but it seems to work - // on at least win7 + ubuntu. All bets are off for older windows - std::replace(path.begin(), path.end(), '\\', '/'); - - // clean up in case of multiples - auto contains_end = [&](std::string& in) -> bool { - size_t size = in.size(); - if(!size) return false; - char end = in[size-1]; - return (end == '/' || end == ' '); - }; - - while(contains_end(path)) { path.erase(path.size()-1); } - if(!path.empty()) { - path.insert(path.end(), '/'); - } - path.insert(path.size(), file_name); - return path; -} - - -std::string createLogFileName(const std::string& verified_prefix) -{ - std::stringstream oss_name; - oss_name.fill('0'); - oss_name << verified_prefix << ".g2log."; - oss_name << g2::localtime_formatted(g2::systemtime_now(), file_name_time_formatted); - oss_name << ".log"; - return oss_name.str(); -} - - -bool openLogFile(const std::string& complete_file_with_path, std::ofstream& outstream) -{ - std::ios_base::openmode mode = std::ios_base::out; // for clarity: it's really overkill since it's an ofstream - mode |= std::ios_base::trunc; - outstream.open(complete_file_with_path, mode); - if(!outstream.is_open()) - { - std::ostringstream ss_error; - ss_error << "FILE ERROR: could not open log file:[" << complete_file_with_path << "]"; - ss_error << "\n\t\t std::ios_base state = " << outstream.rdstate(); - std::cerr << ss_error.str().c_str() << std::endl << std::flush; - outstream.close(); - return false; - } - std::ostringstream ss_entry; - // Day Month Date Time Year: is written as "%a %b %d %H:%M:%S %Y" and formatted output as : Wed Sep 19 08:28:16 2012 - ss_entry << "\t\tg2log created log file at: "<< g2::localtime_formatted(g2::systemtime_now(), "%a %b %d %H:%M:%S %Y") << "\n"; - ss_entry << "\t\tLOG format: [YYYY/MM/DD hh:mm:ss.uuu* LEVEL FILE:LINE] message\n\n"; // TODO: if(header) - outstream << ss_entry.str() << std::flush; - outstream.fill('0'); - return true; -} - - -std::unique_ptr createLogFile(const std::string& file_with_full_path) -{ - std::unique_ptr out(new std::ofstream); - std::ofstream& stream(*(out.get())); - bool success_with_open_file = openLogFile(file_with_full_path, stream); - if(false == success_with_open_file) - { - out.release(); // nullptr contained ptr signals error in creating the log file - } - return out; -} -} // end anonymous namespace - - -/** The Real McCoy Background worker, while g2LogWorker gives the -* asynchronous API to put job in the background the g2LogWorkerImpl -* does the actual background thread work */ struct g2LogWorkerImpl { - 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); - std::string backgroundChangeLogFile(const std::string& directory); - std::string backgroundFileName(); - - std::string log_file_with_path_; - std::string log_prefix_backup_; // needed in case of future log file changes of directory - std::unique_ptr bg_; - std::unique_ptr outptr_; - steady_time_point steady_start_time_; - -private: - g2LogWorkerImpl& operator=(const g2LogWorkerImpl&); // c++11 feature not yet in vs2010 = delete; - g2LogWorkerImpl(const g2LogWorkerImpl& other); // c++11 feature not yet in vs2010 = delete; - std::ofstream& filestream(){return *(outptr_.get());} + typedef std::shared_ptr SinkWrapperPtr; + + g2LogWorkerImpl(){} + ~g2LogWorkerImpl(){ _bg.reset(); _sinks.clear(); } + + std::unique_ptr _bg; + std::vector _sinks; + std::shared_ptr> _default_sink_handle; + void bgSave(g2::internal::LogEntry msg) { + for(auto& sink : _sinks) { + sink->send(msg); + } + } + + void bgFatal(g2::internal::FatalMessage fatal_message){ + auto entry = fatal_message.message_; + bgSave(entry); + _sinks.clear(); // flush all queues + exitWithDefaultSignalHandler(fatal_message.signal_id_); + } }; - -// -// Private API implementation : g2LogWorkerImpl -g2LogWorkerImpl::g2LogWorkerImpl(const std::string& log_prefix, const std::string& log_directory) - : log_file_with_path_(log_directory) - , log_prefix_backup_(log_prefix) - , bg_(kjellkod::Active::createActive()) - , outptr_(new std::ofstream) - , steady_start_time_(std::chrono::steady_clock::now()) // TODO: ha en timer function steadyTimer som har koll på start -{ - log_prefix_backup_ = prefixSanityFix(log_prefix); - if(!isValidFilename(log_prefix_backup_)) - { - // illegal prefix, refuse to start - std::cerr << "g2log: forced abort due to illegal log prefix [" << log_prefix <<"]" << std::endl << std::flush; - abort(); - } - - std::string file_name = createLogFileName(log_prefix_backup_); - log_file_with_path_ = pathSanityFix(log_file_with_path_, file_name); - outptr_ = createLogFile(log_file_with_path_); - if(!outptr_) { - std::cerr << "Cannot write logfile to location, attempting current directory" << std::endl; - log_file_with_path_ = file_name; - outptr_ = createLogFile(log_file_with_path_); - } - assert((outptr_) && "cannot open log file at startup"); -} - - -g2LogWorkerImpl::~g2LogWorkerImpl() -{ - std::ostringstream ss_exit; - bg_.reset(); // flush the log queue - ss_exit << "\n\t\tg2log file shutdown at: " << g2::localtime_formatted(g2::systemtime_now(), time_formatted); - filestream() << ss_exit.str() << std::flush; -} - - -void g2LogWorkerImpl::backgroundFileWrite(LogEntry message) -{ - using namespace std; - std::ofstream& out(filestream()); - auto system_time = g2::systemtime_now(); - auto steady_time = std::chrono::steady_clock::now(); - out << "\n" << g2::localtime_formatted(system_time, date_formatted); - out << " " << g2::localtime_formatted(system_time, time_formatted); // TODO: time kommer från LogEntry - out << "." << chrono::duration_cast(steady_time - steady_start_time_).count(); //microseconds TODO: ta in min g2clocka här StopWatch - out << "\t" << message << std::flush; -} - - -void g2LogWorkerImpl::backgroundExitFatal(FatalMessage fatal_message) -{ - backgroundFileWrite(fatal_message.message_); - backgroundFileWrite("Log flushed successfully to disk \nExiting"); - std::cerr << "g2log exiting after receiving fatal event" << std::endl; - std::cerr << "Log file at: [" << log_file_with_path_ << "]\n" << std::endl << std::flush; - filestream().close(); - exitWithDefaultSignalHandler(fatal_message.signal_id_); - perror("g2log exited after receiving FATAL trigger. Flush message status: "); // should never reach this point -} - - -std::string g2LogWorkerImpl::backgroundChangeLogFile(const std::string& directory) -{ - std::string file_name = createLogFileName(log_prefix_backup_); - std::string prospect_log = directory + file_name; - std::unique_ptr log_stream = createLogFile(prospect_log); - if(nullptr == log_stream) - { - backgroundFileWrite("Unable to change log file. Illegal filename or busy? Unsuccessful log name was:" + prospect_log); - return ""; // no success - } - - std::ostringstream ss_change; - ss_change << "\n\tChanging log file from : " << log_file_with_path_; - ss_change << "\n\tto new location: " << prospect_log << "\n"; - backgroundFileWrite(ss_change.str().c_str()); - ss_change.str(""); - - // setting the new log as active - std::string old_log = log_file_with_path_; - log_file_with_path_ = prospect_log; - outptr_ = std::move(log_stream); - ss_change << "\n\tNew log file. The previous log file was at: "; - ss_change << old_log; - backgroundFileWrite(ss_change.str()); - return log_file_with_path_; -} - -std::string g2LogWorkerImpl::backgroundFileName() -{ - return log_file_with_path_; -} - - - - -// -// ***** BELOW g2LogWorker ***** -// Public API implementation -// +// Default constructor will have one sink: g2filesink. 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_) -{ - assert((pimpl_ != nullptr) && "shouild never happen"); -} + : _pimpl(std2::make_unique()) + { +// auto unique = std::unique_ptr(new g2FileSink(log_prefix, log_directory)); +// auto handle = addSink(std::move(unique), &g2FileSink::writeToFile); +// _pimpl._file_handle.reset(handle.release()); + } g2LogWorker::~g2LogWorker() { - pimpl_.reset(); - std::cerr << "\nExiting, log location: " << log_file_with_path_ << std::endl << std::flush; + _pimpl.reset(); } void g2LogWorker::save(g2::internal::LogEntry msg) { - pimpl_->bg_->send(std::bind(&g2LogWorkerImpl::backgroundFileWrite, pimpl_.get(), msg)); + _pimpl->_bg->send([this, msg]{ _pimpl->bgSave(msg); }); + //std::bind(&g2LogWorkerImpl::backgroundFileWrite, _pimpl.get(), msg)); } void g2LogWorker::fatal(g2::internal::FatalMessage fatal_message) { - pimpl_->bg_->send(std::bind(&g2LogWorkerImpl::backgroundExitFatal, pimpl_.get(), fatal_message)); + _pimpl->_bg->send([this, fatal_message]{ _pimpl->bgFatal(fatal_message); }); + //std::bind(&g2LogWorkerImpl::backgroundExitFatal, _pimpl.get(), fatal_message)); } -std::future g2LogWorker::changeLogFile(const std::string& log_directory) -{ - kjellkod::Active* bgWorker = pimpl_->bg_.get(); - //auto future_result = g2::spawn_task(std::bind(&g2LogWorkerImpl::backgroundChangeLogFile, pimpl_.get(), log_directory), bgWorker); - auto bg_call = [this, log_directory]() {return pimpl_->backgroundChangeLogFile(log_directory);}; - auto future_result = g2::spawn_task(bg_call, bgWorker); - return std::move(future_result); +void g2LogWorker::addWrappedSink(std::shared_ptr sink) { + auto bg_addsink_call = [this, sink] { _pimpl->_sinks.push_back(sink); }; + auto token_done = g2::spawn_task(bg_addsink_call, _pimpl->_bg.get()); + token_done.wait(); } -std::future g2LogWorker::logFileName() -{ - kjellkod::Active* bgWorker = pimpl_->bg_.get(); - auto bg_call=[&](){return pimpl_->backgroundFileName();}; - auto future_result = g2::spawn_task(bg_call ,bgWorker); - return std::move(future_result); -} + + + std::shared_ptr> g2LogWorker::getFileSinkHandle() + { + return _pimpl->_default_sink_handle; + } \ No newline at end of file diff --git a/g2log/src/g2logworker.h b/g2log/src/g2logworker.h index 01f11bc..eb13e7a 100644 --- a/g2log/src/g2logworker.h +++ b/g2log/src/g2logworker.h @@ -15,10 +15,15 @@ #include #include #include +#include "std2_make_unique.hpp" #include "g2log.h" +#include "g2sinkwrapper.h" +#include "g2sinkhandle.h" + struct g2LogWorkerImpl; +struct g2FileSink; /** * \param log_prefix is the 'name' of the binary, this give the log name 'LOG-'name'-... @@ -37,18 +42,33 @@ public: /// Will abort the application! void fatal(g2::internal::FatalMessage fatal_message); + template + std::unique_ptr> addSink(std::unique_ptr real_sink, DefaultLogCall call) + { + using namespace g2; + using namespace g2::internal; + auto shared_sink = std::shared_ptr(real_sink.release()); + auto sink = std::make_shared>(shared_sink, call); + auto add_result = addWrappedSink(sink); + return std2::make_unique>(sink); + } + + + + /// DEPRECATED - SHOULD BE Called through a sink handler instead /// Attempt to change the current log file to another name/location. /// returns filename with full path if successful, else empty string - std::future changeLogFile(const std::string& log_directory); - + //std::future changeLogFile(const std::string& log_directory); /// Probably only needed for unit-testing or specific log management post logging /// request to get log name is processed in FIFO order just like any other background job. - std::future logFileName(); + //std::future logFileName(); + std::shared_ptr> getFileSinkHandle(); private: - std::unique_ptr pimpl_; - const std::string log_file_with_path_; + void addWrappedSink(std::shared_ptr wrapper); + + std::unique_ptr _pimpl; 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/std2_make_unique.hpp b/g2log/src/std2_make_unique.hpp index 184cbbd..928c82e 100644 --- a/g2log/src/std2_make_unique.hpp +++ b/g2log/src/std2_make_unique.hpp @@ -15,6 +15,9 @@ * auto an_int_array = make_unique(11, 22, 33); * ********************************************* */ +#ifndef STD2_MAKE_UNIQUE_HPP_ +#define STD2_MAKE_UNIQUE_HPP_ + #include #include #include @@ -42,5 +45,5 @@ namespace std2 { } } - +#endif diff --git a/g2log/test_unit/test_filechange.cpp b/g2log/test_unit/test_filechange.cpp index 4692b7b..2ecb577 100644 --- a/g2log/test_unit/test_filechange.cpp +++ b/g2log/test_unit/test_filechange.cpp @@ -1,137 +1,137 @@ -/** ========================================================================== - * 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes - * with no warranties. This code is yours to share, use and modify with no - * strings attached and no restrictions or obligations. - * ============================================================================*/ - - -#include -#include -#include -#include -#include -#include -#include - - -#include -#include "g2log.h" -#include "g2logworker.h" -#include "testing_helpers.h" - -using namespace testing_helper__cleaner; - - -namespace { // anonymous - const char* name_path_1 = "./some_fake_DirectoryOrName_1_"; - const char* name_path_2 = "./some_fake_DirectoryOrName_3_"; - g2LogWorker* g_logger_ptr = nullptr; - LogFileCleaner* g_cleaner_ptr = nullptr; - - - - bool isTextAvailableInContent(const std::string &total_text, std::string msg_to_find) { - std::string content(total_text); - size_t location = content.find(msg_to_find); - return (location != std::string::npos); - } - - std::string readFileToText(std::string filename) { - std::ifstream in; - in.open(filename.c_str(), std::ios_base::in); - if (!in.is_open()) { - return ""; // error just return empty string - test will 'fault' - } - std::ostringstream oss; - oss << in.rdbuf(); - std::string content(oss.str()); - return content; - } - - std::string changeDirectoryOrName(std::string new_file_to_create) { - static std::mutex m; - static int count; - std::lock_guard lock(m); - { - std::string add_count = std::to_string(++count) + "_"; - auto new_log = g_logger_ptr->changeLogFile(new_file_to_create + add_count).get(); - if (!new_log.empty()) g_cleaner_ptr->addLogToClean(new_log); - return new_log; - } - } -} // anonymous - - - - - - -// TODO: this must change. Initialization of this is done here! and not in a special test_main.cpp -// which MAY be OK ... however it is also very redundant with test_io - -TEST(TestOf_GetFileName, Expecting_ValidLogFile) { - - LOG(INFO) << "test_filechange, Retrieving file name: "; - ASSERT_NE(g_logger_ptr, nullptr); - std::future f_get_old_name = g_logger_ptr->logFileName(); - ASSERT_TRUE(f_get_old_name.valid()); - ASSERT_FALSE(f_get_old_name.get().empty()); -} - -TEST(TestOf_ChangingLogFile, Expecting_NewLogFileUsed) { - auto old_log = g_logger_ptr->logFileName().get(); - std::string name = changeDirectoryOrName(name_path_1); - auto new_log = g_logger_ptr->changeLogFile(name).get(); -} - -TEST(TestOf_ManyThreadsChangingLogFileName, Expecting_EqualNumberLogsCreated) { - auto old_log = g_logger_ptr->logFileName().get(); - if (!old_log.empty()) g_cleaner_ptr->addLogToClean(old_log); - - LOG(INFO) << "SoManyThreadsAllDoingChangeFileName"; - std::vector threads; - auto max = 2; - auto size = g_cleaner_ptr->size(); - for (auto count = 0; count < max; ++count) { - std::string drive = ((count % 2) == 0) ? "./_threadEven_" : "./_threaOdd_"; - threads.push_back(std::thread(changeDirectoryOrName, drive)); - } - for (auto& thread : threads) - thread.join(); - - // check that all logs were created - ASSERT_EQ(size + max, g_cleaner_ptr->size()); -} - -TEST(TestOf_IllegalLogFileName, Expecting_NoChangeToOriginalFileName) { - std::string original = g_logger_ptr->logFileName().get(); - std::cerr << "Below WILL print 'FiLE ERROR'. This is part of the testing and perfectly OK" << std::endl; - std::cerr << "****" << std::endl; - std::future perhaps_a_name = g_logger_ptr->changeLogFile("XY:/"); // does not exist - ASSERT_TRUE(perhaps_a_name.get().empty()); - std::cerr << "****" << std::endl; - std::string post_illegal = g_logger_ptr->logFileName().get(); - ASSERT_STREQ(original.c_str(), post_illegal.c_str()); -} - -int main(int argc, char *argv[]) { - LogFileCleaner cleaner; - g_cleaner_ptr = &cleaner; - int return_value = 1; - - std::string last_log_file; - { - g2LogWorker logger("ReplaceLogFile", name_path_2); - testing::InitGoogleTest(&argc, argv); - g_logger_ptr = &logger; // ugly but fine for this test - g2::initializeLogging(g_logger_ptr); - cleaner.addLogToClean(g_logger_ptr->logFileName().get()); - return_value = RUN_ALL_TESTS(); - last_log_file = g_logger_ptr->logFileName().get(); - //g2::shutDownLogging(); - } - std::cout << "FINISHED WITH THE TESTING" << std::endl; - // cleaning up - cleaner.addLogToClean(last_log_file); - return return_value; -} +///** ========================================================================== +// * 2012 by KjellKod.cc. This is PUBLIC DOMAIN to use at your own risk and comes +// * with no warranties. This code is yours to share, use and modify with no +// * strings attached and no restrictions or obligations. +// * ============================================================================*/ +// +// +//#include +//#include +//#include +//#include +//#include +//#include +//#include +// +// +//#include +//#include "g2log.h" +//#include "g2logworker.h" +//#include "testing_helpers.h" +// +//using namespace testing_helper__cleaner; +// +// +//namespace { // anonymous +// const char* name_path_1 = "./some_fake_DirectoryOrName_1_"; +// const char* name_path_2 = "./some_fake_DirectoryOrName_3_"; +// g2LogWorker* g_logger_ptr = nullptr; +// LogFileCleaner* g_cleaner_ptr = nullptr; +// +// +// +// bool isTextAvailableInContent(const std::string &total_text, std::string msg_to_find) { +// std::string content(total_text); +// size_t location = content.find(msg_to_find); +// return (location != std::string::npos); +// } +// +// std::string readFileToText(std::string filename) { +// std::ifstream in; +// in.open(filename.c_str(), std::ios_base::in); +// if (!in.is_open()) { +// return ""; // error just return empty string - test will 'fault' +// } +// std::ostringstream oss; +// oss << in.rdbuf(); +// std::string content(oss.str()); +// return content; +// } +// +// std::string changeDirectoryOrName(std::string new_file_to_create) { +// static std::mutex m; +// static int count; +// std::lock_guard lock(m); +// { +// std::string add_count = std::to_string(++count) + "_"; +// auto new_log = g_logger_ptr->changeLogFile(new_file_to_create + add_count).get(); +// if (!new_log.empty()) g_cleaner_ptr->addLogToClean(new_log); +// return new_log; +// } +// } +//} // anonymous +// +// +// +// +// +// +//// TODO: this must change. Initialization of this is done here! and not in a special test_main.cpp +//// which MAY be OK ... however it is also very redundant with test_io +// +//TEST(TestOf_GetFileName, Expecting_ValidLogFile) { +// +// LOG(INFO) << "test_filechange, Retrieving file name: "; +// ASSERT_NE(g_logger_ptr, nullptr); +// std::future f_get_old_name = g_logger_ptr->logFileName(); +// ASSERT_TRUE(f_get_old_name.valid()); +// ASSERT_FALSE(f_get_old_name.get().empty()); +//} +// +//TEST(TestOf_ChangingLogFile, Expecting_NewLogFileUsed) { +// auto old_log = g_logger_ptr->logFileName().get(); +// std::string name = changeDirectoryOrName(name_path_1); +// auto new_log = g_logger_ptr->changeLogFile(name).get(); +//} +// +//TEST(TestOf_ManyThreadsChangingLogFileName, Expecting_EqualNumberLogsCreated) { +// auto old_log = g_logger_ptr->logFileName().get(); +// if (!old_log.empty()) g_cleaner_ptr->addLogToClean(old_log); +// +// LOG(INFO) << "SoManyThreadsAllDoingChangeFileName"; +// std::vector threads; +// auto max = 2; +// auto size = g_cleaner_ptr->size(); +// for (auto count = 0; count < max; ++count) { +// std::string drive = ((count % 2) == 0) ? "./_threadEven_" : "./_threaOdd_"; +// threads.push_back(std::thread(changeDirectoryOrName, drive)); +// } +// for (auto& thread : threads) +// thread.join(); +// +// // check that all logs were created +// ASSERT_EQ(size + max, g_cleaner_ptr->size()); +//} +// +//TEST(TestOf_IllegalLogFileName, Expecting_NoChangeToOriginalFileName) { +// std::string original = g_logger_ptr->logFileName().get(); +// std::cerr << "Below WILL print 'FiLE ERROR'. This is part of the testing and perfectly OK" << std::endl; +// std::cerr << "****" << std::endl; +// std::future perhaps_a_name = g_logger_ptr->changeLogFile("XY:/"); // does not exist +// ASSERT_TRUE(perhaps_a_name.get().empty()); +// std::cerr << "****" << std::endl; +// std::string post_illegal = g_logger_ptr->logFileName().get(); +// ASSERT_STREQ(original.c_str(), post_illegal.c_str()); +//} +// +//int main(int argc, char *argv[]) { +// LogFileCleaner cleaner; +// g_cleaner_ptr = &cleaner; +// int return_value = 1; +// +// std::string last_log_file; +// { +// g2LogWorker logger("ReplaceLogFile", name_path_2); +// testing::InitGoogleTest(&argc, argv); +// g_logger_ptr = &logger; // ugly but fine for this test +// g2::initializeLogging(g_logger_ptr); +// cleaner.addLogToClean(g_logger_ptr->logFileName().get()); +// return_value = RUN_ALL_TESTS(); +// last_log_file = g_logger_ptr->logFileName().get(); +// //g2::shutDownLogging(); +// } +// std::cout << "FINISHED WITH THE TESTING" << std::endl; +// // cleaning up +// cleaner.addLogToClean(last_log_file); +// return return_value; +//} diff --git a/g2log/test_unit/test_sink.cpp b/g2log/test_unit/test_sink.cpp index 2abe34a..41324f8 100644 --- a/g2log/test_unit/test_sink.cpp +++ b/g2log/test_unit/test_sink.cpp @@ -121,9 +121,13 @@ namespace g2 { auto h1 = worker.addSink(CoutSink::createSink(), &CoutSink::save); auto h2 = worker.addSink(std2::make_unique(), &StringSink::append); worker.save("Hello World!"); + + std::this_thread::sleep_for(std::chrono::milliseconds(100)); auto first = h1->call(&CoutSink::string); auto second = h2->call(&StringSink::string); + + ASSERT_EQ("Hello World!", first.get()); ASSERT_EQ("Hello World!", second.get()); } diff --git a/g2log/test_unit/testing_helpers.cpp b/g2log/test_unit/testing_helpers.cpp index a464b8a..ea0f172 100644 --- a/g2log/test_unit/testing_helpers.cpp +++ b/g2log/test_unit/testing_helpers.cpp @@ -3,6 +3,7 @@ #include "testing_helpers.h" #include "g2log.h" #include "g2logworker.h" +#include "g2filesink.h" #include "std2_make_unique.hpp" using namespace std; @@ -25,8 +26,9 @@ RestoreLogger::RestoreLogger(std::string directory) oldworker = g2::shutDownLogging(); g2::initializeLogging(logger_.get()); g2::internal::changeFatalInitHandlerForUnitTesting(); - - std::future filename(logger_->logFileName()); + + auto filehandler = logger_->getFileSinkHandle(); + auto filename = filehandler->call(&g2FileSink::logFileName); if (!filename.valid()) ADD_FAILURE(); log_file_ = filename.get(); }