• 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/types.h>
18 #include <sys/wait.h>
19 #include <unistd.h>
20 
21 #include <gtest/gtest.h>
22 
23 #include <string>
24 #include <vector>
25 
26 #include <meminfo/pageacct.h>
27 #include <meminfo/procmeminfo.h>
28 #include <meminfo/sysmeminfo.h>
29 
30 #include <android-base/file.h>
31 #include <android-base/logging.h>
32 #include <android-base/stringprintf.h>
33 
34 using namespace std;
35 using namespace android::meminfo;
36 
37 pid_t pid = -1;
38 
TEST(ProcMemInfo,TestWorkingTestReset)39 TEST(ProcMemInfo, TestWorkingTestReset) {
40     // Expect reset to succeed
41     EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid));
42 }
43 
TEST(ProcMemInfo,UsageEmpty)44 TEST(ProcMemInfo, UsageEmpty) {
45     // If we created the object for getting working set,
46     // the usage must be empty
47     ProcMemInfo proc_mem(pid, true);
48     const MemUsage& usage = proc_mem.Usage();
49     EXPECT_EQ(usage.rss, 0);
50     EXPECT_EQ(usage.vss, 0);
51     EXPECT_EQ(usage.pss, 0);
52     EXPECT_EQ(usage.uss, 0);
53     EXPECT_EQ(usage.swap, 0);
54 }
55 
TEST(ProcMemInfo,MapsNotEmpty)56 TEST(ProcMemInfo, MapsNotEmpty) {
57     // Make sure the process maps are never empty
58     ProcMemInfo proc_mem(pid);
59     const std::vector<Vma>& maps = proc_mem.Maps();
60     EXPECT_FALSE(maps.empty());
61 }
62 
TEST(ProcMemInfo,WssEmpty)63 TEST(ProcMemInfo, WssEmpty) {
64     // If we created the object for getting usage,
65     // the working set must be empty
66     ProcMemInfo proc_mem(pid, false);
67     const MemUsage& wss = proc_mem.Wss();
68     EXPECT_EQ(wss.rss, 0);
69     EXPECT_EQ(wss.vss, 0);
70     EXPECT_EQ(wss.pss, 0);
71     EXPECT_EQ(wss.uss, 0);
72     EXPECT_EQ(wss.swap, 0);
73 }
74 
TEST(ProcMemInfo,SwapOffsetsEmpty)75 TEST(ProcMemInfo, SwapOffsetsEmpty) {
76     // If we created the object for getting working set,
77     // the swap offsets must be empty
78     ProcMemInfo proc_mem(pid, true);
79     const std::vector<uint16_t>& swap_offsets = proc_mem.SwapOffsets();
80     EXPECT_EQ(swap_offsets.size(), 0);
81 }
82 
TEST(ProcMemInfo,IsSmapsSupportedTest)83 TEST(ProcMemInfo, IsSmapsSupportedTest) {
84     // Get any pid and check if /proc/<pid>/smaps_rollup exists using the API.
85     // The API must return the appropriate value regardless of the after it succeeds
86     // once.
87     std::string path = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid);
88     bool supported = IsSmapsRollupSupported(pid);
89     EXPECT_EQ(!access(path.c_str(), F_OK | R_OK), supported);
90     // Second call must return what the first one returned regardless of the pid parameter.
91     // So, deliberately pass invalid pid.
92     EXPECT_EQ(supported, IsSmapsRollupSupported(-1));
93 }
94 
TEST(ProcMemInfo,SmapsOrRollupTest)95 TEST(ProcMemInfo, SmapsOrRollupTest) {
96     // Make sure we can parse 'smaps_rollup' correctly
97     std::string rollup =
98             R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0                                [rollup]
99 Rss:              331908 kB
100 Pss:              202052 kB
101 Shared_Clean:     158492 kB
102 Shared_Dirty:      18928 kB
103 Private_Clean:     90472 kB
104 Private_Dirty:     64016 kB
105 Referenced:       318700 kB
106 Anonymous:         81984 kB
107 AnonHugePages:         0 kB
108 Shared_Hugetlb:        0 kB
109 Private_Hugetlb:       0 kB
110 Swap:               5344 kB
111 SwapPss:             442 kB
112 Locked:          1523537 kB)rollup";
113 
114     TemporaryFile tf;
115     ASSERT_TRUE(tf.fd != -1);
116     ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd));
117 
118     MemUsage stats;
119     ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
120     EXPECT_EQ(stats.rss, 331908);
121     EXPECT_EQ(stats.pss, 202052);
122     EXPECT_EQ(stats.uss, 154488);
123     EXPECT_EQ(stats.private_clean, 90472);
124     EXPECT_EQ(stats.private_dirty, 64016);
125     EXPECT_EQ(stats.swap_pss, 442);
126 }
127 
TEST(ProcMemInfo,SmapsOrRollupSmapsTest)128 TEST(ProcMemInfo, SmapsOrRollupSmapsTest) {
129     // Make sure /proc/<pid>/smaps is parsed correctly
130     std::string smaps =
131             R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)]
132 Name:           [anon:dalvik-main space (region space)]
133 Size:               8448 kB
134 KernelPageSize:        4 kB
135 MMUPageSize:           4 kB
136 Rss:                2652 kB
137 Pss:                2652 kB
138 Shared_Clean:        840 kB
139 Shared_Dirty:         40 kB
140 Private_Clean:        84 kB
141 Private_Dirty:      2652 kB
142 Referenced:         2652 kB
143 Anonymous:          2652 kB
144 AnonHugePages:         0 kB
145 ShmemPmdMapped:        0 kB
146 Shared_Hugetlb:        0 kB
147 Private_Hugetlb:       0 kB
148 Swap:                102 kB
149 SwapPss:              70 kB
150 Locked:             2652 kB
151 VmFlags: rd wr mr mw me ac
152 )smaps";
153 
154     TemporaryFile tf;
155     ASSERT_TRUE(tf.fd != -1);
156     ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
157 
158     MemUsage stats;
159     ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
160     EXPECT_EQ(stats.rss, 2652);
161     EXPECT_EQ(stats.pss, 2652);
162     EXPECT_EQ(stats.uss, 2736);
163     EXPECT_EQ(stats.private_clean, 84);
164     EXPECT_EQ(stats.private_dirty, 2652);
165     EXPECT_EQ(stats.swap_pss, 70);
166 }
167 
TEST(ProcMemInfo,SmapsOrRollupPssRollupTest)168 TEST(ProcMemInfo, SmapsOrRollupPssRollupTest) {
169     // Make sure /proc/<pid>/smaps is parsed correctly
170     // to get the PSS
171     std::string smaps =
172             R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)]
173 Name:           [anon:dalvik-main space (region space)]
174 Size:               8448 kB
175 KernelPageSize:        4 kB
176 MMUPageSize:           4 kB
177 Rss:                2652 kB
178 Pss:                2652 kB
179 Shared_Clean:        840 kB
180 Shared_Dirty:         40 kB
181 Private_Clean:        84 kB
182 Private_Dirty:      2652 kB
183 Referenced:         2652 kB
184 Anonymous:          2652 kB
185 AnonHugePages:         0 kB
186 ShmemPmdMapped:        0 kB
187 Shared_Hugetlb:        0 kB
188 Private_Hugetlb:       0 kB
189 Swap:                102 kB
190 SwapPss:              70 kB
191 Locked:             2652 kB
192 VmFlags: rd wr mr mw me ac
193 )smaps";
194 
195     TemporaryFile tf;
196     ASSERT_TRUE(tf.fd != -1);
197     ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
198 
199     uint64_t pss;
200     ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
201     EXPECT_EQ(pss, 2652);
202 }
203 
TEST(ProcMemInfo,SmapsOrRollupPssSmapsTest)204 TEST(ProcMemInfo, SmapsOrRollupPssSmapsTest) {
205     // Correctly parse smaps file to gather pss
206     std::string exec_dir = ::android::base::GetExecutableDirectory();
207     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
208 
209     uint64_t pss;
210     ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
211     EXPECT_EQ(pss, 19119);
212 }
213 
TEST(ProcMemInfo,ForEachVmaFromFileTest)214 TEST(ProcMemInfo, ForEachVmaFromFileTest) {
215     // Parse smaps file correctly to make callbacks for each virtual memory area (vma)
216     std::string exec_dir = ::android::base::GetExecutableDirectory();
217     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
218     ProcMemInfo proc_mem(pid);
219 
220     std::vector<Vma> vmas;
221     auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
222     ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
223 
224     // We should get a total of 6 vmas
225     ASSERT_EQ(vmas.size(), 6);
226 
227     // Expect values to be equal to what we have in testdata1/smaps_short
228     // Check for sizes first
229     ASSERT_EQ(vmas[0].usage.vss, 32768);
230     EXPECT_EQ(vmas[1].usage.vss, 11204);
231     EXPECT_EQ(vmas[2].usage.vss, 16896);
232     EXPECT_EQ(vmas[3].usage.vss, 260);
233     EXPECT_EQ(vmas[4].usage.vss, 6060);
234     EXPECT_EQ(vmas[5].usage.vss, 4);
235 
236     // Check for names
237     EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
238     EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
239     EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]");
240     EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
241     EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
242     EXPECT_EQ(vmas[5].name, "[vsyscall]");
243 
244     EXPECT_EQ(vmas[0].usage.rss, 2048);
245     EXPECT_EQ(vmas[1].usage.rss, 11188);
246     EXPECT_EQ(vmas[2].usage.rss, 15272);
247     EXPECT_EQ(vmas[3].usage.rss, 260);
248     EXPECT_EQ(vmas[4].usage.rss, 4132);
249     EXPECT_EQ(vmas[5].usage.rss, 0);
250 
251     EXPECT_EQ(vmas[0].usage.pss, 113);
252     EXPECT_EQ(vmas[1].usage.pss, 2200);
253     EXPECT_EQ(vmas[2].usage.pss, 15272);
254     EXPECT_EQ(vmas[3].usage.pss, 260);
255     EXPECT_EQ(vmas[4].usage.pss, 1274);
256     EXPECT_EQ(vmas[5].usage.pss, 0);
257 
258     EXPECT_EQ(vmas[0].usage.uss, 0);
259     EXPECT_EQ(vmas[1].usage.uss, 1660);
260     EXPECT_EQ(vmas[2].usage.uss, 15272);
261     EXPECT_EQ(vmas[3].usage.uss, 260);
262     EXPECT_EQ(vmas[4].usage.uss, 0);
263     EXPECT_EQ(vmas[5].usage.uss, 0);
264 
265     EXPECT_EQ(vmas[0].usage.private_clean, 0);
266     EXPECT_EQ(vmas[1].usage.private_clean, 0);
267     EXPECT_EQ(vmas[2].usage.private_clean, 0);
268     EXPECT_EQ(vmas[3].usage.private_clean, 260);
269     EXPECT_EQ(vmas[4].usage.private_clean, 0);
270     EXPECT_EQ(vmas[5].usage.private_clean, 0);
271 
272     EXPECT_EQ(vmas[0].usage.private_dirty, 0);
273     EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
274     EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
275     EXPECT_EQ(vmas[3].usage.private_dirty, 0);
276     EXPECT_EQ(vmas[4].usage.private_dirty, 0);
277     EXPECT_EQ(vmas[5].usage.private_dirty, 0);
278 
279     EXPECT_EQ(vmas[0].usage.shared_clean, 0);
280     EXPECT_EQ(vmas[1].usage.shared_clean, 80);
281     EXPECT_EQ(vmas[2].usage.shared_clean, 0);
282     EXPECT_EQ(vmas[3].usage.shared_clean, 0);
283     EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
284     EXPECT_EQ(vmas[5].usage.shared_clean, 0);
285 
286     EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
287     EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
288     EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
289     EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
290     EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
291     EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
292 
293     EXPECT_EQ(vmas[0].usage.swap, 0);
294     EXPECT_EQ(vmas[1].usage.swap, 0);
295     EXPECT_EQ(vmas[2].usage.swap, 0);
296     EXPECT_EQ(vmas[3].usage.swap, 0);
297     EXPECT_EQ(vmas[4].usage.swap, 0);
298     EXPECT_EQ(vmas[5].usage.swap, 0);
299 
300     EXPECT_EQ(vmas[0].usage.swap_pss, 0);
301     EXPECT_EQ(vmas[1].usage.swap_pss, 0);
302     EXPECT_EQ(vmas[2].usage.swap_pss, 0);
303     EXPECT_EQ(vmas[3].usage.swap_pss, 0);
304     EXPECT_EQ(vmas[4].usage.swap_pss, 0);
305     EXPECT_EQ(vmas[5].usage.swap_pss, 0);
306 }
307 
TEST(ProcMemInfo,SmapsReturnTest)308 TEST(ProcMemInfo, SmapsReturnTest) {
309     // Make sure Smaps() is never empty for any process
310     ProcMemInfo proc_mem(pid);
311     auto vmas = proc_mem.Smaps();
312     EXPECT_FALSE(vmas.empty());
313 }
314 
TEST(ProcMemInfo,SmapsTest)315 TEST(ProcMemInfo, SmapsTest) {
316     std::string exec_dir = ::android::base::GetExecutableDirectory();
317     std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
318     ProcMemInfo proc_mem(pid);
319     auto vmas = proc_mem.Smaps(path);
320 
321     ASSERT_FALSE(vmas.empty());
322     // We should get a total of 6 vmas
323     ASSERT_EQ(vmas.size(), 6);
324 
325     // Expect values to be equal to what we have in testdata1/smaps_short
326     // Check for sizes first
327     ASSERT_EQ(vmas[0].usage.vss, 32768);
328     EXPECT_EQ(vmas[1].usage.vss, 11204);
329     EXPECT_EQ(vmas[2].usage.vss, 16896);
330     EXPECT_EQ(vmas[3].usage.vss, 260);
331     EXPECT_EQ(vmas[4].usage.vss, 6060);
332     EXPECT_EQ(vmas[5].usage.vss, 4);
333 
334     // Check for names
335     EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
336     EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
337     EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]");
338     EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
339     EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
340     EXPECT_EQ(vmas[5].name, "[vsyscall]");
341 
342     EXPECT_EQ(vmas[0].usage.rss, 2048);
343     EXPECT_EQ(vmas[1].usage.rss, 11188);
344     EXPECT_EQ(vmas[2].usage.rss, 15272);
345     EXPECT_EQ(vmas[3].usage.rss, 260);
346     EXPECT_EQ(vmas[4].usage.rss, 4132);
347     EXPECT_EQ(vmas[5].usage.rss, 0);
348 
349     EXPECT_EQ(vmas[0].usage.pss, 113);
350     EXPECT_EQ(vmas[1].usage.pss, 2200);
351     EXPECT_EQ(vmas[2].usage.pss, 15272);
352     EXPECT_EQ(vmas[3].usage.pss, 260);
353     EXPECT_EQ(vmas[4].usage.pss, 1274);
354     EXPECT_EQ(vmas[5].usage.pss, 0);
355 
356     EXPECT_EQ(vmas[0].usage.uss, 0);
357     EXPECT_EQ(vmas[1].usage.uss, 1660);
358     EXPECT_EQ(vmas[2].usage.uss, 15272);
359     EXPECT_EQ(vmas[3].usage.uss, 260);
360     EXPECT_EQ(vmas[4].usage.uss, 0);
361     EXPECT_EQ(vmas[5].usage.uss, 0);
362 
363     EXPECT_EQ(vmas[0].usage.private_clean, 0);
364     EXPECT_EQ(vmas[1].usage.private_clean, 0);
365     EXPECT_EQ(vmas[2].usage.private_clean, 0);
366     EXPECT_EQ(vmas[3].usage.private_clean, 260);
367     EXPECT_EQ(vmas[4].usage.private_clean, 0);
368     EXPECT_EQ(vmas[5].usage.private_clean, 0);
369 
370     EXPECT_EQ(vmas[0].usage.private_dirty, 0);
371     EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
372     EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
373     EXPECT_EQ(vmas[3].usage.private_dirty, 0);
374     EXPECT_EQ(vmas[4].usage.private_dirty, 0);
375     EXPECT_EQ(vmas[5].usage.private_dirty, 0);
376 
377     EXPECT_EQ(vmas[0].usage.shared_clean, 0);
378     EXPECT_EQ(vmas[1].usage.shared_clean, 80);
379     EXPECT_EQ(vmas[2].usage.shared_clean, 0);
380     EXPECT_EQ(vmas[3].usage.shared_clean, 0);
381     EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
382     EXPECT_EQ(vmas[5].usage.shared_clean, 0);
383 
384     EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
385     EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
386     EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
387     EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
388     EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
389     EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
390 
391     EXPECT_EQ(vmas[0].usage.swap, 0);
392     EXPECT_EQ(vmas[1].usage.swap, 0);
393     EXPECT_EQ(vmas[2].usage.swap, 0);
394     EXPECT_EQ(vmas[3].usage.swap, 0);
395     EXPECT_EQ(vmas[4].usage.swap, 0);
396     EXPECT_EQ(vmas[5].usage.swap, 0);
397 
398     EXPECT_EQ(vmas[0].usage.swap_pss, 0);
399     EXPECT_EQ(vmas[1].usage.swap_pss, 0);
400     EXPECT_EQ(vmas[2].usage.swap_pss, 0);
401     EXPECT_EQ(vmas[3].usage.swap_pss, 0);
402     EXPECT_EQ(vmas[4].usage.swap_pss, 0);
403     EXPECT_EQ(vmas[5].usage.swap_pss, 0);
404 }
405 
TEST(SysMemInfo,TestSysMemInfoFile)406 TEST(SysMemInfo, TestSysMemInfoFile) {
407     std::string meminfo = R"meminfo(MemTotal:        3019740 kB
408 MemFree:         1809728 kB
409 MemAvailable:    2546560 kB
410 Buffers:           54736 kB
411 Cached:           776052 kB
412 SwapCached:            0 kB
413 Active:           445856 kB
414 Inactive:         459092 kB
415 Active(anon):      78492 kB
416 Inactive(anon):     2240 kB
417 Active(file):     367364 kB
418 Inactive(file):   456852 kB
419 Unevictable:        3096 kB
420 Mlocked:            3096 kB
421 SwapTotal:         32768 kB
422 SwapFree:           4096 kB
423 Dirty:                32 kB
424 Writeback:             0 kB
425 AnonPages:         74988 kB
426 Mapped:            62624 kB
427 Shmem:              4020 kB
428 Slab:              86464 kB
429 SReclaimable:      44432 kB
430 SUnreclaim:        42032 kB
431 KernelStack:        4880 kB
432 PageTables:         2900 kB
433 NFS_Unstable:          0 kB
434 Bounce:                0 kB
435 WritebackTmp:          0 kB
436 CommitLimit:     1509868 kB
437 Committed_AS:      80296 kB
438 VmallocTotal:   263061440 kB
439 VmallocUsed:       65536 kB
440 VmallocChunk:          0 kB
441 AnonHugePages:      6144 kB
442 ShmemHugePages:        0 kB
443 ShmemPmdMapped:        0 kB
444 CmaTotal:         131072 kB
445 CmaFree:          130380 kB
446 HugePages_Total:       0
447 HugePages_Free:        0
448 HugePages_Rsvd:        0
449 HugePages_Surp:        0
450 Hugepagesize:       2048 kB)meminfo";
451 
452     TemporaryFile tf;
453     ASSERT_TRUE(tf.fd != -1);
454     ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
455 
456     SysMemInfo mi;
457     ASSERT_TRUE(mi.ReadMemInfo(tf.path));
458     EXPECT_EQ(mi.mem_total_kb(), 3019740);
459     EXPECT_EQ(mi.mem_free_kb(), 1809728);
460     EXPECT_EQ(mi.mem_buffers_kb(), 54736);
461     EXPECT_EQ(mi.mem_cached_kb(), 776052);
462     EXPECT_EQ(mi.mem_shmem_kb(), 4020);
463     EXPECT_EQ(mi.mem_slab_kb(), 86464);
464     EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432);
465     EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032);
466     EXPECT_EQ(mi.mem_swap_kb(), 32768);
467     EXPECT_EQ(mi.mem_swap_free_kb(), 4096);
468     EXPECT_EQ(mi.mem_mapped_kb(), 62624);
469     EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536);
470     EXPECT_EQ(mi.mem_page_tables_kb(), 2900);
471     EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880);
472 }
473 
TEST(SysMemInfo,TestEmptyFile)474 TEST(SysMemInfo, TestEmptyFile) {
475     TemporaryFile tf;
476     std::string empty_string = "";
477     ASSERT_TRUE(tf.fd != -1);
478     ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd));
479 
480     SysMemInfo mi;
481     EXPECT_TRUE(mi.ReadMemInfo(tf.path));
482     EXPECT_EQ(mi.mem_total_kb(), 0);
483 }
484 
TEST(SysMemInfo,TestZramTotal)485 TEST(SysMemInfo, TestZramTotal) {
486     std::string exec_dir = ::android::base::GetExecutableDirectory();
487 
488     SysMemInfo mi;
489     std::string zram_mmstat_dir = exec_dir + "/testdata1/";
490     EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir), 30504);
491 
492     std::string zram_memused_dir = exec_dir + "/testdata2/";
493     EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir), 30504);
494 }
495 
496 enum {
497     MEMINFO_TOTAL,
498     MEMINFO_FREE,
499     MEMINFO_BUFFERS,
500     MEMINFO_CACHED,
501     MEMINFO_SHMEM,
502     MEMINFO_SLAB,
503     MEMINFO_SLAB_RECLAIMABLE,
504     MEMINFO_SLAB_UNRECLAIMABLE,
505     MEMINFO_SWAP_TOTAL,
506     MEMINFO_SWAP_FREE,
507     MEMINFO_ZRAM_TOTAL,
508     MEMINFO_MAPPED,
509     MEMINFO_VMALLOC_USED,
510     MEMINFO_PAGE_TABLES,
511     MEMINFO_KERNEL_STACK,
512     MEMINFO_COUNT
513 };
514 
TEST(SysMemInfo,TestZramWithTags)515 TEST(SysMemInfo, TestZramWithTags) {
516     std::string meminfo = R"meminfo(MemTotal:        3019740 kB
517 MemFree:         1809728 kB
518 MemAvailable:    2546560 kB
519 Buffers:           54736 kB
520 Cached:           776052 kB
521 SwapCached:            0 kB
522 Active:           445856 kB
523 Inactive:         459092 kB
524 Active(anon):      78492 kB
525 Inactive(anon):     2240 kB
526 Active(file):     367364 kB
527 Inactive(file):   456852 kB
528 Unevictable:        3096 kB
529 Mlocked:            3096 kB
530 SwapTotal:         32768 kB
531 SwapFree:           4096 kB
532 Dirty:                32 kB
533 Writeback:             0 kB
534 AnonPages:         74988 kB
535 Mapped:            62624 kB
536 Shmem:              4020 kB
537 Slab:              86464 kB
538 SReclaimable:      44432 kB
539 SUnreclaim:        42032 kB
540 KernelStack:        4880 kB
541 PageTables:         2900 kB
542 NFS_Unstable:          0 kB
543 Bounce:                0 kB
544 WritebackTmp:          0 kB
545 CommitLimit:     1509868 kB
546 Committed_AS:      80296 kB
547 VmallocTotal:   263061440 kB
548 VmallocUsed:       65536 kB
549 VmallocChunk:          0 kB
550 AnonHugePages:      6144 kB
551 ShmemHugePages:        0 kB
552 ShmemPmdMapped:        0 kB
553 CmaTotal:         131072 kB
554 CmaFree:          130380 kB
555 HugePages_Total:       0
556 HugePages_Free:        0
557 HugePages_Rsvd:        0
558 HugePages_Surp:        0
559 Hugepagesize:       2048 kB)meminfo";
560 
561     TemporaryFile tf;
562     ASSERT_TRUE(tf.fd != -1);
563     ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
564     std::string file = std::string(tf.path);
565     std::vector<uint64_t> mem(MEMINFO_COUNT);
566     std::vector<std::string> tags(SysMemInfo::kDefaultSysMemInfoTags);
567     auto it = tags.begin();
568     tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:");
569     SysMemInfo mi;
570 
571     // Read system memory info
572     EXPECT_TRUE(mi.ReadMemInfo(tags, &mem, file));
573 
574     EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740);
575     EXPECT_EQ(mem[MEMINFO_FREE], 1809728);
576     EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736);
577     EXPECT_EQ(mem[MEMINFO_CACHED], 776052);
578     EXPECT_EQ(mem[MEMINFO_SHMEM], 4020);
579     EXPECT_EQ(mem[MEMINFO_SLAB], 86464);
580     EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432);
581     EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032);
582     EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768);
583     EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096);
584     EXPECT_EQ(mem[MEMINFO_MAPPED], 62624);
585     EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536);
586     EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900);
587     EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880);
588 }
589 
TEST(SysMemInfo,TestVmallocInfoNoMemory)590 TEST(SysMemInfo, TestVmallocInfoNoMemory) {
591     std::string vmallocinfo =
592             R"vmallocinfo(0x0000000000000000-0x0000000000000000   69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
593 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
594 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
595 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo";
596 
597     TemporaryFile tf;
598     ASSERT_TRUE(tf.fd != -1);
599     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
600     std::string file = std::string(tf.path);
601 
602     EXPECT_EQ(ReadVmallocInfo(file), 0);
603 }
604 
TEST(SysMemInfo,TestVmallocInfoKernel)605 TEST(SysMemInfo, TestVmallocInfoKernel) {
606     std::string vmallocinfo =
607             R"vmallocinfo(0x0000000000000000-0x0000000000000000    8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo";
608 
609     TemporaryFile tf;
610     ASSERT_TRUE(tf.fd != -1);
611     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
612     std::string file = std::string(tf.path);
613 
614     EXPECT_EQ(ReadVmallocInfo(file), getpagesize());
615 }
616 
TEST(SysMemInfo,TestVmallocInfoModule)617 TEST(SysMemInfo, TestVmallocInfoModule) {
618     std::string vmallocinfo =
619             R"vmallocinfo(0x0000000000000000-0x0000000000000000   28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
620 
621     TemporaryFile tf;
622     ASSERT_TRUE(tf.fd != -1);
623     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
624     std::string file = std::string(tf.path);
625 
626     EXPECT_EQ(ReadVmallocInfo(file), 6 * getpagesize());
627 }
628 
TEST(SysMemInfo,TestVmallocInfoAll)629 TEST(SysMemInfo, TestVmallocInfoAll) {
630     std::string vmallocinfo =
631             R"vmallocinfo(0x0000000000000000-0x0000000000000000   69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
632 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
633 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
634 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap
635 0x0000000000000000-0x0000000000000000    8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc
636 0x0000000000000000-0x0000000000000000   28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
637 
638     TemporaryFile tf;
639     ASSERT_TRUE(tf.fd != -1);
640     ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
641     std::string file = std::string(tf.path);
642 
643     EXPECT_EQ(ReadVmallocInfo(file), 7 * getpagesize());
644 }
645 
main(int argc,char ** argv)646 int main(int argc, char** argv) {
647     ::testing::InitGoogleTest(&argc, argv);
648     ::android::base::InitLogging(argv, android::base::StderrLogger);
649     pid = getpid();
650     return RUN_ALL_TESTS();
651 }
652