Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(298)

Side by Side Diff: chrome/browser/metrics/leak_detector_controller_unittest.cc

Issue 1868193003: Store alloc history data in memory leak report protobuf (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@leak-history
Patch Set: Call MergeFrom(); Update comment about repeated fields; Use braces for single-line for loops Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/metrics/leak_detector_controller.h" 5 #include "chrome/browser/metrics/leak_detector_controller.h"
6 6
7 #include <set> 7 #include <set>
8 8
9 #include "base/lazy_instance.h" 9 #include "base/lazy_instance.h"
10 #include "base/macros.h" 10 #include "base/macros.h"
11 #include "components/metrics/proto/memory_leak_report.pb.h" 11 #include "components/metrics/proto/memory_leak_report.pb.h"
12 #include "testing/gtest/include/gtest/gtest.h" 12 #include "testing/gtest/include/gtest/gtest.h"
13 13
14 namespace metrics { 14 namespace metrics {
15 15
16 namespace {
17
18 // Converts a vector of values into a protobuf RepeatedField. Although there is
19 // no hard requirement, T should be a POD type since that is what RepeatedField
20 // is used for in protobuf classes.
21 template <typename T>
22 void InitializeRepeatedField(const std::vector<T>& input,
23 ::google::protobuf::RepeatedField<T>* output) {
24 *output = ::google::protobuf::RepeatedField<T>(input.begin(), input.end());
25 }
26
27 } // namespace
28
16 // Test class for LeakDetectorController that exposes protected methods. 29 // Test class for LeakDetectorController that exposes protected methods.
17 class TestLeakDetectorController : public LeakDetectorController { 30 class TestLeakDetectorController : public LeakDetectorController {
18 public: 31 public:
19 using LeakDetectorController::OnLeakFound; 32 using LeakDetectorController::OnLeaksFound;
20 33
21 TestLeakDetectorController() {} 34 TestLeakDetectorController() {}
22 35
23 private: 36 private:
24 DISALLOW_COPY_AND_ASSIGN(TestLeakDetectorController); 37 DISALLOW_COPY_AND_ASSIGN(TestLeakDetectorController);
25 }; 38 };
26 39
27 using LeakReport = LeakDetector::LeakReport;
28
29 // Use a global instance of the test class because LeakDetectorController 40 // Use a global instance of the test class because LeakDetectorController
30 // initializes class LeakDetector, which can only be initialized once, enforced 41 // initializes class LeakDetector, which can only be initialized once, enforced
31 // by an internal CHECK. Multiple initializations of LeakDetectorController in 42 // by an internal CHECK. Multiple initializations of LeakDetectorController in
32 // the same process will result in multiple initializations of class 43 // the same process will result in multiple initializations of class
33 // LeakDetector. 44 // LeakDetector.
34 // 45 //
35 // See src/components/metrics/leak_detector/leak_detector.h for more info. 46 // See src/components/metrics/leak_detector/leak_detector.h for more info.
36 base::LazyInstance<TestLeakDetectorController> g_instance = 47 base::LazyInstance<TestLeakDetectorController> g_instance =
37 LAZY_INSTANCE_INITIALIZER; 48 LAZY_INSTANCE_INITIALIZER;
38 49
39 TEST(LeakDetectorControllerTest, SingleReport) { 50 TEST(LeakDetectorControllerTest, SingleReport) {
40 LeakReport report; 51 MemoryLeakReportProto report;
41 report.alloc_size_bytes = 8; 52 report.set_size_bytes(8);
42 report.call_stack = {1, 2, 3, 4}; 53 InitializeRepeatedField({1, 2, 3, 4}, report.mutable_call_stack());
43 54
44 TestLeakDetectorController* controller = &g_instance.Get(); 55 TestLeakDetectorController* controller = &g_instance.Get();
45 controller->OnLeakFound(report); 56 controller->OnLeaksFound({report});
46 57
47 std::vector<MemoryLeakReportProto> stored_reports; 58 std::vector<MemoryLeakReportProto> stored_reports;
48 controller->GetLeakReports(&stored_reports); 59 controller->GetLeakReports(&stored_reports);
49 ASSERT_EQ(1U, stored_reports.size()); 60 ASSERT_EQ(1U, stored_reports.size());
50 61
51 const MemoryLeakReportProto& proto = stored_reports[0]; 62 const MemoryLeakReportProto& proto = stored_reports[0];
52 EXPECT_EQ(8U, proto.size_bytes()); 63 EXPECT_EQ(8U, proto.size_bytes());
53 ASSERT_EQ(4, proto.call_stack().size()); 64 ASSERT_EQ(4, proto.call_stack().size());
54 EXPECT_EQ(1U, proto.call_stack().Get(0)); 65 EXPECT_EQ(1U, proto.call_stack().Get(0));
55 EXPECT_EQ(2U, proto.call_stack().Get(1)); 66 EXPECT_EQ(2U, proto.call_stack().Get(1));
56 EXPECT_EQ(3U, proto.call_stack().Get(2)); 67 EXPECT_EQ(3U, proto.call_stack().Get(2));
57 EXPECT_EQ(4U, proto.call_stack().Get(3)); 68 EXPECT_EQ(4U, proto.call_stack().Get(3));
58 69
59 // Check that default leak detector parameters are stored in the leak report. 70 // Check that default leak detector parameters are stored in the leak report.
60 // Default values are listed in leak_detector_controller.cc. 71 // Default values are listed in leak_detector_controller.cc.
61 EXPECT_DOUBLE_EQ(1.0f / 256, proto.sampling_rate()); 72 EXPECT_DOUBLE_EQ(1.0f / 256, proto.sampling_rate());
62 EXPECT_EQ(4U, proto.max_stack_depth()); 73 EXPECT_EQ(4U, proto.max_stack_depth());
63 EXPECT_EQ(32U * 1024 * 1024, proto.analysis_interval_bytes()); 74 EXPECT_EQ(32U * 1024 * 1024, proto.analysis_interval_bytes());
64 EXPECT_EQ(4U, proto.size_suspicion_threshold()); 75 EXPECT_EQ(4U, proto.size_suspicion_threshold());
65 EXPECT_EQ(4U, proto.call_stack_suspicion_threshold()); 76 EXPECT_EQ(4U, proto.call_stack_suspicion_threshold());
66 77
67 // No more reports. 78 // No more reports.
68 controller->GetLeakReports(&stored_reports); 79 controller->GetLeakReports(&stored_reports);
69 ASSERT_EQ(0U, stored_reports.size()); 80 ASSERT_EQ(0U, stored_reports.size());
70 } 81 }
71 82
83 TEST(LeakDetectorControllerTest, SingleReportHistory) {
84 MemoryLeakReportProto report;
85
86 auto entry = report.add_alloc_breakdown_history();
87 InitializeRepeatedField({100, 200, 300}, entry->mutable_counts_by_size());
88 entry->set_count_for_call_stack(15);
89
90 entry = report.add_alloc_breakdown_history();
91 InitializeRepeatedField({150, 250, 350, 650},
92 entry->mutable_counts_by_size());
93 entry->set_count_for_call_stack(30);
94
95 entry = report.add_alloc_breakdown_history();
96 InitializeRepeatedField({200, 300, 400, 700, 800},
97 entry->mutable_counts_by_size());
98 entry->set_count_for_call_stack(45);
99
100 TestLeakDetectorController* controller = &g_instance.Get();
101 controller->OnLeaksFound({report});
102
103 std::vector<MemoryLeakReportProto> stored_reports;
104 controller->GetLeakReports(&stored_reports);
105 ASSERT_EQ(1U, stored_reports.size());
106
107 const auto& history = stored_reports[0].alloc_breakdown_history();
108 ASSERT_EQ(3, history.size());
109
110 ASSERT_EQ(3, history.Get(0).counts_by_size().size());
111 EXPECT_EQ(100U, history.Get(0).counts_by_size(0));
112 EXPECT_EQ(200U, history.Get(0).counts_by_size(1));
113 EXPECT_EQ(300U, history.Get(0).counts_by_size(2));
114 EXPECT_EQ(15U, history.Get(0).count_for_call_stack());
115
116 ASSERT_EQ(4, history.Get(1).counts_by_size_size());
117 EXPECT_EQ(150U, history.Get(1).counts_by_size(0));
118 EXPECT_EQ(250U, history.Get(1).counts_by_size(1));
119 EXPECT_EQ(350U, history.Get(1).counts_by_size(2));
120 EXPECT_EQ(650U, history.Get(1).counts_by_size(3));
121 EXPECT_EQ(30U, history.Get(1).count_for_call_stack());
122
123 ASSERT_EQ(5, history.Get(2).counts_by_size_size());
124 EXPECT_EQ(200U, history.Get(2).counts_by_size(0));
125 EXPECT_EQ(300U, history.Get(2).counts_by_size(1));
126 EXPECT_EQ(400U, history.Get(2).counts_by_size(2));
127 EXPECT_EQ(700U, history.Get(2).counts_by_size(3));
128 EXPECT_EQ(800U, history.Get(2).counts_by_size(4));
129 EXPECT_EQ(45U, history.Get(2).count_for_call_stack());
130
131 // No more reports.
132 controller->GetLeakReports(&stored_reports);
133 ASSERT_EQ(0U, stored_reports.size());
134 }
135
72 TEST(LeakDetectorControllerTest, MultipleReportsSeparately) { 136 TEST(LeakDetectorControllerTest, MultipleReportsSeparately) {
73 TestLeakDetectorController* controller = &g_instance.Get(); 137 TestLeakDetectorController* controller = &g_instance.Get();
74 std::vector<MemoryLeakReportProto> stored_reports; 138 std::vector<MemoryLeakReportProto> stored_reports;
75 139
76 // Pass in first report. 140 // Pass in first report.
77 LeakReport report; 141 MemoryLeakReportProto report1;
78 report.alloc_size_bytes = 8; 142 report1.set_size_bytes(8);
79 report.call_stack = {1, 2, 3, 4}; 143 InitializeRepeatedField({1, 2, 3, 4}, report1.mutable_call_stack());
80 144
81 controller->OnLeakFound(report); 145 controller->OnLeaksFound({report1});
82 controller->GetLeakReports(&stored_reports); 146 controller->GetLeakReports(&stored_reports);
83 ASSERT_EQ(1U, stored_reports.size()); 147 ASSERT_EQ(1U, stored_reports.size());
84 148
85 EXPECT_EQ(8U, stored_reports[0].size_bytes()); 149 EXPECT_EQ(8U, stored_reports[0].size_bytes());
86 ASSERT_EQ(4, stored_reports[0].call_stack().size()); 150 ASSERT_EQ(4, stored_reports[0].call_stack().size());
87 EXPECT_EQ(1U, stored_reports[0].call_stack().Get(0)); 151 EXPECT_EQ(1U, stored_reports[0].call_stack().Get(0));
88 EXPECT_EQ(2U, stored_reports[0].call_stack().Get(1)); 152 EXPECT_EQ(2U, stored_reports[0].call_stack().Get(1));
89 EXPECT_EQ(3U, stored_reports[0].call_stack().Get(2)); 153 EXPECT_EQ(3U, stored_reports[0].call_stack().Get(2));
90 EXPECT_EQ(4U, stored_reports[0].call_stack().Get(3)); 154 EXPECT_EQ(4U, stored_reports[0].call_stack().Get(3));
91 155
92 controller->GetLeakReports(&stored_reports); 156 controller->GetLeakReports(&stored_reports);
93 ASSERT_EQ(0U, stored_reports.size()); 157 ASSERT_EQ(0U, stored_reports.size());
94 158
95 // Pass in second report. 159 // Pass in second report.
96 report.alloc_size_bytes = 16; 160 MemoryLeakReportProto report2;
97 report.call_stack = {5, 6, 7, 8, 9, 10}; 161 report2.set_size_bytes(16);
98 controller->OnLeakFound(report); 162 InitializeRepeatedField({5, 6, 7, 8, 9, 10}, report2.mutable_call_stack());
163 controller->OnLeaksFound({report2});
99 164
100 controller->GetLeakReports(&stored_reports); 165 controller->GetLeakReports(&stored_reports);
101 ASSERT_EQ(1U, stored_reports.size()); 166 ASSERT_EQ(1U, stored_reports.size());
102 167
103 EXPECT_EQ(16U, stored_reports[0].size_bytes()); 168 EXPECT_EQ(16U, stored_reports[0].size_bytes());
104 ASSERT_EQ(6, stored_reports[0].call_stack().size()); 169 ASSERT_EQ(6, stored_reports[0].call_stack().size());
105 EXPECT_EQ(5U, stored_reports[0].call_stack().Get(0)); 170 EXPECT_EQ(5U, stored_reports[0].call_stack().Get(0));
106 EXPECT_EQ(6U, stored_reports[0].call_stack().Get(1)); 171 EXPECT_EQ(6U, stored_reports[0].call_stack().Get(1));
107 EXPECT_EQ(7U, stored_reports[0].call_stack().Get(2)); 172 EXPECT_EQ(7U, stored_reports[0].call_stack().Get(2));
108 EXPECT_EQ(8U, stored_reports[0].call_stack().Get(3)); 173 EXPECT_EQ(8U, stored_reports[0].call_stack().Get(3));
109 EXPECT_EQ(9U, stored_reports[0].call_stack().Get(4)); 174 EXPECT_EQ(9U, stored_reports[0].call_stack().Get(4));
110 EXPECT_EQ(10U, stored_reports[0].call_stack().Get(5)); 175 EXPECT_EQ(10U, stored_reports[0].call_stack().Get(5));
111 176
112 controller->GetLeakReports(&stored_reports); 177 controller->GetLeakReports(&stored_reports);
113 ASSERT_EQ(0U, stored_reports.size()); 178 ASSERT_EQ(0U, stored_reports.size());
114 179
115 // Pass in third report. 180 // Pass in third report.
116 report.alloc_size_bytes = 24; 181 MemoryLeakReportProto report3;
117 report.call_stack = {9, 10, 11, 12, 13, 14, 15, 16}; 182 report3.set_size_bytes(24);
118 controller->OnLeakFound(report); 183 InitializeRepeatedField({9, 10, 11, 12, 13, 14, 15, 16},
184 report3.mutable_call_stack());
185 controller->OnLeaksFound({report3});
119 186
120 controller->GetLeakReports(&stored_reports); 187 controller->GetLeakReports(&stored_reports);
121 ASSERT_EQ(1U, stored_reports.size()); 188 ASSERT_EQ(1U, stored_reports.size());
122 189
123 EXPECT_EQ(24U, stored_reports[0].size_bytes()); 190 EXPECT_EQ(24U, stored_reports[0].size_bytes());
124 ASSERT_EQ(8, stored_reports[0].call_stack().size()); 191 ASSERT_EQ(8, stored_reports[0].call_stack().size());
125 EXPECT_EQ(9U, stored_reports[0].call_stack().Get(0)); 192 EXPECT_EQ(9U, stored_reports[0].call_stack().Get(0));
126 EXPECT_EQ(10U, stored_reports[0].call_stack().Get(1)); 193 EXPECT_EQ(10U, stored_reports[0].call_stack().Get(1));
127 EXPECT_EQ(11U, stored_reports[0].call_stack().Get(2)); 194 EXPECT_EQ(11U, stored_reports[0].call_stack().Get(2));
128 EXPECT_EQ(12U, stored_reports[0].call_stack().Get(3)); 195 EXPECT_EQ(12U, stored_reports[0].call_stack().Get(3));
129 EXPECT_EQ(13U, stored_reports[0].call_stack().Get(4)); 196 EXPECT_EQ(13U, stored_reports[0].call_stack().Get(4));
130 EXPECT_EQ(14U, stored_reports[0].call_stack().Get(5)); 197 EXPECT_EQ(14U, stored_reports[0].call_stack().Get(5));
131 EXPECT_EQ(15U, stored_reports[0].call_stack().Get(6)); 198 EXPECT_EQ(15U, stored_reports[0].call_stack().Get(6));
132 EXPECT_EQ(16U, stored_reports[0].call_stack().Get(7)); 199 EXPECT_EQ(16U, stored_reports[0].call_stack().Get(7));
133 200
134 controller->GetLeakReports(&stored_reports); 201 controller->GetLeakReports(&stored_reports);
135 ASSERT_EQ(0U, stored_reports.size()); 202 ASSERT_EQ(0U, stored_reports.size());
136 } 203 }
137 204
138 TEST(LeakDetectorControllerTest, MultipleReportsTogether) { 205 TEST(LeakDetectorControllerTest, MultipleReportsTogether) {
139 LeakReport report1, report2, report3; 206 std::vector<MemoryLeakReportProto> reports(3);
140 report1.alloc_size_bytes = 8; 207 reports[0].set_size_bytes(8);
141 report1.call_stack = {1, 2, 3, 4}; 208 InitializeRepeatedField({1, 2, 3, 4}, reports[0].mutable_call_stack());
142 report2.alloc_size_bytes = 16; 209 reports[1].set_size_bytes(16);
143 report2.call_stack = {5, 6, 7, 8, 9, 10}; 210 InitializeRepeatedField({5, 6, 7, 8, 9, 10}, reports[1].mutable_call_stack());
144 report3.alloc_size_bytes = 24; 211 reports[2].set_size_bytes(24);
145 report3.call_stack = {9, 10, 11, 12, 13, 14, 15, 16}; 212 InitializeRepeatedField({9, 10, 11, 12, 13, 14, 15, 16},
213 reports[2].mutable_call_stack());
146 214
147 TestLeakDetectorController* controller = &g_instance.Get(); 215 TestLeakDetectorController* controller = &g_instance.Get();
148 controller->OnLeakFound(report1); 216 controller->OnLeaksFound(reports);
149 controller->OnLeakFound(report2);
150 controller->OnLeakFound(report3);
151 217
152 std::vector<MemoryLeakReportProto> stored_reports; 218 std::vector<MemoryLeakReportProto> stored_reports;
153 219
154 controller->GetLeakReports(&stored_reports); 220 controller->GetLeakReports(&stored_reports);
155 ASSERT_EQ(3U, stored_reports.size()); 221 ASSERT_EQ(3U, stored_reports.size());
156 222
157 EXPECT_EQ(8U, stored_reports[0].size_bytes()); 223 EXPECT_EQ(8U, stored_reports[0].size_bytes());
158 ASSERT_EQ(4, stored_reports[0].call_stack().size()); 224 ASSERT_EQ(4, stored_reports[0].call_stack().size());
159 EXPECT_EQ(1U, stored_reports[0].call_stack().Get(0)); 225 EXPECT_EQ(1U, stored_reports[0].call_stack().Get(0));
160 EXPECT_EQ(2U, stored_reports[0].call_stack().Get(1)); 226 EXPECT_EQ(2U, stored_reports[0].call_stack().Get(1));
(...skipping 18 matching lines...) Expand all
179 EXPECT_EQ(13U, stored_reports[2].call_stack().Get(4)); 245 EXPECT_EQ(13U, stored_reports[2].call_stack().Get(4));
180 EXPECT_EQ(14U, stored_reports[2].call_stack().Get(5)); 246 EXPECT_EQ(14U, stored_reports[2].call_stack().Get(5));
181 EXPECT_EQ(15U, stored_reports[2].call_stack().Get(6)); 247 EXPECT_EQ(15U, stored_reports[2].call_stack().Get(6));
182 EXPECT_EQ(16U, stored_reports[2].call_stack().Get(7)); 248 EXPECT_EQ(16U, stored_reports[2].call_stack().Get(7));
183 249
184 controller->GetLeakReports(&stored_reports); 250 controller->GetLeakReports(&stored_reports);
185 ASSERT_EQ(0U, stored_reports.size()); 251 ASSERT_EQ(0U, stored_reports.size());
186 } 252 }
187 253
188 } // namespace metrics 254 } // namespace metrics
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698