[Orxonox-commit 4875] r9544 - in code/branches/testing: src/libraries/util/output test/util/output
landauf at orxonox.net
landauf at orxonox.net
Mon Mar 11 23:13:21 CET 2013
Author: landauf
Date: 2013-03-11 23:13:21 +0100 (Mon, 11 Mar 2013)
New Revision: 9544
Modified:
code/branches/testing/src/libraries/util/output/LogWriter.cc
code/branches/testing/src/libraries/util/output/LogWriter.h
code/branches/testing/test/util/output/LogWriterTest.cc
Log:
added archive feature to LogWriter which archives up to nine old log-files (orxonox.log.1 to orxonox.log.9)
Modified: code/branches/testing/src/libraries/util/output/LogWriter.cc
===================================================================
--- code/branches/testing/src/libraries/util/output/LogWriter.cc 2013-03-10 18:22:59 UTC (rev 9543)
+++ code/branches/testing/src/libraries/util/output/LogWriter.cc 2013-03-11 22:13:21 UTC (rev 9544)
@@ -38,9 +38,12 @@
#include "OutputManager.h"
#include "MemoryWriter.h"
+#include "util/Convert.h"
namespace orxonox
{
+ static const int MAX_ARCHIVED_FILES = 9;
+
/**
@brief Constructor, initializes the desired output levels and the name and path of the log-file, and opens the log-file.
@@ -81,6 +84,9 @@
*/
void LogWriter::openFile()
{
+ // archive the old log file
+ this->archive();
+
// open the file
this->file_.open(this->getPath().c_str(), std::fstream::out);
@@ -104,6 +110,50 @@
}
/**
+ * @brief Archives old copies of the log file by adding increasing numbers to the filename.
+ */
+ void LogWriter::archive(int index)
+ {
+ std::string oldPath = this->getArchivedPath(index);
+
+ // see if the file already exists, otherwise return
+ std::ifstream stream(oldPath.c_str());
+ bool exists = stream.is_open();
+ stream.close();
+
+ if (!exists)
+ return;
+
+ if (index < MAX_ARCHIVED_FILES)
+ {
+ // increment the index and archive the file with the next higher index
+ this->archive(++index);
+
+ // create the new path based on the incremented index
+ std::string newPath = this->getArchivedPath(index);
+
+ // move the file
+ std::rename(oldPath.c_str(), newPath.c_str());
+ }
+ else
+ {
+ // delete the file
+ std::remove(oldPath.c_str());
+ }
+ }
+
+ /**
+ * @brief Returns the path for archived copies of the logfile (based on the archive index)
+ */
+ std::string LogWriter::getArchivedPath(int index) const
+ {
+ std::string path = this->getPath();
+ if (index > 0)
+ path += '.' + multi_cast<std::string>(index);
+ return path;
+ }
+
+ /**
@brief Changes the path of the log-file. Re-writes the log-file by using MemoryWriter.
*/
void LogWriter::setLogDirectory(const std::string& directory)
Modified: code/branches/testing/src/libraries/util/output/LogWriter.h
===================================================================
--- code/branches/testing/src/libraries/util/output/LogWriter.h 2013-03-10 18:22:59 UTC (rev 9543)
+++ code/branches/testing/src/libraries/util/output/LogWriter.h 2013-03-11 22:13:21 UTC (rev 9544)
@@ -75,6 +75,9 @@
void openFile();
void closeFile();
+ void archive(int index = 0);
+ std::string getArchivedPath(int index) const;
+
std::string filename_; ///< The name of the log-file (without directory)
std::string directory_; ///< The directory where the log-file resided (without file-name)
std::ofstream file_; ///< The output file stream.
Modified: code/branches/testing/test/util/output/LogWriterTest.cc
===================================================================
--- code/branches/testing/test/util/output/LogWriterTest.cc 2013-03-10 18:22:59 UTC (rev 9543)
+++ code/branches/testing/test/util/output/LogWriterTest.cc 2013-03-11 22:13:21 UTC (rev 9544)
@@ -1,9 +1,20 @@
#include <gtest/gtest.h>
#include "util/Output.h"
#include "util/output/LogWriter.h"
+#include "util/Convert.h"
namespace orxonox
{
+ namespace
+ {
+ class MockLogWriter : public LogWriter
+ {
+ public:
+ virtual void printLine(const std::string& line, OutputLevel level)
+ { this->LogWriter::printLine(line, level); }
+ };
+ }
+
// test constructor opens file
TEST(LogWriterTest, ConstructorOpensFile)
{
@@ -14,23 +25,50 @@
// setLogDirectory changes file, opens correct file
bool fileExists(const std::string& path)
{
- std::ifstream stream(path.c_str(), std::fstream::in);
- bool exists = stream.is_open();
+ std::ifstream stream(path.c_str());
+ bool exists = stream.is_open() && stream.good();
stream.close();
return exists;
}
- bool fileSuccessfullyDeleted(const std::string& path)
+ std::string getLineWhichContains(const std::string& path, const std::string& message)
{
- return std::remove(path.c_str()) == 0;
+ std::ifstream file(path.c_str());
+ EXPECT_TRUE(file.is_open());
+ EXPECT_TRUE(file.good());
+ EXPECT_FALSE(file.eof());
+
+ while (file.is_open() && file.good() && !file.eof())
+ {
+ std::string line;
+ std::getline(file, line);
+
+ // see if we find the output and return
+ if (line.find(message) == (line.size() - message.size()))
+ return line;
+ }
+
+ return std::string();
}
+ bool fileContains(const std::string& path, const std::string& message)
+ {
+ return !getLineWhichContains(path, message).empty();
+ }
+
+ bool deleteFile(const std::string& path)
+ {
+ bool result = std::remove(path.c_str()) == 0;
+ EXPECT_FALSE(fileExists(path));
+ return result;
+ }
+
TEST(LogWriterTest, SetLogDirectoryOpensNewFile)
{
std::string path = "./orxonox.log";
// cleanup before test
- fileSuccessfullyDeleted(path);
+ deleteFile(path);
{
LogWriter logWriter;
@@ -40,7 +78,7 @@
}
// cleanup after test
- EXPECT_TRUE(fileSuccessfullyDeleted(path));
+ EXPECT_TRUE(deleteFile(path));
}
// prints output to logfile
@@ -60,25 +98,7 @@
path = logWriter.getPath();
}
- {
- std::ifstream file(path.c_str(), std::fstream::in);
- ASSERT_TRUE(file.is_open());
- ASSERT_TRUE(file.good());
- ASSERT_FALSE(file.eof());
-
- while (!file.eof())
- {
- std::string line;
- std::getline(file, line);
-
- // see if we find the output and return
- if (line.find("mytestoutput") != std::string::npos)
- return;
- }
-
- // output not found - failure!
- FAIL();
- }
+ EXPECT_TRUE(fileContains(path, "mytestoutput"));
}
// prints time to logfile
@@ -98,35 +118,106 @@
path = logWriter.getPath();
}
+ std::string line = getLineWhichContains(path, "myothertestoutput");
+ EXPECT_FALSE(line.empty());
+ EXPECT_TRUE(std::isdigit(line[0]));
+ EXPECT_TRUE(std::isdigit(line[1]));
+ EXPECT_EQ(':', line[2]);
+ EXPECT_TRUE(std::isdigit(line[3]));
+ EXPECT_TRUE(std::isdigit(line[4]));
+ EXPECT_EQ(':', line[5]);
+ EXPECT_TRUE(std::isdigit(line[6]));
+ EXPECT_TRUE(std::isdigit(line[7]));
+ EXPECT_EQ(' ', line[8]);
+ }
+
+ void deleteAllLogFiles()
+ {
+ std::string path;
{
- std::ifstream file(path.c_str(), std::fstream::in);
- ASSERT_TRUE(file.is_open());
- ASSERT_TRUE(file.good());
- ASSERT_FALSE(file.eof());
+ LogWriter writer;
+ path = writer.getPath();
+ }
- while (!file.eof())
- {
- std::string line;
- std::getline(file, line);
+ deleteFile(path);
+ deleteFile(path + ".1");
+ deleteFile(path + ".2");
+ deleteFile(path + ".3");
+ deleteFile(path + ".4");
+ deleteFile(path + ".5");
+ deleteFile(path + ".6");
+ deleteFile(path + ".7");
+ deleteFile(path + ".8");
+ deleteFile(path + ".9");
+ }
- // see if we find the output and return
- if (line.find("myothertestoutput") != std::string::npos)
- {
- EXPECT_TRUE(std::isdigit(line[0]));
- EXPECT_TRUE(std::isdigit(line[1]));
- EXPECT_EQ(':', line[2]);
- EXPECT_TRUE(std::isdigit(line[3]));
- EXPECT_TRUE(std::isdigit(line[4]));
- EXPECT_EQ(':', line[5]);
- EXPECT_TRUE(std::isdigit(line[6]));
- EXPECT_TRUE(std::isdigit(line[7]));
- EXPECT_EQ(' ', line[8]);
- return;
- }
- }
+ TEST(LogWriterTest, ArchivesOldLogFile)
+ {
+ deleteAllLogFiles();
- // output not found - failure!
- FAIL();
+ std::string path;
+
+ {
+ MockLogWriter writer;
+ path = writer.getPath();
+ writer.printLine("test1", level::message);
}
+
+ EXPECT_TRUE(fileExists(path));
+ EXPECT_TRUE(fileContains(path, "test1"));
+ EXPECT_FALSE(fileExists(path + ".1"));
+ EXPECT_FALSE(fileExists(path + ".2"));
+ EXPECT_FALSE(fileExists(path + ".3"));
+
+ {
+ MockLogWriter writer;
+ writer.printLine("test2", level::message);
+ }
+
+ EXPECT_TRUE(fileExists(path));
+ EXPECT_TRUE(fileContains(path, "test2"));
+ EXPECT_TRUE(fileExists(path + ".1"));
+ EXPECT_TRUE(fileContains(path + ".1", "test1"));
+ EXPECT_FALSE(fileExists(path + ".2"));
+ EXPECT_FALSE(fileExists(path + ".3"));
+
+ {
+ MockLogWriter writer;
+ writer.printLine("test3", level::message);
+ }
+
+ EXPECT_TRUE(fileExists(path));
+ EXPECT_TRUE(fileContains(path, "test3"));
+ EXPECT_TRUE(fileExists(path + ".1"));
+ EXPECT_TRUE(fileContains(path + ".1", "test2"));
+ EXPECT_TRUE(fileExists(path + ".2"));
+ EXPECT_TRUE(fileContains(path + ".2", "test1"));
+ EXPECT_FALSE(fileExists(path + ".3"));
}
+
+ TEST(LogWriterTest, ArchivesNineLogFiles)
+ {
+ deleteAllLogFiles();
+
+ std::string path;
+ for (int i = 0; i < 20; ++i)
+ {
+ MockLogWriter writer;
+ path = writer.getPath();
+ writer.printLine("test" + multi_cast<std::string>(i), level::message);
+ }
+
+ EXPECT_TRUE(fileContains(path, "test19"));
+ EXPECT_TRUE(fileContains(path + ".1", "test18"));
+ EXPECT_TRUE(fileContains(path + ".2", "test17"));
+ EXPECT_TRUE(fileContains(path + ".3", "test16"));
+ EXPECT_TRUE(fileContains(path + ".4", "test15"));
+ EXPECT_TRUE(fileContains(path + ".5", "test14"));
+ EXPECT_TRUE(fileContains(path + ".6", "test13"));
+ EXPECT_TRUE(fileContains(path + ".7", "test12"));
+ EXPECT_TRUE(fileContains(path + ".8", "test11"));
+ EXPECT_TRUE(fileContains(path + ".9", "test10"));
+ EXPECT_FALSE(fileExists(path + ".10"));
+ EXPECT_FALSE(fileExists(path + ".11"));
+ }
}
More information about the Orxonox-commit
mailing list