summaryrefslogtreecommitdiffstats
path: root/base/memory/singleton_unittest.cc
diff options
context:
space:
mode:
authorlevin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 01:54:15 +0000
committerlevin@chromium.org <levin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-28 01:54:15 +0000
commit3b63f8f451afcf414a59c529f627c620e4d449d9 (patch)
tree2dcbab1c060b29a260c29bb19b67bf97a8293ca3 /base/memory/singleton_unittest.cc
parent9174a108509c2aafe513da68e6e63fbc7df38c85 (diff)
downloadchromium_src-3b63f8f451afcf414a59c529f627c620e4d449d9.zip
chromium_src-3b63f8f451afcf414a59c529f627c620e4d449d9.tar.gz
chromium_src-3b63f8f451afcf414a59c529f627c620e4d449d9.tar.bz2
Move some files from base to base/memory.
raw_scoped_refptr_mismatch_checker.h ref_counted.cc ref_counted.h ref_counted_memory.cc ref_counted_memory.h ref_counted_unittest.cc scoped_callback_factory.h scoped_comptr_win.h scoped_handle.h scoped_native_library.cc scoped_native_library.h scoped_native_library_unittest.cc scoped_nsobject.h scoped_open_process.h scoped_ptr.h scoped_ptr_unittest.cc scoped_temp_dir.cc scoped_temp_dir.h scoped_temp_dir_unittest.cc scoped_vector.h singleton.h singleton_objc.h singleton_unittest.cc linked_ptr.h linked_ptr_unittest.cc weak_ptr.cc weak_ptr.h weak_ptr_unittest.cc BUG=None TEST=Compile Review URL: http://codereview.chromium.org/6714032 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79524 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/memory/singleton_unittest.cc')
-rw-r--r--base/memory/singleton_unittest.cc256
1 files changed, 256 insertions, 0 deletions
diff --git a/base/memory/singleton_unittest.cc b/base/memory/singleton_unittest.cc
new file mode 100644
index 0000000..a605885
--- /dev/null
+++ b/base/memory/singleton_unittest.cc
@@ -0,0 +1,256 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/at_exit.h"
+#include "base/file_util.h"
+#include "base/memory/singleton.h"
+#include "base/path_service.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace {
+
+COMPILE_ASSERT(DefaultSingletonTraits<int>::kRegisterAtExit == true, a);
+
+typedef void (*CallbackFunc)();
+
+class IntSingleton {
+ public:
+ static IntSingleton* GetInstance() {
+ return Singleton<IntSingleton>::get();
+ }
+
+ int value_;
+};
+
+class Init5Singleton {
+ public:
+ struct Trait;
+
+ static Init5Singleton* GetInstance() {
+ return Singleton<Init5Singleton, Trait>::get();
+ }
+
+ int value_;
+};
+
+struct Init5Singleton::Trait : public DefaultSingletonTraits<Init5Singleton> {
+ static Init5Singleton* New() {
+ Init5Singleton* instance = new Init5Singleton();
+ instance->value_ = 5;
+ return instance;
+ }
+};
+
+int* SingletonInt() {
+ return &IntSingleton::GetInstance()->value_;
+}
+
+int* SingletonInt5() {
+ return &Init5Singleton::GetInstance()->value_;
+}
+
+template <typename Type>
+struct CallbackTrait : public DefaultSingletonTraits<Type> {
+ static void Delete(Type* instance) {
+ if (instance->callback_)
+ (instance->callback_)();
+ DefaultSingletonTraits<Type>::Delete(instance);
+ }
+};
+
+class CallbackSingleton {
+ public:
+ CallbackSingleton() : callback_(NULL) { }
+ CallbackFunc callback_;
+};
+
+class CallbackSingletonWithNoLeakTrait : public CallbackSingleton {
+ public:
+ struct Trait : public CallbackTrait<CallbackSingletonWithNoLeakTrait> { };
+
+ CallbackSingletonWithNoLeakTrait() : CallbackSingleton() { }
+
+ static CallbackSingletonWithNoLeakTrait* GetInstance() {
+ return Singleton<CallbackSingletonWithNoLeakTrait, Trait>::get();
+ }
+};
+
+class CallbackSingletonWithLeakTrait : public CallbackSingleton {
+ public:
+ struct Trait : public CallbackTrait<CallbackSingletonWithLeakTrait> {
+ static const bool kRegisterAtExit = false;
+ };
+
+ CallbackSingletonWithLeakTrait() : CallbackSingleton() { }
+
+ static CallbackSingletonWithLeakTrait* GetInstance() {
+ return Singleton<CallbackSingletonWithLeakTrait, Trait>::get();
+ }
+};
+
+class CallbackSingletonWithStaticTrait : public CallbackSingleton {
+ public:
+ struct Trait;
+
+ CallbackSingletonWithStaticTrait() : CallbackSingleton() { }
+
+ static CallbackSingletonWithStaticTrait* GetInstance() {
+ return Singleton<CallbackSingletonWithStaticTrait, Trait>::get();
+ }
+};
+
+struct CallbackSingletonWithStaticTrait::Trait
+ : public StaticMemorySingletonTraits<CallbackSingletonWithStaticTrait> {
+ static void Delete(CallbackSingletonWithStaticTrait* instance) {
+ if (instance->callback_)
+ (instance->callback_)();
+ StaticMemorySingletonTraits<CallbackSingletonWithStaticTrait>::Delete(
+ instance);
+ }
+};
+
+
+void SingletonNoLeak(CallbackFunc CallOnQuit) {
+ CallbackSingletonWithNoLeakTrait::GetInstance()->callback_ = CallOnQuit;
+}
+
+void SingletonLeak(CallbackFunc CallOnQuit) {
+ CallbackSingletonWithLeakTrait::GetInstance()->callback_ = CallOnQuit;
+}
+
+CallbackFunc* GetLeakySingleton() {
+ return &CallbackSingletonWithLeakTrait::GetInstance()->callback_;
+}
+
+void DeleteLeakySingleton() {
+ DefaultSingletonTraits<CallbackSingletonWithLeakTrait>::Delete(
+ CallbackSingletonWithLeakTrait::GetInstance());
+}
+
+void SingletonStatic(CallbackFunc CallOnQuit) {
+ CallbackSingletonWithStaticTrait::GetInstance()->callback_ = CallOnQuit;
+}
+
+CallbackFunc* GetStaticSingleton() {
+ return &CallbackSingletonWithStaticTrait::GetInstance()->callback_;
+}
+
+void ResurrectStaticSingleton() {
+}
+
+} // namespace
+
+class SingletonTest : public testing::Test {
+ public:
+ SingletonTest() { }
+
+ virtual void SetUp() {
+ non_leak_called_ = false;
+ leaky_called_ = false;
+ static_called_ = false;
+ }
+
+ protected:
+ void VerifiesCallbacks() {
+ EXPECT_TRUE(non_leak_called_);
+ EXPECT_FALSE(leaky_called_);
+ EXPECT_TRUE(static_called_);
+ non_leak_called_ = false;
+ leaky_called_ = false;
+ static_called_ = false;
+ }
+
+ void VerifiesCallbacksNotCalled() {
+ EXPECT_FALSE(non_leak_called_);
+ EXPECT_FALSE(leaky_called_);
+ EXPECT_FALSE(static_called_);
+ non_leak_called_ = false;
+ leaky_called_ = false;
+ static_called_ = false;
+ }
+
+ static void CallbackNoLeak() {
+ non_leak_called_ = true;
+ }
+
+ static void CallbackLeak() {
+ leaky_called_ = true;
+ }
+
+ static void CallbackStatic() {
+ static_called_ = true;
+ }
+
+ private:
+ static bool non_leak_called_;
+ static bool leaky_called_;
+ static bool static_called_;
+};
+
+bool SingletonTest::non_leak_called_ = false;
+bool SingletonTest::leaky_called_ = false;
+bool SingletonTest::static_called_ = false;
+
+TEST_F(SingletonTest, Basic) {
+ int* singleton_int;
+ int* singleton_int_5;
+ CallbackFunc* leaky_singleton;
+ CallbackFunc* static_singleton;
+
+ {
+ base::ShadowingAtExitManager sem;
+ {
+ singleton_int = SingletonInt();
+ }
+ // Ensure POD type initialization.
+ EXPECT_EQ(*singleton_int, 0);
+ *singleton_int = 1;
+
+ EXPECT_EQ(singleton_int, SingletonInt());
+ EXPECT_EQ(*singleton_int, 1);
+
+ {
+ singleton_int_5 = SingletonInt5();
+ }
+ // Is default initialized to 5.
+ EXPECT_EQ(*singleton_int_5, 5);
+
+ SingletonNoLeak(&CallbackNoLeak);
+ SingletonLeak(&CallbackLeak);
+ SingletonStatic(&CallbackStatic);
+ static_singleton = GetStaticSingleton();
+ leaky_singleton = GetLeakySingleton();
+ EXPECT_TRUE(leaky_singleton);
+ }
+
+ // Verify that only the expected callback has been called.
+ VerifiesCallbacks();
+ // Delete the leaky singleton. It is interesting to note that Purify does
+ // *not* detect the leak when this call is commented out. :(
+ DeleteLeakySingleton();
+
+ // The static singleton can't be acquired post-atexit.
+ EXPECT_EQ(NULL, GetStaticSingleton());
+
+ {
+ base::ShadowingAtExitManager sem;
+ // Verifiy that the variables were reset.
+ {
+ singleton_int = SingletonInt();
+ EXPECT_EQ(*singleton_int, 0);
+ }
+ {
+ singleton_int_5 = SingletonInt5();
+ EXPECT_EQ(*singleton_int_5, 5);
+ }
+ {
+ // Resurrect the static singleton, and assert that it
+ // still points to the same (static) memory.
+ CallbackSingletonWithStaticTrait::Trait::Resurrect();
+ EXPECT_EQ(GetStaticSingleton(), static_singleton);
+ }
+ }
+ // The leaky singleton shouldn't leak since SingletonLeak has not been called.
+ VerifiesCallbacksNotCalled();
+}