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