blob: cf5341d14dcb3bae8e7a202851465fb4fae45a69 [file] [log] [blame]
Sandeep Patil54d87212018-08-29 17:10:47 -07001/*
2 * Copyright (C) 2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Christopher Ferris504d2cc2019-07-12 14:25:48 -070017#include <sys/mman.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070018#include <sys/types.h>
19#include <sys/wait.h>
20#include <unistd.h>
21
22#include <gtest/gtest.h>
23
24#include <string>
25#include <vector>
26
27#include <meminfo/pageacct.h>
28#include <meminfo/procmeminfo.h>
29#include <meminfo/sysmeminfo.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070030
31#include <android-base/file.h>
32#include <android-base/logging.h>
Sandeep Patilc24f1e32018-12-29 14:34:20 -080033#include <android-base/stringprintf.h>
Christopher Ferris5db00922019-09-18 10:30:33 -070034#include <android-base/strings.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070035
36using namespace std;
37using namespace android::meminfo;
38
39pid_t pid = -1;
40
Sandeep Patildfa00a72019-01-28 15:05:27 -080041TEST(ProcMemInfo, TestWorkingTestReset) {
Sandeep Patil54d87212018-08-29 17:10:47 -070042 // Expect reset to succeed
Sandeep Patilf1291992018-11-19 15:25:18 -080043 EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid));
Sandeep Patil54d87212018-08-29 17:10:47 -070044}
45
Sandeep Patildfa00a72019-01-28 15:05:27 -080046TEST(ProcMemInfo, UsageEmpty) {
Sandeep Patilc6497eb2018-11-20 09:31:36 -080047 // If we created the object for getting working set,
48 // the usage must be empty
49 ProcMemInfo proc_mem(pid, true);
50 const MemUsage& usage = proc_mem.Usage();
51 EXPECT_EQ(usage.rss, 0);
52 EXPECT_EQ(usage.vss, 0);
53 EXPECT_EQ(usage.pss, 0);
54 EXPECT_EQ(usage.uss, 0);
55 EXPECT_EQ(usage.swap, 0);
56}
57
Sandeep Patildfa00a72019-01-28 15:05:27 -080058TEST(ProcMemInfo, MapsNotEmpty) {
59 // Make sure the process maps are never empty
60 ProcMemInfo proc_mem(pid);
61 const std::vector<Vma>& maps = proc_mem.Maps();
62 EXPECT_FALSE(maps.empty());
63}
64
Christopher Ferris504d2cc2019-07-12 14:25:48 -070065TEST(ProcMemInfo, MapsUsageNotEmpty) {
66 ProcMemInfo proc_mem(pid);
67 const std::vector<Vma>& maps = proc_mem.Maps();
68 EXPECT_FALSE(maps.empty());
69 uint64_t total_pss = 0;
70 uint64_t total_rss = 0;
71 uint64_t total_uss = 0;
72 for (auto& map : maps) {
73 ASSERT_NE(0, map.usage.vss);
74 total_rss += map.usage.rss;
75 total_pss += map.usage.pss;
76 total_uss += map.usage.uss;
77 }
78
79 // Crude check that stats are actually being read.
80 EXPECT_NE(0, total_rss) << "RSS zero for all maps, that is not possible.";
81 EXPECT_NE(0, total_pss) << "PSS zero for all maps, that is not possible.";
82 EXPECT_NE(0, total_uss) << "USS zero for all maps, that is not possible.";
83}
84
85TEST(ProcMemInfo, MapsUsageEmpty) {
86 ProcMemInfo proc_mem(pid);
87 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
88 EXPECT_FALSE(maps.empty());
89 // Verify that all usage stats are zero in every map.
90 for (auto& map : maps) {
91 ASSERT_EQ(0, map.usage.vss);
92 ASSERT_EQ(0, map.usage.rss);
93 ASSERT_EQ(0, map.usage.pss);
94 ASSERT_EQ(0, map.usage.uss);
95 ASSERT_EQ(0, map.usage.swap);
96 ASSERT_EQ(0, map.usage.swap_pss);
97 ASSERT_EQ(0, map.usage.private_clean);
98 ASSERT_EQ(0, map.usage.private_dirty);
99 ASSERT_EQ(0, map.usage.shared_clean);
100 ASSERT_EQ(0, map.usage.shared_dirty);
101 }
102}
103
104TEST(ProcMemInfo, PageMapPresent) {
105 static constexpr size_t kNumPages = 20;
106 size_t pagesize = getpagesize();
107 void* ptr = mmap(nullptr, pagesize * (kNumPages + 2), PROT_READ | PROT_WRITE,
108 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
109 ASSERT_NE(MAP_FAILED, ptr);
110
111 // Unmap the first page and the last page so that we guarantee this
112 // map is in a map by itself.
113 ASSERT_EQ(0, munmap(ptr, pagesize));
114 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr) + pagesize;
115 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr + kNumPages * pagesize), pagesize));
116
117 ProcMemInfo proc_mem(getpid());
118 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
119 ASSERT_FALSE(maps.empty());
120
121 // Find the vma associated with our previously created map.
122 const Vma* test_vma = nullptr;
123 for (const Vma& vma : maps) {
124 if (vma.start == addr) {
125 test_vma = &vma;
126 break;
127 }
128 }
129 ASSERT_TRUE(test_vma != nullptr) << "Cannot find test map.";
130
131 // Verify that none of the pages are listed as present.
132 std::vector<uint64_t> pagemap;
133 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
134 ASSERT_EQ(kNumPages, pagemap.size());
135 for (size_t i = 0; i < pagemap.size(); i++) {
136 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
137 << "Page " << i << " is present and it should not be.";
138 }
139
140 // Make some of the pages present and verify that we see them
141 // as present.
142 uint8_t* data = reinterpret_cast<uint8_t*>(addr);
143 data[0] = 1;
144 data[pagesize * 5] = 1;
145 data[pagesize * 11] = 1;
146
147 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
148 ASSERT_EQ(kNumPages, pagemap.size());
149 for (size_t i = 0; i < pagemap.size(); i++) {
150 if (i == 0 || i == 5 || i == 11) {
151 EXPECT_TRUE(android::meminfo::page_present(pagemap[i]))
152 << "Page " << i << " is not present and it should be.";
153 } else {
154 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
155 << "Page " << i << " is present and it should not be.";
156 }
157 }
158
159 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr), kNumPages * pagesize));
160}
161
Sandeep Patildfa00a72019-01-28 15:05:27 -0800162TEST(ProcMemInfo, WssEmpty) {
Sandeep Patilc6497eb2018-11-20 09:31:36 -0800163 // If we created the object for getting usage,
164 // the working set must be empty
165 ProcMemInfo proc_mem(pid, false);
166 const MemUsage& wss = proc_mem.Wss();
167 EXPECT_EQ(wss.rss, 0);
168 EXPECT_EQ(wss.vss, 0);
169 EXPECT_EQ(wss.pss, 0);
170 EXPECT_EQ(wss.uss, 0);
171 EXPECT_EQ(wss.swap, 0);
172}
173
Sandeep Patildfa00a72019-01-28 15:05:27 -0800174TEST(ProcMemInfo, SwapOffsetsEmpty) {
Sandeep Patilc6497eb2018-11-20 09:31:36 -0800175 // If we created the object for getting working set,
176 // the swap offsets must be empty
177 ProcMemInfo proc_mem(pid, true);
178 const std::vector<uint16_t>& swap_offsets = proc_mem.SwapOffsets();
179 EXPECT_EQ(swap_offsets.size(), 0);
180}
181
Sandeep Patildfa00a72019-01-28 15:05:27 -0800182TEST(ProcMemInfo, IsSmapsSupportedTest) {
183 // Get any pid and check if /proc/<pid>/smaps_rollup exists using the API.
184 // The API must return the appropriate value regardless of the after it succeeds
185 // once.
Sandeep Patildfd34be2019-01-13 17:39:08 -0800186 std::string path = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid);
187 bool supported = IsSmapsRollupSupported(pid);
188 EXPECT_EQ(!access(path.c_str(), F_OK | R_OK), supported);
189 // Second call must return what the first one returned regardless of the pid parameter.
190 // So, deliberately pass invalid pid.
191 EXPECT_EQ(supported, IsSmapsRollupSupported(-1));
192}
193
Sandeep Patildfa00a72019-01-28 15:05:27 -0800194TEST(ProcMemInfo, SmapsOrRollupTest) {
195 // Make sure we can parse 'smaps_rollup' correctly
Sandeep Patilfa2d8d52018-12-29 21:05:38 -0800196 std::string rollup =
197 R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0 [rollup]
198Rss: 331908 kB
199Pss: 202052 kB
200Shared_Clean: 158492 kB
201Shared_Dirty: 18928 kB
202Private_Clean: 90472 kB
203Private_Dirty: 64016 kB
204Referenced: 318700 kB
205Anonymous: 81984 kB
206AnonHugePages: 0 kB
207Shared_Hugetlb: 0 kB
208Private_Hugetlb: 0 kB
209Swap: 5344 kB
210SwapPss: 442 kB
211Locked: 1523537 kB)rollup";
212
213 TemporaryFile tf;
214 ASSERT_TRUE(tf.fd != -1);
215 ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd));
216
217 MemUsage stats;
218 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
219 EXPECT_EQ(stats.rss, 331908);
220 EXPECT_EQ(stats.pss, 202052);
221 EXPECT_EQ(stats.uss, 154488);
222 EXPECT_EQ(stats.private_clean, 90472);
223 EXPECT_EQ(stats.private_dirty, 64016);
224 EXPECT_EQ(stats.swap_pss, 442);
225}
226
Sandeep Patildfa00a72019-01-28 15:05:27 -0800227TEST(ProcMemInfo, SmapsOrRollupSmapsTest) {
228 // Make sure /proc/<pid>/smaps is parsed correctly
Sandeep Patilfa2d8d52018-12-29 21:05:38 -0800229 std::string smaps =
230 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
231Name: [anon:dalvik-main space (region space)]
232Size: 8448 kB
233KernelPageSize: 4 kB
234MMUPageSize: 4 kB
235Rss: 2652 kB
236Pss: 2652 kB
237Shared_Clean: 840 kB
238Shared_Dirty: 40 kB
239Private_Clean: 84 kB
240Private_Dirty: 2652 kB
241Referenced: 2652 kB
242Anonymous: 2652 kB
243AnonHugePages: 0 kB
244ShmemPmdMapped: 0 kB
245Shared_Hugetlb: 0 kB
246Private_Hugetlb: 0 kB
247Swap: 102 kB
248SwapPss: 70 kB
249Locked: 2652 kB
250VmFlags: rd wr mr mw me ac
251)smaps";
252
253 TemporaryFile tf;
254 ASSERT_TRUE(tf.fd != -1);
255 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
256
257 MemUsage stats;
258 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
259 EXPECT_EQ(stats.rss, 2652);
260 EXPECT_EQ(stats.pss, 2652);
261 EXPECT_EQ(stats.uss, 2736);
262 EXPECT_EQ(stats.private_clean, 84);
263 EXPECT_EQ(stats.private_dirty, 2652);
264 EXPECT_EQ(stats.swap_pss, 70);
265}
266
Sandeep Patildfa00a72019-01-28 15:05:27 -0800267TEST(ProcMemInfo, SmapsOrRollupPssRollupTest) {
268 // Make sure /proc/<pid>/smaps is parsed correctly
269 // to get the PSS
Sandeep Patil8871e7e2019-01-13 16:47:20 -0800270 std::string smaps =
271 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
272Name: [anon:dalvik-main space (region space)]
273Size: 8448 kB
274KernelPageSize: 4 kB
275MMUPageSize: 4 kB
276Rss: 2652 kB
277Pss: 2652 kB
278Shared_Clean: 840 kB
279Shared_Dirty: 40 kB
280Private_Clean: 84 kB
281Private_Dirty: 2652 kB
282Referenced: 2652 kB
283Anonymous: 2652 kB
284AnonHugePages: 0 kB
285ShmemPmdMapped: 0 kB
286Shared_Hugetlb: 0 kB
287Private_Hugetlb: 0 kB
288Swap: 102 kB
289SwapPss: 70 kB
290Locked: 2652 kB
291VmFlags: rd wr mr mw me ac
292)smaps";
293
294 TemporaryFile tf;
295 ASSERT_TRUE(tf.fd != -1);
296 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
297
298 uint64_t pss;
299 ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
300 EXPECT_EQ(pss, 2652);
301}
302
Sandeep Patildfa00a72019-01-28 15:05:27 -0800303TEST(ProcMemInfo, SmapsOrRollupPssSmapsTest) {
304 // Correctly parse smaps file to gather pss
Sandeep Patil8871e7e2019-01-13 16:47:20 -0800305 std::string exec_dir = ::android::base::GetExecutableDirectory();
306 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
307
308 uint64_t pss;
309 ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
310 EXPECT_EQ(pss, 19119);
311}
312
Sandeep Patildfa00a72019-01-28 15:05:27 -0800313TEST(ProcMemInfo, ForEachVmaFromFileTest) {
314 // Parse smaps file correctly to make callbacks for each virtual memory area (vma)
Sandeep Patil82a48b12019-01-01 16:04:04 -0800315 std::string exec_dir = ::android::base::GetExecutableDirectory();
316 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
317 ProcMemInfo proc_mem(pid);
318
319 std::vector<Vma> vmas;
320 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
321 ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
322
Sandeep Patil002f02e2019-01-13 19:39:46 -0800323 // We should get a total of 6 vmas
324 ASSERT_EQ(vmas.size(), 6);
325
Sandeep Patil82a48b12019-01-01 16:04:04 -0800326 // Expect values to be equal to what we have in testdata1/smaps_short
327 // Check for sizes first
328 ASSERT_EQ(vmas[0].usage.vss, 32768);
329 EXPECT_EQ(vmas[1].usage.vss, 11204);
330 EXPECT_EQ(vmas[2].usage.vss, 16896);
331 EXPECT_EQ(vmas[3].usage.vss, 260);
332 EXPECT_EQ(vmas[4].usage.vss, 6060);
333 EXPECT_EQ(vmas[5].usage.vss, 4);
334
335 // Check for names
336 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
337 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
Christopher Ferris5db00922019-09-18 10:30:33 -0700338 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
339 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
340 << "Unknown map name " << vmas[2].name;
Sandeep Patil82a48b12019-01-01 16:04:04 -0800341 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
342 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
343 EXPECT_EQ(vmas[5].name, "[vsyscall]");
344
345 EXPECT_EQ(vmas[0].usage.rss, 2048);
346 EXPECT_EQ(vmas[1].usage.rss, 11188);
347 EXPECT_EQ(vmas[2].usage.rss, 15272);
348 EXPECT_EQ(vmas[3].usage.rss, 260);
349 EXPECT_EQ(vmas[4].usage.rss, 4132);
350 EXPECT_EQ(vmas[5].usage.rss, 0);
351
352 EXPECT_EQ(vmas[0].usage.pss, 113);
353 EXPECT_EQ(vmas[1].usage.pss, 2200);
354 EXPECT_EQ(vmas[2].usage.pss, 15272);
355 EXPECT_EQ(vmas[3].usage.pss, 260);
356 EXPECT_EQ(vmas[4].usage.pss, 1274);
357 EXPECT_EQ(vmas[5].usage.pss, 0);
358
359 EXPECT_EQ(vmas[0].usage.uss, 0);
360 EXPECT_EQ(vmas[1].usage.uss, 1660);
361 EXPECT_EQ(vmas[2].usage.uss, 15272);
362 EXPECT_EQ(vmas[3].usage.uss, 260);
363 EXPECT_EQ(vmas[4].usage.uss, 0);
364 EXPECT_EQ(vmas[5].usage.uss, 0);
365
366 EXPECT_EQ(vmas[0].usage.private_clean, 0);
367 EXPECT_EQ(vmas[1].usage.private_clean, 0);
368 EXPECT_EQ(vmas[2].usage.private_clean, 0);
369 EXPECT_EQ(vmas[3].usage.private_clean, 260);
370 EXPECT_EQ(vmas[4].usage.private_clean, 0);
371 EXPECT_EQ(vmas[5].usage.private_clean, 0);
372
373 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
374 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
375 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
376 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
377 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
378 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
379
380 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
381 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
382 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
383 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
384 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
385 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
386
387 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
388 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
389 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
390 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
391 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
392 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
393
394 EXPECT_EQ(vmas[0].usage.swap, 0);
395 EXPECT_EQ(vmas[1].usage.swap, 0);
396 EXPECT_EQ(vmas[2].usage.swap, 0);
397 EXPECT_EQ(vmas[3].usage.swap, 0);
398 EXPECT_EQ(vmas[4].usage.swap, 0);
399 EXPECT_EQ(vmas[5].usage.swap, 0);
400
401 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
402 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
403 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
404 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
405 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
406 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
407}
408
Sandeep Patildfa00a72019-01-28 15:05:27 -0800409TEST(ProcMemInfo, SmapsReturnTest) {
410 // Make sure Smaps() is never empty for any process
Sandeep Patil82a48b12019-01-01 16:04:04 -0800411 ProcMemInfo proc_mem(pid);
412 auto vmas = proc_mem.Smaps();
413 EXPECT_FALSE(vmas.empty());
414}
415
Sandeep Patildfa00a72019-01-28 15:05:27 -0800416TEST(ProcMemInfo, SmapsTest) {
Sandeep Patil82a48b12019-01-01 16:04:04 -0800417 std::string exec_dir = ::android::base::GetExecutableDirectory();
418 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
419 ProcMemInfo proc_mem(pid);
420 auto vmas = proc_mem.Smaps(path);
421
422 ASSERT_FALSE(vmas.empty());
Sandeep Patil002f02e2019-01-13 19:39:46 -0800423 // We should get a total of 6 vmas
424 ASSERT_EQ(vmas.size(), 6);
Sandeep Patil82a48b12019-01-01 16:04:04 -0800425
426 // Expect values to be equal to what we have in testdata1/smaps_short
427 // Check for sizes first
428 ASSERT_EQ(vmas[0].usage.vss, 32768);
429 EXPECT_EQ(vmas[1].usage.vss, 11204);
430 EXPECT_EQ(vmas[2].usage.vss, 16896);
431 EXPECT_EQ(vmas[3].usage.vss, 260);
432 EXPECT_EQ(vmas[4].usage.vss, 6060);
433 EXPECT_EQ(vmas[5].usage.vss, 4);
434
435 // Check for names
436 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
437 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
Christopher Ferris5db00922019-09-18 10:30:33 -0700438 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
439 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
440 << "Unknown map name " << vmas[2].name;
Sandeep Patil82a48b12019-01-01 16:04:04 -0800441 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
442 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
443 EXPECT_EQ(vmas[5].name, "[vsyscall]");
444
445 EXPECT_EQ(vmas[0].usage.rss, 2048);
446 EXPECT_EQ(vmas[1].usage.rss, 11188);
447 EXPECT_EQ(vmas[2].usage.rss, 15272);
448 EXPECT_EQ(vmas[3].usage.rss, 260);
449 EXPECT_EQ(vmas[4].usage.rss, 4132);
450 EXPECT_EQ(vmas[5].usage.rss, 0);
451
452 EXPECT_EQ(vmas[0].usage.pss, 113);
453 EXPECT_EQ(vmas[1].usage.pss, 2200);
454 EXPECT_EQ(vmas[2].usage.pss, 15272);
455 EXPECT_EQ(vmas[3].usage.pss, 260);
456 EXPECT_EQ(vmas[4].usage.pss, 1274);
457 EXPECT_EQ(vmas[5].usage.pss, 0);
458
459 EXPECT_EQ(vmas[0].usage.uss, 0);
460 EXPECT_EQ(vmas[1].usage.uss, 1660);
461 EXPECT_EQ(vmas[2].usage.uss, 15272);
462 EXPECT_EQ(vmas[3].usage.uss, 260);
463 EXPECT_EQ(vmas[4].usage.uss, 0);
464 EXPECT_EQ(vmas[5].usage.uss, 0);
465
466 EXPECT_EQ(vmas[0].usage.private_clean, 0);
467 EXPECT_EQ(vmas[1].usage.private_clean, 0);
468 EXPECT_EQ(vmas[2].usage.private_clean, 0);
469 EXPECT_EQ(vmas[3].usage.private_clean, 260);
470 EXPECT_EQ(vmas[4].usage.private_clean, 0);
471 EXPECT_EQ(vmas[5].usage.private_clean, 0);
472
473 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
474 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
475 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
476 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
477 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
478 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
479
480 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
481 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
482 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
483 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
484 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
485 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
486
487 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
488 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
489 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
490 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
491 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
492 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
493
494 EXPECT_EQ(vmas[0].usage.swap, 0);
495 EXPECT_EQ(vmas[1].usage.swap, 0);
496 EXPECT_EQ(vmas[2].usage.swap, 0);
497 EXPECT_EQ(vmas[3].usage.swap, 0);
498 EXPECT_EQ(vmas[4].usage.swap, 0);
499 EXPECT_EQ(vmas[5].usage.swap, 0);
500
501 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
502 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
503 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
504 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
505 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
506 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
507}
508
Sandeep Patildfa00a72019-01-28 15:05:27 -0800509TEST(SysMemInfo, TestSysMemInfoFile) {
Sandeep Patil54d87212018-08-29 17:10:47 -0700510 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
511MemFree: 1809728 kB
512MemAvailable: 2546560 kB
513Buffers: 54736 kB
514Cached: 776052 kB
515SwapCached: 0 kB
516Active: 445856 kB
517Inactive: 459092 kB
518Active(anon): 78492 kB
519Inactive(anon): 2240 kB
520Active(file): 367364 kB
521Inactive(file): 456852 kB
522Unevictable: 3096 kB
523Mlocked: 3096 kB
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800524SwapTotal: 32768 kB
525SwapFree: 4096 kB
Sandeep Patil54d87212018-08-29 17:10:47 -0700526Dirty: 32 kB
527Writeback: 0 kB
528AnonPages: 74988 kB
529Mapped: 62624 kB
530Shmem: 4020 kB
531Slab: 86464 kB
532SReclaimable: 44432 kB
533SUnreclaim: 42032 kB
534KernelStack: 4880 kB
535PageTables: 2900 kB
536NFS_Unstable: 0 kB
537Bounce: 0 kB
538WritebackTmp: 0 kB
539CommitLimit: 1509868 kB
540Committed_AS: 80296 kB
541VmallocTotal: 263061440 kB
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800542VmallocUsed: 65536 kB
Sandeep Patil54d87212018-08-29 17:10:47 -0700543VmallocChunk: 0 kB
544AnonHugePages: 6144 kB
545ShmemHugePages: 0 kB
546ShmemPmdMapped: 0 kB
547CmaTotal: 131072 kB
548CmaFree: 130380 kB
549HugePages_Total: 0
550HugePages_Free: 0
551HugePages_Rsvd: 0
552HugePages_Surp: 0
553Hugepagesize: 2048 kB)meminfo";
554
555 TemporaryFile tf;
556 ASSERT_TRUE(tf.fd != -1);
557 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
558
559 SysMemInfo mi;
560 ASSERT_TRUE(mi.ReadMemInfo(tf.path));
561 EXPECT_EQ(mi.mem_total_kb(), 3019740);
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800562 EXPECT_EQ(mi.mem_free_kb(), 1809728);
563 EXPECT_EQ(mi.mem_buffers_kb(), 54736);
564 EXPECT_EQ(mi.mem_cached_kb(), 776052);
565 EXPECT_EQ(mi.mem_shmem_kb(), 4020);
566 EXPECT_EQ(mi.mem_slab_kb(), 86464);
567 EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432);
568 EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032);
569 EXPECT_EQ(mi.mem_swap_kb(), 32768);
570 EXPECT_EQ(mi.mem_swap_free_kb(), 4096);
571 EXPECT_EQ(mi.mem_mapped_kb(), 62624);
572 EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536);
Sandeep Patil54d87212018-08-29 17:10:47 -0700573 EXPECT_EQ(mi.mem_page_tables_kb(), 2900);
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800574 EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880);
Sandeep Patil54d87212018-08-29 17:10:47 -0700575}
576
Sandeep Patildfa00a72019-01-28 15:05:27 -0800577TEST(SysMemInfo, TestEmptyFile) {
Sandeep Patil54d87212018-08-29 17:10:47 -0700578 TemporaryFile tf;
579 std::string empty_string = "";
580 ASSERT_TRUE(tf.fd != -1);
581 ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd));
582
583 SysMemInfo mi;
584 EXPECT_TRUE(mi.ReadMemInfo(tf.path));
585 EXPECT_EQ(mi.mem_total_kb(), 0);
586}
587
Sandeep Patildfa00a72019-01-28 15:05:27 -0800588TEST(SysMemInfo, TestZramTotal) {
Sandeep Patil70fa72d2018-11-09 19:18:29 -0800589 std::string exec_dir = ::android::base::GetExecutableDirectory();
590
591 SysMemInfo mi;
592 std::string zram_mmstat_dir = exec_dir + "/testdata1/";
593 EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir), 30504);
594
595 std::string zram_memused_dir = exec_dir + "/testdata2/";
596 EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir), 30504);
597}
598
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800599enum {
600 MEMINFO_TOTAL,
601 MEMINFO_FREE,
602 MEMINFO_BUFFERS,
603 MEMINFO_CACHED,
604 MEMINFO_SHMEM,
605 MEMINFO_SLAB,
606 MEMINFO_SLAB_RECLAIMABLE,
607 MEMINFO_SLAB_UNRECLAIMABLE,
608 MEMINFO_SWAP_TOTAL,
609 MEMINFO_SWAP_FREE,
610 MEMINFO_ZRAM_TOTAL,
611 MEMINFO_MAPPED,
612 MEMINFO_VMALLOC_USED,
613 MEMINFO_PAGE_TABLES,
614 MEMINFO_KERNEL_STACK,
615 MEMINFO_COUNT
616};
617
Sandeep Patildfa00a72019-01-28 15:05:27 -0800618TEST(SysMemInfo, TestZramWithTags) {
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800619 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
620MemFree: 1809728 kB
621MemAvailable: 2546560 kB
622Buffers: 54736 kB
623Cached: 776052 kB
624SwapCached: 0 kB
625Active: 445856 kB
626Inactive: 459092 kB
627Active(anon): 78492 kB
628Inactive(anon): 2240 kB
629Active(file): 367364 kB
630Inactive(file): 456852 kB
631Unevictable: 3096 kB
632Mlocked: 3096 kB
633SwapTotal: 32768 kB
634SwapFree: 4096 kB
635Dirty: 32 kB
636Writeback: 0 kB
637AnonPages: 74988 kB
638Mapped: 62624 kB
639Shmem: 4020 kB
640Slab: 86464 kB
641SReclaimable: 44432 kB
642SUnreclaim: 42032 kB
643KernelStack: 4880 kB
644PageTables: 2900 kB
645NFS_Unstable: 0 kB
646Bounce: 0 kB
647WritebackTmp: 0 kB
648CommitLimit: 1509868 kB
649Committed_AS: 80296 kB
650VmallocTotal: 263061440 kB
651VmallocUsed: 65536 kB
652VmallocChunk: 0 kB
653AnonHugePages: 6144 kB
654ShmemHugePages: 0 kB
655ShmemPmdMapped: 0 kB
656CmaTotal: 131072 kB
657CmaFree: 130380 kB
658HugePages_Total: 0
659HugePages_Free: 0
660HugePages_Rsvd: 0
661HugePages_Surp: 0
662Hugepagesize: 2048 kB)meminfo";
663
664 TemporaryFile tf;
665 ASSERT_TRUE(tf.fd != -1);
666 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
667 std::string file = std::string(tf.path);
668 std::vector<uint64_t> mem(MEMINFO_COUNT);
669 std::vector<std::string> tags(SysMemInfo::kDefaultSysMemInfoTags);
670 auto it = tags.begin();
671 tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:");
672 SysMemInfo mi;
673
674 // Read system memory info
675 EXPECT_TRUE(mi.ReadMemInfo(tags, &mem, file));
676
677 EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740);
678 EXPECT_EQ(mem[MEMINFO_FREE], 1809728);
679 EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736);
680 EXPECT_EQ(mem[MEMINFO_CACHED], 776052);
681 EXPECT_EQ(mem[MEMINFO_SHMEM], 4020);
682 EXPECT_EQ(mem[MEMINFO_SLAB], 86464);
683 EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432);
684 EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032);
685 EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768);
686 EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096);
687 EXPECT_EQ(mem[MEMINFO_MAPPED], 62624);
688 EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536);
689 EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900);
690 EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880);
691}
692
Sandeep Patildfa00a72019-01-28 15:05:27 -0800693TEST(SysMemInfo, TestVmallocInfoNoMemory) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800694 std::string vmallocinfo =
695 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
6960x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
6970x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
6980x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo";
699
700 TemporaryFile tf;
701 ASSERT_TRUE(tf.fd != -1);
702 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
703 std::string file = std::string(tf.path);
704
Sandeep Patile04680d2019-01-19 12:04:18 -0800705 EXPECT_EQ(ReadVmallocInfo(file), 0);
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800706}
707
Sandeep Patildfa00a72019-01-28 15:05:27 -0800708TEST(SysMemInfo, TestVmallocInfoKernel) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800709 std::string vmallocinfo =
710 R"vmallocinfo(0x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo";
711
712 TemporaryFile tf;
713 ASSERT_TRUE(tf.fd != -1);
714 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
715 std::string file = std::string(tf.path);
716
Sandeep Patile04680d2019-01-19 12:04:18 -0800717 EXPECT_EQ(ReadVmallocInfo(file), getpagesize());
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800718}
719
Sandeep Patildfa00a72019-01-28 15:05:27 -0800720TEST(SysMemInfo, TestVmallocInfoModule) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800721 std::string vmallocinfo =
722 R"vmallocinfo(0x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
723
724 TemporaryFile tf;
725 ASSERT_TRUE(tf.fd != -1);
726 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
727 std::string file = std::string(tf.path);
728
Sandeep Patile04680d2019-01-19 12:04:18 -0800729 EXPECT_EQ(ReadVmallocInfo(file), 6 * getpagesize());
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800730}
731
Sandeep Patildfa00a72019-01-28 15:05:27 -0800732TEST(SysMemInfo, TestVmallocInfoAll) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800733 std::string vmallocinfo =
734 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
7350x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
7360x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
7370x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap
7380x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc
7390x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
740
741 TemporaryFile tf;
742 ASSERT_TRUE(tf.fd != -1);
743 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
744 std::string file = std::string(tf.path);
745
Sandeep Patile04680d2019-01-19 12:04:18 -0800746 EXPECT_EQ(ReadVmallocInfo(file), 7 * getpagesize());
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800747}
748
Sandeep Patil54d87212018-08-29 17:10:47 -0700749int main(int argc, char** argv) {
750 ::testing::InitGoogleTest(&argc, argv);
Sandeep Patil54d87212018-08-29 17:10:47 -0700751 ::android::base::InitLogging(argv, android::base::StderrLogger);
Sandeep Patildfa00a72019-01-28 15:05:27 -0800752 pid = getpid();
Sandeep Patil54d87212018-08-29 17:10:47 -0700753 return RUN_ALL_TESTS();
754}