Skip to content

Commit

Permalink
#5382: Add TestLogFile class, which will (unlike the regular DarkRadi…
Browse files Browse the repository at this point in the history
…ant.log) append text to the output file, not clearing it on open.
  • Loading branch information
codereader committed Dec 10, 2020
1 parent 4de94e4 commit 889c079
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 0 deletions.
16 changes: 16 additions & 0 deletions test/RadiantTest.h
Expand Up @@ -10,6 +10,7 @@
#include "icommandsystem.h"

#include "TestContext.h"
#include "TestLogFile.h"
#include "HeadlessOpenGLContext.h"
#include "module/CoreModule.h"
#include "messages/GameConfigNeededMessage.h"
Expand Down Expand Up @@ -37,6 +38,8 @@ class RadiantTest :

std::shared_ptr<gl::HeadlessOpenGLContextModule> _glContextModule;

std::unique_ptr<TestLogFile> _testLogFile;

protected:
RadiantTest()
{
Expand All @@ -54,6 +57,8 @@ class RadiantTest :

module::RegistryReference::Instance().setRegistry(radiant->getModuleRegistry());
module::initialiseStreams(radiant->getLogWriter());

initTestLog();
}
catch (module::CoreModule::FailureException & ex)
{
Expand Down Expand Up @@ -107,11 +112,22 @@ class RadiantTest :

~RadiantTest()
{
_coreModule->get()->getLogWriter().detach(_testLogFile.get());
_testLogFile->close();
_testLogFile.reset();

module::shutdownStreams();
_coreModule.reset();
}

protected:
void initTestLog()
{
auto fullPath = _context.getCacheDataPath() + "test.log";
_testLogFile.reset(new TestLogFile(fullPath));
_coreModule->get()->getLogWriter().attach(_testLogFile.get());
}

virtual void setupGameFolder()
{}

Expand Down
79 changes: 79 additions & 0 deletions test/TestLogFile.h
@@ -0,0 +1,79 @@
#pragma once

#include <fstream>
#include <thread>
#include <iomanip>
#include "ilogwriter.h"
#include "itextstream.h"

namespace test
{

class TestLogFile :
public applog::ILogDevice
{
// The log file name including path
std::string _logFilePath;

// We write line by line
std::string _buffer;

// The file stream which will be filled with bytes
std::ofstream _logStream;

const char* const _timeFormat;

public:
TestLogFile(const std::string& fullPath) :
_logFilePath(fullPath),
_logStream(_logFilePath.c_str(), std::ios_base::app),
_timeFormat("%Y-%m-%d %H:%M:%S")
{}

// Returns true if the log stream was successfully opened
bool isOpen()
{
return _logStream.good();
}

void writeLog(const std::string& outputStr, applog::LogLevel level) override
{
_buffer.append(outputStr);

// Hold back until we hit a newline
if (outputStr.rfind('\n') != std::string::npos)
{
std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);

// Write timestamp and thread information
_logStream << std::put_time(&tm, _timeFormat);
_logStream << " (" << std::this_thread::get_id() << ") ";

// Insert the string into the stream and flush the buffer
_logStream << _buffer;

_buffer.clear();
_logStream.flush();
}
}

void close()
{
std::time_t t = std::time(nullptr);
std::tm tm = *std::localtime(&t);
rMessage() << std::put_time(&tm, _timeFormat) << " Closing log file." << std::endl;

// Insert the last few remaining bytes into the stream
if (!_buffer.empty())
{
_logStream << _buffer << std::endl;
_buffer.clear();
}

_logStream.flush();
_logStream.close();
}
};

} // namespace
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj
Expand Up @@ -65,6 +65,7 @@
<ClInclude Include="..\..\..\test\HeadlessOpenGLContext.h" />
<ClInclude Include="..\..\..\test\RadiantTest.h" />
<ClInclude Include="..\..\..\test\TestContext.h" />
<ClInclude Include="..\..\..\test\TestLogFile.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\test\Camera.cpp" />
Expand Down
1 change: 1 addition & 0 deletions tools/msvc/Tests/Tests.vcxproj.filters
Expand Up @@ -47,6 +47,7 @@
<ClInclude Include="..\..\..\test\algorithm\Primitives.h">
<Filter>algorithm</Filter>
</ClInclude>
<ClInclude Include="..\..\..\test\TestLogFile.h" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
Expand Down

0 comments on commit 889c079

Please sign in to comment.