diff options
Diffstat (limited to 'src/mongo')
-rw-r--r-- | src/mongo/unittest/unittest.cpp | 44 | ||||
-rw-r--r-- | src/mongo/unittest/unittest.h | 28 |
2 files changed, 70 insertions, 2 deletions
diff --git a/src/mongo/unittest/unittest.cpp b/src/mongo/unittest/unittest.cpp index e728ced46b1..feb9a2aeb05 100644 --- a/src/mongo/unittest/unittest.cpp +++ b/src/mongo/unittest/unittest.cpp @@ -36,6 +36,7 @@ #include "mongo/base/init.h" #include "mongo/logger/console_appender.h" #include "mongo/logger/log_manager.h" +#include "mongo/logger/logger.h" #include "mongo/logger/message_event_utf8_encoder.h" #include "mongo/logger/message_log_domain.h" #include "mongo/util/assert_util.h" @@ -111,8 +112,13 @@ namespace mongo { Result* Result::cur = 0; - Test::Test() {} - Test::~Test() {} + Test::Test() : _isCapturingLogMessages(false) {} + + Test::~Test() { + if (_isCapturingLogMessages) { + stopCapturingLogMessages(); + } + } void Test::run() { setUp(); @@ -139,6 +145,40 @@ namespace mongo { void Test::setUp() {} void Test::tearDown() {} +namespace { + class StringVectorAppender : public logger::MessageLogDomain::EventAppender { + public: + explicit StringVectorAppender(std::vector<std::string>* lines) : _lines(lines) {} + virtual ~StringVectorAppender() {} + virtual Status append(const logger::MessageLogDomain::Event& event) { + std::ostringstream _os; + if (!_encoder.encode(event, _os)) { + return Status(ErrorCodes::LogWriteFailed, "Failed to append to LogTestAppender."); + } + _lines->push_back(_os.str()); + return Status::OK(); + } + private: + logger::MessageEventDetailsEncoder _encoder; + std::vector<std::string>* _lines; + }; +} // namespace + + void Test::startCapturingLogMessages() { + invariant(!_isCapturingLogMessages); + _capturedLogMessages.clear(); + _captureAppenderHandle = logger::globalLogDomain()->attachAppender( + logger::MessageLogDomain::AppenderAutoPtr(new StringVectorAppender( + &_capturedLogMessages))); + _isCapturingLogMessages = true; + } + + void Test::stopCapturingLogMessages() { + invariant(_isCapturingLogMessages); + logger::globalLogDomain()->detachAppender(_captureAppenderHandle); + _isCapturingLogMessages = false; + } + Suite::Suite( const std::string& name ) : _name( name ) { registerSuite( name , this ); } diff --git a/src/mongo/unittest/unittest.h b/src/mongo/unittest/unittest.h index 8e27707b391..ccef6dc9925 100644 --- a/src/mongo/unittest/unittest.h +++ b/src/mongo/unittest/unittest.h @@ -45,6 +45,7 @@ #include "mongo/base/status_with.h" #include "mongo/logger/logstream_builder.h" +#include "mongo/logger/message_log_domain.h" #include "mongo/stdx/functional.h" #include "mongo/util/assert_util.h" #include "mongo/util/mongoutils/str.h" @@ -263,6 +264,29 @@ namespace mongo { class FixtureExceptionForTesting : public std::exception { }; + /** + * Starts capturing messages logged by code under test. + * + * Log messages will still also go to their default destination; this + * code simply adds an additional sink for log messages. + * + * Clears any previously captured log lines. + */ + void startCapturingLogMessages(); + + /** + * Stops capturing log messages logged by code under test. + */ + void stopCapturingLogMessages(); + + /** + * Gets a vector of strings, one log line per string, captured since + * the last call to startCapturingLogMessages() in this test. + */ + const std::vector<std::string>& getCapturedLogMessages() const { + return _capturedLogMessages; + } + private: /** * Called on the test object before running the test. @@ -278,6 +302,10 @@ namespace mongo { * The test itself. */ virtual void _doTest() = 0; + + bool _isCapturingLogMessages; + std::vector<std::string> _capturedLogMessages; + logger::MessageLogDomain::AppenderHandle _captureAppenderHandle; }; /** |