1 /*
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
17 #include <sys/mman.h>
18 #include <sys/types.h>
19 #include <sys/wait.h>
20 #include <unistd.h>
21
22 #include <gtest/gtest.h>
23
24 #include <filesystem>
25 #include <string>
26 #include <vector>
27
28 #include <meminfo/pageacct.h>
29 #include <meminfo/procmeminfo.h>
30 #include <meminfo/sysmeminfo.h>
31 #include <vintf/VintfObject.h>
32
33 #include <android-base/file.h>
34 #include <android-base/logging.h>
35 #include <android-base/properties.h>
36 #include <android-base/stringprintf.h>
37 #include <android-base/strings.h>
38
39 using namespace std;
40 using namespace android::meminfo;
41 using android::vintf::KernelVersion;
42 using android::vintf::RuntimeInfo;
43 using android::vintf::VintfObject;
44
45 namespace fs = std::filesystem;
46
47 pid_t pid = -1;
48
TEST(ProcMemInfo,TestWorkingTestReset)49 TEST(ProcMemInfo, TestWorkingTestReset) {
50 // Expect reset to succeed
51 EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid));
52 }
53
TEST(ProcMemInfo,UsageEmpty)54 TEST(ProcMemInfo, UsageEmpty) {
55 // If we created the object for getting working set,
56 // the usage must be empty
57 ProcMemInfo proc_mem(pid, true);
58 const MemUsage& usage = proc_mem.Usage();
59 EXPECT_EQ(usage.rss, 0);
60 EXPECT_EQ(usage.vss, 0);
61 EXPECT_EQ(usage.pss, 0);
62 EXPECT_EQ(usage.uss, 0);
63 EXPECT_EQ(usage.swap, 0);
64 }
65
TEST(ProcMemInfo,MapsNotEmpty)66 TEST(ProcMemInfo, MapsNotEmpty) {
67 // Make sure the process maps are never empty
68 ProcMemInfo proc_mem(pid);
69 const std::vector<Vma>& maps = proc_mem.Maps();
70 EXPECT_FALSE(maps.empty());
71 }
72
TEST(ProcMemInfo,MapsUsageNotEmpty)73 TEST(ProcMemInfo, MapsUsageNotEmpty) {
74 ProcMemInfo proc_mem(pid);
75 const std::vector<Vma>& maps = proc_mem.Maps();
76 EXPECT_FALSE(maps.empty());
77 uint64_t total_pss = 0;
78 uint64_t total_rss = 0;
79 uint64_t total_uss = 0;
80 for (auto& map : maps) {
81 ASSERT_NE(0, map.usage.vss);
82 total_rss += map.usage.rss;
83 total_pss += map.usage.pss;
84 total_uss += map.usage.uss;
85 }
86
87 // Crude check that stats are actually being read.
88 EXPECT_NE(0, total_rss) << "RSS zero for all maps, that is not possible.";
89 EXPECT_NE(0, total_pss) << "PSS zero for all maps, that is not possible.";
90 EXPECT_NE(0, total_uss) << "USS zero for all maps, that is not possible.";
91 }
92
TEST(ProcMemInfo,MapsUsageEmpty)93 TEST(ProcMemInfo, MapsUsageEmpty) {
94 ProcMemInfo proc_mem(pid);
95 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
96 EXPECT_FALSE(maps.empty());
97 // Verify that all usage stats are zero in every map.
98 for (auto& map : maps) {
99 ASSERT_EQ(0, map.usage.vss);
100 ASSERT_EQ(0, map.usage.rss);
101 ASSERT_EQ(0, map.usage.pss);
102 ASSERT_EQ(0, map.usage.uss);
103 ASSERT_EQ(0, map.usage.swap);
104 ASSERT_EQ(0, map.usage.swap_pss);
105 ASSERT_EQ(0, map.usage.private_clean);
106 ASSERT_EQ(0, map.usage.private_dirty);
107 ASSERT_EQ(0, map.usage.shared_clean);
108 ASSERT_EQ(0, map.usage.shared_dirty);
109 }
110 }
111
TEST(ProcMemInfo,MapsUsageFillInLater)112 TEST(ProcMemInfo, MapsUsageFillInLater) {
113 ProcMemInfo proc_mem(pid);
114 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
115 EXPECT_FALSE(maps.empty());
116 for (auto& map : maps) {
117 Vma update_map(map);
118 ASSERT_EQ(map.start, update_map.start);
119 ASSERT_EQ(map.end, update_map.end);
120 ASSERT_EQ(map.offset, update_map.offset);
121 ASSERT_EQ(map.flags, update_map.flags);
122 ASSERT_EQ(map.name, update_map.name);
123 ASSERT_EQ(0, update_map.usage.vss);
124 ASSERT_EQ(0, update_map.usage.rss);
125 ASSERT_EQ(0, update_map.usage.pss);
126 ASSERT_EQ(0, update_map.usage.uss);
127 ASSERT_EQ(0, update_map.usage.swap);
128 ASSERT_EQ(0, update_map.usage.swap_pss);
129 ASSERT_EQ(0, update_map.usage.private_clean);
130 ASSERT_EQ(0, update_map.usage.private_dirty);
131 ASSERT_EQ(0, update_map.usage.shared_clean);
132 ASSERT_EQ(0, update_map.usage.shared_dirty);
133 ASSERT_TRUE(proc_mem.FillInVmaStats(update_map));
134 // Check that at least one usage stat was updated.
135 ASSERT_NE(0, update_map.usage.vss);
136 }
137 }
138
TEST(ProcMemInfo,MapsUsageFillInAll)139 TEST(ProcMemInfo, MapsUsageFillInAll) {
140 ProcMemInfo proc_mem(pid);
141 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
142 EXPECT_FALSE(maps.empty());
143 for (auto& map : maps) {
144 ASSERT_EQ(0, map.usage.vss);
145 ASSERT_EQ(0, map.usage.rss);
146 ASSERT_EQ(0, map.usage.pss);
147 ASSERT_EQ(0, map.usage.uss);
148 ASSERT_EQ(0, map.usage.swap);
149 ASSERT_EQ(0, map.usage.swap_pss);
150 ASSERT_EQ(0, map.usage.private_clean);
151 ASSERT_EQ(0, map.usage.private_dirty);
152 ASSERT_EQ(0, map.usage.shared_clean);
153 ASSERT_EQ(0, map.usage.shared_dirty);
154 }
155 // GetUsageStats' non-default parameter get_wss is false by default in
156 // ProcMemInfo's constructor.
157 ASSERT_TRUE(proc_mem.GetUsageStats(false));
158 for (auto& map : maps) {
159 // Check that at least one usage stat was updated.
160 ASSERT_NE(0, map.usage.vss);
161 }
162 }
163
TEST(ProcMemInfo,PageMapPresent)164 TEST(ProcMemInfo, PageMapPresent) {
165 static constexpr size_t kNumPages = 20;
166 size_t pagesize = getpagesize();
167 void* ptr = mmap(nullptr, pagesize * (kNumPages + 2), PROT_READ | PROT_WRITE,
168 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
169 ASSERT_NE(MAP_FAILED, ptr);
170
171 // Unmap the first page and the last page so that we guarantee this
172 // map is in a map by itself.
173 ASSERT_EQ(0, munmap(ptr, pagesize));
174 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr) + pagesize;
175 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr + kNumPages * pagesize), pagesize));
176
177 ProcMemInfo proc_mem(getpid());
178 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
179 ASSERT_FALSE(maps.empty());
180
181 // Find the vma associated with our previously created map.
182 const Vma* test_vma = nullptr;
183 for (const Vma& vma : maps) {
184 if (vma.start == addr) {
185 test_vma = &vma;
186 break;
187 }
188 }
189 ASSERT_TRUE(test_vma != nullptr) << "Cannot find test map.";
190
191 // Verify that none of the pages are listed as present.
192 std::vector<uint64_t> pagemap;
193 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
194 ASSERT_EQ(kNumPages, pagemap.size());
195 for (size_t i = 0; i < pagemap.size(); i++) {
196 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
197 << "Page " << i << " is present and it should not be.";
198 }
199
200 // Make some of the pages present and verify that we see them
201 // as present.
202 uint8_t* data = reinterpret_cast<uint8_t*>(addr);
203 data[0] = 1;
204 data[pagesize * 5] = 1;
205 data[pagesize * 11] = 1;
206
207 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
208 ASSERT_EQ(kNumPages, pagemap.size());
209 for (size_t i = 0; i < pagemap.size(); i++) {
210 if (i == 0 || i == 5 || i == 11) {
211 EXPECT_TRUE(android::meminfo::page_present(pagemap[i]))
212 << "Page " << i << " is not present and it should be.";
213 } else {
214 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
215 << "Page " << i << " is present and it should not be.";
216 }
217 }
218
219 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr), kNumPages * pagesize));
220 }
221
TEST(ProcMemInfo,WssEmpty)222 TEST(ProcMemInfo, WssEmpty) {
223 // If we created the object for getting usage,
224 // the working set must be empty
225 ProcMemInfo proc_mem(pid, false);
226 const MemUsage& wss = proc_mem.Wss();
227 EXPECT_EQ(wss.rss, 0);
228 EXPECT_EQ(wss.vss, 0);
229 EXPECT_EQ(wss.pss, 0);
230 EXPECT_EQ(wss.uss, 0);
231 EXPECT_EQ(wss.swap, 0);
232 }
233
TEST(ProcMemInfo,SwapOffsetsEmpty)234 TEST(ProcMemInfo, SwapOffsetsEmpty) {
235 // If we created the object for getting working set,
236 // the swap offsets must be empty
237 ProcMemInfo proc_mem(pid, true);
238 const std::vector<uint64_t>& swap_offsets = proc_mem.SwapOffsets();
239 EXPECT_EQ(swap_offsets.size(), 0);
240 }
241
TEST(ProcMemInfo,IsSmapsSupportedTest)242 TEST(ProcMemInfo, IsSmapsSupportedTest) {
243 // Check if /proc/self/smaps_rollup exists using the API.
244 bool supported = IsSmapsRollupSupported();
245 EXPECT_EQ(!access("/proc/self/smaps_rollup", F_OK | R_OK), supported);
246 }
247
TEST(ProcMemInfo,SmapsOrRollupTest)248 TEST(ProcMemInfo, SmapsOrRollupTest) {
249 // Make sure we can parse 'smaps_rollup' correctly
250 std::string rollup =
251 R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0 [rollup]
252 Rss: 331908 kB
253 Pss: 202052 kB
254 Shared_Clean: 158492 kB
255 Shared_Dirty: 18928 kB
256 Private_Clean: 90472 kB
257 Private_Dirty: 64016 kB
258 Referenced: 318700 kB
259 Anonymous: 81984 kB
260 AnonHugePages: 0 kB
261 Shared_Hugetlb: 0 kB
262 Private_Hugetlb: 0 kB
263 Swap: 5344 kB
264 SwapPss: 442 kB
265 Locked: 1523537 kB)rollup";
266
267 TemporaryFile tf;
268 ASSERT_TRUE(tf.fd != -1);
269 ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd));
270
271 MemUsage stats;
272 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
273 EXPECT_EQ(stats.rss, 331908);
274 EXPECT_EQ(stats.pss, 202052);
275 EXPECT_EQ(stats.uss, 154488);
276 EXPECT_EQ(stats.private_clean, 90472);
277 EXPECT_EQ(stats.private_dirty, 64016);
278 EXPECT_EQ(stats.swap_pss, 442);
279 }
280
TEST(ProcMemInfo,SmapsOrRollupSmapsTest)281 TEST(ProcMemInfo, SmapsOrRollupSmapsTest) {
282 // Make sure /proc/<pid>/smaps is parsed correctly
283 std::string smaps =
284 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
285 Name: [anon:dalvik-main space (region space)]
286 Size: 8448 kB
287 KernelPageSize: 4 kB
288 MMUPageSize: 4 kB
289 Rss: 2652 kB
290 Pss: 2652 kB
291 Shared_Clean: 840 kB
292 Shared_Dirty: 40 kB
293 Private_Clean: 84 kB
294 Private_Dirty: 2652 kB
295 Referenced: 2652 kB
296 Anonymous: 2652 kB
297 AnonHugePages: 0 kB
298 ShmemPmdMapped: 0 kB
299 Shared_Hugetlb: 0 kB
300 Private_Hugetlb: 0 kB
301 Swap: 102 kB
302 SwapPss: 70 kB
303 Locked: 2652 kB
304 VmFlags: rd wr mr mw me ac
305 )smaps";
306
307 TemporaryFile tf;
308 ASSERT_TRUE(tf.fd != -1);
309 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
310
311 MemUsage stats;
312 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
313 EXPECT_EQ(stats.rss, 2652);
314 EXPECT_EQ(stats.pss, 2652);
315 EXPECT_EQ(stats.uss, 2736);
316 EXPECT_EQ(stats.private_clean, 84);
317 EXPECT_EQ(stats.private_dirty, 2652);
318 EXPECT_EQ(stats.swap_pss, 70);
319 }
320
TEST(ProcMemInfo,SmapsOrRollupPssRollupTest)321 TEST(ProcMemInfo, SmapsOrRollupPssRollupTest) {
322 // Make sure /proc/<pid>/smaps is parsed correctly
323 // to get the PSS
324 std::string smaps =
325 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
326 Name: [anon:dalvik-main space (region space)]
327 Size: 8448 kB
328 KernelPageSize: 4 kB
329 MMUPageSize: 4 kB
330 Rss: 2652 kB
331 Pss: 2652 kB
332 Shared_Clean: 840 kB
333 Shared_Dirty: 40 kB
334 Private_Clean: 84 kB
335 Private_Dirty: 2652 kB
336 Referenced: 2652 kB
337 Anonymous: 2652 kB
338 AnonHugePages: 0 kB
339 ShmemPmdMapped: 0 kB
340 Shared_Hugetlb: 0 kB
341 Private_Hugetlb: 0 kB
342 Swap: 102 kB
343 SwapPss: 70 kB
344 Locked: 2652 kB
345 VmFlags: rd wr mr mw me ac
346 )smaps";
347
348 TemporaryFile tf;
349 ASSERT_TRUE(tf.fd != -1);
350 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
351
352 uint64_t pss;
353 ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
354 EXPECT_EQ(pss, 2652);
355 }
356
TEST(ProcMemInfo,SmapsOrRollupPssSmapsTest)357 TEST(ProcMemInfo, SmapsOrRollupPssSmapsTest) {
358 // Correctly parse smaps file to gather pss
359 std::string exec_dir = ::android::base::GetExecutableDirectory();
360 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
361
362 uint64_t pss;
363 ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
364 EXPECT_EQ(pss, 19119);
365 }
366
TEST(ProcMemInfo,ForEachExistingVmaTest)367 TEST(ProcMemInfo, ForEachExistingVmaTest) {
368 std::string exec_dir = ::android::base::GetExecutableDirectory();
369 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
370 ProcMemInfo proc_mem(pid);
371 // Populate maps_.
372 proc_mem.Smaps(path);
373 std::vector<Vma> vmas;
374 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
375 EXPECT_TRUE(proc_mem.ForEachExistingVma(collect_vmas));
376
377 // The size of vmas is not checked because Smaps() will return 5 vmas on x86
378 // and 6 vmas otherwise, as [vsyscall] is not processed on x86.
379
380 // Expect values to be equal to what we have in testdata1/smaps_short
381 // Check for names
382 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
383 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
384 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
385 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
386 << "Unknown map name " << vmas[2].name;
387 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
388 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
389
390 // Check start address
391 EXPECT_EQ(vmas[0].start, 0x54c00000);
392 EXPECT_EQ(vmas[1].start, 0x701ea000);
393 EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
394 EXPECT_EQ(vmas[3].start, 0x700755a2d000);
395 EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
396
397 // Check end address
398 EXPECT_EQ(vmas[0].end, 0x56c00000);
399 EXPECT_EQ(vmas[1].end, 0x70cdb000);
400 EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
401 EXPECT_EQ(vmas[3].end, 0x700755a6e000);
402 EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
403
404 // Check Flags
405 EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
406 EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
407 EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
408 EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
409 EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
410
411 // Check Shared
412 EXPECT_FALSE(vmas[0].is_shared);
413 EXPECT_FALSE(vmas[1].is_shared);
414 EXPECT_FALSE(vmas[2].is_shared);
415 EXPECT_FALSE(vmas[3].is_shared);
416 EXPECT_FALSE(vmas[4].is_shared);
417
418 // Check Offset
419 EXPECT_EQ(vmas[0].offset, 0x0);
420 EXPECT_EQ(vmas[1].offset, 0x0);
421 EXPECT_EQ(vmas[2].offset, 0x0);
422 EXPECT_EQ(vmas[3].offset, 0x00016000);
423 EXPECT_EQ(vmas[4].offset, 0x001ee000);
424
425 // Check Inode
426 EXPECT_EQ(vmas[0].inode, 0);
427 EXPECT_EQ(vmas[1].inode, 3165);
428 EXPECT_EQ(vmas[2].inode, 0);
429 EXPECT_EQ(vmas[3].inode, 1947);
430 EXPECT_EQ(vmas[4].inode, 1537);
431
432 // Check smaps specific fields
433 ASSERT_EQ(vmas[0].usage.vss, 32768);
434 EXPECT_EQ(vmas[1].usage.vss, 11204);
435 EXPECT_EQ(vmas[2].usage.vss, 16896);
436 EXPECT_EQ(vmas[3].usage.vss, 260);
437 EXPECT_EQ(vmas[4].usage.vss, 6060);
438
439 EXPECT_EQ(vmas[0].usage.rss, 2048);
440 EXPECT_EQ(vmas[1].usage.rss, 11188);
441 EXPECT_EQ(vmas[2].usage.rss, 15272);
442 EXPECT_EQ(vmas[3].usage.rss, 260);
443 EXPECT_EQ(vmas[4].usage.rss, 4132);
444
445 EXPECT_EQ(vmas[0].usage.pss, 113);
446 EXPECT_EQ(vmas[1].usage.pss, 2200);
447 EXPECT_EQ(vmas[2].usage.pss, 15272);
448 EXPECT_EQ(vmas[3].usage.pss, 260);
449 EXPECT_EQ(vmas[4].usage.pss, 1274);
450
451 EXPECT_EQ(vmas[0].usage.uss, 0);
452 EXPECT_EQ(vmas[1].usage.uss, 1660);
453 EXPECT_EQ(vmas[2].usage.uss, 15272);
454 EXPECT_EQ(vmas[3].usage.uss, 260);
455 EXPECT_EQ(vmas[4].usage.uss, 0);
456
457 EXPECT_EQ(vmas[0].usage.private_clean, 0);
458 EXPECT_EQ(vmas[1].usage.private_clean, 0);
459 EXPECT_EQ(vmas[2].usage.private_clean, 0);
460 EXPECT_EQ(vmas[3].usage.private_clean, 260);
461 EXPECT_EQ(vmas[4].usage.private_clean, 0);
462
463 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
464 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
465 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
466 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
467 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
468
469 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
470 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
471 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
472 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
473 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
474
475 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
476 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
477 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
478 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
479 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
480
481 EXPECT_EQ(vmas[0].usage.swap, 0);
482 EXPECT_EQ(vmas[1].usage.swap, 0);
483 EXPECT_EQ(vmas[2].usage.swap, 0);
484 EXPECT_EQ(vmas[3].usage.swap, 0);
485 EXPECT_EQ(vmas[4].usage.swap, 0);
486
487 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
488 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
489 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
490 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
491 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
492
493 #ifndef __x86_64__
494 // vmas[5] will not exist on x86, as [vsyscall] would not be processed.
495 EXPECT_EQ(vmas[5].name, "[vsyscall]");
496 EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
497 EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
498 EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
499 EXPECT_FALSE(vmas[5].is_shared);
500 EXPECT_EQ(vmas[5].offset, 0x0);
501 EXPECT_EQ(vmas[5].inode, 0);
502 EXPECT_EQ(vmas[5].usage.vss, 4);
503 EXPECT_EQ(vmas[5].usage.rss, 0);
504 EXPECT_EQ(vmas[5].usage.pss, 0);
505 EXPECT_EQ(vmas[5].usage.uss, 0);
506 EXPECT_EQ(vmas[5].usage.private_clean, 0);
507 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
508 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
509 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
510 EXPECT_EQ(vmas[5].usage.swap, 0);
511 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
512 #endif
513 }
514
TEST(ProcMemInfo,ForEachVmaFromFile_SmapsTest)515 TEST(ProcMemInfo, ForEachVmaFromFile_SmapsTest) {
516 // Parse smaps file correctly to make callbacks for each virtual memory area (vma)
517 std::string exec_dir = ::android::base::GetExecutableDirectory();
518 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
519 ProcMemInfo proc_mem(pid);
520
521 std::vector<Vma> vmas;
522 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
523 ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
524
525 // We should get a total of 6 vmas
526 ASSERT_EQ(vmas.size(), 6);
527
528 // Expect values to be equal to what we have in testdata1/smaps_short
529 // Check for names
530 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
531 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
532 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
533 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
534 << "Unknown map name " << vmas[2].name;
535 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
536 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
537 EXPECT_EQ(vmas[5].name, "[vsyscall]");
538
539 // Check start address
540 EXPECT_EQ(vmas[0].start, 0x54c00000);
541 EXPECT_EQ(vmas[1].start, 0x701ea000);
542 EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
543 EXPECT_EQ(vmas[3].start, 0x700755a2d000);
544 EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
545 EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
546
547 // Check end address
548 EXPECT_EQ(vmas[0].end, 0x56c00000);
549 EXPECT_EQ(vmas[1].end, 0x70cdb000);
550 EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
551 EXPECT_EQ(vmas[3].end, 0x700755a6e000);
552 EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
553 EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
554
555 // Check Flags
556 EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
557 EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
558 EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
559 EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
560 EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
561 EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
562
563 // Check Shared
564 EXPECT_FALSE(vmas[0].is_shared);
565 EXPECT_FALSE(vmas[1].is_shared);
566 EXPECT_FALSE(vmas[2].is_shared);
567 EXPECT_FALSE(vmas[3].is_shared);
568 EXPECT_FALSE(vmas[4].is_shared);
569 EXPECT_FALSE(vmas[5].is_shared);
570
571 // Check Offset
572 EXPECT_EQ(vmas[0].offset, 0x0);
573 EXPECT_EQ(vmas[1].offset, 0x0);
574 EXPECT_EQ(vmas[2].offset, 0x0);
575 EXPECT_EQ(vmas[3].offset, 0x00016000);
576 EXPECT_EQ(vmas[4].offset, 0x001ee000);
577 EXPECT_EQ(vmas[5].offset, 0x0);
578
579 // Check Inode
580 EXPECT_EQ(vmas[0].inode, 0);
581 EXPECT_EQ(vmas[1].inode, 3165);
582 EXPECT_EQ(vmas[2].inode, 0);
583 EXPECT_EQ(vmas[3].inode, 1947);
584 EXPECT_EQ(vmas[4].inode, 1537);
585 EXPECT_EQ(vmas[5].inode, 0);
586
587 // Check smaps specific fields
588 ASSERT_EQ(vmas[0].usage.vss, 32768);
589 EXPECT_EQ(vmas[1].usage.vss, 11204);
590 EXPECT_EQ(vmas[2].usage.vss, 16896);
591 EXPECT_EQ(vmas[3].usage.vss, 260);
592 EXPECT_EQ(vmas[4].usage.vss, 6060);
593 EXPECT_EQ(vmas[5].usage.vss, 4);
594
595 EXPECT_EQ(vmas[0].usage.rss, 2048);
596 EXPECT_EQ(vmas[1].usage.rss, 11188);
597 EXPECT_EQ(vmas[2].usage.rss, 15272);
598 EXPECT_EQ(vmas[3].usage.rss, 260);
599 EXPECT_EQ(vmas[4].usage.rss, 4132);
600 EXPECT_EQ(vmas[5].usage.rss, 0);
601
602 EXPECT_EQ(vmas[0].usage.pss, 113);
603 EXPECT_EQ(vmas[1].usage.pss, 2200);
604 EXPECT_EQ(vmas[2].usage.pss, 15272);
605 EXPECT_EQ(vmas[3].usage.pss, 260);
606 EXPECT_EQ(vmas[4].usage.pss, 1274);
607 EXPECT_EQ(vmas[5].usage.pss, 0);
608
609 EXPECT_EQ(vmas[0].usage.uss, 0);
610 EXPECT_EQ(vmas[1].usage.uss, 1660);
611 EXPECT_EQ(vmas[2].usage.uss, 15272);
612 EXPECT_EQ(vmas[3].usage.uss, 260);
613 EXPECT_EQ(vmas[4].usage.uss, 0);
614 EXPECT_EQ(vmas[5].usage.uss, 0);
615
616 EXPECT_EQ(vmas[0].usage.private_clean, 0);
617 EXPECT_EQ(vmas[1].usage.private_clean, 0);
618 EXPECT_EQ(vmas[2].usage.private_clean, 0);
619 EXPECT_EQ(vmas[3].usage.private_clean, 260);
620 EXPECT_EQ(vmas[4].usage.private_clean, 0);
621 EXPECT_EQ(vmas[5].usage.private_clean, 0);
622
623 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
624 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
625 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
626 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
627 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
628 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
629
630 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
631 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
632 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
633 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
634 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
635 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
636
637 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
638 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
639 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
640 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
641 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
642 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
643
644 EXPECT_EQ(vmas[0].usage.swap, 0);
645 EXPECT_EQ(vmas[1].usage.swap, 0);
646 EXPECT_EQ(vmas[2].usage.swap, 0);
647 EXPECT_EQ(vmas[3].usage.swap, 0);
648 EXPECT_EQ(vmas[4].usage.swap, 0);
649 EXPECT_EQ(vmas[5].usage.swap, 0);
650
651 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
652 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
653 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
654 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
655 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
656 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
657 }
658
TEST(ProcMemInfo,ForEachVmaFromFile_MapsTest)659 TEST(ProcMemInfo, ForEachVmaFromFile_MapsTest) {
660 // Parse maps file correctly to make callbacks for each virtual memory area (vma)
661 std::string exec_dir = ::android::base::GetExecutableDirectory();
662 std::string path = ::android::base::StringPrintf("%s/testdata1/maps_short", exec_dir.c_str());
663 ProcMemInfo proc_mem(pid);
664
665 std::vector<Vma> vmas;
666 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
667 ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas, false));
668
669 // We should get a total of 6 vmas
670 ASSERT_EQ(vmas.size(), 6);
671
672 // Expect values to be equal to what we have in testdata1/maps_short
673 // Check for names
674 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
675 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
676 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
677 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
678 << "Unknown map name " << vmas[2].name;
679 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
680 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
681 EXPECT_EQ(vmas[5].name, "[vsyscall]");
682
683 // Check start address
684 EXPECT_EQ(vmas[0].start, 0x54c00000);
685 EXPECT_EQ(vmas[1].start, 0x701ea000);
686 EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
687 EXPECT_EQ(vmas[3].start, 0x700755a2d000);
688 EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
689 EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
690
691 // Check end address
692 EXPECT_EQ(vmas[0].end, 0x56c00000);
693 EXPECT_EQ(vmas[1].end, 0x70cdb000);
694 EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
695 EXPECT_EQ(vmas[3].end, 0x700755a6e000);
696 EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
697 EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
698
699 // Check Flags
700 EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
701 EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
702 EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
703 EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
704 EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
705 EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
706
707 // Check Shared
708 EXPECT_FALSE(vmas[0].is_shared);
709 EXPECT_FALSE(vmas[1].is_shared);
710 EXPECT_FALSE(vmas[2].is_shared);
711 EXPECT_FALSE(vmas[3].is_shared);
712 EXPECT_FALSE(vmas[4].is_shared);
713 EXPECT_FALSE(vmas[5].is_shared);
714
715 // Check Offset
716 EXPECT_EQ(vmas[0].offset, 0x0);
717 EXPECT_EQ(vmas[1].offset, 0x0);
718 EXPECT_EQ(vmas[2].offset, 0x0);
719 EXPECT_EQ(vmas[3].offset, 0x00016000);
720 EXPECT_EQ(vmas[4].offset, 0x001ee000);
721 EXPECT_EQ(vmas[5].offset, 0x0);
722
723 // Check Inode
724 EXPECT_EQ(vmas[0].inode, 0);
725 EXPECT_EQ(vmas[1].inode, 3165);
726 EXPECT_EQ(vmas[2].inode, 0);
727 EXPECT_EQ(vmas[3].inode, 1947);
728 EXPECT_EQ(vmas[4].inode, 1537);
729 EXPECT_EQ(vmas[5].inode, 0);
730 }
731
TEST(ProcMemInfo,SmapsReturnTest)732 TEST(ProcMemInfo, SmapsReturnTest) {
733 // Make sure Smaps() is never empty for any process
734 ProcMemInfo proc_mem(pid);
735 auto vmas = proc_mem.Smaps();
736 EXPECT_FALSE(vmas.empty());
737 }
738
TEST(ProcMemInfo,SmapsTest)739 TEST(ProcMemInfo, SmapsTest) {
740 std::string exec_dir = ::android::base::GetExecutableDirectory();
741 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
742 ProcMemInfo proc_mem(pid);
743 auto vmas = proc_mem.Smaps(path);
744
745 ASSERT_FALSE(vmas.empty());
746 #ifndef __x86_64__
747 // We should get a total of 6 vmas
748 ASSERT_EQ(vmas.size(), 6);
749 #else
750 // We should get a total of 5 vmas ([vsyscall] is excluded)
751 ASSERT_EQ(vmas.size(), 5);
752 #endif
753
754 // Expect values to be equal to what we have in testdata1/smaps_short
755 // Check for sizes first
756 ASSERT_EQ(vmas[0].usage.vss, 32768);
757 EXPECT_EQ(vmas[1].usage.vss, 11204);
758 EXPECT_EQ(vmas[2].usage.vss, 16896);
759 EXPECT_EQ(vmas[3].usage.vss, 260);
760 EXPECT_EQ(vmas[4].usage.vss, 6060);
761 #ifndef __x86_64__
762 EXPECT_EQ(vmas[5].usage.vss, 4);
763 #endif
764
765 // Check for names
766 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
767 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
768 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
769 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
770 << "Unknown map name " << vmas[2].name;
771 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
772 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
773 #ifndef __x86_64__
774 EXPECT_EQ(vmas[5].name, "[vsyscall]");
775 #endif
776
777 EXPECT_EQ(vmas[0].usage.rss, 2048);
778 EXPECT_EQ(vmas[1].usage.rss, 11188);
779 EXPECT_EQ(vmas[2].usage.rss, 15272);
780 EXPECT_EQ(vmas[3].usage.rss, 260);
781 EXPECT_EQ(vmas[4].usage.rss, 4132);
782 #ifndef __x86_64__
783 EXPECT_EQ(vmas[5].usage.rss, 0);
784 #endif
785
786 EXPECT_EQ(vmas[0].usage.pss, 113);
787 EXPECT_EQ(vmas[1].usage.pss, 2200);
788 EXPECT_EQ(vmas[2].usage.pss, 15272);
789 EXPECT_EQ(vmas[3].usage.pss, 260);
790 EXPECT_EQ(vmas[4].usage.pss, 1274);
791 #ifndef __x86_64__
792 EXPECT_EQ(vmas[5].usage.pss, 0);
793 #endif
794
795 EXPECT_EQ(vmas[0].usage.uss, 0);
796 EXPECT_EQ(vmas[1].usage.uss, 1660);
797 EXPECT_EQ(vmas[2].usage.uss, 15272);
798 EXPECT_EQ(vmas[3].usage.uss, 260);
799 EXPECT_EQ(vmas[4].usage.uss, 0);
800 #ifndef __x86_64__
801 EXPECT_EQ(vmas[5].usage.uss, 0);
802 #endif
803
804 EXPECT_EQ(vmas[0].usage.private_clean, 0);
805 EXPECT_EQ(vmas[1].usage.private_clean, 0);
806 EXPECT_EQ(vmas[2].usage.private_clean, 0);
807 EXPECT_EQ(vmas[3].usage.private_clean, 260);
808 EXPECT_EQ(vmas[4].usage.private_clean, 0);
809 #ifndef __x86_64__
810 EXPECT_EQ(vmas[5].usage.private_clean, 0);
811 #endif
812
813 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
814 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
815 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
816 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
817 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
818 #ifndef __x86_64__
819 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
820 #endif
821
822 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
823 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
824 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
825 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
826 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
827 #ifndef __x86_64__
828 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
829 #endif
830
831 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
832 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
833 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
834 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
835 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
836 #ifndef __x86_64__
837 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
838 #endif
839
840 EXPECT_EQ(vmas[0].usage.swap, 0);
841 EXPECT_EQ(vmas[1].usage.swap, 0);
842 EXPECT_EQ(vmas[2].usage.swap, 0);
843 EXPECT_EQ(vmas[3].usage.swap, 0);
844 EXPECT_EQ(vmas[4].usage.swap, 0);
845 #ifndef __x86_64__
846 EXPECT_EQ(vmas[5].usage.swap, 0);
847 #endif
848
849 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
850 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
851 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
852 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
853 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
854 #ifndef __x86_64__
855 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
856 #endif
857 }
858
TEST(ProcMemInfo,SmapsPopulatesUsageTest)859 TEST(ProcMemInfo, SmapsPopulatesUsageTest) {
860 std::string exec_dir = ::android::base::GetExecutableDirectory();
861 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
862 ProcMemInfo proc_mem(pid);
863 auto vmas = proc_mem.Smaps(path, true);
864
865 // Expect values to be equal to sums of usage in testdata1/smaps_short. For
866 // this data, only vss differs on x86.
867 #ifndef __x86_64__
868 EXPECT_EQ(proc_mem.Usage().vss, 67192);
869 #else
870 EXPECT_EQ(proc_mem.Usage().vss, 67188);
871 #endif
872 EXPECT_EQ(proc_mem.Usage().rss, 32900);
873 EXPECT_EQ(proc_mem.Usage().pss, 19119);
874 EXPECT_EQ(proc_mem.Usage().uss, 17192);
875 EXPECT_EQ(proc_mem.Usage().private_clean, 260);
876 EXPECT_EQ(proc_mem.Usage().private_dirty, 16932);
877 EXPECT_EQ(proc_mem.Usage().shared_clean, 4212);
878 EXPECT_EQ(proc_mem.Usage().shared_dirty, 11496);
879 EXPECT_EQ(proc_mem.Usage().swap, 0);
880 EXPECT_EQ(proc_mem.Usage().swap_pss, 0);
881 }
882
TEST(SysMemInfo,TestSysMemInfoFile)883 TEST(SysMemInfo, TestSysMemInfoFile) {
884 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
885 MemFree: 1809728 kB
886 MemAvailable: 2546560 kB
887 Buffers: 54736 kB
888 Cached: 776052 kB
889 SwapCached: 0 kB
890 Active: 445856 kB
891 Inactive: 459092 kB
892 Active(anon): 78492 kB
893 Inactive(anon): 2240 kB
894 Active(file): 367364 kB
895 Inactive(file): 456852 kB
896 Unevictable: 3096 kB
897 Mlocked: 3096 kB
898 SwapTotal: 32768 kB
899 SwapFree: 4096 kB
900 Dirty: 32 kB
901 Writeback: 0 kB
902 AnonPages: 74988 kB
903 Mapped: 62624 kB
904 Shmem: 4020 kB
905 KReclaimable: 87324 kB
906 Slab: 86464 kB
907 SReclaimable: 44432 kB
908 SUnreclaim: 42032 kB
909 KernelStack: 4880 kB
910 PageTables: 2900 kB
911 NFS_Unstable: 0 kB
912 Bounce: 0 kB
913 WritebackTmp: 0 kB
914 CommitLimit: 1509868 kB
915 Committed_AS: 80296 kB
916 VmallocTotal: 263061440 kB
917 VmallocUsed: 65536 kB
918 VmallocChunk: 0 kB
919 AnonHugePages: 6144 kB
920 ShmemHugePages: 0 kB
921 ShmemPmdMapped: 0 kB
922 CmaTotal: 131072 kB
923 CmaFree: 130380 kB
924 HugePages_Total: 0
925 HugePages_Free: 0
926 HugePages_Rsvd: 0
927 HugePages_Surp: 0
928 Hugepagesize: 2048 kB)meminfo";
929
930 TemporaryFile tf;
931 ASSERT_TRUE(tf.fd != -1);
932 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
933
934 SysMemInfo mi;
935 ASSERT_TRUE(mi.ReadMemInfo(tf.path));
936 EXPECT_EQ(mi.mem_total_kb(), 3019740);
937 EXPECT_EQ(mi.mem_free_kb(), 1809728);
938 EXPECT_EQ(mi.mem_buffers_kb(), 54736);
939 EXPECT_EQ(mi.mem_cached_kb(), 776052);
940 EXPECT_EQ(mi.mem_shmem_kb(), 4020);
941 EXPECT_EQ(mi.mem_slab_kb(), 86464);
942 EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432);
943 EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032);
944 EXPECT_EQ(mi.mem_swap_kb(), 32768);
945 EXPECT_EQ(mi.mem_swap_free_kb(), 4096);
946 EXPECT_EQ(mi.mem_mapped_kb(), 62624);
947 EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536);
948 EXPECT_EQ(mi.mem_page_tables_kb(), 2900);
949 EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880);
950 EXPECT_EQ(mi.mem_kreclaimable_kb(), 87324);
951 EXPECT_EQ(mi.mem_active_kb(), 445856);
952 EXPECT_EQ(mi.mem_inactive_kb(), 459092);
953 EXPECT_EQ(mi.mem_unevictable_kb(), 3096);
954 EXPECT_EQ(mi.mem_available_kb(), 2546560);
955 EXPECT_EQ(mi.mem_active_anon_kb(), 78492);
956 EXPECT_EQ(mi.mem_inactive_anon_kb(), 2240);
957 EXPECT_EQ(mi.mem_active_file_kb(), 367364);
958 EXPECT_EQ(mi.mem_inactive_file_kb(), 456852);
959 EXPECT_EQ(mi.mem_cma_total_kb(), 131072);
960 EXPECT_EQ(mi.mem_cma_free_kb(), 130380);
961 }
962
TEST(SysMemInfo,TestEmptyFile)963 TEST(SysMemInfo, TestEmptyFile) {
964 TemporaryFile tf;
965 std::string empty_string = "";
966 ASSERT_TRUE(tf.fd != -1);
967 ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd));
968
969 SysMemInfo mi;
970 EXPECT_TRUE(mi.ReadMemInfo(tf.path));
971 EXPECT_EQ(mi.mem_total_kb(), 0);
972 }
973
TEST(SysMemInfo,TestZramTotal)974 TEST(SysMemInfo, TestZramTotal) {
975 std::string exec_dir = ::android::base::GetExecutableDirectory();
976
977 SysMemInfo mi;
978 std::string zram_mmstat_dir = exec_dir + "/testdata1/";
979 EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir.c_str()), 30504);
980
981 std::string zram_memused_dir = exec_dir + "/testdata2/";
982 EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir.c_str()), 30504);
983 }
984
985 enum {
986 MEMINFO_TOTAL,
987 MEMINFO_FREE,
988 MEMINFO_BUFFERS,
989 MEMINFO_CACHED,
990 MEMINFO_SHMEM,
991 MEMINFO_SLAB,
992 MEMINFO_SLAB_RECLAIMABLE,
993 MEMINFO_SLAB_UNRECLAIMABLE,
994 MEMINFO_SWAP_TOTAL,
995 MEMINFO_SWAP_FREE,
996 MEMINFO_ZRAM_TOTAL,
997 MEMINFO_MAPPED,
998 MEMINFO_VMALLOC_USED,
999 MEMINFO_PAGE_TABLES,
1000 MEMINFO_KERNEL_STACK,
1001 MEMINFO_KRECLAIMABLE,
1002 MEMINFO_ACTIVE,
1003 MEMINFO_INACTIVE,
1004 MEMINFO_UNEVICTABLE,
1005 MEMINFO_AVAILABLE,
1006 MEMINFO_ACTIVE_ANON,
1007 MEMINFO_INACTIVE_ANON,
1008 MEMINFO_ACTIVE_FILE,
1009 MEMINFO_INACTIVE_FILE,
1010 MEMINFO_CMA_TOTAL,
1011 MEMINFO_CMA_FREE,
1012 MEMINFO_COUNT
1013 };
1014
TEST(SysMemInfo,TestZramWithTags)1015 TEST(SysMemInfo, TestZramWithTags) {
1016 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
1017 MemFree: 1809728 kB
1018 MemAvailable: 2546560 kB
1019 Buffers: 54736 kB
1020 Cached: 776052 kB
1021 SwapCached: 0 kB
1022 Active: 445856 kB
1023 Inactive: 459092 kB
1024 Active(anon): 78492 kB
1025 Inactive(anon): 2240 kB
1026 Active(file): 367364 kB
1027 Inactive(file): 456852 kB
1028 Unevictable: 3096 kB
1029 Mlocked: 3096 kB
1030 SwapTotal: 32768 kB
1031 SwapFree: 4096 kB
1032 Dirty: 32 kB
1033 Writeback: 0 kB
1034 AnonPages: 74988 kB
1035 Mapped: 62624 kB
1036 Shmem: 4020 kB
1037 KReclaimable: 87324 kB
1038 Slab: 86464 kB
1039 SReclaimable: 44432 kB
1040 SUnreclaim: 42032 kB
1041 KernelStack: 4880 kB
1042 PageTables: 2900 kB
1043 NFS_Unstable: 0 kB
1044 Bounce: 0 kB
1045 WritebackTmp: 0 kB
1046 CommitLimit: 1509868 kB
1047 Committed_AS: 80296 kB
1048 VmallocTotal: 263061440 kB
1049 VmallocUsed: 65536 kB
1050 VmallocChunk: 0 kB
1051 AnonHugePages: 6144 kB
1052 ShmemHugePages: 0 kB
1053 ShmemPmdMapped: 0 kB
1054 CmaTotal: 131072 kB
1055 CmaFree: 130380 kB
1056 HugePages_Total: 0
1057 HugePages_Free: 0
1058 HugePages_Rsvd: 0
1059 HugePages_Surp: 0
1060 Hugepagesize: 2048 kB)meminfo";
1061
1062 TemporaryFile tf;
1063 ASSERT_TRUE(tf.fd != -1);
1064 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
1065 std::string file = std::string(tf.path);
1066 std::vector<uint64_t> mem;
1067 std::vector<std::string_view> tags(SysMemInfo::kDefaultSysMemInfoTags.begin(),
1068 SysMemInfo::kDefaultSysMemInfoTags.end());
1069 auto it = tags.begin();
1070 tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:");
1071 SysMemInfo mi;
1072
1073 // Read system memory info
1074 mem.resize(tags.size());
1075 EXPECT_TRUE(mi.ReadMemInfo(tags.size(), tags.data(), mem.data(), file.c_str()));
1076 EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740);
1077 EXPECT_EQ(mem[MEMINFO_FREE], 1809728);
1078 EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736);
1079 EXPECT_EQ(mem[MEMINFO_CACHED], 776052);
1080 EXPECT_EQ(mem[MEMINFO_SHMEM], 4020);
1081 EXPECT_EQ(mem[MEMINFO_SLAB], 86464);
1082 EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432);
1083 EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032);
1084 EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768);
1085 EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096);
1086 EXPECT_EQ(mem[MEMINFO_MAPPED], 62624);
1087 EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536);
1088 EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900);
1089 EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880);
1090 EXPECT_EQ(mem[MEMINFO_KRECLAIMABLE], 87324);
1091 EXPECT_EQ(mem[MEMINFO_ACTIVE], 445856);
1092 EXPECT_EQ(mem[MEMINFO_INACTIVE], 459092);
1093 EXPECT_EQ(mem[MEMINFO_UNEVICTABLE], 3096);
1094 EXPECT_EQ(mem[MEMINFO_AVAILABLE], 2546560);
1095 EXPECT_EQ(mem[MEMINFO_ACTIVE_ANON], 78492);
1096 EXPECT_EQ(mem[MEMINFO_INACTIVE_ANON], 2240);
1097 EXPECT_EQ(mem[MEMINFO_ACTIVE_FILE], 367364);
1098 EXPECT_EQ(mem[MEMINFO_INACTIVE_FILE], 456852);
1099 EXPECT_EQ(mem[MEMINFO_CMA_TOTAL], 131072);
1100 EXPECT_EQ(mem[MEMINFO_CMA_FREE], 130380);
1101 }
1102
TEST(SysMemInfo,TestVmallocInfoNoMemory)1103 TEST(SysMemInfo, TestVmallocInfoNoMemory) {
1104 std::string vmallocinfo =
1105 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
1106 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
1107 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
1108 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo";
1109
1110 TemporaryFile tf;
1111 ASSERT_TRUE(tf.fd != -1);
1112 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1113 std::string file = std::string(tf.path);
1114
1115 EXPECT_EQ(ReadVmallocInfo(file.c_str()), 0);
1116 }
1117
TEST(SysMemInfo,TestVmallocInfoKernel)1118 TEST(SysMemInfo, TestVmallocInfoKernel) {
1119 std::string vmallocinfo =
1120 R"vmallocinfo(0x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo";
1121
1122 TemporaryFile tf;
1123 ASSERT_TRUE(tf.fd != -1);
1124 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1125 std::string file = std::string(tf.path);
1126
1127 EXPECT_EQ(ReadVmallocInfo(file.c_str()), getpagesize());
1128 }
1129
TEST(SysMemInfo,TestVmallocInfoModule)1130 TEST(SysMemInfo, TestVmallocInfoModule) {
1131 std::string vmallocinfo =
1132 R"vmallocinfo(0x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
1133
1134 TemporaryFile tf;
1135 ASSERT_TRUE(tf.fd != -1);
1136 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1137 std::string file = std::string(tf.path);
1138
1139 EXPECT_EQ(ReadVmallocInfo(file.c_str()), 6 * getpagesize());
1140 }
1141
TEST(SysMemInfo,TestVmallocInfoAll)1142 TEST(SysMemInfo, TestVmallocInfoAll) {
1143 std::string vmallocinfo =
1144 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
1145 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
1146 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
1147 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap
1148 0x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc
1149 0x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
1150
1151 TemporaryFile tf;
1152 ASSERT_TRUE(tf.fd != -1);
1153 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
1154 std::string file = std::string(tf.path);
1155
1156 EXPECT_EQ(ReadVmallocInfo(file.c_str()), 7 * getpagesize());
1157 }
1158
TEST(SysMemInfo,TestReadIonHeapsSizeKb)1159 TEST(SysMemInfo, TestReadIonHeapsSizeKb) {
1160 std::string total_heaps_kb = R"total_heaps_kb(98480)total_heaps_kb";
1161 uint64_t size;
1162
1163 TemporaryFile tf;
1164 ASSERT_TRUE(tf.fd != -1);
1165 ASSERT_TRUE(::android::base::WriteStringToFd(total_heaps_kb, tf.fd));
1166 std::string file = std::string(tf.path);
1167
1168 ASSERT_TRUE(ReadIonHeapsSizeKb(&size, file));
1169 EXPECT_EQ(size, 98480);
1170 }
1171
TEST(SysMemInfo,TestReadIonPoolsSizeKb)1172 TEST(SysMemInfo, TestReadIonPoolsSizeKb) {
1173 std::string total_pools_kb = R"total_pools_kb(416)total_pools_kb";
1174 uint64_t size;
1175
1176 TemporaryFile tf;
1177 ASSERT_TRUE(tf.fd != -1);
1178 ASSERT_TRUE(::android::base::WriteStringToFd(total_pools_kb, tf.fd));
1179 std::string file = std::string(tf.path);
1180
1181 ASSERT_TRUE(ReadIonPoolsSizeKb(&size, file));
1182 EXPECT_EQ(size, 416);
1183 }
1184
TEST(SysMemInfo,TestReadGpuTotalUsageKb)1185 TEST(SysMemInfo, TestReadGpuTotalUsageKb) {
1186 uint64_t size;
1187
1188 if (android::base::GetIntProperty("ro.vendor.api_level", 0) < __ANDROID_API_S__) {
1189 GTEST_SKIP();
1190 }
1191
1192 KernelVersion min_kernel_version = KernelVersion(5, 4, 0);
1193 KernelVersion kernel_version = VintfObject::GetInstance()
1194 ->getRuntimeInfo(RuntimeInfo::FetchFlag::CPU_VERSION)
1195 ->kernelVersion();
1196 if (kernel_version < min_kernel_version) {
1197 GTEST_SKIP();
1198 }
1199
1200 ASSERT_TRUE(ReadGpuTotalUsageKb(&size));
1201 EXPECT_TRUE(size >= 0);
1202 }
1203
1204 class DmabufHeapStats : public ::testing::Test {
1205 public:
SetUp()1206 virtual void SetUp() {
1207 fs::current_path(fs::temp_directory_path());
1208 buffer_stats_path = fs::current_path() / "buffers";
1209 ASSERT_TRUE(fs::create_directory(buffer_stats_path));
1210 heap_root_path = fs::current_path() / "dma_heap";
1211 ASSERT_TRUE(fs::create_directory(heap_root_path));
1212 }
TearDown()1213 virtual void TearDown() {
1214 fs::remove_all(buffer_stats_path);
1215 fs::remove_all(heap_root_path);
1216 }
1217
1218 fs::path buffer_stats_path;
1219 fs::path heap_root_path;
1220 };
1221
TEST_F(DmabufHeapStats,TestDmabufHeapTotalExportedKb)1222 TEST_F(DmabufHeapStats, TestDmabufHeapTotalExportedKb) {
1223 using android::base::StringPrintf;
1224 uint64_t size;
1225
1226 auto system_heap_path = heap_root_path / "system";
1227 ASSERT_TRUE(android::base::WriteStringToFile("test", system_heap_path));
1228
1229 for (unsigned int inode_number = 74831; inode_number < 74841; inode_number++) {
1230 auto buffer_path = buffer_stats_path / StringPrintf("%u", inode_number);
1231 ASSERT_TRUE(fs::create_directories(buffer_path));
1232
1233 auto buffer_size_path = buffer_path / "size";
1234 const std::string buffer_size = "4096";
1235 ASSERT_TRUE(android::base::WriteStringToFile(buffer_size, buffer_size_path));
1236
1237 auto exp_name_path = buffer_path / "exporter_name";
1238 const std::string exp_name = inode_number % 2 ? "system" : "other";
1239 ASSERT_TRUE(android::base::WriteStringToFile(exp_name, exp_name_path));
1240 }
1241
1242 ASSERT_TRUE(ReadDmabufHeapTotalExportedKb(&size, heap_root_path, buffer_stats_path));
1243 ASSERT_EQ(size, 20);
1244 }
1245
TEST(SysMemInfo,TestReadDmaBufHeapPoolsSizeKb)1246 TEST(SysMemInfo, TestReadDmaBufHeapPoolsSizeKb) {
1247 std::string total_pools_kb = R"total_pools_kb(416)total_pools_kb";
1248 uint64_t size;
1249
1250 TemporaryFile tf;
1251 ASSERT_TRUE(tf.fd != -1);
1252 ASSERT_TRUE(::android::base::WriteStringToFd(total_pools_kb, tf.fd));
1253 std::string file = std::string(tf.path);
1254
1255 ASSERT_TRUE(ReadDmabufHeapPoolsSizeKb(&size, file));
1256 EXPECT_EQ(size, 416);
1257 }
1258
main(int argc,char ** argv)1259 int main(int argc, char** argv) {
1260 ::testing::InitGoogleTest(&argc, argv);
1261 ::android::base::InitLogging(argv, android::base::StderrLogger);
1262 pid = getpid();
1263 return RUN_ALL_TESTS();
1264 }
1265