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
3 // found in the LICENSE file.
4
5 #include "chrome/browser/memory/memory_kills_monitor.h"
6
7 #include "base/metrics/histogram_base.h"
8 #include "base/metrics/histogram_samples.h"
9 #include "base/metrics/statistics_recorder.h"
10 #include "base/stl_util.h"
11 #include "base/time/time.h"
12 #include "chrome/browser/memory/memory_kills_histogram.h"
13 #include "content/public/test/browser_task_environment.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 namespace memory {
17
18 namespace {
19
GetLowMemoryKillsCountHistogram()20 base::HistogramBase* GetLowMemoryKillsCountHistogram() {
21 return base::StatisticsRecorder::FindHistogram(
22 "Memory.LowMemoryKiller.Count");
23 }
24
GetOOMKillsCountHistogram()25 base::HistogramBase* GetOOMKillsCountHistogram() {
26 return base::StatisticsRecorder::FindHistogram("Memory.OOMKills.Count");
27 }
28
29 } // namespace.
30
31 class MemoryKillsMonitorTest : public testing::Test {
32 private:
33 content::BrowserTaskEnvironment task_environment_;
34 };
35
TEST_F(MemoryKillsMonitorTest,TestHistograms)36 TEST_F(MemoryKillsMonitorTest, TestHistograms) {
37 std::unique_ptr<base::StatisticsRecorder> statistic_recorder(
38 base::StatisticsRecorder::CreateTemporaryForTesting());
39
40 MemoryKillsMonitor* g_memory_kills_monitor_unittest_instance =
41 MemoryKillsMonitor::GetForTesting();
42
43 MemoryKillsMonitor::LogLowMemoryKill("APP", 123);
44 MemoryKillsMonitor::LogLowMemoryKill("APP", 100);
45 MemoryKillsMonitor::LogLowMemoryKill("TAB", 10000);
46
47 auto* lmk_count_histogram = GetLowMemoryKillsCountHistogram();
48 auto* oom_count_histogram = GetOOMKillsCountHistogram();
49 // Before StartMonitoring() is called, nothing is recorded.
50 ASSERT_FALSE(lmk_count_histogram);
51 ASSERT_FALSE(oom_count_histogram);
52
53 // Start monitoring.
54 g_memory_kills_monitor_unittest_instance->StartMonitoring();
55 lmk_count_histogram = GetLowMemoryKillsCountHistogram();
56 oom_count_histogram = GetOOMKillsCountHistogram();
57 ASSERT_TRUE(lmk_count_histogram);
58 ASSERT_TRUE(oom_count_histogram);
59 {
60 auto count_samples = lmk_count_histogram->SnapshotSamples();
61 EXPECT_EQ(1, count_samples->TotalCount());
62 EXPECT_EQ(1, count_samples->GetCount(0));
63 }
64 {
65 auto count_samples = oom_count_histogram->SnapshotSamples();
66 EXPECT_EQ(1, count_samples->TotalCount());
67 EXPECT_EQ(1, count_samples->GetCount(0));
68 }
69
70 // Low memory kills.
71 MemoryKillsMonitor::LogLowMemoryKill("APP", 123);
72 MemoryKillsMonitor::LogLowMemoryKill("APP", 100);
73 MemoryKillsMonitor::LogLowMemoryKill("TAB", 10000);
74 lmk_count_histogram = GetLowMemoryKillsCountHistogram();
75 ASSERT_TRUE(lmk_count_histogram);
76 {
77 auto count_samples = lmk_count_histogram->SnapshotSamples();
78 EXPECT_EQ(4, count_samples->TotalCount());
79 // The zero count is implicitly added when StartMonitoring() is called.
80 EXPECT_EQ(1, count_samples->GetCount(0));
81 EXPECT_EQ(1, count_samples->GetCount(1));
82 EXPECT_EQ(1, count_samples->GetCount(2));
83 EXPECT_EQ(1, count_samples->GetCount(3));
84 }
85
86 {
87 auto* histogram_freed_size = base::StatisticsRecorder::FindHistogram(
88 "Memory.LowMemoryKiller.FreedSize");
89 ASSERT_TRUE(histogram_freed_size);
90 auto freed_size_samples = histogram_freed_size->SnapshotSamples();
91 EXPECT_EQ(3, freed_size_samples->TotalCount());
92 // 123 and 100 are in the same bucket.
93 EXPECT_EQ(2, freed_size_samples->GetCount(123));
94 EXPECT_EQ(2, freed_size_samples->GetCount(100));
95 EXPECT_EQ(1, freed_size_samples->GetCount(10000));
96 }
97
98 {
99 auto* histogram_time_delta = base::StatisticsRecorder::FindHistogram(
100 "Memory.LowMemoryKiller.TimeDelta");
101 ASSERT_TRUE(histogram_time_delta);
102 auto time_delta_samples = histogram_time_delta->SnapshotSamples();
103 EXPECT_EQ(3, time_delta_samples->TotalCount());
104 // First time delta is set to kMaxMemoryKillTimeDelta.
105 EXPECT_EQ(1, time_delta_samples->GetCount(
106 kMaxMemoryKillTimeDelta.InMilliseconds()));
107 // Time delta for the other 2 events depends on Now() so we skip testing it
108 // here.
109 }
110
111 // OOM kills.
112 // Simulate getting 3 more oom kills.
113 g_memory_kills_monitor_unittest_instance->CheckOOMKillImpl(
114 g_memory_kills_monitor_unittest_instance->last_oom_kills_count_ + 3);
115
116 oom_count_histogram = GetOOMKillsCountHistogram();
117 ASSERT_TRUE(oom_count_histogram);
118 {
119 auto count_samples = oom_count_histogram->SnapshotSamples();
120 EXPECT_EQ(4, count_samples->TotalCount());
121 // The zero count is implicitly added when StartMonitoring() is called.
122 EXPECT_EQ(1, count_samples->GetCount(0));
123 EXPECT_EQ(1, count_samples->GetCount(1));
124 EXPECT_EQ(1, count_samples->GetCount(2));
125 EXPECT_EQ(1, count_samples->GetCount(3));
126 }
127
128 lmk_count_histogram = GetLowMemoryKillsCountHistogram();
129 ASSERT_TRUE(lmk_count_histogram);
130 {
131 auto count_samples = lmk_count_histogram->SnapshotSamples();
132 // Ensure zero count is not increased.
133 EXPECT_EQ(1, count_samples->GetCount(0));
134 }
135 oom_count_histogram = GetOOMKillsCountHistogram();
136 ASSERT_TRUE(oom_count_histogram);
137 {
138 auto count_samples = oom_count_histogram->SnapshotSamples();
139 // Ensure zero count is not increased.
140 EXPECT_EQ(1, count_samples->GetCount(0));
141 }
142 }
143
144 } // namespace memory
145