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

Side by Side Diff: base/win/memory_pressure_monitor_unittest.cc

Issue 1122863005: Create base::win::MemoryPressureMonitor class. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebased. Created 5 years, 7 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
(Empty)
1 // Copyright 2015 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/win/memory_pressure_monitor.h"
6
7 #include "base/basictypes.h"
8 #include "base/memory/memory_pressure_listener.h"
9 #include "base/message_loop/message_loop.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace base {
14 namespace win {
15
16 namespace {
17
18 struct PressureSettings {
19 int phys_left_mb;
20 MemoryPressureListener::MemoryPressureLevel level;
21 };
22
23 } // namespace
24
25 // This is outside of the anonymous namespace so that it can be seen as a friend
26 // to the monitor class.
27 class TestMemoryPressureMonitor : public MemoryPressureMonitor {
28 public:
29 using MemoryPressureMonitor::CalculateCurrentPressureLevel;
30 using MemoryPressureMonitor::CheckMemoryPressure;
31
32 static const DWORDLONG kMBBytes = 1024 * 1024;
33
34 TestMemoryPressureMonitor(bool high_memory) {
grt (UTC plus 2) 2015/05/07 02:12:11 explicit
grt (UTC plus 2) 2015/05/07 02:12:12 : mem_status_() to default-initialize it (which wi
35 // Generate a plausible amount of memory.
36 mem_status_.ullTotalPhys =
37 static_cast<DWORDLONG>(GenerateTotalMemoryMb(high_memory)) * kMBBytes;
38
39 // Rerun InferThresholds using the test fixture's GetSystemMemoryStatus.
40 InferThresholds();
41 // Stop the timer.
42 StopObserving();
43 }
44
45 TestMemoryPressureMonitor(int system_memory_mb,
46 int moderate_threshold_mb,
47 int critical_threshold_mb)
48 : MemoryPressureMonitor(moderate_threshold_mb, critical_threshold_mb) {
grt (UTC plus 2) 2015/05/07 02:12:12 , mem_status_() here, too
chrisha 2015/05/07 21:17:36 Done.
49 // Set the amount of system memory.
50 mem_status_.ullTotalPhys = static_cast<DWORDLONG>(
51 system_memory_mb * kMBBytes);
52
53 // Stop the timer.
54 StopObserving();
55 }
56
57 virtual ~TestMemoryPressureMonitor() {}
58
59 MOCK_METHOD1(OnMemoryPressure,
60 void(MemoryPressureListener::MemoryPressureLevel level));
61
62 // Generates an amount of total memory that is consistent with the requested
63 // memory model.
64 int GenerateTotalMemoryMb(bool high_memory) {
65 int total_mb = 64;
66 while (total_mb < MemoryPressureMonitor::kHighMemoryThresholdMb)
67 total_mb *= 2;
68 if (high_memory)
69 return total_mb * 2;
70 return total_mb / 2;
71 }
72
73 // Sets up the memory status to reflect the provided absolute memory left.
74 void SetMemoryFree(int phys_left_mb) {
75 // ullTotalPhys is set in the constructor and not modified.
76
77 // Set the amount of available memory.
78 mem_status_.ullAvailPhys =
79 static_cast<DWORDLONG>(phys_left_mb) * kMBBytes;
80 DCHECK_LT(mem_status_.ullAvailPhys, mem_status_.ullTotalPhys);
81
82 // These fields are unused.
83 mem_status_.dwMemoryLoad = 0;
84 mem_status_.ullTotalPageFile = 0;
85 mem_status_.ullAvailPageFile = 0;
86 mem_status_.ullTotalVirtual = 0;
87 mem_status_.ullAvailVirtual = 0;
88 }
89
90 void SetNone() {
91 SetMemoryFree(moderate_threshold_mb() + 1);
92 }
93
94 void SetModerate() {
95 SetMemoryFree(moderate_threshold_mb() - 1);
96 }
97
98 void SetCritical() {
99 SetMemoryFree(critical_threshold_mb() - 1);
100 }
101
102 private:
103 bool GetSystemMemoryStatus(MEMORYSTATUSEX* mem_status) override {
104 // Simply copy the memory status set by the test fixture.
105 *mem_status = mem_status_;
106 return true;
107 }
108
109 MEMORYSTATUSEX mem_status_;
110
111 DISALLOW_COPY_AND_ASSIGN(TestMemoryPressureMonitor);
112 };
113
114 namespace {
grt (UTC plus 2) 2015/05/07 02:12:12 remove this: don't put the test fixture in the unn
115
116 class WinMemoryPressureMonitorTest : public testing::Test {
117 public:
grt (UTC plus 2) 2015/05/07 02:12:11 protected: (each individual TEST_F ends up being a
118 ~WinMemoryPressureMonitorTest() override { }
grt (UTC plus 2) 2015/05/07 02:12:12 remove; not needed
chrisha 2015/05/07 21:17:36 Done.
119
120 void CalculateCurrentMemoryPressureLevelTest(
121 TestMemoryPressureMonitor* monitor) {
122 int mod = monitor->moderate_threshold_mb();
123 int crit = monitor->critical_threshold_mb();
grt (UTC plus 2) 2015/05/07 02:12:11 nit: move down to line 136 so its definition is "a
chrisha 2015/05/07 21:17:36 Done.
124
125 monitor->SetMemoryFree(mod + 1);
126 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
127 monitor->CalculateCurrentPressureLevel());
128
129 monitor->SetMemoryFree(mod);
130 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
131 monitor->CalculateCurrentPressureLevel());
132
133 monitor->SetMemoryFree(mod - 1);
134 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
135 monitor->CalculateCurrentPressureLevel());
136
137 monitor->SetMemoryFree(crit + 1);
138 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
139 monitor->CalculateCurrentPressureLevel());
140
141 monitor->SetMemoryFree(crit);
142 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
143 monitor->CalculateCurrentPressureLevel());
144
145 monitor->SetMemoryFree(crit - 1);
146 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
147 monitor->CalculateCurrentPressureLevel());
148 }
149 };
150
151 } // namespace
152
153 // Tests the fundamental direct calculation of memory pressure with automatic
154 // low-memory thresholds.
155 TEST_F(WinMemoryPressureMonitorTest, CalculateCurrentMemoryPressureLevelLow) {
156 static const int kModerateMb =
157 MemoryPressureMonitor::kLowMemoryDefaultModerateThresholdMb;
158 static const int kCriticalMb =
159 MemoryPressureMonitor::kLowMemoryDefaultCriticalThresholdMb;
160
161 base::MessageLoopForUI message_loop;
grt (UTC plus 2) 2015/05/07 02:12:11 now that you have a test fixture, make the Message
chrisha 2015/05/07 21:17:36 Done.
162 TestMemoryPressureMonitor monitor(false); // Low-memory model.
163
164 EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
165 EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());
166
167 ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
168 }
169
170 // Tests the fundamental direct calculation of memory pressure with automatic
171 // high-memory thresholds.
172 TEST_F(WinMemoryPressureMonitorTest, CalculateCurrentMemoryPressureLevelHigh) {
173 static const int kModerateMb =
174 MemoryPressureMonitor::kHighMemoryDefaultModerateThresholdMb;
175 static const int kCriticalMb =
176 MemoryPressureMonitor::kHighMemoryDefaultCriticalThresholdMb;
177
178 base::MessageLoopForUI message_loop;
179 TestMemoryPressureMonitor monitor(true); // High-memory model.
180
181 EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
182 EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());
183
184 ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
185 }
186
187 // Tests the fundamental direct calculation of memory pressure with manually
188 // specified threshold levels.
189 TEST_F(WinMemoryPressureMonitorTest,
190 CalculateCurrentMemoryPressureLevelCustom) {
191 static const int kSystemMb = 512;
192 static const int kModerateMb = 256;
193 static const int kCriticalMb = 128;
194
195 base::MessageLoopForUI message_loop;
196 TestMemoryPressureMonitor monitor(kSystemMb, kModerateMb, kCriticalMb);
197
198 EXPECT_EQ(kModerateMb, monitor.moderate_threshold_mb());
199 EXPECT_EQ(kCriticalMb, monitor.critical_threshold_mb());
200
201 ASSERT_NO_FATAL_FAILURE(CalculateCurrentMemoryPressureLevelTest(&monitor));
202 }
203
204 // This test tests the various transition states from memory pressure, looking
205 // for the correct behavior on event reposting as well as state updates.
206 TEST_F(WinMemoryPressureMonitorTest, CheckMemoryPressure) {
207 base::MessageLoopForUI message_loop;
208 testing::StrictMock<TestMemoryPressureMonitor> monitor(true); // High-memory.
209 MemoryPressureListener listener(
210 base::Bind(&TestMemoryPressureMonitor::OnMemoryPressure,
211 base::Unretained(&monitor)));
212
213 // Checking the memory pressure at 0% load should not produce any
214 // events.
215 monitor.SetNone();
216 monitor.CheckMemoryPressure();
217 message_loop.RunUntilIdle();
218 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
219 monitor.GetCurrentPressureLevel());
220
221 // Setting the memory level to 80% should produce a moderate pressure level.
222 EXPECT_CALL(monitor,
223 OnMemoryPressure(MemoryPressureListener::
224 MEMORY_PRESSURE_LEVEL_MODERATE));
225 monitor.SetModerate();
226 monitor.CheckMemoryPressure();
227 message_loop.RunUntilIdle();
228 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
229 monitor.GetCurrentPressureLevel());
230 testing::Mock::VerifyAndClearExpectations(&monitor);
231
232 // Check that the event gets reposted after a while.
233 for (int i = 0; i < monitor.kModeratePressureCooldownCycles; ++i) {
234 if (i + 1 == monitor.kModeratePressureCooldownCycles) {
235 EXPECT_CALL(monitor,
236 OnMemoryPressure(MemoryPressureListener::
237 MEMORY_PRESSURE_LEVEL_MODERATE));
238 }
239 monitor.CheckMemoryPressure();
240 message_loop.RunUntilIdle();
241 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
242 monitor.GetCurrentPressureLevel());
243 testing::Mock::VerifyAndClearExpectations(&monitor);
244 }
245
246 // Setting the memory usage to 99% should produce critical levels.
247 EXPECT_CALL(monitor,
248 OnMemoryPressure(MemoryPressureListener::
249 MEMORY_PRESSURE_LEVEL_CRITICAL));
250 monitor.SetCritical();
251 monitor.CheckMemoryPressure();
252 message_loop.RunUntilIdle();
253 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
254 monitor.GetCurrentPressureLevel());
255 testing::Mock::VerifyAndClearExpectations(&monitor);
256
257 // Calling it again should immediately produce a second call.
258 EXPECT_CALL(monitor,
259 OnMemoryPressure(MemoryPressureListener::
260 MEMORY_PRESSURE_LEVEL_CRITICAL));
261 monitor.CheckMemoryPressure();
262 message_loop.RunUntilIdle();
263 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL,
264 monitor.GetCurrentPressureLevel());
265 testing::Mock::VerifyAndClearExpectations(&monitor);
266
267 // When lowering the pressure again there should be a notification and the
268 // pressure should go back to moderate.
269 EXPECT_CALL(monitor,
270 OnMemoryPressure(MemoryPressureListener::
271 MEMORY_PRESSURE_LEVEL_MODERATE));
272 monitor.SetModerate();
273 monitor.CheckMemoryPressure();
274 message_loop.RunUntilIdle();
275 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
276 monitor.GetCurrentPressureLevel());
277 testing::Mock::VerifyAndClearExpectations(&monitor);
278
279 // Check that the event gets reposted after a while.
280 for (int i = 0; i < monitor.kModeratePressureCooldownCycles; ++i) {
281 if (i + 1 == monitor.kModeratePressureCooldownCycles) {
282 EXPECT_CALL(monitor,
283 OnMemoryPressure(MemoryPressureListener::
284 MEMORY_PRESSURE_LEVEL_MODERATE));
285 }
286 monitor.CheckMemoryPressure();
287 message_loop.RunUntilIdle();
288 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE,
289 monitor.GetCurrentPressureLevel());
290 testing::Mock::VerifyAndClearExpectations(&monitor);
291 }
292
293 // Going down to no pressure should not produce an notification.
294 monitor.SetNone();
295 monitor.CheckMemoryPressure();
296 message_loop.RunUntilIdle();
297 EXPECT_EQ(MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE,
298 monitor.GetCurrentPressureLevel());
299 testing::Mock::VerifyAndClearExpectations(&monitor);
300 }
301
302 } // namespace win
303 } // namespace base
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698