| OLD | NEW |
| 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/leak_detector_controller.h" | 5 #include "chrome/browser/metrics/leak_detector/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 "content/public/test/test_browser_thread_bundle.h" |
| 12 #include "testing/gtest/include/gtest/gtest.h" | 13 #include "testing/gtest/include/gtest/gtest.h" |
| 13 | 14 |
| 14 namespace metrics { | 15 namespace metrics { |
| 15 | 16 |
| 16 namespace { | 17 namespace { |
| 17 | 18 |
| 18 // Converts a vector of values into a protobuf RepeatedField. Although there is | 19 // 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 // no hard requirement, T should be a POD type since that is what RepeatedField |
| 20 // is used for in protobuf classes. | 21 // is used for in protobuf classes. |
| 21 template <typename T> | 22 template <typename T> |
| 22 void InitializeRepeatedField(const std::vector<T>& input, | 23 void InitializeRepeatedField(const std::vector<T>& input, |
| 23 ::google::protobuf::RepeatedField<T>* output) { | 24 ::google::protobuf::RepeatedField<T>* output) { |
| 24 *output = ::google::protobuf::RepeatedField<T>(input.begin(), input.end()); | 25 *output = ::google::protobuf::RepeatedField<T>(input.begin(), input.end()); |
| 25 } | 26 } |
| 26 | 27 |
| 27 } // namespace | 28 } // namespace |
| 28 | 29 |
| 29 // Test class for LeakDetectorController that exposes protected methods. | 30 // Test class for LeakDetectorController that exposes protected methods. |
| 30 class TestLeakDetectorController : public LeakDetectorController { | 31 class TestLeakDetectorController : public LeakDetectorController { |
| 31 public: | 32 public: |
| 32 using LeakDetectorController::OnLeaksFound; | 33 using LeakDetectorController::OnLeaksFound; |
| 33 | 34 |
| 34 TestLeakDetectorController() {} | 35 TestLeakDetectorController() {} |
| 35 | 36 |
| 36 private: | 37 private: |
| 37 DISALLOW_COPY_AND_ASSIGN(TestLeakDetectorController); | 38 DISALLOW_COPY_AND_ASSIGN(TestLeakDetectorController); |
| 38 }; | 39 }; |
| 39 | 40 |
| 41 class LeakDetectorControllerTest : public ::testing::Test { |
| 42 public: |
| 43 LeakDetectorControllerTest() {} |
| 44 |
| 45 private: |
| 46 // For supporting content::BrowserThread operations. |
| 47 content::TestBrowserThreadBundle thread_bundle_; |
| 48 |
| 49 DISALLOW_COPY_AND_ASSIGN(LeakDetectorControllerTest); |
| 50 }; |
| 51 |
| 40 // Use a global instance of the test class because LeakDetectorController | 52 // Use a global instance of the test class because LeakDetectorController |
| 41 // initializes class LeakDetector, which can only be initialized once, enforced | 53 // initializes class LeakDetector, which can only be initialized once, enforced |
| 42 // by an internal CHECK. Multiple initializations of LeakDetectorController in | 54 // by an internal CHECK. Multiple initializations of LeakDetectorController in |
| 43 // the same process will result in multiple initializations of class | 55 // the same process will result in multiple initializations of class |
| 44 // LeakDetector. | 56 // LeakDetector. |
| 45 // | 57 // |
| 46 // See src/components/metrics/leak_detector/leak_detector.h for more info. | 58 // See src/components/metrics/leak_detector/leak_detector.h for more info. |
| 47 base::LazyInstance<TestLeakDetectorController> g_instance = | 59 base::LazyInstance<TestLeakDetectorController> g_instance = |
| 48 LAZY_INSTANCE_INITIALIZER; | 60 LAZY_INSTANCE_INITIALIZER; |
| 49 | 61 |
| 50 TEST(LeakDetectorControllerTest, SingleReport) { | 62 TEST_F(LeakDetectorControllerTest, SingleReport) { |
| 51 MemoryLeakReportProto report; | 63 MemoryLeakReportProto report; |
| 52 report.set_size_bytes(8); | 64 report.set_size_bytes(8); |
| 53 InitializeRepeatedField({1, 2, 3, 4}, report.mutable_call_stack()); | 65 InitializeRepeatedField({1, 2, 3, 4}, report.mutable_call_stack()); |
| 54 | 66 |
| 55 TestLeakDetectorController* controller = &g_instance.Get(); | 67 TestLeakDetectorController* controller = &g_instance.Get(); |
| 56 controller->OnLeaksFound({report}); | 68 controller->OnLeaksFound({report}); |
| 57 | 69 |
| 58 std::vector<MemoryLeakReportProto> stored_reports; | 70 std::vector<MemoryLeakReportProto> stored_reports; |
| 59 controller->GetLeakReports(&stored_reports); | 71 controller->GetLeakReports(&stored_reports); |
| 60 ASSERT_EQ(1U, stored_reports.size()); | 72 ASSERT_EQ(1U, stored_reports.size()); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 73 EXPECT_EQ(4U, proto.params().max_stack_depth()); | 85 EXPECT_EQ(4U, proto.params().max_stack_depth()); |
| 74 EXPECT_EQ(32U * 1024 * 1024, proto.params().analysis_interval_bytes()); | 86 EXPECT_EQ(32U * 1024 * 1024, proto.params().analysis_interval_bytes()); |
| 75 EXPECT_EQ(4U, proto.params().size_suspicion_threshold()); | 87 EXPECT_EQ(4U, proto.params().size_suspicion_threshold()); |
| 76 EXPECT_EQ(4U, proto.params().call_stack_suspicion_threshold()); | 88 EXPECT_EQ(4U, proto.params().call_stack_suspicion_threshold()); |
| 77 | 89 |
| 78 // No more reports. | 90 // No more reports. |
| 79 controller->GetLeakReports(&stored_reports); | 91 controller->GetLeakReports(&stored_reports); |
| 80 ASSERT_EQ(0U, stored_reports.size()); | 92 ASSERT_EQ(0U, stored_reports.size()); |
| 81 } | 93 } |
| 82 | 94 |
| 83 TEST(LeakDetectorControllerTest, SingleReportHistory) { | 95 TEST_F(LeakDetectorControllerTest, SingleReportHistory) { |
| 84 MemoryLeakReportProto report; | 96 MemoryLeakReportProto report; |
| 85 | 97 |
| 86 auto* entry = report.add_alloc_breakdown_history(); | 98 auto* entry = report.add_alloc_breakdown_history(); |
| 87 InitializeRepeatedField({100, 200, 300}, entry->mutable_counts_by_size()); | 99 InitializeRepeatedField({100, 200, 300}, entry->mutable_counts_by_size()); |
| 88 entry->set_count_for_call_stack(15); | 100 entry->set_count_for_call_stack(15); |
| 89 | 101 |
| 90 entry = report.add_alloc_breakdown_history(); | 102 entry = report.add_alloc_breakdown_history(); |
| 91 InitializeRepeatedField({150, 250, 350, 650}, | 103 InitializeRepeatedField({150, 250, 350, 650}, |
| 92 entry->mutable_counts_by_size()); | 104 entry->mutable_counts_by_size()); |
| 93 entry->set_count_for_call_stack(30); | 105 entry->set_count_for_call_stack(30); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 EXPECT_EQ(400U, history.Get(2).counts_by_size(2)); | 138 EXPECT_EQ(400U, history.Get(2).counts_by_size(2)); |
| 127 EXPECT_EQ(700U, history.Get(2).counts_by_size(3)); | 139 EXPECT_EQ(700U, history.Get(2).counts_by_size(3)); |
| 128 EXPECT_EQ(800U, history.Get(2).counts_by_size(4)); | 140 EXPECT_EQ(800U, history.Get(2).counts_by_size(4)); |
| 129 EXPECT_EQ(45U, history.Get(2).count_for_call_stack()); | 141 EXPECT_EQ(45U, history.Get(2).count_for_call_stack()); |
| 130 | 142 |
| 131 // No more reports. | 143 // No more reports. |
| 132 controller->GetLeakReports(&stored_reports); | 144 controller->GetLeakReports(&stored_reports); |
| 133 ASSERT_EQ(0U, stored_reports.size()); | 145 ASSERT_EQ(0U, stored_reports.size()); |
| 134 } | 146 } |
| 135 | 147 |
| 136 TEST(LeakDetectorControllerTest, MultipleReportsSeparately) { | 148 TEST_F(LeakDetectorControllerTest, MultipleReportsSeparately) { |
| 137 TestLeakDetectorController* controller = &g_instance.Get(); | 149 TestLeakDetectorController* controller = &g_instance.Get(); |
| 138 std::vector<MemoryLeakReportProto> stored_reports; | 150 std::vector<MemoryLeakReportProto> stored_reports; |
| 139 | 151 |
| 140 // Pass in first report. | 152 // Pass in first report. |
| 141 MemoryLeakReportProto report1; | 153 MemoryLeakReportProto report1; |
| 142 report1.set_size_bytes(8); | 154 report1.set_size_bytes(8); |
| 143 InitializeRepeatedField({1, 2, 3, 4}, report1.mutable_call_stack()); | 155 InitializeRepeatedField({1, 2, 3, 4}, report1.mutable_call_stack()); |
| 144 | 156 |
| 145 controller->OnLeaksFound({report1}); | 157 controller->OnLeaksFound({report1}); |
| 146 controller->GetLeakReports(&stored_reports); | 158 controller->GetLeakReports(&stored_reports); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 EXPECT_EQ(12U, stored_reports[0].call_stack().Get(3)); | 207 EXPECT_EQ(12U, stored_reports[0].call_stack().Get(3)); |
| 196 EXPECT_EQ(13U, stored_reports[0].call_stack().Get(4)); | 208 EXPECT_EQ(13U, stored_reports[0].call_stack().Get(4)); |
| 197 EXPECT_EQ(14U, stored_reports[0].call_stack().Get(5)); | 209 EXPECT_EQ(14U, stored_reports[0].call_stack().Get(5)); |
| 198 EXPECT_EQ(15U, stored_reports[0].call_stack().Get(6)); | 210 EXPECT_EQ(15U, stored_reports[0].call_stack().Get(6)); |
| 199 EXPECT_EQ(16U, stored_reports[0].call_stack().Get(7)); | 211 EXPECT_EQ(16U, stored_reports[0].call_stack().Get(7)); |
| 200 | 212 |
| 201 controller->GetLeakReports(&stored_reports); | 213 controller->GetLeakReports(&stored_reports); |
| 202 ASSERT_EQ(0U, stored_reports.size()); | 214 ASSERT_EQ(0U, stored_reports.size()); |
| 203 } | 215 } |
| 204 | 216 |
| 205 TEST(LeakDetectorControllerTest, MultipleReportsTogether) { | 217 TEST_F(LeakDetectorControllerTest, MultipleReportsTogether) { |
| 206 std::vector<MemoryLeakReportProto> reports(3); | 218 std::vector<MemoryLeakReportProto> reports(3); |
| 207 reports[0].set_size_bytes(8); | 219 reports[0].set_size_bytes(8); |
| 208 InitializeRepeatedField({1, 2, 3, 4}, reports[0].mutable_call_stack()); | 220 InitializeRepeatedField({1, 2, 3, 4}, reports[0].mutable_call_stack()); |
| 209 reports[1].set_size_bytes(16); | 221 reports[1].set_size_bytes(16); |
| 210 InitializeRepeatedField({5, 6, 7, 8, 9, 10}, reports[1].mutable_call_stack()); | 222 InitializeRepeatedField({5, 6, 7, 8, 9, 10}, reports[1].mutable_call_stack()); |
| 211 reports[2].set_size_bytes(24); | 223 reports[2].set_size_bytes(24); |
| 212 InitializeRepeatedField({9, 10, 11, 12, 13, 14, 15, 16}, | 224 InitializeRepeatedField({9, 10, 11, 12, 13, 14, 15, 16}, |
| 213 reports[2].mutable_call_stack()); | 225 reports[2].mutable_call_stack()); |
| 214 | 226 |
| 215 TestLeakDetectorController* controller = &g_instance.Get(); | 227 TestLeakDetectorController* controller = &g_instance.Get(); |
| (...skipping 29 matching lines...) Expand all Loading... |
| 245 EXPECT_EQ(13U, stored_reports[2].call_stack().Get(4)); | 257 EXPECT_EQ(13U, stored_reports[2].call_stack().Get(4)); |
| 246 EXPECT_EQ(14U, stored_reports[2].call_stack().Get(5)); | 258 EXPECT_EQ(14U, stored_reports[2].call_stack().Get(5)); |
| 247 EXPECT_EQ(15U, stored_reports[2].call_stack().Get(6)); | 259 EXPECT_EQ(15U, stored_reports[2].call_stack().Get(6)); |
| 248 EXPECT_EQ(16U, stored_reports[2].call_stack().Get(7)); | 260 EXPECT_EQ(16U, stored_reports[2].call_stack().Get(7)); |
| 249 | 261 |
| 250 controller->GetLeakReports(&stored_reports); | 262 controller->GetLeakReports(&stored_reports); |
| 251 ASSERT_EQ(0U, stored_reports.size()); | 263 ASSERT_EQ(0U, stored_reports.size()); |
| 252 } | 264 } |
| 253 | 265 |
| 254 } // namespace metrics | 266 } // namespace metrics |
| OLD | NEW |