summaryrefslogtreecommitdiff
path: root/indra/test/test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/test/test.cpp')
-rw-r--r--indra/test/test.cpp70
1 files changed, 53 insertions, 17 deletions
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index 172b6e3542..6e280819df 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -36,6 +36,7 @@
#include "linden_common.h"
#include "llerrorcontrol.h"
+#include "llexception.h"
#include "lltut.h"
#include "chained_callback.h"
#include "stringize.h"
@@ -164,10 +165,6 @@ public:
LLTestCallback(bool verbose_mode, std::ostream *stream,
std::shared_ptr<LLReplayLog> replayer) :
mVerboseMode(verbose_mode),
- mTotalTests(0),
- mPassedTests(0),
- mFailedTests(0),
- mSkippedTests(0),
// By default, capture a shared_ptr to std::cout, with a no-op "deleter"
// so that destroying the shared_ptr makes no attempt to delete std::cout.
mStream(std::shared_ptr<std::ostream>(&std::cout, [](std::ostream*){})),
@@ -203,6 +200,8 @@ public:
virtual void group_started(const std::string& name) {
LL_INFOS("TestRunner")<<"Unit test group_started name=" << name << LL_ENDL;
*mStream << "Unit test group_started name=" << name << std::endl;
+ mGroup = name;
+ mGroupTests = 0;
super::group_started(name);
}
@@ -215,6 +214,7 @@ public:
virtual void test_completed(const tut::test_result& tr)
{
++mTotalTests;
+ ++mGroupTests;
// If this test failed, dump requested log messages BEFORE stating the
// test result.
@@ -302,12 +302,15 @@ public:
super::run_completed();
}
+ std::string mGroup;
+ int mGroupTests{ 0 };
+
protected:
- bool mVerboseMode;
- int mTotalTests;
- int mPassedTests;
- int mFailedTests;
- int mSkippedTests;
+ bool mVerboseMode{ false };
+ int mTotalTests{ 0 };
+ int mPassedTests{ 0 };
+ int mFailedTests{ 0 };
+ int mSkippedTests{ 0 };
std::shared_ptr<std::ostream> mStream;
std::shared_ptr<LLReplayLog> mReplayer;
};
@@ -635,14 +638,47 @@ int main(int argc, char **argv)
// a chained_callback subclass must be linked with previous
mycallback->link();
- if(test_group.empty())
- {
- tut::runner.get().run_tests();
- }
- else
- {
- tut::runner.get().run_tests(test_group);
- }
+ LL::seh::catcher(
+ // __try
+ [test_group]
+ {
+ if(test_group.empty())
+ {
+ tut::runner.get().run_tests();
+ }
+ else
+ {
+ tut::runner.get().run_tests(test_group);
+ }
+ },
+ // __except
+ [mycallback](U32 code, const std::string& /*stacktrace*/)
+ {
+ static std::map<U32, const char*> codes = {
+ { 0xC0000005, "Access Violation" },
+ { 0xC00000FD, "Stack Overflow" },
+ // ... continue filling in as desired
+ };
+
+ auto found{ codes.find(code) };
+ const char* name = ((found == codes.end())? "unknown" : found->second);
+ auto msg{ stringize("test threw ", std::hex, code, " (", name, ")") };
+
+ // Instead of bombing the whole test run, report this as a test
+ // failure. Arguably, catching structured exceptions should be
+ // hacked into TUT itself.
+ mycallback->test_completed(tut::test_result(
+ mycallback->mGroup,
+ mycallback->mGroupTests+1, // test within group
+ "unknown", // test name
+ tut::test_result::ex, // result: exception
+ // we don't have to throw this exception subclass to use it to
+ // populate the test_result struct
+ Windows_SEH_exception(msg)));
+ // we've left the TUT framework -- finish up by hand
+ mycallback->group_completed(mycallback->mGroup);
+ mycallback->run_completed();
+ });
bool success = (mycallback->getFailedTests() == 0);