summaryrefslogtreecommitdiff
path: root/indra/llcommon/tests/llsingleton_test.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/llcommon/tests/llsingleton_test.cpp')
-rwxr-xr-xindra/llcommon/tests/llsingleton_test.cpp205
1 files changed, 165 insertions, 40 deletions
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
index bed436283a..a05f650f25 100755
--- a/indra/llcommon/tests/llsingleton_test.cpp
+++ b/indra/llcommon/tests/llsingleton_test.cpp
@@ -30,46 +30,171 @@
#include "llsingleton.h"
#include "../test/lltut.h"
+
+// Capture execution sequence by appending to log string.
+std::string sLog;
+
+#define DECLARE_CLASS(CLS) \
+struct CLS: public LLSingleton<CLS> \
+{ \
+ static enum dep_flag { \
+ DEP_NONE, /* no dependency */ \
+ DEP_CTOR, /* dependency in ctor */ \
+ DEP_INIT /* dependency in initSingleton */ \
+ } sDepFlag; \
+ \
+ CLS(); \
+ void initSingleton(); \
+ void cleanupSingleton(); \
+ ~CLS(); \
+}; \
+ \
+CLS::dep_flag CLS::sDepFlag = DEP_NONE
+
+DECLARE_CLASS(A);
+DECLARE_CLASS(B);
+
+#define DEFINE_MEMBERS(CLS, OTHER) \
+CLS::CLS() \
+{ \
+ sLog.append(#CLS); \
+ if (sDepFlag == DEP_CTOR) \
+ { \
+ (void)OTHER::instance(); \
+ } \
+} \
+ \
+void CLS::initSingleton() \
+{ \
+ sLog.append("i" #CLS); \
+ if (sDepFlag == DEP_INIT) \
+ { \
+ (void)OTHER::instance(); \
+ } \
+} \
+ \
+void CLS::cleanupSingleton() \
+{ \
+ sLog.append("x" #CLS); \
+} \
+ \
+CLS::~CLS() \
+{ \
+ sLog.append("~" #CLS); \
+}
+
+DEFINE_MEMBERS(A, B)
+DEFINE_MEMBERS(B, A)
+
namespace tut
{
- struct singleton
- {
- // We need a class created with the LLSingleton template to test with.
- class LLSingletonTest: public LLSingleton<LLSingletonTest>
- {
-
- };
- };
-
- typedef test_group<singleton> singleton_t;
- typedef singleton_t::object singleton_object_t;
- tut::singleton_t tut_singleton("LLSingleton");
-
- template<> template<>
- void singleton_object_t::test<1>()
- {
-
- }
- template<> template<>
- void singleton_object_t::test<2>()
- {
- LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
- ensure(singleton_test);
- }
- template<> template<>
- void singleton_object_t::test<3>()
- {
- //Construct the instance
- LLSingletonTest::getInstance();
- ensure(LLSingletonTest::instanceExists());
-
- //Delete the instance
- LLSingletonTest::deleteSingleton();
- ensure(!LLSingletonTest::instanceExists());
-
- //Construct it again.
- LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
- ensure(singleton_test);
- ensure(LLSingletonTest::instanceExists());
- }
+ struct singleton
+ {
+ // We need a class created with the LLSingleton template to test with.
+ class LLSingletonTest: public LLSingleton<LLSingletonTest>
+ {
+
+ };
+ };
+
+ typedef test_group<singleton> singleton_t;
+ typedef singleton_t::object singleton_object_t;
+ tut::singleton_t tut_singleton("LLSingleton");
+
+ template<> template<>
+ void singleton_object_t::test<1>()
+ {
+
+ }
+ template<> template<>
+ void singleton_object_t::test<2>()
+ {
+ LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+ ensure(singleton_test);
+ }
+
+ template<> template<>
+ void singleton_object_t::test<3>()
+ {
+ //Construct the instance
+ LLSingletonTest::getInstance();
+ ensure(LLSingletonTest::instanceExists());
+
+ //Delete the instance
+ LLSingletonTest::deleteSingleton();
+ ensure(!LLSingletonTest::instanceExists());
+
+ //Construct it again.
+ LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+ ensure(singleton_test);
+ ensure(LLSingletonTest::instanceExists());
+ }
+
+#define TESTS(CLS, OTHER, N0, N1, N2, N3) \
+ template<> template<> \
+ void singleton_object_t::test<N0>() \
+ { \
+ set_test_name("just " #CLS); \
+ CLS::sDepFlag = CLS::DEP_NONE; \
+ OTHER::sDepFlag = OTHER::DEP_NONE; \
+ sLog.clear(); \
+ \
+ (void)CLS::instance(); \
+ ensure_equals(sLog, #CLS "i" #CLS); \
+ LLSingletonBase::cleanupAll(); \
+ ensure_equals(sLog, #CLS "i" #CLS "x" #CLS); \
+ LLSingletonBase::deleteAll(); \
+ ensure_equals(sLog, #CLS "i" #CLS "x" #CLS "~" #CLS); \
+ } \
+ \
+ template<> template<> \
+ void singleton_object_t::test<N1>() \
+ { \
+ set_test_name(#CLS " ctor depends " #OTHER); \
+ CLS::sDepFlag = CLS::DEP_CTOR; \
+ OTHER::sDepFlag = OTHER::DEP_NONE; \
+ sLog.clear(); \
+ \
+ (void)CLS::instance(); \
+ ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS); \
+ LLSingletonBase::cleanupAll(); \
+ ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER); \
+ LLSingletonBase::deleteAll(); \
+ ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \
+ } \
+ \
+ template<> template<> \
+ void singleton_object_t::test<N2>() \
+ { \
+ set_test_name(#CLS " init depends " #OTHER); \
+ CLS::sDepFlag = CLS::DEP_INIT; \
+ OTHER::sDepFlag = OTHER::DEP_NONE; \
+ sLog.clear(); \
+ \
+ (void)CLS::instance(); \
+ ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER); \
+ LLSingletonBase::cleanupAll(); \
+ ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \
+ LLSingletonBase::deleteAll(); \
+ ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \
+ } \
+ \
+ template<> template<> \
+ void singleton_object_t::test<N3>() \
+ { \
+ set_test_name(#CLS " circular init"); \
+ CLS::sDepFlag = CLS::DEP_INIT; \
+ OTHER::sDepFlag = OTHER::DEP_CTOR; \
+ sLog.clear(); \
+ \
+ (void)CLS::instance(); \
+ ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER); \
+ LLSingletonBase::cleanupAll(); \
+ ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \
+ LLSingletonBase::deleteAll(); \
+ ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \
+ }
+
+ TESTS(A, B, 4, 5, 6, 7)
+ TESTS(B, A, 8, 9, 10, 11)
}