blob: 4c2be91861c257e93d422645f1f7e4beb0b3cd54 [file] [log] [blame]
Sandeep Patil54d87212018-08-29 17:10:47 -07001/*
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
Christopher Ferris504d2cc2019-07-12 14:25:48 -070017#include <sys/mman.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070018#include <sys/types.h>
19#include <sys/wait.h>
20#include <unistd.h>
21
22#include <gtest/gtest.h>
23
24#include <string>
25#include <vector>
26
27#include <meminfo/pageacct.h>
28#include <meminfo/procmeminfo.h>
29#include <meminfo/sysmeminfo.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070030
31#include <android-base/file.h>
32#include <android-base/logging.h>
Sandeep Patilc24f1e32018-12-29 14:34:20 -080033#include <android-base/stringprintf.h>
Sandeep Patil54d87212018-08-29 17:10:47 -070034
35using namespace std;
36using namespace android::meminfo;
37
38pid_t pid = -1;
39
Sandeep Patildfa00a72019-01-28 15:05:27 -080040TEST(ProcMemInfo, TestWorkingTestReset) {
Sandeep Patil54d87212018-08-29 17:10:47 -070041 // Expect reset to succeed
Sandeep Patilf1291992018-11-19 15:25:18 -080042 EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid));
Sandeep Patil54d87212018-08-29 17:10:47 -070043}
44
Sandeep Patildfa00a72019-01-28 15:05:27 -080045TEST(ProcMemInfo, UsageEmpty) {
Sandeep Patilc6497eb2018-11-20 09:31:36 -080046 // If we created the object for getting working set,
47 // the usage must be empty
48 ProcMemInfo proc_mem(pid, true);
49 const MemUsage& usage = proc_mem.Usage();
50 EXPECT_EQ(usage.rss, 0);
51 EXPECT_EQ(usage.vss, 0);
52 EXPECT_EQ(usage.pss, 0);
53 EXPECT_EQ(usage.uss, 0);
54 EXPECT_EQ(usage.swap, 0);
55}
56
Sandeep Patildfa00a72019-01-28 15:05:27 -080057TEST(ProcMemInfo, MapsNotEmpty) {
58 // Make sure the process maps are never empty
59 ProcMemInfo proc_mem(pid);
60 const std::vector<Vma>& maps = proc_mem.Maps();
61 EXPECT_FALSE(maps.empty());
62}
63
Christopher Ferris504d2cc2019-07-12 14:25:48 -070064TEST(ProcMemInfo, MapsUsageNotEmpty) {
65 ProcMemInfo proc_mem(pid);
66 const std::vector<Vma>& maps = proc_mem.Maps();
67 EXPECT_FALSE(maps.empty());
68 uint64_t total_pss = 0;
69 uint64_t total_rss = 0;
70 uint64_t total_uss = 0;
71 for (auto& map : maps) {
72 ASSERT_NE(0, map.usage.vss);
73 total_rss += map.usage.rss;
74 total_pss += map.usage.pss;
75 total_uss += map.usage.uss;
76 }
77
78 // Crude check that stats are actually being read.
79 EXPECT_NE(0, total_rss) << "RSS zero for all maps, that is not possible.";
80 EXPECT_NE(0, total_pss) << "PSS zero for all maps, that is not possible.";
81 EXPECT_NE(0, total_uss) << "USS zero for all maps, that is not possible.";
82}
83
84TEST(ProcMemInfo, MapsUsageEmpty) {
85 ProcMemInfo proc_mem(pid);
86 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
87 EXPECT_FALSE(maps.empty());
88 // Verify that all usage stats are zero in every map.
89 for (auto& map : maps) {
90 ASSERT_EQ(0, map.usage.vss);
91 ASSERT_EQ(0, map.usage.rss);
92 ASSERT_EQ(0, map.usage.pss);
93 ASSERT_EQ(0, map.usage.uss);
94 ASSERT_EQ(0, map.usage.swap);
95 ASSERT_EQ(0, map.usage.swap_pss);
96 ASSERT_EQ(0, map.usage.private_clean);
97 ASSERT_EQ(0, map.usage.private_dirty);
98 ASSERT_EQ(0, map.usage.shared_clean);
99 ASSERT_EQ(0, map.usage.shared_dirty);
100 }
101}
102
103TEST(ProcMemInfo, PageMapPresent) {
104 static constexpr size_t kNumPages = 20;
105 size_t pagesize = getpagesize();
106 void* ptr = mmap(nullptr, pagesize * (kNumPages + 2), PROT_READ | PROT_WRITE,
107 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
108 ASSERT_NE(MAP_FAILED, ptr);
109
110 // Unmap the first page and the last page so that we guarantee this
111 // map is in a map by itself.
112 ASSERT_EQ(0, munmap(ptr, pagesize));
113 uintptr_t addr = reinterpret_cast<uintptr_t>(ptr) + pagesize;
114 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr + kNumPages * pagesize), pagesize));
115
116 ProcMemInfo proc_mem(getpid());
117 const std::vector<Vma>& maps = proc_mem.MapsWithoutUsageStats();
118 ASSERT_FALSE(maps.empty());
119
120 // Find the vma associated with our previously created map.
121 const Vma* test_vma = nullptr;
122 for (const Vma& vma : maps) {
123 if (vma.start == addr) {
124 test_vma = &vma;
125 break;
126 }
127 }
128 ASSERT_TRUE(test_vma != nullptr) << "Cannot find test map.";
129
130 // Verify that none of the pages are listed as present.
131 std::vector<uint64_t> pagemap;
132 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
133 ASSERT_EQ(kNumPages, pagemap.size());
134 for (size_t i = 0; i < pagemap.size(); i++) {
135 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
136 << "Page " << i << " is present and it should not be.";
137 }
138
139 // Make some of the pages present and verify that we see them
140 // as present.
141 uint8_t* data = reinterpret_cast<uint8_t*>(addr);
142 data[0] = 1;
143 data[pagesize * 5] = 1;
144 data[pagesize * 11] = 1;
145
146 ASSERT_TRUE(proc_mem.PageMap(*test_vma, &pagemap));
147 ASSERT_EQ(kNumPages, pagemap.size());
148 for (size_t i = 0; i < pagemap.size(); i++) {
149 if (i == 0 || i == 5 || i == 11) {
150 EXPECT_TRUE(android::meminfo::page_present(pagemap[i]))
151 << "Page " << i << " is not present and it should be.";
152 } else {
153 EXPECT_FALSE(android::meminfo::page_present(pagemap[i]))
154 << "Page " << i << " is present and it should not be.";
155 }
156 }
157
158 ASSERT_EQ(0, munmap(reinterpret_cast<void*>(addr), kNumPages * pagesize));
159}
160
Sandeep Patildfa00a72019-01-28 15:05:27 -0800161TEST(ProcMemInfo, WssEmpty) {
Sandeep Patilc6497eb2018-11-20 09:31:36 -0800162 // If we created the object for getting usage,
163 // the working set must be empty
164 ProcMemInfo proc_mem(pid, false);
165 const MemUsage& wss = proc_mem.Wss();
166 EXPECT_EQ(wss.rss, 0);
167 EXPECT_EQ(wss.vss, 0);
168 EXPECT_EQ(wss.pss, 0);
169 EXPECT_EQ(wss.uss, 0);
170 EXPECT_EQ(wss.swap, 0);
171}
172
Sandeep Patildfa00a72019-01-28 15:05:27 -0800173TEST(ProcMemInfo, SwapOffsetsEmpty) {
Sandeep Patilc6497eb2018-11-20 09:31:36 -0800174 // If we created the object for getting working set,
175 // the swap offsets must be empty
176 ProcMemInfo proc_mem(pid, true);
177 const std::vector<uint16_t>& swap_offsets = proc_mem.SwapOffsets();
178 EXPECT_EQ(swap_offsets.size(), 0);
179}
180
Sandeep Patildfa00a72019-01-28 15:05:27 -0800181TEST(ProcMemInfo, IsSmapsSupportedTest) {
182 // Get any pid and check if /proc/<pid>/smaps_rollup exists using the API.
183 // The API must return the appropriate value regardless of the after it succeeds
184 // once.
Sandeep Patildfd34be2019-01-13 17:39:08 -0800185 std::string path = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid);
186 bool supported = IsSmapsRollupSupported(pid);
187 EXPECT_EQ(!access(path.c_str(), F_OK | R_OK), supported);
188 // Second call must return what the first one returned regardless of the pid parameter.
189 // So, deliberately pass invalid pid.
190 EXPECT_EQ(supported, IsSmapsRollupSupported(-1));
191}
192
Sandeep Patildfa00a72019-01-28 15:05:27 -0800193TEST(ProcMemInfo, SmapsOrRollupTest) {
194 // Make sure we can parse 'smaps_rollup' correctly
Sandeep Patilfa2d8d52018-12-29 21:05:38 -0800195 std::string rollup =
196 R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0 [rollup]
197Rss: 331908 kB
198Pss: 202052 kB
199Shared_Clean: 158492 kB
200Shared_Dirty: 18928 kB
201Private_Clean: 90472 kB
202Private_Dirty: 64016 kB
203Referenced: 318700 kB
204Anonymous: 81984 kB
205AnonHugePages: 0 kB
206Shared_Hugetlb: 0 kB
207Private_Hugetlb: 0 kB
208Swap: 5344 kB
209SwapPss: 442 kB
210Locked: 1523537 kB)rollup";
211
212 TemporaryFile tf;
213 ASSERT_TRUE(tf.fd != -1);
214 ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd));
215
216 MemUsage stats;
217 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
218 EXPECT_EQ(stats.rss, 331908);
219 EXPECT_EQ(stats.pss, 202052);
220 EXPECT_EQ(stats.uss, 154488);
221 EXPECT_EQ(stats.private_clean, 90472);
222 EXPECT_EQ(stats.private_dirty, 64016);
223 EXPECT_EQ(stats.swap_pss, 442);
224}
225
Sandeep Patildfa00a72019-01-28 15:05:27 -0800226TEST(ProcMemInfo, SmapsOrRollupSmapsTest) {
227 // Make sure /proc/<pid>/smaps is parsed correctly
Sandeep Patilfa2d8d52018-12-29 21:05:38 -0800228 std::string smaps =
229 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
230Name: [anon:dalvik-main space (region space)]
231Size: 8448 kB
232KernelPageSize: 4 kB
233MMUPageSize: 4 kB
234Rss: 2652 kB
235Pss: 2652 kB
236Shared_Clean: 840 kB
237Shared_Dirty: 40 kB
238Private_Clean: 84 kB
239Private_Dirty: 2652 kB
240Referenced: 2652 kB
241Anonymous: 2652 kB
242AnonHugePages: 0 kB
243ShmemPmdMapped: 0 kB
244Shared_Hugetlb: 0 kB
245Private_Hugetlb: 0 kB
246Swap: 102 kB
247SwapPss: 70 kB
248Locked: 2652 kB
249VmFlags: rd wr mr mw me ac
250)smaps";
251
252 TemporaryFile tf;
253 ASSERT_TRUE(tf.fd != -1);
254 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
255
256 MemUsage stats;
257 ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true);
258 EXPECT_EQ(stats.rss, 2652);
259 EXPECT_EQ(stats.pss, 2652);
260 EXPECT_EQ(stats.uss, 2736);
261 EXPECT_EQ(stats.private_clean, 84);
262 EXPECT_EQ(stats.private_dirty, 2652);
263 EXPECT_EQ(stats.swap_pss, 70);
264}
265
Sandeep Patildfa00a72019-01-28 15:05:27 -0800266TEST(ProcMemInfo, SmapsOrRollupPssRollupTest) {
267 // Make sure /proc/<pid>/smaps is parsed correctly
268 // to get the PSS
Sandeep Patil8871e7e2019-01-13 16:47:20 -0800269 std::string smaps =
270 R"smaps(12c00000-13440000 rw-p 00000000 00:00 0 [anon:dalvik-main space (region space)]
271Name: [anon:dalvik-main space (region space)]
272Size: 8448 kB
273KernelPageSize: 4 kB
274MMUPageSize: 4 kB
275Rss: 2652 kB
276Pss: 2652 kB
277Shared_Clean: 840 kB
278Shared_Dirty: 40 kB
279Private_Clean: 84 kB
280Private_Dirty: 2652 kB
281Referenced: 2652 kB
282Anonymous: 2652 kB
283AnonHugePages: 0 kB
284ShmemPmdMapped: 0 kB
285Shared_Hugetlb: 0 kB
286Private_Hugetlb: 0 kB
287Swap: 102 kB
288SwapPss: 70 kB
289Locked: 2652 kB
290VmFlags: rd wr mr mw me ac
291)smaps";
292
293 TemporaryFile tf;
294 ASSERT_TRUE(tf.fd != -1);
295 ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd));
296
297 uint64_t pss;
298 ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true);
299 EXPECT_EQ(pss, 2652);
300}
301
Sandeep Patildfa00a72019-01-28 15:05:27 -0800302TEST(ProcMemInfo, SmapsOrRollupPssSmapsTest) {
303 // Correctly parse smaps file to gather pss
Sandeep Patil8871e7e2019-01-13 16:47:20 -0800304 std::string exec_dir = ::android::base::GetExecutableDirectory();
305 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
306
307 uint64_t pss;
308 ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true);
309 EXPECT_EQ(pss, 19119);
310}
311
Sandeep Patildfa00a72019-01-28 15:05:27 -0800312TEST(ProcMemInfo, ForEachVmaFromFileTest) {
313 // Parse smaps file correctly to make callbacks for each virtual memory area (vma)
Sandeep Patil82a48b12019-01-01 16:04:04 -0800314 std::string exec_dir = ::android::base::GetExecutableDirectory();
315 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
316 ProcMemInfo proc_mem(pid);
317
318 std::vector<Vma> vmas;
319 auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); };
320 ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas));
321
Sandeep Patil002f02e2019-01-13 19:39:46 -0800322 // We should get a total of 6 vmas
323 ASSERT_EQ(vmas.size(), 6);
324
Sandeep Patil82a48b12019-01-01 16:04:04 -0800325 // 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
Sandeep Patildfa00a72019-01-28 15:05:27 -0800406TEST(ProcMemInfo, SmapsReturnTest) {
407 // Make sure Smaps() is never empty for any process
Sandeep Patil82a48b12019-01-01 16:04:04 -0800408 ProcMemInfo proc_mem(pid);
409 auto vmas = proc_mem.Smaps();
410 EXPECT_FALSE(vmas.empty());
411}
412
Sandeep Patildfa00a72019-01-28 15:05:27 -0800413TEST(ProcMemInfo, SmapsTest) {
Sandeep Patil82a48b12019-01-01 16:04:04 -0800414 std::string exec_dir = ::android::base::GetExecutableDirectory();
415 std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str());
416 ProcMemInfo proc_mem(pid);
417 auto vmas = proc_mem.Smaps(path);
418
419 ASSERT_FALSE(vmas.empty());
Sandeep Patil002f02e2019-01-13 19:39:46 -0800420 // We should get a total of 6 vmas
421 ASSERT_EQ(vmas.size(), 6);
Sandeep Patil82a48b12019-01-01 16:04:04 -0800422
423 // Expect values to be equal to what we have in testdata1/smaps_short
424 // Check for sizes first
425 ASSERT_EQ(vmas[0].usage.vss, 32768);
426 EXPECT_EQ(vmas[1].usage.vss, 11204);
427 EXPECT_EQ(vmas[2].usage.vss, 16896);
428 EXPECT_EQ(vmas[3].usage.vss, 260);
429 EXPECT_EQ(vmas[4].usage.vss, 6060);
430 EXPECT_EQ(vmas[5].usage.vss, 4);
431
432 // Check for names
433 EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]");
434 EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art");
435 EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]");
436 EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex");
437 EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so");
438 EXPECT_EQ(vmas[5].name, "[vsyscall]");
439
440 EXPECT_EQ(vmas[0].usage.rss, 2048);
441 EXPECT_EQ(vmas[1].usage.rss, 11188);
442 EXPECT_EQ(vmas[2].usage.rss, 15272);
443 EXPECT_EQ(vmas[3].usage.rss, 260);
444 EXPECT_EQ(vmas[4].usage.rss, 4132);
445 EXPECT_EQ(vmas[5].usage.rss, 0);
446
447 EXPECT_EQ(vmas[0].usage.pss, 113);
448 EXPECT_EQ(vmas[1].usage.pss, 2200);
449 EXPECT_EQ(vmas[2].usage.pss, 15272);
450 EXPECT_EQ(vmas[3].usage.pss, 260);
451 EXPECT_EQ(vmas[4].usage.pss, 1274);
452 EXPECT_EQ(vmas[5].usage.pss, 0);
453
454 EXPECT_EQ(vmas[0].usage.uss, 0);
455 EXPECT_EQ(vmas[1].usage.uss, 1660);
456 EXPECT_EQ(vmas[2].usage.uss, 15272);
457 EXPECT_EQ(vmas[3].usage.uss, 260);
458 EXPECT_EQ(vmas[4].usage.uss, 0);
459 EXPECT_EQ(vmas[5].usage.uss, 0);
460
461 EXPECT_EQ(vmas[0].usage.private_clean, 0);
462 EXPECT_EQ(vmas[1].usage.private_clean, 0);
463 EXPECT_EQ(vmas[2].usage.private_clean, 0);
464 EXPECT_EQ(vmas[3].usage.private_clean, 260);
465 EXPECT_EQ(vmas[4].usage.private_clean, 0);
466 EXPECT_EQ(vmas[5].usage.private_clean, 0);
467
468 EXPECT_EQ(vmas[0].usage.private_dirty, 0);
469 EXPECT_EQ(vmas[1].usage.private_dirty, 1660);
470 EXPECT_EQ(vmas[2].usage.private_dirty, 15272);
471 EXPECT_EQ(vmas[3].usage.private_dirty, 0);
472 EXPECT_EQ(vmas[4].usage.private_dirty, 0);
473 EXPECT_EQ(vmas[5].usage.private_dirty, 0);
474
475 EXPECT_EQ(vmas[0].usage.shared_clean, 0);
476 EXPECT_EQ(vmas[1].usage.shared_clean, 80);
477 EXPECT_EQ(vmas[2].usage.shared_clean, 0);
478 EXPECT_EQ(vmas[3].usage.shared_clean, 0);
479 EXPECT_EQ(vmas[4].usage.shared_clean, 4132);
480 EXPECT_EQ(vmas[5].usage.shared_clean, 0);
481
482 EXPECT_EQ(vmas[0].usage.shared_dirty, 2048);
483 EXPECT_EQ(vmas[1].usage.shared_dirty, 9448);
484 EXPECT_EQ(vmas[2].usage.shared_dirty, 0);
485 EXPECT_EQ(vmas[3].usage.shared_dirty, 0);
486 EXPECT_EQ(vmas[4].usage.shared_dirty, 0);
487 EXPECT_EQ(vmas[5].usage.shared_dirty, 0);
488
489 EXPECT_EQ(vmas[0].usage.swap, 0);
490 EXPECT_EQ(vmas[1].usage.swap, 0);
491 EXPECT_EQ(vmas[2].usage.swap, 0);
492 EXPECT_EQ(vmas[3].usage.swap, 0);
493 EXPECT_EQ(vmas[4].usage.swap, 0);
494 EXPECT_EQ(vmas[5].usage.swap, 0);
495
496 EXPECT_EQ(vmas[0].usage.swap_pss, 0);
497 EXPECT_EQ(vmas[1].usage.swap_pss, 0);
498 EXPECT_EQ(vmas[2].usage.swap_pss, 0);
499 EXPECT_EQ(vmas[3].usage.swap_pss, 0);
500 EXPECT_EQ(vmas[4].usage.swap_pss, 0);
501 EXPECT_EQ(vmas[5].usage.swap_pss, 0);
502}
503
Sandeep Patildfa00a72019-01-28 15:05:27 -0800504TEST(SysMemInfo, TestSysMemInfoFile) {
Sandeep Patil54d87212018-08-29 17:10:47 -0700505 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
506MemFree: 1809728 kB
507MemAvailable: 2546560 kB
508Buffers: 54736 kB
509Cached: 776052 kB
510SwapCached: 0 kB
511Active: 445856 kB
512Inactive: 459092 kB
513Active(anon): 78492 kB
514Inactive(anon): 2240 kB
515Active(file): 367364 kB
516Inactive(file): 456852 kB
517Unevictable: 3096 kB
518Mlocked: 3096 kB
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800519SwapTotal: 32768 kB
520SwapFree: 4096 kB
Sandeep Patil54d87212018-08-29 17:10:47 -0700521Dirty: 32 kB
522Writeback: 0 kB
523AnonPages: 74988 kB
524Mapped: 62624 kB
525Shmem: 4020 kB
526Slab: 86464 kB
527SReclaimable: 44432 kB
528SUnreclaim: 42032 kB
529KernelStack: 4880 kB
530PageTables: 2900 kB
531NFS_Unstable: 0 kB
532Bounce: 0 kB
533WritebackTmp: 0 kB
534CommitLimit: 1509868 kB
535Committed_AS: 80296 kB
536VmallocTotal: 263061440 kB
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800537VmallocUsed: 65536 kB
Sandeep Patil54d87212018-08-29 17:10:47 -0700538VmallocChunk: 0 kB
539AnonHugePages: 6144 kB
540ShmemHugePages: 0 kB
541ShmemPmdMapped: 0 kB
542CmaTotal: 131072 kB
543CmaFree: 130380 kB
544HugePages_Total: 0
545HugePages_Free: 0
546HugePages_Rsvd: 0
547HugePages_Surp: 0
548Hugepagesize: 2048 kB)meminfo";
549
550 TemporaryFile tf;
551 ASSERT_TRUE(tf.fd != -1);
552 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
553
554 SysMemInfo mi;
555 ASSERT_TRUE(mi.ReadMemInfo(tf.path));
556 EXPECT_EQ(mi.mem_total_kb(), 3019740);
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800557 EXPECT_EQ(mi.mem_free_kb(), 1809728);
558 EXPECT_EQ(mi.mem_buffers_kb(), 54736);
559 EXPECT_EQ(mi.mem_cached_kb(), 776052);
560 EXPECT_EQ(mi.mem_shmem_kb(), 4020);
561 EXPECT_EQ(mi.mem_slab_kb(), 86464);
562 EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432);
563 EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032);
564 EXPECT_EQ(mi.mem_swap_kb(), 32768);
565 EXPECT_EQ(mi.mem_swap_free_kb(), 4096);
566 EXPECT_EQ(mi.mem_mapped_kb(), 62624);
567 EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536);
Sandeep Patil54d87212018-08-29 17:10:47 -0700568 EXPECT_EQ(mi.mem_page_tables_kb(), 2900);
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800569 EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880);
Sandeep Patil54d87212018-08-29 17:10:47 -0700570}
571
Sandeep Patildfa00a72019-01-28 15:05:27 -0800572TEST(SysMemInfo, TestEmptyFile) {
Sandeep Patil54d87212018-08-29 17:10:47 -0700573 TemporaryFile tf;
574 std::string empty_string = "";
575 ASSERT_TRUE(tf.fd != -1);
576 ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd));
577
578 SysMemInfo mi;
579 EXPECT_TRUE(mi.ReadMemInfo(tf.path));
580 EXPECT_EQ(mi.mem_total_kb(), 0);
581}
582
Sandeep Patildfa00a72019-01-28 15:05:27 -0800583TEST(SysMemInfo, TestZramTotal) {
Sandeep Patil70fa72d2018-11-09 19:18:29 -0800584 std::string exec_dir = ::android::base::GetExecutableDirectory();
585
586 SysMemInfo mi;
587 std::string zram_mmstat_dir = exec_dir + "/testdata1/";
588 EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir), 30504);
589
590 std::string zram_memused_dir = exec_dir + "/testdata2/";
591 EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir), 30504);
592}
593
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800594enum {
595 MEMINFO_TOTAL,
596 MEMINFO_FREE,
597 MEMINFO_BUFFERS,
598 MEMINFO_CACHED,
599 MEMINFO_SHMEM,
600 MEMINFO_SLAB,
601 MEMINFO_SLAB_RECLAIMABLE,
602 MEMINFO_SLAB_UNRECLAIMABLE,
603 MEMINFO_SWAP_TOTAL,
604 MEMINFO_SWAP_FREE,
605 MEMINFO_ZRAM_TOTAL,
606 MEMINFO_MAPPED,
607 MEMINFO_VMALLOC_USED,
608 MEMINFO_PAGE_TABLES,
609 MEMINFO_KERNEL_STACK,
610 MEMINFO_COUNT
611};
612
Sandeep Patildfa00a72019-01-28 15:05:27 -0800613TEST(SysMemInfo, TestZramWithTags) {
Sandeep Patil2f0b6eb2018-12-11 09:28:38 -0800614 std::string meminfo = R"meminfo(MemTotal: 3019740 kB
615MemFree: 1809728 kB
616MemAvailable: 2546560 kB
617Buffers: 54736 kB
618Cached: 776052 kB
619SwapCached: 0 kB
620Active: 445856 kB
621Inactive: 459092 kB
622Active(anon): 78492 kB
623Inactive(anon): 2240 kB
624Active(file): 367364 kB
625Inactive(file): 456852 kB
626Unevictable: 3096 kB
627Mlocked: 3096 kB
628SwapTotal: 32768 kB
629SwapFree: 4096 kB
630Dirty: 32 kB
631Writeback: 0 kB
632AnonPages: 74988 kB
633Mapped: 62624 kB
634Shmem: 4020 kB
635Slab: 86464 kB
636SReclaimable: 44432 kB
637SUnreclaim: 42032 kB
638KernelStack: 4880 kB
639PageTables: 2900 kB
640NFS_Unstable: 0 kB
641Bounce: 0 kB
642WritebackTmp: 0 kB
643CommitLimit: 1509868 kB
644Committed_AS: 80296 kB
645VmallocTotal: 263061440 kB
646VmallocUsed: 65536 kB
647VmallocChunk: 0 kB
648AnonHugePages: 6144 kB
649ShmemHugePages: 0 kB
650ShmemPmdMapped: 0 kB
651CmaTotal: 131072 kB
652CmaFree: 130380 kB
653HugePages_Total: 0
654HugePages_Free: 0
655HugePages_Rsvd: 0
656HugePages_Surp: 0
657Hugepagesize: 2048 kB)meminfo";
658
659 TemporaryFile tf;
660 ASSERT_TRUE(tf.fd != -1);
661 ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd));
662 std::string file = std::string(tf.path);
663 std::vector<uint64_t> mem(MEMINFO_COUNT);
664 std::vector<std::string> tags(SysMemInfo::kDefaultSysMemInfoTags);
665 auto it = tags.begin();
666 tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:");
667 SysMemInfo mi;
668
669 // Read system memory info
670 EXPECT_TRUE(mi.ReadMemInfo(tags, &mem, file));
671
672 EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740);
673 EXPECT_EQ(mem[MEMINFO_FREE], 1809728);
674 EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736);
675 EXPECT_EQ(mem[MEMINFO_CACHED], 776052);
676 EXPECT_EQ(mem[MEMINFO_SHMEM], 4020);
677 EXPECT_EQ(mem[MEMINFO_SLAB], 86464);
678 EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432);
679 EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032);
680 EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768);
681 EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096);
682 EXPECT_EQ(mem[MEMINFO_MAPPED], 62624);
683 EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536);
684 EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900);
685 EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880);
686}
687
Sandeep Patildfa00a72019-01-28 15:05:27 -0800688TEST(SysMemInfo, TestVmallocInfoNoMemory) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800689 std::string vmallocinfo =
690 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
6910x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
6920x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
6930x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo";
694
695 TemporaryFile tf;
696 ASSERT_TRUE(tf.fd != -1);
697 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
698 std::string file = std::string(tf.path);
699
Sandeep Patile04680d2019-01-19 12:04:18 -0800700 EXPECT_EQ(ReadVmallocInfo(file), 0);
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800701}
702
Sandeep Patildfa00a72019-01-28 15:05:27 -0800703TEST(SysMemInfo, TestVmallocInfoKernel) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800704 std::string vmallocinfo =
705 R"vmallocinfo(0x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo";
706
707 TemporaryFile tf;
708 ASSERT_TRUE(tf.fd != -1);
709 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
710 std::string file = std::string(tf.path);
711
Sandeep Patile04680d2019-01-19 12:04:18 -0800712 EXPECT_EQ(ReadVmallocInfo(file), getpagesize());
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800713}
714
Sandeep Patildfa00a72019-01-28 15:05:27 -0800715TEST(SysMemInfo, TestVmallocInfoModule) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800716 std::string vmallocinfo =
717 R"vmallocinfo(0x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
718
719 TemporaryFile tf;
720 ASSERT_TRUE(tf.fd != -1);
721 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
722 std::string file = std::string(tf.path);
723
Sandeep Patile04680d2019-01-19 12:04:18 -0800724 EXPECT_EQ(ReadVmallocInfo(file), 6 * getpagesize());
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800725}
726
Sandeep Patildfa00a72019-01-28 15:05:27 -0800727TEST(SysMemInfo, TestVmallocInfoAll) {
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800728 std::string vmallocinfo =
729 R"vmallocinfo(0x0000000000000000-0x0000000000000000 69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap
7300x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=b220000 ioremap
7310x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap
7320x0000000000000000-0x0000000000000000 8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap
7330x0000000000000000-0x0000000000000000 8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc
7340x0000000000000000-0x0000000000000000 28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo";
735
736 TemporaryFile tf;
737 ASSERT_TRUE(tf.fd != -1);
738 ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd));
739 std::string file = std::string(tf.path);
740
Sandeep Patile04680d2019-01-19 12:04:18 -0800741 EXPECT_EQ(ReadVmallocInfo(file), 7 * getpagesize());
Sandeep Patilc24f1e32018-12-29 14:34:20 -0800742}
743
Sandeep Patil54d87212018-08-29 17:10:47 -0700744int main(int argc, char** argv) {
745 ::testing::InitGoogleTest(&argc, argv);
Sandeep Patil54d87212018-08-29 17:10:47 -0700746 ::android::base::InitLogging(argv, android::base::StderrLogger);
Sandeep Patildfa00a72019-01-28 15:05:27 -0800747 pid = getpid();
Sandeep Patil54d87212018-08-29 17:10:47 -0700748 return RUN_ALL_TESTS();
749}