• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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