summaryrefslogtreecommitdiff
path: root/indra/llcommon/tests/wrapllerrs.h
diff options
context:
space:
mode:
authorNat Goodspeed <nat@lindenlab.com>2012-03-01 13:43:52 -0500
committerNat Goodspeed <nat@lindenlab.com>2012-03-01 13:43:52 -0500
commit2596816f316e13b717bcdacddad0da48c90c3b6d (patch)
tree13a4404bfda7dcb5cf65ff5dfcba71c14927d72a /indra/llcommon/tests/wrapllerrs.h
parent40dc3e0d3bee6ff70fb68d9ba7f0a2ee9da96f68 (diff)
Break out TestRecorder class as CaptureLog into wrapllerrs.h.
Giving more unit tests the ability to capture and examine log output is generally useful. Renaming the class just makes it less ambiguous: what's a TestRecorder? Something that records tests?
Diffstat (limited to 'indra/llcommon/tests/wrapllerrs.h')
-rw-r--r--indra/llcommon/tests/wrapllerrs.h65
1 files changed, 65 insertions, 0 deletions
diff --git a/indra/llcommon/tests/wrapllerrs.h b/indra/llcommon/tests/wrapllerrs.h
index ffda84729b..a61f8451b3 100644
--- a/indra/llcommon/tests/wrapllerrs.h
+++ b/indra/llcommon/tests/wrapllerrs.h
@@ -30,6 +30,14 @@
#define LL_WRAPLLERRS_H
#include "llerrorcontrol.h"
+#include <boost/bind.hpp>
+#include <list>
+#include <string>
+#include <stdexcept>
+
+// statically reference the function in test.cpp... it's short, we could
+// replicate, but better to reuse
+extern void wouldHaveCrashed(const std::string& message);
struct WrapLL_ERRS
{
@@ -70,4 +78,61 @@ struct WrapLL_ERRS
LLError::FatalFunction mPriorFatal;
};
+/**
+ * Capture log messages. This is adapted (simplified) from the one in
+ * llerror_test.cpp.
+ */
+class CaptureLog : public LLError::Recorder
+{
+public:
+ CaptureLog():
+ // Mostly what we're trying to accomplish by saving and resetting
+ // LLError::Settings is to bypass the default RecordToStderr and
+ // RecordToWinDebug Recorders. As these are visible only inside
+ // llerror.cpp, we can't just call LLError::removeRecorder() with
+ // each. For certain tests we need to produce, capture and examine
+ // DEBUG log messages -- but we don't want to spam the user's console
+ // with that output. If it turns out that saveAndResetSettings() has
+ // some bad effect, give up and just let the DEBUG level log messages
+ // display.
+ mOldSettings(LLError::saveAndResetSettings())
+ {
+ LLError::setFatalFunction(wouldHaveCrashed);
+ LLError::setDefaultLevel(LLError::LEVEL_DEBUG);
+ LLError::addRecorder(this);
+ }
+
+ ~CaptureLog()
+ {
+ LLError::removeRecorder(this);
+ LLError::restoreSettings(mOldSettings);
+ }
+
+ void recordMessage(LLError::ELevel level,
+ const std::string& message)
+ {
+ mMessages.push_back(message);
+ }
+
+ /// Don't assume the message we want is necessarily the LAST log message
+ /// emitted by the underlying code; search backwards through all messages
+ /// for the sought string.
+ std::string messageWith(const std::string& search)
+ {
+ for (std::list<std::string>::const_reverse_iterator rmi(mMessages.rbegin()),
+ rmend(mMessages.rend());
+ rmi != rmend; ++rmi)
+ {
+ if (rmi->find(search) != std::string::npos)
+ return *rmi;
+ }
+ // failed to find any such message
+ return std::string();
+ }
+
+ typedef std::list<std::string> MessageList;
+ MessageList mMessages;
+ LLError::Settings* mOldSettings;
+};
+
#endif /* ! defined(LL_WRAPLLERRS_H) */