// 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/debug/leak_tracker.h" #include "base/memory/scoped_ptr.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { namespace debug { namespace { class ClassA { private: LeakTracker<ClassA> leak_tracker_; }; class ClassB { private: LeakTracker<ClassB> leak_tracker_; }; #ifndef ENABLE_LEAK_TRACKER // If leak tracking is disabled, we should do nothing. TEST(LeakTrackerTest, NotEnabled) { EXPECT_EQ(-1, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(-1, LeakTracker<ClassB>::NumLiveInstances()); // Use scoped_ptr so compiler doesn't complain about unused variables. scoped_ptr<ClassA> a1(new ClassA); scoped_ptr<ClassB> b1(new ClassB); scoped_ptr<ClassB> b2(new ClassB); EXPECT_EQ(-1, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(-1, LeakTracker<ClassB>::NumLiveInstances()); } #else TEST(LeakTrackerTest, Basic) { { ClassA a1; EXPECT_EQ(1, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(0, LeakTracker<ClassB>::NumLiveInstances()); ClassB b1; ClassB b2; EXPECT_EQ(1, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(2, LeakTracker<ClassB>::NumLiveInstances()); scoped_ptr<ClassA> a2(new ClassA); EXPECT_EQ(2, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(2, LeakTracker<ClassB>::NumLiveInstances()); a2.reset(); EXPECT_EQ(1, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(2, LeakTracker<ClassB>::NumLiveInstances()); } EXPECT_EQ(0, LeakTracker<ClassA>::NumLiveInstances()); EXPECT_EQ(0, LeakTracker<ClassB>::NumLiveInstances()); } // Try some orderings of create/remove to hit different cases in the linked-list // assembly. TEST(LeakTrackerTest, LinkedList) { EXPECT_EQ(0, LeakTracker<ClassB>::NumLiveInstances()); scoped_ptr<ClassA> a1(new ClassA); scoped_ptr<ClassA> a2(new ClassA); scoped_ptr<ClassA> a3(new ClassA); scoped_ptr<ClassA> a4(new ClassA); EXPECT_EQ(4, LeakTracker<ClassA>::NumLiveInstances()); // Remove the head of the list (a1). a1.reset(); EXPECT_EQ(3, LeakTracker<ClassA>::NumLiveInstances()); // Remove the tail of the list (a4). a4.reset(); EXPECT_EQ(2, LeakTracker<ClassA>::NumLiveInstances()); // Append to the new tail of the list (a3). scoped_ptr<ClassA> a5(new ClassA); EXPECT_EQ(3, LeakTracker<ClassA>::NumLiveInstances()); a2.reset(); a3.reset(); EXPECT_EQ(1, LeakTracker<ClassA>::NumLiveInstances()); a5.reset(); EXPECT_EQ(0, LeakTracker<ClassA>::NumLiveInstances()); } TEST(LeakTrackerTest, NoOpCheckForLeaks) { // There are no live instances of ClassA, so this should do nothing. LeakTracker<ClassA>::CheckForLeaks(); } #endif // ENABLE_LEAK_TRACKER } // namespace } // namespace debug } // namespace base