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,PageMapPresent)139 TEST(ProcMemInfo, PageMapPresent) {
140 static constexpr size_t kNumPages = 20;
141 size_t pagesize = getpagesize();
142 void* ptr = mmap(nullptr, pagesize * (kNumPages + 2), PROT_READ | PROT_WRITE,
143 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
144 ASSERT_NE(MAP_FAILED, ptr);
145
146 // Unmap the first page and the last page so that we guarantee this
147 // map is in a map by itself.
148 ASSERT_EQ(0, munmap(ptr, pagesize));
149 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr) + pagesize;
150 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr + kNumPages * pagesize), pagesize));
151
152 ProcMemInfo proc_mem(getpid());
153 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
154 ASSERT_FALSE(maps.empty());
155
156 // Find the vma associated with our previously created map.
157 const Vma* test_vma = nullptr;
158 for (const Vma& vma : maps) {
159 if (vma.start == addr) {
160 test_vma = &vma;
161 break;
162 }
163 }
164 ASSERT_TRUE(test_vma != nullptr) << "Cannot find test map.";
165
166 // Verify that none of the pages are listed as present.
167 std::vector<uint64_t> pagemap;
168 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
169 ASSERT_EQ(kNumPages, pagemap.size());
170 for (size_t i = 0; i < pagemap.size(); i++) {
171 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
172 << "Page " << i << " is present and it should not be.";
173 }
174
175 // Make some of the pages present and verify that we see them
176 // as present.
177 uint8_t* data = reinterpret_cast<uint8_t*>(addr);
178 data[0] = 1;
179 data[pagesize * 5] = 1;
180 data[pagesize * 11] = 1;
181
182 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
183 ASSERT_EQ(kNumPages, pagemap.size());
184 for (size_t i = 0; i < pagemap.size(); i++) {
185 if (i == 0 || i == 5 || i == 11) {
186 EXPECT_TRUE(android::meminfo::page_present(pagemap[i]))
187 << "Page " << i << " is not present and it should be.";
188 } else {
189 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
190 << "Page " << i << " is present and it should not be.";
191 }
192 }
193
194 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr), kNumPages * pagesize));
195 }
196
TEST(ProcMemInfo,WssEmpty)197 TEST(ProcMemInfo, WssEmpty) {
198 // If we created the object for getting usage,
199 // the working set must be empty
200 ProcMemInfo proc_mem(pid, false);
201 const MemUsage& wss = proc_mem.Wss();
202 EXPECT_EQ(wss.rss, 0);
203 EXPECT_EQ(wss.vss, 0);
204 EXPECT_EQ(wss.pss, 0);
205 EXPECT_EQ(wss.uss, 0);
206 EXPECT_EQ(wss.swap, 0);
207 }
208
TEST(ProcMemInfo,SwapOffsetsEmpty)209 TEST(ProcMemInfo, SwapOffsetsEmpty) {
210 // If we created the object for getting working set,
211 // the swap offsets must be empty
212 ProcMemInfo proc_mem(pid, true);
213 const std::vector<uint64_t>& swap_offsets = proc_mem.SwapOffsets();
214 EXPECT_EQ(swap_offsets.size(), 0);
215 }
216
TEST(ProcMemInfo,IsSmapsSupportedTest)217 TEST(ProcMemInfo, IsSmapsSupportedTest) {
218 // Check if /proc/self/smaps_rollup exists using the API.
219 bool supported = IsSmapsRollupSupported();
220 EXPECT_EQ(!access("/proc/self/smaps_rollup", F_OK | R_OK), supported);
221 }
222
TEST(ProcMemInfo,SmapsOrRollupTest)223 TEST(ProcMemInfo, SmapsOrRollupTest) {
224 // Make sure we can parse 'smaps_rollup' correctly
225 std::string rollup =
226 R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0 [rollup]
227 Rss: 331908 kB
228 Pss: 202052 kB
229 Shared_Clean: 158492 kB
230 Shared_Dirty: 18928 kB
231 Private_Clean: 90472 kB
232 Private_Dirty: 64016 kB
233 Referenced: 318700 kB
234 Anonymous: 81984 kB
235 AnonHugePages: 0 kB
236 Shared_Hugetlb: 0 kB
237 Private_Hugetlb: 0 kB
238 Swap: 5344 kB
239 SwapPss: 442 kB
240 Locked: 1523537 kB)rollup";
241
242 TemporaryFile tf;
243 ASSERT_TRUE(tf.fd != -1);
244 ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd));
245
246 MemUsage stats;
247 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
248 EXPECT_EQ(stats.rss, 331908);
249 EXPECT_EQ(stats.pss, 202052);
250 EXPECT_EQ(stats.uss, 154488);
251 EXPECT_EQ(stats.private_clean, 90472);
252 EXPECT_EQ(stats.private_dirty, 64016);
253 EXPECT_EQ(stats.swap_pss, 442);
254 }
255
TEST(ProcMemInfo,SmapsOrRollupSmapsTest)256 TEST(ProcMemInfo, SmapsOrRollupSmapsTest) {
257 // Make sure /proc/<pid>/smaps is parsed correctly
258 std::string smaps =
259 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
260 Name: [anon:dalvik-main space (region space)]
261 Size: 8448 kB
262 KernelPageSize: 4 kB
263 MMUPageSize: 4 kB
264 Rss: 2652 kB
265 Pss: 2652 kB
266 Shared_Clean: 840 kB
267 Shared_Dirty: 40 kB
268 Private_Clean: 84 kB
269 Private_Dirty: 2652 kB
270 Referenced: 2652 kB
271 Anonymous: 2652 kB
272 AnonHugePages: 0 kB
273 ShmemPmdMapped: 0 kB
274 Shared_Hugetlb: 0 kB
275 Private_Hugetlb: 0 kB
276 Swap: 102 kB
277 SwapPss: 70 kB
278 Locked: 2652 kB
279 VmFlags: rd wr mr mw me ac
280 )smaps";
281
282 TemporaryFile tf;
283 ASSERT_TRUE(tf.fd != -1);
284 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
285
286 MemUsage stats;
287 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
288 EXPECT_EQ(stats.rss, 2652);
289 EXPECT_EQ(stats.pss, 2652);
290 EXPECT_EQ(stats.uss, 2736);
291 EXPECT_EQ(stats.private_clean, 84);
292 EXPECT_EQ(stats.private_dirty, 2652);
293 EXPECT_EQ(stats.swap_pss, 70);
294 }
295
TEST(ProcMemInfo,SmapsOrRollupPssRollupTest)296 TEST(ProcMemInfo, SmapsOrRollupPssRollupTest) {
297 // Make sure /proc/<pid>/smaps is parsed correctly
298 // to get the PSS
299 std::string smaps =
300 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
301 Name: [anon:dalvik-main space (region space)]
302 Size: 8448 kB
303 KernelPageSize: 4 kB
304 MMUPageSize: 4 kB
305 Rss: 2652 kB
306 Pss: 2652 kB
307 Shared_Clean: 840 kB
308 Shared_Dirty: 40 kB
309 Private_Clean: 84 kB
310 Private_Dirty: 2652 kB
311 Referenced: 2652 kB
312 Anonymous: 2652 kB
313 AnonHugePages: 0 kB
314 ShmemPmdMapped: 0 kB
315 Shared_Hugetlb: 0 kB
316 Private_Hugetlb: 0 kB
317 Swap: 102 kB
318 SwapPss: 70 kB
319 Locked: 2652 kB
320 VmFlags: rd wr mr mw me ac
321 )smaps";
322
323 TemporaryFile tf;
324 ASSERT_TRUE(tf.fd != -1);
325 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
326
327 uint64_t pss;
328 ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
329 EXPECT_EQ(pss, 2652);
330 }
331
TEST(ProcMemInfo,SmapsOrRollupPssSmapsTest)332 TEST(ProcMemInfo, SmapsOrRollupPssSmapsTest) {
333 // Correctly parse smaps file to gather pss
334 std::string exec_dir = ::android::base::GetExecutableDirectory();
335 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
336
337 uint64_t pss;
338 ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
339 EXPECT_EQ(pss, 19119);
340 }
341
TEST(ProcMemInfo,ForEachVmaFromFile_SmapsTest)342 TEST(ProcMemInfo, ForEachVmaFromFile_SmapsTest) {
343 // Parse smaps file correctly to make callbacks for each virtual memory area (vma)
344 std::string exec_dir = ::android::base::GetExecutableDirectory();
345 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
346 ProcMemInfo proc_mem(pid);
347
348 std::vector<Vma> vmas;
349 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
350 ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
351
352 // We should get a total of 6 vmas
353 ASSERT_EQ(vmas.size(), 6);
354
355 // Expect values to be equal to what we have in testdata1/smaps_short
356 // Check for names
357 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
358 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
359 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
360 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
361 << "Unknown map name " << vmas[2].name;
362 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
363 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
364 EXPECT_EQ(vmas[5].name, "[vsyscall]");
365
366 // Check start address
367 EXPECT_EQ(vmas[0].start, 0x54c00000);
368 EXPECT_EQ(vmas[1].start, 0x701ea000);
369 EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
370 EXPECT_EQ(vmas[3].start, 0x700755a2d000);
371 EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
372 EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
373
374 // Check end address
375 EXPECT_EQ(vmas[0].end, 0x56c00000);
376 EXPECT_EQ(vmas[1].end, 0x70cdb000);
377 EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
378 EXPECT_EQ(vmas[3].end, 0x700755a6e000);
379 EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
380 EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
381
382 // Check Flags
383 EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
384 EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
385 EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
386 EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
387 EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
388 EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
389
390 // Check Shared
391 EXPECT_FALSE(vmas[0].is_shared);
392 EXPECT_FALSE(vmas[1].is_shared);
393 EXPECT_FALSE(vmas[2].is_shared);
394 EXPECT_FALSE(vmas[3].is_shared);
395 EXPECT_FALSE(vmas[4].is_shared);
396 EXPECT_FALSE(vmas[5].is_shared);
397
398 // Check Offset
399 EXPECT_EQ(vmas[0].offset, 0x0);
400 EXPECT_EQ(vmas[1].offset, 0x0);
401 EXPECT_EQ(vmas[2].offset, 0x0);
402 EXPECT_EQ(vmas[3].offset, 0x00016000);
403 EXPECT_EQ(vmas[4].offset, 0x001ee000);
404 EXPECT_EQ(vmas[5].offset, 0x0);
405
406 // Check Inode
407 EXPECT_EQ(vmas[0].inode, 0);
408 EXPECT_EQ(vmas[1].inode, 3165);
409 EXPECT_EQ(vmas[2].inode, 0);
410 EXPECT_EQ(vmas[3].inode, 1947);
411 EXPECT_EQ(vmas[4].inode, 1537);
412 EXPECT_EQ(vmas[5].inode, 0);
413
414 // Check smaps specific fields
415 ASSERT_EQ(vmas[0].usage.vss, 32768);
416 EXPECT_EQ(vmas[1].usage.vss, 11204);
417 EXPECT_EQ(vmas[2].usage.vss, 16896);
418 EXPECT_EQ(vmas[3].usage.vss, 260);
419 EXPECT_EQ(vmas[4].usage.vss, 6060);
420 EXPECT_EQ(vmas[5].usage.vss, 4);
421
422 EXPECT_EQ(vmas[0].usage.rss, 2048);
423 EXPECT_EQ(vmas[1].usage.rss, 11188);
424 EXPECT_EQ(vmas[2].usage.rss, 15272);
425 EXPECT_EQ(vmas[3].usage.rss, 260);
426 EXPECT_EQ(vmas[4].usage.rss, 4132);
427 EXPECT_EQ(vmas[5].usage.rss, 0);
428
429 EXPECT_EQ(vmas[0].usage.pss, 113);
430 EXPECT_EQ(vmas[1].usage.pss, 2200);
431 EXPECT_EQ(vmas[2].usage.pss, 15272);
432 EXPECT_EQ(vmas[3].usage.pss, 260);
433 EXPECT_EQ(vmas[4].usage.pss, 1274);
434 EXPECT_EQ(vmas[5].usage.pss, 0);
435
436 EXPECT_EQ(vmas[0].usage.uss, 0);
437 EXPECT_EQ(vmas[1].usage.uss, 1660);
438 EXPECT_EQ(vmas[2].usage.uss, 15272);
439 EXPECT_EQ(vmas[3].usage.uss, 260);
440 EXPECT_EQ(vmas[4].usage.uss, 0);
441 EXPECT_EQ(vmas[5].usage.uss, 0);
442
443 EXPECT_EQ(vmas[0].usage.private_clean, 0);
444 EXPECT_EQ(vmas[1].usage.private_clean, 0);
445 EXPECT_EQ(vmas[2].usage.private_clean, 0);
446 EXPECT_EQ(vmas[3].usage.private_clean, 260);
447 EXPECT_EQ(vmas[4].usage.private_clean, 0);
448 EXPECT_EQ(vmas[5].usage.private_clean, 0);
449
450 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
451 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
452 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
453 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
454 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
455 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
456
457 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
458 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
459 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
460 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
461 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
462 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
463
464 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
465 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
466 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
467 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
468 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
469 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
470
471 EXPECT_EQ(vmas[0].usage.swap, 0);
472 EXPECT_EQ(vmas[1].usage.swap, 0);
473 EXPECT_EQ(vmas[2].usage.swap, 0);
474 EXPECT_EQ(vmas[3].usage.swap, 0);
475 EXPECT_EQ(vmas[4].usage.swap, 0);
476 EXPECT_EQ(vmas[5].usage.swap, 0);
477
478 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
479 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
480 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
481 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
482 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
483 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
484 }
485
TEST(ProcMemInfo,ForEachVmaFromFile_MapsTest)486 TEST(ProcMemInfo, ForEachVmaFromFile_MapsTest) {
487 // Parse maps file correctly to make callbacks for each virtual memory area (vma)
488 std::string exec_dir = ::android::base::GetExecutableDirectory();
489 std::string path = ::android::base::StringPrintf("%s/testdata1/maps_short", exec_dir.c_str());
490 ProcMemInfo proc_mem(pid);
491
492 std::vector<Vma> vmas;
493 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
494 ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas, false));
495
496 // We should get a total of 6 vmas
497 ASSERT_EQ(vmas.size(), 6);
498
499 // Expect values to be equal to what we have in testdata1/maps_short
500 // Check for names
501 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
502 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
503 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
504 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
505 << "Unknown map name " << vmas[2].name;
506 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
507 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
508 EXPECT_EQ(vmas[5].name, "[vsyscall]");
509
510 // Check start address
511 EXPECT_EQ(vmas[0].start, 0x54c00000);
512 EXPECT_EQ(vmas[1].start, 0x701ea000);
513 EXPECT_EQ(vmas[2].start, 0x70074dd8d000);
514 EXPECT_EQ(vmas[3].start, 0x700755a2d000);
515 EXPECT_EQ(vmas[4].start, 0x7007f85b0000);
516 EXPECT_EQ(vmas[5].start, 0xffffffffff600000);
517
518 // Check end address
519 EXPECT_EQ(vmas[0].end, 0x56c00000);
520 EXPECT_EQ(vmas[1].end, 0x70cdb000);
521 EXPECT_EQ(vmas[2].end, 0x70074ee0d000);
522 EXPECT_EQ(vmas[3].end, 0x700755a6e000);
523 EXPECT_EQ(vmas[4].end, 0x7007f8b9b000);
524 EXPECT_EQ(vmas[5].end, 0xffffffffff601000);
525
526 // Check Flags
527 EXPECT_EQ(vmas[0].flags, PROT_READ | PROT_EXEC);
528 EXPECT_EQ(vmas[1].flags, PROT_READ | PROT_WRITE);
529 EXPECT_EQ(vmas[2].flags, PROT_READ | PROT_WRITE);
530 EXPECT_EQ(vmas[3].flags, PROT_READ | PROT_EXEC);
531 EXPECT_EQ(vmas[4].flags, PROT_READ | PROT_EXEC);
532 EXPECT_EQ(vmas[5].flags, PROT_READ | PROT_EXEC);
533
534 // Check Shared
535 EXPECT_FALSE(vmas[0].is_shared);
536 EXPECT_FALSE(vmas[1].is_shared);
537 EXPECT_FALSE(vmas[2].is_shared);
538 EXPECT_FALSE(vmas[3].is_shared);
539 EXPECT_FALSE(vmas[4].is_shared);
540 EXPECT_FALSE(vmas[5].is_shared);
541
542 // Check Offset
543 EXPECT_EQ(vmas[0].offset, 0x0);
544 EXPECT_EQ(vmas[1].offset, 0x0);
545 EXPECT_EQ(vmas[2].offset, 0x0);
546 EXPECT_EQ(vmas[3].offset, 0x00016000);
547 EXPECT_EQ(vmas[4].offset, 0x001ee000);
548 EXPECT_EQ(vmas[5].offset, 0x0);
549
550 // Check Inode
551 EXPECT_EQ(vmas[0].inode, 0);
552 EXPECT_EQ(vmas[1].inode, 3165);
553 EXPECT_EQ(vmas[2].inode, 0);
554 EXPECT_EQ(vmas[3].inode, 1947);
555 EXPECT_EQ(vmas[4].inode, 1537);
556 EXPECT_EQ(vmas[5].inode, 0);
557 }
558
TEST(ProcMemInfo,SmapsReturnTest)559 TEST(ProcMemInfo, SmapsReturnTest) {
560 // Make sure Smaps() is never empty for any process
561 ProcMemInfo proc_mem(pid);
562 auto vmas = proc_mem.Smaps();
563 EXPECT_FALSE(vmas.empty());
564 }
565
TEST(ProcMemInfo,SmapsTest)566 TEST(ProcMemInfo, SmapsTest) {
567 std::string exec_dir = ::android::base::GetExecutableDirectory();
568 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
569 ProcMemInfo proc_mem(pid);
570 auto vmas = proc_mem.Smaps(path);
571
572 ASSERT_FALSE(vmas.empty());
573 #ifndef __x86_64__
574 // We should get a total of 6 vmas
575 ASSERT_EQ(vmas.size(), 6);
576 #else
577 // We should get a total of 5 vmas ([vsyscall] is excluded)
578 ASSERT_EQ(vmas.size(), 5);
579 #endif
580
581 // Expect values to be equal to what we have in testdata1/smaps_short
582 // Check for sizes first
583 ASSERT_EQ(vmas[0].usage.vss, 32768);
584 EXPECT_EQ(vmas[1].usage.vss, 11204);
585 EXPECT_EQ(vmas[2].usage.vss, 16896);
586 EXPECT_EQ(vmas[3].usage.vss, 260);
587 EXPECT_EQ(vmas[4].usage.vss, 6060);
588 #ifndef __x86_64__
589 EXPECT_EQ(vmas[5].usage.vss, 4);
590 #endif
591
592 // Check for names
593 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
594 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
595 EXPECT_TRUE(vmas[2].name == "[anon:libc_malloc]" ||
596 android::base::StartsWith(vmas[2].name, "[anon:scudo:"))
597 << "Unknown map name " << vmas[2].name;
598 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
599 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
600 #ifndef __x86_64__
601 EXPECT_EQ(vmas[5].name, "[vsyscall]");
602 #endif
603
604 EXPECT_EQ(vmas[0].usage.rss, 2048);
605 EXPECT_EQ(vmas[1].usage.rss, 11188);
606 EXPECT_EQ(vmas[2].usage.rss, 15272);
607 EXPECT_EQ(vmas[3].usage.rss, 260);
608 EXPECT_EQ(vmas[4].usage.rss, 4132);
609 #ifndef __x86_64__
610 EXPECT_EQ(vmas[5].usage.rss, 0);
611 #endif
612
613 EXPECT_EQ(vmas[0].usage.pss, 113);
614 EXPECT_EQ(vmas[1].usage.pss, 2200);
615 EXPECT_EQ(vmas[2].usage.pss, 15272);
616 EXPECT_EQ(vmas[3].usage.pss, 260);
617 EXPECT_EQ(vmas[4].usage.pss, 1274);
618 #ifndef __x86_64__
619 EXPECT_EQ(vmas[5].usage.pss, 0);
620 #endif
621
622 EXPECT_EQ(vmas[0].usage.uss, 0);
623 EXPECT_EQ(vmas[1].usage.uss, 1660);
624 EXPECT_EQ(vmas[2].usage.uss, 15272);
625 EXPECT_EQ(vmas[3].usage.uss, 260);
626 EXPECT_EQ(vmas[4].usage.uss, 0);
627 #ifndef __x86_64__
628 EXPECT_EQ(vmas[5].usage.uss, 0);
629 #endif
630
631 EXPECT_EQ(vmas[0].usage.private_clean, 0);
632 EXPECT_EQ(vmas[1].usage.private_clean, 0);
633 EXPECT_EQ(vmas[2].usage.private_clean, 0);
634 EXPECT_EQ(vmas[3].usage.private_clean, 260);
635 EXPECT_EQ(vmas[4].usage.private_clean, 0);
636 #ifndef __x86_64__
637 EXPECT_EQ(vmas[5].usage.private_clean, 0);
638 #endif
639
640 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
641 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
642 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
643 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
644 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
645 #ifndef __x86_64__
646 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
647 #endif
648
649 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
650 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
651 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
652 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
653 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
654 #ifndef __x86_64__
655 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
656 #endif
657
658 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
659 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
660 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
661 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
662 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
663 #ifndef __x86_64__
664 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
665 #endif
666
667 EXPECT_EQ(vmas[0].usage.swap, 0);
668 EXPECT_EQ(vmas[1].usage.swap, 0);
669 EXPECT_EQ(vmas[2].usage.swap, 0);
670 EXPECT_EQ(vmas[3].usage.swap, 0);
671 EXPECT_EQ(vmas[4].usage.swap, 0);
672 #ifndef __x86_64__
673 EXPECT_EQ(vmas[5].usage.swap, 0);
674 #endif
675
676 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
677 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
678 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
679 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
680 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
681 #ifndef __x86_64__
682 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
683 #endif
684 }
685
TEST(SysMemInfo,TestSysMemInfoFile)686 TEST(SysMemInfo, TestSysMemInfoFile) {
687 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
688 MemFree: 1809728 kB
689 MemAvailable: 2546560 kB
690 Buffers: 54736 kB
691 Cached: 776052 kB
692 SwapCached: 0 kB
693 Active: 445856 kB
694 Inactive: 459092 kB
695 Active(anon): 78492 kB
696 Inactive(anon): 2240 kB
697 Active(file): 367364 kB
698 Inactive(file): 456852 kB
699 Unevictable: 3096 kB
700 Mlocked: 3096 kB
701 SwapTotal: 32768 kB
702 SwapFree: 4096 kB
703 Dirty: 32 kB
704 Writeback: 0 kB
705 AnonPages: 74988 kB
706 Mapped: 62624 kB
707 Shmem: 4020 kB
708 KReclaimable: 87324 kB
709 Slab: 86464 kB
710 SReclaimable: 44432 kB
711 SUnreclaim: 42032 kB
712 KernelStack: 4880 kB
713 PageTables: 2900 kB
714 NFS_Unstable: 0 kB
715 Bounce: 0 kB
716 WritebackTmp: 0 kB
717 CommitLimit: 1509868 kB
718 Committed_AS: 80296 kB
719 VmallocTotal: 263061440 kB
720 VmallocUsed: 65536 kB
721 VmallocChunk: 0 kB
722 AnonHugePages: 6144 kB
723 ShmemHugePages: 0 kB
724 ShmemPmdMapped: 0 kB
725 CmaTotal: 131072 kB
726 CmaFree: 130380 kB
727 HugePages_Total: 0
728 HugePages_Free: 0
729 HugePages_Rsvd: 0
730 HugePages_Surp: 0
731 Hugepagesize: 2048 kB)meminfo";
732
733 TemporaryFile tf;
734 ASSERT_TRUE(tf.fd != -1);
735 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
736
737 SysMemInfo mi;
738 ASSERT_TRUE(mi.ReadMemInfo(tf.path));
739 EXPECT_EQ(mi.mem_total_kb(), 3019740);
740 EXPECT_EQ(mi.mem_free_kb(), 1809728);
741 EXPECT_EQ(mi.mem_buffers_kb(), 54736);
742 EXPECT_EQ(mi.mem_cached_kb(), 776052);
743 EXPECT_EQ(mi.mem_shmem_kb(), 4020);
744 EXPECT_EQ(mi.mem_slab_kb(), 86464);
745 EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432);
746 EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032);
747 EXPECT_EQ(mi.mem_swap_kb(), 32768);
748 EXPECT_EQ(mi.mem_swap_free_kb(), 4096);
749 EXPECT_EQ(mi.mem_mapped_kb(), 62624);
750 EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536);
751 EXPECT_EQ(mi.mem_page_tables_kb(), 2900);
752 EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880);
753 EXPECT_EQ(mi.mem_kreclaimable_kb(), 87324);
754 EXPECT_EQ(mi.mem_active_kb(), 445856);
755 EXPECT_EQ(mi.mem_inactive_kb(), 459092);
756 EXPECT_EQ(mi.mem_unevictable_kb(), 3096);
757 }
758
TEST(SysMemInfo,TestEmptyFile)759 TEST(SysMemInfo, TestEmptyFile) {
760 TemporaryFile tf;
761 std::string empty_string = "";
762 ASSERT_TRUE(tf.fd != -1);
763 ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd));
764
765 SysMemInfo mi;
766 EXPECT_TRUE(mi.ReadMemInfo(tf.path));
767 EXPECT_EQ(mi.mem_total_kb(), 0);
768 }
769
TEST(SysMemInfo,TestZramTotal)770 TEST(SysMemInfo, TestZramTotal) {
771 std::string exec_dir = ::android::base::GetExecutableDirectory();
772
773 SysMemInfo mi;
774 std::string zram_mmstat_dir = exec_dir + "/testdata1/";
775 EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir.c_str()), 30504);
776
777 std::string zram_memused_dir = exec_dir + "/testdata2/";
778 EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir.c_str()), 30504);
779 }
780
781 enum {
782 MEMINFO_TOTAL,
783 MEMINFO_FREE,
784 MEMINFO_BUFFERS,
785 MEMINFO_CACHED,
786 MEMINFO_SHMEM,
787 MEMINFO_SLAB,
788 MEMINFO_SLAB_RECLAIMABLE,
789 MEMINFO_SLAB_UNRECLAIMABLE,
790 MEMINFO_SWAP_TOTAL,
791 MEMINFO_SWAP_FREE,
792 MEMINFO_ZRAM_TOTAL,
793 MEMINFO_MAPPED,
794 MEMINFO_VMALLOC_USED,
795 MEMINFO_PAGE_TABLES,
796 MEMINFO_KERNEL_STACK,
797 MEMINFO_KRECLAIMABLE,
798 MEMINFO_ACTIVE,
799 MEMINFO_INACTIVE,
800 MEMINFO_UNEVICTABLE,
801 MEMINFO_COUNT
802 };
803
TEST(SysMemInfo,TestZramWithTags)804 TEST(SysMemInfo, TestZramWithTags) {
805 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
806 MemFree: 1809728 kB
807 MemAvailable: 2546560 kB
808 Buffers: 54736 kB
809 Cached: 776052 kB
810 SwapCached: 0 kB
811 Active: 445856 kB
812 Inactive: 459092 kB
813 Active(anon): 78492 kB
814 Inactive(anon): 2240 kB
815 Active(file): 367364 kB
816 Inactive(file): 456852 kB
817 Unevictable: 3096 kB
818 Mlocked: 3096 kB
819 SwapTotal: 32768 kB
820 SwapFree: 4096 kB
821 Dirty: 32 kB
822 Writeback: 0 kB
823 AnonPages: 74988 kB
824 Mapped: 62624 kB
825 Shmem: 4020 kB
826 KReclaimable: 87324 kB
827 Slab: 86464 kB
828 SReclaimable: 44432 kB
829 SUnreclaim: 42032 kB
830 KernelStack: 4880 kB
831 PageTables: 2900 kB
832 NFS_Unstable: 0 kB
833 Bounce: 0 kB
834 WritebackTmp: 0 kB
835 CommitLimit: 1509868 kB
836 Committed_AS: 80296 kB
837 VmallocTotal: 263061440 kB
838 VmallocUsed: 65536 kB
839 VmallocChunk: 0 kB
840 AnonHugePages: 6144 kB
841 ShmemHugePages: 0 kB
842 ShmemPmdMapped: 0 kB
843 CmaTotal: 131072 kB
844 CmaFree: 130380 kB
845 HugePages_Total: 0
846 HugePages_Free: 0
847 HugePages_Rsvd: 0
848 HugePages_Surp: 0
849 Hugepagesize: 2048 kB)meminfo";
850
851 TemporaryFile tf;
852 ASSERT_TRUE(tf.fd != -1);
853 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
854 std::string file = std::string(tf.path);
855 std::vector<uint64_t> mem;
856 std::vector<std::string_view> tags(SysMemInfo::kDefaultSysMemInfoTags.begin(),
857 SysMemInfo::kDefaultSysMemInfoTags.end());
858 auto it = tags.begin();
859 tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:");
860 SysMemInfo mi;
861
862 // Read system memory info
863 mem.resize(tags.size());
864 EXPECT_TRUE(mi.ReadMemInfo(tags.size(), tags.data(), mem.data(), file.c_str()));
865 EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740);
866 EXPECT_EQ(mem[MEMINFO_FREE], 1809728);
867 EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736);
868 EXPECT_EQ(mem[MEMINFO_CACHED], 776052);
869 EXPECT_EQ(mem[MEMINFO_SHMEM], 4020);
870 EXPECT_EQ(mem[MEMINFO_SLAB], 86464);
871 EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432);
872 EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032);
873 EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768);
874 EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096);
875 EXPECT_EQ(mem[MEMINFO_MAPPED], 62624);
876 EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536);
877 EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900);
878 EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880);
879 EXPECT_EQ(mem[MEMINFO_KRECLAIMABLE], 87324);
880 EXPECT_EQ(mem[MEMINFO_ACTIVE], 445856);
881 EXPECT_EQ(mem[MEMINFO_INACTIVE], 459092);
882 EXPECT_EQ(mem[MEMINFO_UNEVICTABLE], 3096);
883 }
884
TEST(SysMemInfo,TestVmallocInfoNoMemory)885 TEST(SysMemInfo, TestVmallocInfoNoMemory) {
886 std::string vmallocinfo =
887 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
888 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
889 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
890 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo";
891
892 TemporaryFile tf;
893 ASSERT_TRUE(tf.fd != -1);
894 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
895 std::string file = std::string(tf.path);
896
897 EXPECT_EQ(ReadVmallocInfo(file.c_str()), 0);
898 }
899
TEST(SysMemInfo,TestVmallocInfoKernel)900 TEST(SysMemInfo, TestVmallocInfoKernel) {
901 std::string vmallocinfo =
902 R"vmallocinfo(0x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo";
903
904 TemporaryFile tf;
905 ASSERT_TRUE(tf.fd != -1);
906 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
907 std::string file = std::string(tf.path);
908
909 EXPECT_EQ(ReadVmallocInfo(file.c_str()), getpagesize());
910 }
911
TEST(SysMemInfo,TestVmallocInfoModule)912 TEST(SysMemInfo, TestVmallocInfoModule) {
913 std::string vmallocinfo =
914 R"vmallocinfo(0x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
915
916 TemporaryFile tf;
917 ASSERT_TRUE(tf.fd != -1);
918 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
919 std::string file = std::string(tf.path);
920
921 EXPECT_EQ(ReadVmallocInfo(file.c_str()), 6 * getpagesize());
922 }
923
TEST(SysMemInfo,TestVmallocInfoAll)924 TEST(SysMemInfo, TestVmallocInfoAll) {
925 std::string vmallocinfo =
926 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
927 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
928 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
929 0x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap
930 0x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc
931 0x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
932
933 TemporaryFile tf;
934 ASSERT_TRUE(tf.fd != -1);
935 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
936 std::string file = std::string(tf.path);
937
938 EXPECT_EQ(ReadVmallocInfo(file.c_str()), 7 * getpagesize());
939 }
940
TEST(SysMemInfo,TestReadIonHeapsSizeKb)941 TEST(SysMemInfo, TestReadIonHeapsSizeKb) {
942 std::string total_heaps_kb = R"total_heaps_kb(98480)total_heaps_kb";
943 uint64_t size;
944
945 TemporaryFile tf;
946 ASSERT_TRUE(tf.fd != -1);
947 ASSERT_TRUE(::android::base::WriteStringToFd(total_heaps_kb, tf.fd));
948 std::string file = std::string(tf.path);
949
950 ASSERT_TRUE(ReadIonHeapsSizeKb(&size, file));
951 EXPECT_EQ(size, 98480);
952 }
953
TEST(SysMemInfo,TestReadIonPoolsSizeKb)954 TEST(SysMemInfo, TestReadIonPoolsSizeKb) {
955 std::string total_pools_kb = R"total_pools_kb(416)total_pools_kb";
956 uint64_t size;
957
958 TemporaryFile tf;
959 ASSERT_TRUE(tf.fd != -1);
960 ASSERT_TRUE(::android::base::WriteStringToFd(total_pools_kb, tf.fd));
961 std::string file = std::string(tf.path);
962
963 ASSERT_TRUE(ReadIonPoolsSizeKb(&size, file));
964 EXPECT_EQ(size, 416);
965 }
966
TEST(SysMemInfo,TestReadGpuTotalUsageKb)967 TEST(SysMemInfo, TestReadGpuTotalUsageKb) {
968 uint64_t size;
969
970 if (android::base::GetIntProperty("ro.product.first_api_level", 0) < __ANDROID_API_S__) {
971 GTEST_SKIP();
972 }
973
974 KernelVersion min_kernel_version = KernelVersion(5, 4, 0);
975 KernelVersion kernel_version = VintfObject::GetInstance()
976 ->getRuntimeInfo(RuntimeInfo::FetchFlag::CPU_VERSION)
977 ->kernelVersion();
978 if (kernel_version < min_kernel_version) {
979 GTEST_SKIP();
980 }
981
982 ASSERT_TRUE(ReadGpuTotalUsageKb(&size));
983 EXPECT_TRUE(size >= 0);
984 }
985
986 class DmabufHeapStats : public ::testing::Test {
987 public:
SetUp()988 virtual void SetUp() {
989 fs::current_path(fs::temp_directory_path());
990 buffer_stats_path = fs::current_path() / "buffers";
991 ASSERT_TRUE(fs::create_directory(buffer_stats_path));
992 heap_root_path = fs::current_path() / "dma_heap";
993 ASSERT_TRUE(fs::create_directory(heap_root_path));
994 }
TearDown()995 virtual void TearDown() {
996 fs::remove_all(buffer_stats_path);
997 fs::remove_all(heap_root_path);
998 }
999
1000 fs::path buffer_stats_path;
1001 fs::path heap_root_path;
1002 };
1003
TEST_F(DmabufHeapStats,TestDmabufHeapTotalExportedKb)1004 TEST_F(DmabufHeapStats, TestDmabufHeapTotalExportedKb) {
1005 using android::base::StringPrintf;
1006 uint64_t size;
1007
1008 auto system_heap_path = heap_root_path / "system";
1009 ASSERT_TRUE(android::base::WriteStringToFile("test", system_heap_path));
1010
1011 for (unsigned int inode_number = 74831; inode_number < 74841; inode_number++) {
1012 auto buffer_path = buffer_stats_path / StringPrintf("%u", inode_number);
1013 ASSERT_TRUE(fs::create_directories(buffer_path));
1014
1015 auto buffer_size_path = buffer_path / "size";
1016 const std::string buffer_size = "4096";
1017 ASSERT_TRUE(android::base::WriteStringToFile(buffer_size, buffer_size_path));
1018
1019 auto exp_name_path = buffer_path / "exporter_name";
1020 const std::string exp_name = inode_number % 2 ? "system" : "other";
1021 ASSERT_TRUE(android::base::WriteStringToFile(exp_name, exp_name_path));
1022 }
1023
1024 ASSERT_TRUE(ReadDmabufHeapTotalExportedKb(&size, heap_root_path, buffer_stats_path));
1025 ASSERT_EQ(size, 20);
1026 }
1027
TEST(SysMemInfo,TestReadDmaBufHeapPoolsSizeKb)1028 TEST(SysMemInfo, TestReadDmaBufHeapPoolsSizeKb) {
1029 std::string total_pools_kb = R"total_pools_kb(416)total_pools_kb";
1030 uint64_t size;
1031
1032 TemporaryFile tf;
1033 ASSERT_TRUE(tf.fd != -1);
1034 ASSERT_TRUE(::android::base::WriteStringToFd(total_pools_kb, tf.fd));
1035 std::string file = std::string(tf.path);
1036
1037 ASSERT_TRUE(ReadDmabufHeapPoolsSizeKb(&size, file));
1038 EXPECT_EQ(size, 416);
1039 }
1040
main(int argc,char ** argv)1041 int main(int argc, char** argv) {
1042 ::testing::InitGoogleTest(&argc, argv);
1043 ::android::base::InitLogging(argv, android::base::StderrLogger);
1044 pid = getpid();
1045 return RUN_ALL_TESTS();
1046 }
1047