summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/unittest/unittest.cpp44
-rw-r--r--src/mongo/unittest/unittest.h28
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;
};
/**