blob: 8f0e2f2d158bbf5408ceddb5024d6e20ce1e3d3b [file] [log] [blame]
ericroman@google.com7e41f132009-08-12 06:38:54 +09001// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "base/leak_tracker.h"
6#include "base/scoped_ptr.h"
7#include "testing/gtest/include/gtest/gtest.h"
8
9namespace {
10
11class ClassA {
12 private:
13 base::LeakTracker<ClassA> leak_tracker_;
14};
15
16class ClassB {
17 private:
18 base::LeakTracker<ClassB> leak_tracker_;
19};
20
21#ifdef NDEBUG
22
23// In RELEASE mode, leak tracking is disabled.
24TEST(LeakTrackerTest, ReleaseMode) {
25 EXPECT_EQ(-1, base::LeakTracker<ClassA>::NumLiveInstances());
26 EXPECT_EQ(-1, base::LeakTracker<ClassB>::NumLiveInstances());
27
28 // Use scoped_ptr so compiler doesn't complain about unused variables.
29 scoped_ptr<ClassA> a1(new ClassA);
30 scoped_ptr<ClassB> b1(new ClassB);
31 scoped_ptr<ClassB> b2(new ClassB);
32
33 EXPECT_EQ(-1, base::LeakTracker<ClassA>::NumLiveInstances());
34 EXPECT_EQ(-1, base::LeakTracker<ClassB>::NumLiveInstances());
35}
36
37#else
38
39// In DEBUG mode, leak tracking should work.
40TEST(LeakTrackerTest, DebugMode) {
41 {
42 ClassA a1;
43
44 EXPECT_EQ(1, base::LeakTracker<ClassA>::NumLiveInstances());
45 EXPECT_EQ(0, base::LeakTracker<ClassB>::NumLiveInstances());
46
47 ClassB b1;
48 ClassB b2;
49
50 EXPECT_EQ(1, base::LeakTracker<ClassA>::NumLiveInstances());
51 EXPECT_EQ(2, base::LeakTracker<ClassB>::NumLiveInstances());
52
53 scoped_ptr<ClassA> a2(new ClassA);
54
55 EXPECT_EQ(2, base::LeakTracker<ClassA>::NumLiveInstances());
56 EXPECT_EQ(2, base::LeakTracker<ClassB>::NumLiveInstances());
57
58 a2.reset();
59
60 EXPECT_EQ(1, base::LeakTracker<ClassA>::NumLiveInstances());
61 EXPECT_EQ(2, base::LeakTracker<ClassB>::NumLiveInstances());
62 }
63
64 EXPECT_EQ(0, base::LeakTracker<ClassA>::NumLiveInstances());
65 EXPECT_EQ(0, base::LeakTracker<ClassB>::NumLiveInstances());
66}
67
68// Try some orderings of create/remove to hit different cases in the linked-list
69// assembly.
70TEST(LeakTrackerTest, DebugMode_LinkedList) {
71 EXPECT_EQ(0, base::LeakTracker<ClassB>::NumLiveInstances());
72
73 scoped_ptr<ClassA> a1(new ClassA);
74 scoped_ptr<ClassA> a2(new ClassA);
75 scoped_ptr<ClassA> a3(new ClassA);
76 scoped_ptr<ClassA> a4(new ClassA);
77
78 EXPECT_EQ(4, base::LeakTracker<ClassA>::NumLiveInstances());
79
80 // Remove the head of the list (a1).
81 a1.reset();
82 EXPECT_EQ(3, base::LeakTracker<ClassA>::NumLiveInstances());
83
84 // Remove the tail of the list (a4).
85 a4.reset();
86 EXPECT_EQ(2, base::LeakTracker<ClassA>::NumLiveInstances());
87
88 // Append to the new tail of the list (a3).
89 scoped_ptr<ClassA> a5(new ClassA);
90 EXPECT_EQ(3, base::LeakTracker<ClassA>::NumLiveInstances());
91
92 a2.reset();
93 a3.reset();
94
95 EXPECT_EQ(1, base::LeakTracker<ClassA>::NumLiveInstances());
96
97 a5.reset();
98 EXPECT_EQ(0, base::LeakTracker<ClassA>::NumLiveInstances());
99}
100
101TEST(LeakTrackerTest, DebugMode_NoOpCheckForLeaks) {
102 // There are no live instances of ClassA, so this should do nothing.
103 base::LeakTracker<ClassA>::CheckForLeaks();
104}
105
106#endif // NDEBUG
107
108} // namespace