Improved unit test logging:

Logging from the Application object in the Env is
redirected to the suite::log, with the severity level
set to error and above.
This commit is contained in:
Vinnie Falco
2016-01-26 13:43:20 -05:00
committed by Nik Bougalis
parent 5ac744ff66
commit 2be11874e3
4 changed files with 95 additions and 22 deletions

View File

@@ -25,6 +25,7 @@
#include <beast/utility/Journal.h> #include <beast/utility/Journal.h>
#include <boost/filesystem.hpp> #include <boost/filesystem.hpp>
#include <map> #include <map>
#include <memory>
#include <mutex> #include <mutex>
#include <utility> #include <utility>
@@ -145,7 +146,9 @@ private:
}; };
std::mutex mutable mutex_; std::mutex mutable mutex_;
std::map <std::string, Sink, beast::ci_less> sinks_; std::map <std::string,
std::unique_ptr<beast::Journal::Sink>,
beast::ci_less> sinks_;
beast::Journal::Severity level_; beast::Journal::Severity level_;
File file_; File file_;
bool silent_ = false; bool silent_ = false;
@@ -159,10 +162,10 @@ public:
bool bool
open (boost::filesystem::path const& pathToLogFile); open (boost::filesystem::path const& pathToLogFile);
Sink& beast::Journal::Sink&
get (std::string const& name); get (std::string const& name);
Sink& beast::Journal::Sink&
operator[] (std::string const& name); operator[] (std::string const& name);
beast::Journal beast::Journal
@@ -195,6 +198,11 @@ public:
silent_ = bSilent; silent_ = bSilent;
} }
virtual
std::unique_ptr<beast::Journal::Sink>
makeSink(std::string const& partition,
beast::Journal::Severity startingLevel);
public: public:
static static
LogSeverity LogSeverity

View File

@@ -119,17 +119,16 @@ Logs::open (boost::filesystem::path const& pathToLogFile)
return file_.open(pathToLogFile); return file_.open(pathToLogFile);
} }
Logs::Sink& beast::Journal::Sink&
Logs::get (std::string const& name) Logs::get (std::string const& name)
{ {
std::lock_guard <std::mutex> lock (mutex_); std::lock_guard <std::mutex> lock (mutex_);
auto const result (sinks_.emplace (std::piecewise_construct, auto const result =
std::forward_as_tuple(name), std::forward_as_tuple (name, sinks_.emplace(name, makeSink(name, level_));
level_, *this))); return *result.first->second;
return result.first->second;
} }
Logs::Sink& beast::Journal::Sink&
Logs::operator[] (std::string const& name) Logs::operator[] (std::string const& name)
{ {
return get(name); return get(name);
@@ -153,7 +152,7 @@ Logs::severity (beast::Journal::Severity level)
std::lock_guard <std::mutex> lock (mutex_); std::lock_guard <std::mutex> lock (mutex_);
level_ = level; level_ = level;
for (auto& sink : sinks_) for (auto& sink : sinks_)
sink.second.severity (level); sink.second->severity (level);
} }
std::vector<std::pair<std::string, std::string>> std::vector<std::pair<std::string, std::string>>
@@ -164,7 +163,7 @@ Logs::partition_severities() const
list.reserve (sinks_.size()); list.reserve (sinks_.size());
for (auto const& e : sinks_) for (auto const& e : sinks_)
list.push_back(std::make_pair(e.first, list.push_back(std::make_pair(e.first,
toString(fromSeverity(e.second.severity())))); toString(fromSeverity(e.second->severity()))));
return list; return list;
} }
@@ -193,6 +192,14 @@ Logs::rotate()
return "The log file could not be closed and reopened."; return "The log file could not be closed and reopened.";
} }
std::unique_ptr<beast::Journal::Sink>
Logs::makeSink(std::string const& name,
beast::Journal::Severity startingLevel)
{
return std::make_unique<Sink>(
name, startingLevel, *this);
}
LogSeverity LogSeverity
Logs::fromSeverity (beast::Journal::Severity level) Logs::fromSeverity (beast::Journal::Severity level)
{ {

View File

@@ -101,8 +101,10 @@ private:
std::thread thread; std::thread thread;
std::unique_ptr<AbstractClient> client; std::unique_ptr<AbstractClient> client;
AppBundle (std::unique_ptr<Config> config); AppBundle (beast::unit_test::suite& suite,
AppBundle (Application* app_); std::unique_ptr<Config> config);
AppBundle (beast::unit_test::suite& suite,
Application* app_);
~AppBundle(); ~AppBundle();
}; };
@@ -139,11 +141,11 @@ public:
// VFALCO Could wrap the suite::log in a Journal here // VFALCO Could wrap the suite::log in a Journal here
template <class... Args> template <class... Args>
Env (beast::unit_test::suite& test_, Env (beast::unit_test::suite& suite_,
std::unique_ptr<Config> config, std::unique_ptr<Config> config,
Args&&... args) Args&&... args)
: test (test_) : test (suite_)
, bundle_ (std::move(config)) , bundle_ (suite_, std::move(config))
{ {
memoize(Account::master); memoize(Account::master);
Pathfinder::initPathTable(); Pathfinder::initPathTable();
@@ -151,9 +153,9 @@ public:
} }
template <class... Args> template <class... Args>
Env (beast::unit_test::suite& test_, Env (beast::unit_test::suite& suite_,
Args&&... args) Args&&... args)
: Env(test_, []() : Env(suite_, []()
{ {
auto p = std::make_unique<Config>(); auto p = std::make_unique<Config>();
setupConfigForUnitTests(*p); setupConfigForUnitTests(*p);

View File

@@ -85,14 +85,69 @@ setupConfigForUnitTests (Config& cfg)
namespace jtx { namespace jtx {
Env::AppBundle::AppBundle(Application* app_) class SuiteSink : public beast::Journal::Sink
{
std::string partition_;
beast::unit_test::suite& suite_;
public:
SuiteSink(std::string const& partition,
beast::unit_test::suite& suite)
: partition_(partition + " ")
, suite_ (suite)
{
}
void
write(beast::Journal::Severity level,
std::string const& text) override
{
std::string s;
switch(level)
{
case beast::Journal::kTrace: s = "TRC:"; break;
case beast::Journal::kDebug: s = "DBG:"; break;
case beast::Journal::kInfo: s = "INF:"; break;
case beast::Journal::kWarning: s = "WRN:"; break;
case beast::Journal::kError: s = "ERR:"; break;
default:
case beast::Journal::kFatal: s = "FTL:"; break;
}
suite_.log << s << partition_ << text;
}
};
class SuiteLogs : public Logs
{
beast::unit_test::suite& suite_;
public:
explicit
SuiteLogs(beast::unit_test::suite& suite)
: suite_(suite)
{
}
std::unique_ptr<beast::Journal::Sink>
makeSink(std::string const& partition,
beast::Journal::Severity startingLevel) override
{
return std::make_unique<SuiteSink>(partition, suite_);
}
};
//------------------------------------------------------------------------------
Env::AppBundle::AppBundle(beast::unit_test::suite&,
Application* app_)
: app(app_) : app(app_)
{ {
} }
Env::AppBundle::AppBundle(std::unique_ptr<Config> config) Env::AppBundle::AppBundle(beast::unit_test::suite& suite,
std::unique_ptr<Config> config)
{ {
auto logs = std::make_unique<Logs>(); auto logs = std::make_unique<SuiteLogs>(suite);
auto timeKeeper_ = auto timeKeeper_ =
std::make_unique<ManualTimeKeeper>(); std::make_unique<ManualTimeKeeper>();
timeKeeper = timeKeeper_.get(); timeKeeper = timeKeeper_.get();
@@ -101,6 +156,7 @@ Env::AppBundle::AppBundle(std::unique_ptr<Config> config)
owned = make_Application(std::move(config), owned = make_Application(std::move(config),
std::move(logs), std::move(timeKeeper_)); std::move(logs), std::move(timeKeeper_));
app = owned.get(); app = owned.get();
app->logs().severity(beast::Journal::kError);
app->setup(); app->setup();
timeKeeper->set( timeKeeper->set(
app->getLedgerMaster().getClosedLedger()->info().closeTime); app->getLedgerMaster().getClosedLedger()->info().closeTime);