| // 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 <memory> | 
 |  | 
 | #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 unique_ptr so compiler doesn't complain about unused variables. | 
 |   std::unique_ptr<ClassA> a1(new ClassA); | 
 |   std::unique_ptr<ClassB> b1(new ClassB); | 
 |   std::unique_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()); | 
 |  | 
 |     std::unique_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()); | 
 |  | 
 |   std::unique_ptr<ClassA> a1(new ClassA); | 
 |   std::unique_ptr<ClassA> a2(new ClassA); | 
 |   std::unique_ptr<ClassA> a3(new ClassA); | 
 |   std::unique_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). | 
 |   std::unique_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 |