commented out some unit test. corrected other's. rigth now I am pondering to

always keeping the file-handle known in the bglogger.
--- Alternatively there is no zink at startup except colored out maybe?
This commit is contained in:
KjellKod 2013-07-23 22:01:12 -06:00
parent 3c67023389
commit 05018e389a
7 changed files with 219 additions and 406 deletions

View File

@ -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()

View File

@ -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<std::ofstream> createLogFile(const std::string& file_with_full_path)
{
std::unique_ptr<std::ofstream> 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<file> 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<kjellkod::Active> bg_;
std::unique_ptr<std::ofstream> 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<g2::internal::SinkWrapper> SinkWrapperPtr;
g2LogWorkerImpl(){}
~g2LogWorkerImpl(){ _bg.reset(); _sinks.clear(); }
std::unique_ptr<kjellkod::Active> _bg;
std::vector<SinkWrapperPtr> _sinks;
std::shared_ptr<g2::SinkHandle<g2FileSink>> _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<std::chrono::microseconds>(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<std::ofstream> 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<g2LogWorkerImpl>())
{
// auto unique = std::unique_ptr<g2FileSink>(new g2FileSink(log_prefix, log_directory));
// auto handle = addSink<g2FileSink>(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<std::string> 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<g2::internal::SinkWrapper> 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<std::string> 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<g2::SinkHandle<g2FileSink>> g2LogWorker::getFileSinkHandle()
{
return _pimpl->_default_sink_handle;
}

View File

@ -15,10 +15,15 @@
#include <memory>
#include <future>
#include <string>
#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<typename T, typename DefaultLogCall>
std::unique_ptr<g2::SinkHandle<T>> addSink(std::unique_ptr<T> real_sink, DefaultLogCall call)
{
using namespace g2;
using namespace g2::internal;
auto shared_sink = std::shared_ptr<T>(real_sink.release());
auto sink = std::make_shared<Sink<T>>(shared_sink, call);
auto add_result = addWrappedSink(sink);
return std2::make_unique<SinkHandle<T>>(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<std::string> changeLogFile(const std::string& log_directory);
//std::future<std::string> 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<std::string> logFileName();
//std::future<std::string> logFileName();
std::shared_ptr<g2::SinkHandle<g2FileSink>> getFileSinkHandle();
private:
std::unique_ptr<g2LogWorkerImpl> pimpl_;
const std::string log_file_with_path_;
void addWrappedSink(std::shared_ptr<g2::internal::SinkWrapper> wrapper);
std::unique_ptr<g2LogWorkerImpl> _pimpl;
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

@ -15,6 +15,9 @@
* auto an_int_array = make_unique<int[]>(11, 22, 33);
* ********************************************* */
#ifndef STD2_MAKE_UNIQUE_HPP_
#define STD2_MAKE_UNIQUE_HPP_
#include <memory>
#include <utility>
#include <type_traits>
@ -42,5 +45,5 @@ namespace std2 {
}
}
#endif

View File

@ -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 <gtest/gtest.h>
#include <memory>
#include <fstream>
#include <string>
#include <memory>
#include <future>
#include <queue>
#include <thread>
#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<std::mutex> 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<std::string> 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<std::thread> 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<std::string> 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 <gtest/gtest.h>
//#include <memory>
//#include <fstream>
//#include <string>
//#include <memory>
//#include <future>
//#include <queue>
//
//
//#include <thread>
//#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<std::mutex> 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<std::string> 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<std::thread> 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<std::string> 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;
//}

View File

@ -121,9 +121,13 @@ namespace g2 {
auto h1 = worker.addSink(CoutSink::createSink(), &CoutSink::save);
auto h2 = worker.addSink(std2::make_unique<StringSink>(), &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());
}

View File

@ -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<std::string> filename(logger_->logFileName());
auto filehandler = logger_->getFileSinkHandle();
auto filename = filehandler->call(&g2FileSink::logFileName);
if (!filename.valid()) ADD_FAILURE();
log_file_ = filename.get();
}