| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 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 | #include <pagemap/pagemap.h> | 
|  | 30 |  | 
|  | 31 | #include <android-base/file.h> | 
|  | 32 | #include <android-base/logging.h> | 
| Sandeep Patil | c24f1e3 | 2018-12-29 14:34:20 -0800 | [diff] [blame] | 33 | #include <android-base/stringprintf.h> | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 34 |  | 
|  | 35 | using namespace std; | 
|  | 36 | using namespace android::meminfo; | 
|  | 37 |  | 
|  | 38 | pid_t pid = -1; | 
|  | 39 |  | 
|  | 40 | class ValidateProcMemInfo : public ::testing::Test { | 
|  | 41 | protected: | 
|  | 42 | void SetUp() override { | 
|  | 43 | ASSERT_EQ(0, pm_kernel_create(&ker)); | 
|  | 44 | ASSERT_EQ(0, pm_process_create(ker, pid, &proc)); | 
|  | 45 | proc_mem = new ProcMemInfo(pid); | 
|  | 46 | ASSERT_NE(proc_mem, nullptr); | 
|  | 47 | } | 
|  | 48 |  | 
|  | 49 | void TearDown() override { | 
|  | 50 | delete proc_mem; | 
|  | 51 | pm_process_destroy(proc); | 
|  | 52 | pm_kernel_destroy(ker); | 
|  | 53 | } | 
|  | 54 |  | 
|  | 55 | pm_kernel_t* ker; | 
|  | 56 | pm_process_t* proc; | 
|  | 57 | ProcMemInfo* proc_mem; | 
|  | 58 | }; | 
|  | 59 |  | 
|  | 60 | TEST_F(ValidateProcMemInfo, TestMapsSize) { | 
|  | 61 | const std::vector<Vma>& maps = proc_mem->Maps(); | 
|  | 62 | ASSERT_FALSE(maps.empty()) << "Process " << getpid() << " maps are empty"; | 
|  | 63 | } | 
|  | 64 |  | 
|  | 65 | TEST_F(ValidateProcMemInfo, TestMapsEquality) { | 
|  | 66 | const std::vector<Vma>& maps = proc_mem->Maps(); | 
|  | 67 | ASSERT_EQ(proc->num_maps, maps.size()); | 
|  | 68 |  | 
|  | 69 | for (size_t i = 0; i < maps.size(); ++i) { | 
|  | 70 | EXPECT_EQ(proc->maps[i]->start, maps[i].start); | 
|  | 71 | EXPECT_EQ(proc->maps[i]->end, maps[i].end); | 
|  | 72 | EXPECT_EQ(proc->maps[i]->offset, maps[i].offset); | 
|  | 73 | EXPECT_EQ(std::string(proc->maps[i]->name), maps[i].name); | 
|  | 74 | } | 
|  | 75 | } | 
|  | 76 |  | 
| Sandeep Patil | 2259fdf | 2018-11-09 16:42:45 -0800 | [diff] [blame] | 77 | TEST_F(ValidateProcMemInfo, TestMaps) { | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 78 | const std::vector<Vma>& maps = proc_mem->Maps(); | 
|  | 79 | ASSERT_FALSE(maps.empty()); | 
|  | 80 | ASSERT_EQ(proc->num_maps, maps.size()); | 
|  | 81 |  | 
|  | 82 | pm_memusage_t map_usage, proc_usage; | 
|  | 83 | pm_memusage_zero(&map_usage); | 
|  | 84 | pm_memusage_zero(&proc_usage); | 
|  | 85 | for (size_t i = 0; i < maps.size(); i++) { | 
|  | 86 | ASSERT_EQ(0, pm_map_usage(proc->maps[i], &map_usage)); | 
|  | 87 | EXPECT_EQ(map_usage.vss, maps[i].usage.vss) << "VSS mismatch for map: " << maps[i].name; | 
|  | 88 | EXPECT_EQ(map_usage.rss, maps[i].usage.rss) << "RSS mismatch for map: " << maps[i].name; | 
|  | 89 | EXPECT_EQ(map_usage.pss, maps[i].usage.pss) << "PSS mismatch for map: " << maps[i].name; | 
|  | 90 | EXPECT_EQ(map_usage.uss, maps[i].usage.uss) << "USS mismatch for map: " << maps[i].name; | 
|  | 91 | pm_memusage_add(&proc_usage, &map_usage); | 
|  | 92 | } | 
|  | 93 |  | 
|  | 94 | EXPECT_EQ(proc_usage.vss, proc_mem->Usage().vss); | 
|  | 95 | EXPECT_EQ(proc_usage.rss, proc_mem->Usage().rss); | 
|  | 96 | EXPECT_EQ(proc_usage.pss, proc_mem->Usage().pss); | 
|  | 97 | EXPECT_EQ(proc_usage.uss, proc_mem->Usage().uss); | 
|  | 98 | } | 
|  | 99 |  | 
| Sandeep Patil | 2259fdf | 2018-11-09 16:42:45 -0800 | [diff] [blame] | 100 | TEST_F(ValidateProcMemInfo, TestSwapUsage) { | 
|  | 101 | const std::vector<Vma>& maps = proc_mem->Maps(); | 
|  | 102 | ASSERT_FALSE(maps.empty()); | 
|  | 103 | ASSERT_EQ(proc->num_maps, maps.size()); | 
|  | 104 |  | 
|  | 105 | pm_memusage_t map_usage, proc_usage; | 
|  | 106 | pm_memusage_zero(&map_usage); | 
|  | 107 | pm_memusage_zero(&proc_usage); | 
|  | 108 | for (size_t i = 0; i < maps.size(); i++) { | 
|  | 109 | ASSERT_EQ(0, pm_map_usage(proc->maps[i], &map_usage)); | 
|  | 110 | EXPECT_EQ(map_usage.swap, maps[i].usage.swap) << "SWAP mismatch for map: " << maps[i].name; | 
|  | 111 | pm_memusage_add(&proc_usage, &map_usage); | 
|  | 112 | } | 
|  | 113 |  | 
|  | 114 | EXPECT_EQ(proc_usage.swap, proc_mem->Usage().swap); | 
|  | 115 | } | 
|  | 116 |  | 
|  | 117 | TEST_F(ValidateProcMemInfo, TestSwapOffsets) { | 
|  | 118 | const MemUsage& proc_usage = proc_mem->Usage(); | 
|  | 119 | const std::vector<uint16_t>& swap_offsets = proc_mem->SwapOffsets(); | 
|  | 120 |  | 
|  | 121 | EXPECT_EQ(proc_usage.swap / getpagesize(), swap_offsets.size()); | 
|  | 122 | } | 
|  | 123 |  | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 124 | class ValidateProcMemInfoWss : public ::testing::Test { | 
|  | 125 | protected: | 
|  | 126 | void SetUp() override { | 
|  | 127 | ASSERT_EQ(0, pm_kernel_create(&ker)); | 
|  | 128 | ASSERT_EQ(0, pm_process_create(ker, pid, &proc)); | 
|  | 129 | proc_mem = new ProcMemInfo(pid, true); | 
|  | 130 | ASSERT_NE(proc_mem, nullptr); | 
|  | 131 | } | 
|  | 132 |  | 
|  | 133 | void TearDown() override { | 
|  | 134 | delete proc_mem; | 
|  | 135 | pm_process_destroy(proc); | 
|  | 136 | pm_kernel_destroy(ker); | 
|  | 137 | } | 
|  | 138 |  | 
|  | 139 | pm_kernel_t* ker; | 
|  | 140 | pm_process_t* proc; | 
|  | 141 | ProcMemInfo* proc_mem; | 
|  | 142 | }; | 
|  | 143 |  | 
|  | 144 | TEST_F(ValidateProcMemInfoWss, TestWorkingTestReset) { | 
|  | 145 | // Expect reset to succeed | 
| Sandeep Patil | f129199 | 2018-11-19 15:25:18 -0800 | [diff] [blame] | 146 | EXPECT_TRUE(ProcMemInfo::ResetWorkingSet(pid)); | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 147 | } | 
|  | 148 |  | 
|  | 149 | TEST_F(ValidateProcMemInfoWss, TestWssEquality) { | 
|  | 150 | // Read wss using libpagemap | 
|  | 151 | pm_memusage_t wss_pagemap; | 
|  | 152 | EXPECT_EQ(0, pm_process_workingset(proc, &wss_pagemap, 0)); | 
|  | 153 |  | 
|  | 154 | // Read wss using libmeminfo | 
|  | 155 | MemUsage wss = proc_mem->Wss(); | 
|  | 156 |  | 
|  | 157 | // compare | 
|  | 158 | EXPECT_EQ(wss_pagemap.rss, wss.rss); | 
|  | 159 | EXPECT_EQ(wss_pagemap.pss, wss.pss); | 
|  | 160 | EXPECT_EQ(wss_pagemap.uss, wss.uss); | 
|  | 161 | } | 
|  | 162 |  | 
|  | 163 | class ValidatePageAcct : public ::testing::Test { | 
|  | 164 | protected: | 
|  | 165 | void SetUp() override { | 
|  | 166 | ASSERT_EQ(0, pm_kernel_create(&ker)); | 
|  | 167 | ASSERT_EQ(0, pm_process_create(ker, pid, &proc)); | 
|  | 168 | } | 
|  | 169 |  | 
|  | 170 | void TearDown() override { | 
|  | 171 | pm_process_destroy(proc); | 
|  | 172 | pm_kernel_destroy(ker); | 
|  | 173 | } | 
|  | 174 |  | 
|  | 175 | pm_kernel_t* ker; | 
|  | 176 | pm_process_t* proc; | 
|  | 177 | }; | 
|  | 178 |  | 
|  | 179 | TEST_F(ValidatePageAcct, TestPageFlags) { | 
|  | 180 | PageAcct& pi = PageAcct::Instance(); | 
|  | 181 | pi.InitPageAcct(false); | 
|  | 182 |  | 
|  | 183 | uint64_t* pagemap; | 
|  | 184 | size_t num_pages; | 
|  | 185 | for (size_t i = 0; i < proc->num_maps; i++) { | 
|  | 186 | ASSERT_EQ(0, pm_map_pagemap(proc->maps[i], &pagemap, &num_pages)); | 
|  | 187 | for (size_t j = 0; j < num_pages; j++) { | 
|  | 188 | if (!PM_PAGEMAP_PRESENT(pagemap[j])) continue; | 
|  | 189 |  | 
|  | 190 | uint64_t pfn = PM_PAGEMAP_PFN(pagemap[j]); | 
|  | 191 | uint64_t page_flags_pagemap, page_flags_meminfo; | 
|  | 192 |  | 
|  | 193 | ASSERT_EQ(0, pm_kernel_flags(ker, pfn, &page_flags_pagemap)); | 
|  | 194 | ASSERT_TRUE(pi.PageFlags(pfn, &page_flags_meminfo)); | 
|  | 195 | // check if page flags equal | 
|  | 196 | EXPECT_EQ(page_flags_pagemap, page_flags_meminfo); | 
|  | 197 | } | 
|  | 198 | free(pagemap); | 
|  | 199 | } | 
|  | 200 | } | 
|  | 201 |  | 
|  | 202 | TEST_F(ValidatePageAcct, TestPageCounts) { | 
|  | 203 | PageAcct& pi = PageAcct::Instance(); | 
|  | 204 | pi.InitPageAcct(false); | 
|  | 205 |  | 
|  | 206 | uint64_t* pagemap; | 
|  | 207 | size_t num_pages; | 
|  | 208 | for (size_t i = 0; i < proc->num_maps; i++) { | 
|  | 209 | ASSERT_EQ(0, pm_map_pagemap(proc->maps[i], &pagemap, &num_pages)); | 
|  | 210 | for (size_t j = 0; j < num_pages; j++) { | 
|  | 211 | uint64_t pfn = PM_PAGEMAP_PFN(pagemap[j]); | 
|  | 212 | uint64_t map_count_pagemap, map_count_meminfo; | 
|  | 213 |  | 
|  | 214 | ASSERT_EQ(0, pm_kernel_count(ker, pfn, &map_count_pagemap)); | 
|  | 215 | ASSERT_TRUE(pi.PageMapCount(pfn, &map_count_meminfo)); | 
|  | 216 | // check if map counts are equal | 
|  | 217 | EXPECT_EQ(map_count_pagemap, map_count_meminfo); | 
|  | 218 | } | 
|  | 219 | free(pagemap); | 
|  | 220 | } | 
|  | 221 | } | 
|  | 222 |  | 
|  | 223 | TEST_F(ValidatePageAcct, TestPageIdle) { | 
|  | 224 | // skip the test if idle page tracking isn't enabled | 
|  | 225 | if (pm_kernel_init_page_idle(ker) != 0) { | 
|  | 226 | return; | 
|  | 227 | } | 
|  | 228 |  | 
|  | 229 | PageAcct& pi = PageAcct::Instance(); | 
|  | 230 | ASSERT_TRUE(pi.InitPageAcct(true)); | 
|  | 231 |  | 
|  | 232 | uint64_t* pagemap; | 
|  | 233 | size_t num_pages; | 
|  | 234 | for (size_t i = 0; i < proc->num_maps; i++) { | 
|  | 235 | ASSERT_EQ(0, pm_map_pagemap(proc->maps[i], &pagemap, &num_pages)); | 
|  | 236 | for (size_t j = 0; j < num_pages; j++) { | 
|  | 237 | if (!PM_PAGEMAP_PRESENT(pagemap[j])) continue; | 
|  | 238 | uint64_t pfn = PM_PAGEMAP_PFN(pagemap[j]); | 
|  | 239 |  | 
|  | 240 | ASSERT_EQ(0, pm_kernel_mark_page_idle(ker, &pfn, 1)); | 
|  | 241 | int idle_status_pagemap = pm_kernel_get_page_idle(ker, pfn); | 
|  | 242 | int idle_status_meminfo = pi.IsPageIdle(pfn); | 
|  | 243 | EXPECT_EQ(idle_status_pagemap, idle_status_meminfo); | 
|  | 244 | } | 
|  | 245 | free(pagemap); | 
|  | 246 | } | 
|  | 247 | } | 
|  | 248 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 249 | TEST(TestProcMemInfo, MapsEmpty) { | 
| Sandeep Patil | c6497eb | 2018-11-20 09:31:36 -0800 | [diff] [blame] | 250 | ProcMemInfo proc_mem(pid); | 
|  | 251 | const std::vector<Vma>& maps = proc_mem.Maps(); | 
|  | 252 | EXPECT_GT(maps.size(), 0); | 
|  | 253 | } | 
|  | 254 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 255 | TEST(TestProcMemInfo, UsageEmpty) { | 
| Sandeep Patil | c6497eb | 2018-11-20 09:31:36 -0800 | [diff] [blame] | 256 | // If we created the object for getting working set, | 
|  | 257 | // the usage must be empty | 
|  | 258 | ProcMemInfo proc_mem(pid, true); | 
|  | 259 | const MemUsage& usage = proc_mem.Usage(); | 
|  | 260 | EXPECT_EQ(usage.rss, 0); | 
|  | 261 | EXPECT_EQ(usage.vss, 0); | 
|  | 262 | EXPECT_EQ(usage.pss, 0); | 
|  | 263 | EXPECT_EQ(usage.uss, 0); | 
|  | 264 | EXPECT_EQ(usage.swap, 0); | 
|  | 265 | } | 
|  | 266 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 267 | TEST(TestProcMemInfo, WssEmpty) { | 
| Sandeep Patil | c6497eb | 2018-11-20 09:31:36 -0800 | [diff] [blame] | 268 | // If we created the object for getting usage, | 
|  | 269 | // the working set must be empty | 
|  | 270 | ProcMemInfo proc_mem(pid, false); | 
|  | 271 | const MemUsage& wss = proc_mem.Wss(); | 
|  | 272 | EXPECT_EQ(wss.rss, 0); | 
|  | 273 | EXPECT_EQ(wss.vss, 0); | 
|  | 274 | EXPECT_EQ(wss.pss, 0); | 
|  | 275 | EXPECT_EQ(wss.uss, 0); | 
|  | 276 | EXPECT_EQ(wss.swap, 0); | 
|  | 277 | } | 
|  | 278 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 279 | TEST(TestProcMemInfo, SwapOffsetsEmpty) { | 
| Sandeep Patil | c6497eb | 2018-11-20 09:31:36 -0800 | [diff] [blame] | 280 | // If we created the object for getting working set, | 
|  | 281 | // the swap offsets must be empty | 
|  | 282 | ProcMemInfo proc_mem(pid, true); | 
|  | 283 | const std::vector<uint16_t>& swap_offsets = proc_mem.SwapOffsets(); | 
|  | 284 | EXPECT_EQ(swap_offsets.size(), 0); | 
|  | 285 | } | 
|  | 286 |  | 
| Sandeep Patil | dfd34be | 2019-01-13 17:39:08 -0800 | [diff] [blame] | 287 | TEST(TestProcMemInfo, IsSmapsSupportedTest) { | 
|  | 288 | std::string path = ::android::base::StringPrintf("/proc/%d/smaps_rollup", pid); | 
|  | 289 | bool supported = IsSmapsRollupSupported(pid); | 
|  | 290 | EXPECT_EQ(!access(path.c_str(), F_OK | R_OK), supported); | 
|  | 291 | // Second call must return what the first one returned regardless of the pid parameter. | 
|  | 292 | // So, deliberately pass invalid pid. | 
|  | 293 | EXPECT_EQ(supported, IsSmapsRollupSupported(-1)); | 
|  | 294 | } | 
|  | 295 |  | 
| Sandeep Patil | fa2d8d5 | 2018-12-29 21:05:38 -0800 | [diff] [blame] | 296 | TEST(TestProcMemInfo, SmapsOrRollupTest) { | 
|  | 297 | std::string rollup = | 
|  | 298 | R"rollup(12c00000-7fe859e000 ---p 00000000 00:00 0                                [rollup] | 
|  | 299 | Rss:              331908 kB | 
|  | 300 | Pss:              202052 kB | 
|  | 301 | Shared_Clean:     158492 kB | 
|  | 302 | Shared_Dirty:      18928 kB | 
|  | 303 | Private_Clean:     90472 kB | 
|  | 304 | Private_Dirty:     64016 kB | 
|  | 305 | Referenced:       318700 kB | 
|  | 306 | Anonymous:         81984 kB | 
|  | 307 | AnonHugePages:         0 kB | 
|  | 308 | Shared_Hugetlb:        0 kB | 
|  | 309 | Private_Hugetlb:       0 kB | 
|  | 310 | Swap:               5344 kB | 
|  | 311 | SwapPss:             442 kB | 
|  | 312 | Locked:          1523537 kB)rollup"; | 
|  | 313 |  | 
|  | 314 | TemporaryFile tf; | 
|  | 315 | ASSERT_TRUE(tf.fd != -1); | 
|  | 316 | ASSERT_TRUE(::android::base::WriteStringToFd(rollup, tf.fd)); | 
|  | 317 |  | 
|  | 318 | MemUsage stats; | 
|  | 319 | ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true); | 
|  | 320 | EXPECT_EQ(stats.rss, 331908); | 
|  | 321 | EXPECT_EQ(stats.pss, 202052); | 
|  | 322 | EXPECT_EQ(stats.uss, 154488); | 
|  | 323 | EXPECT_EQ(stats.private_clean, 90472); | 
|  | 324 | EXPECT_EQ(stats.private_dirty, 64016); | 
|  | 325 | EXPECT_EQ(stats.swap_pss, 442); | 
|  | 326 | } | 
|  | 327 |  | 
|  | 328 | TEST(TestProcMemInfo, SmapsOrRollupSmapsTest) { | 
|  | 329 | // This is a made up smaps for the test | 
|  | 330 | std::string smaps = | 
|  | 331 | R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)] | 
|  | 332 | Name:           [anon:dalvik-main space (region space)] | 
|  | 333 | Size:               8448 kB | 
|  | 334 | KernelPageSize:        4 kB | 
|  | 335 | MMUPageSize:           4 kB | 
|  | 336 | Rss:                2652 kB | 
|  | 337 | Pss:                2652 kB | 
|  | 338 | Shared_Clean:        840 kB | 
|  | 339 | Shared_Dirty:         40 kB | 
|  | 340 | Private_Clean:        84 kB | 
|  | 341 | Private_Dirty:      2652 kB | 
|  | 342 | Referenced:         2652 kB | 
|  | 343 | Anonymous:          2652 kB | 
|  | 344 | AnonHugePages:         0 kB | 
|  | 345 | ShmemPmdMapped:        0 kB | 
|  | 346 | Shared_Hugetlb:        0 kB | 
|  | 347 | Private_Hugetlb:       0 kB | 
|  | 348 | Swap:                102 kB | 
|  | 349 | SwapPss:              70 kB | 
|  | 350 | Locked:             2652 kB | 
|  | 351 | VmFlags: rd wr mr mw me ac | 
|  | 352 | )smaps"; | 
|  | 353 |  | 
|  | 354 | TemporaryFile tf; | 
|  | 355 | ASSERT_TRUE(tf.fd != -1); | 
|  | 356 | ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd)); | 
|  | 357 |  | 
|  | 358 | MemUsage stats; | 
|  | 359 | ASSERT_EQ(SmapsOrRollupFromFile(tf.path, &stats), true); | 
|  | 360 | EXPECT_EQ(stats.rss, 2652); | 
|  | 361 | EXPECT_EQ(stats.pss, 2652); | 
|  | 362 | EXPECT_EQ(stats.uss, 2736); | 
|  | 363 | EXPECT_EQ(stats.private_clean, 84); | 
|  | 364 | EXPECT_EQ(stats.private_dirty, 2652); | 
|  | 365 | EXPECT_EQ(stats.swap_pss, 70); | 
|  | 366 | } | 
|  | 367 |  | 
| Sandeep Patil | 8871e7e | 2019-01-13 16:47:20 -0800 | [diff] [blame] | 368 | TEST(TestProcMemInfo, SmapsOrRollupPssRollupTest) { | 
|  | 369 | // This is a made up smaps for the test | 
|  | 370 | std::string smaps = | 
|  | 371 | R"smaps(12c00000-13440000 rw-p 00000000 00:00 0                                  [anon:dalvik-main space (region space)] | 
|  | 372 | Name:           [anon:dalvik-main space (region space)] | 
|  | 373 | Size:               8448 kB | 
|  | 374 | KernelPageSize:        4 kB | 
|  | 375 | MMUPageSize:           4 kB | 
|  | 376 | Rss:                2652 kB | 
|  | 377 | Pss:                2652 kB | 
|  | 378 | Shared_Clean:        840 kB | 
|  | 379 | Shared_Dirty:         40 kB | 
|  | 380 | Private_Clean:        84 kB | 
|  | 381 | Private_Dirty:      2652 kB | 
|  | 382 | Referenced:         2652 kB | 
|  | 383 | Anonymous:          2652 kB | 
|  | 384 | AnonHugePages:         0 kB | 
|  | 385 | ShmemPmdMapped:        0 kB | 
|  | 386 | Shared_Hugetlb:        0 kB | 
|  | 387 | Private_Hugetlb:       0 kB | 
|  | 388 | Swap:                102 kB | 
|  | 389 | SwapPss:              70 kB | 
|  | 390 | Locked:             2652 kB | 
|  | 391 | VmFlags: rd wr mr mw me ac | 
|  | 392 | )smaps"; | 
|  | 393 |  | 
|  | 394 | TemporaryFile tf; | 
|  | 395 | ASSERT_TRUE(tf.fd != -1); | 
|  | 396 | ASSERT_TRUE(::android::base::WriteStringToFd(smaps, tf.fd)); | 
|  | 397 |  | 
|  | 398 | uint64_t pss; | 
|  | 399 | ASSERT_EQ(SmapsOrRollupPssFromFile(tf.path, &pss), true); | 
|  | 400 | EXPECT_EQ(pss, 2652); | 
|  | 401 | } | 
|  | 402 |  | 
|  | 403 | TEST(TestProcMemInfo, SmapsOrRollupPssSmapsTest) { | 
|  | 404 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 405 | std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str()); | 
|  | 406 |  | 
|  | 407 | uint64_t pss; | 
|  | 408 | ASSERT_EQ(SmapsOrRollupPssFromFile(path, &pss), true); | 
|  | 409 | EXPECT_EQ(pss, 19119); | 
|  | 410 | } | 
|  | 411 |  | 
| Sandeep Patil | 82a48b1 | 2019-01-01 16:04:04 -0800 | [diff] [blame] | 412 | TEST(TestProcMemInfo, ForEachVmaFromFileTest) { | 
|  | 413 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 414 | std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str()); | 
|  | 415 | ProcMemInfo proc_mem(pid); | 
|  | 416 |  | 
|  | 417 | std::vector<Vma> vmas; | 
|  | 418 | auto collect_vmas = [&](const Vma& v) { vmas.push_back(v); }; | 
|  | 419 | ASSERT_TRUE(ForEachVmaFromFile(path, collect_vmas)); | 
|  | 420 |  | 
| Sandeep Patil | 002f02e | 2019-01-13 19:39:46 -0800 | [diff] [blame] | 421 | // We should get a total of 6 vmas | 
|  | 422 | ASSERT_EQ(vmas.size(), 6); | 
|  | 423 |  | 
| Sandeep Patil | 82a48b1 | 2019-01-01 16:04:04 -0800 | [diff] [blame] | 424 | // Expect values to be equal to what we have in testdata1/smaps_short | 
|  | 425 | // Check for sizes first | 
|  | 426 | ASSERT_EQ(vmas[0].usage.vss, 32768); | 
|  | 427 | EXPECT_EQ(vmas[1].usage.vss, 11204); | 
|  | 428 | EXPECT_EQ(vmas[2].usage.vss, 16896); | 
|  | 429 | EXPECT_EQ(vmas[3].usage.vss, 260); | 
|  | 430 | EXPECT_EQ(vmas[4].usage.vss, 6060); | 
|  | 431 | EXPECT_EQ(vmas[5].usage.vss, 4); | 
|  | 432 |  | 
|  | 433 | // Check for names | 
|  | 434 | EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]"); | 
|  | 435 | EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art"); | 
|  | 436 | EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]"); | 
|  | 437 | EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex"); | 
|  | 438 | EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so"); | 
|  | 439 | EXPECT_EQ(vmas[5].name, "[vsyscall]"); | 
|  | 440 |  | 
|  | 441 | EXPECT_EQ(vmas[0].usage.rss, 2048); | 
|  | 442 | EXPECT_EQ(vmas[1].usage.rss, 11188); | 
|  | 443 | EXPECT_EQ(vmas[2].usage.rss, 15272); | 
|  | 444 | EXPECT_EQ(vmas[3].usage.rss, 260); | 
|  | 445 | EXPECT_EQ(vmas[4].usage.rss, 4132); | 
|  | 446 | EXPECT_EQ(vmas[5].usage.rss, 0); | 
|  | 447 |  | 
|  | 448 | EXPECT_EQ(vmas[0].usage.pss, 113); | 
|  | 449 | EXPECT_EQ(vmas[1].usage.pss, 2200); | 
|  | 450 | EXPECT_EQ(vmas[2].usage.pss, 15272); | 
|  | 451 | EXPECT_EQ(vmas[3].usage.pss, 260); | 
|  | 452 | EXPECT_EQ(vmas[4].usage.pss, 1274); | 
|  | 453 | EXPECT_EQ(vmas[5].usage.pss, 0); | 
|  | 454 |  | 
|  | 455 | EXPECT_EQ(vmas[0].usage.uss, 0); | 
|  | 456 | EXPECT_EQ(vmas[1].usage.uss, 1660); | 
|  | 457 | EXPECT_EQ(vmas[2].usage.uss, 15272); | 
|  | 458 | EXPECT_EQ(vmas[3].usage.uss, 260); | 
|  | 459 | EXPECT_EQ(vmas[4].usage.uss, 0); | 
|  | 460 | EXPECT_EQ(vmas[5].usage.uss, 0); | 
|  | 461 |  | 
|  | 462 | EXPECT_EQ(vmas[0].usage.private_clean, 0); | 
|  | 463 | EXPECT_EQ(vmas[1].usage.private_clean, 0); | 
|  | 464 | EXPECT_EQ(vmas[2].usage.private_clean, 0); | 
|  | 465 | EXPECT_EQ(vmas[3].usage.private_clean, 260); | 
|  | 466 | EXPECT_EQ(vmas[4].usage.private_clean, 0); | 
|  | 467 | EXPECT_EQ(vmas[5].usage.private_clean, 0); | 
|  | 468 |  | 
|  | 469 | EXPECT_EQ(vmas[0].usage.private_dirty, 0); | 
|  | 470 | EXPECT_EQ(vmas[1].usage.private_dirty, 1660); | 
|  | 471 | EXPECT_EQ(vmas[2].usage.private_dirty, 15272); | 
|  | 472 | EXPECT_EQ(vmas[3].usage.private_dirty, 0); | 
|  | 473 | EXPECT_EQ(vmas[4].usage.private_dirty, 0); | 
|  | 474 | EXPECT_EQ(vmas[5].usage.private_dirty, 0); | 
|  | 475 |  | 
|  | 476 | EXPECT_EQ(vmas[0].usage.shared_clean, 0); | 
|  | 477 | EXPECT_EQ(vmas[1].usage.shared_clean, 80); | 
|  | 478 | EXPECT_EQ(vmas[2].usage.shared_clean, 0); | 
|  | 479 | EXPECT_EQ(vmas[3].usage.shared_clean, 0); | 
|  | 480 | EXPECT_EQ(vmas[4].usage.shared_clean, 4132); | 
|  | 481 | EXPECT_EQ(vmas[5].usage.shared_clean, 0); | 
|  | 482 |  | 
|  | 483 | EXPECT_EQ(vmas[0].usage.shared_dirty, 2048); | 
|  | 484 | EXPECT_EQ(vmas[1].usage.shared_dirty, 9448); | 
|  | 485 | EXPECT_EQ(vmas[2].usage.shared_dirty, 0); | 
|  | 486 | EXPECT_EQ(vmas[3].usage.shared_dirty, 0); | 
|  | 487 | EXPECT_EQ(vmas[4].usage.shared_dirty, 0); | 
|  | 488 | EXPECT_EQ(vmas[5].usage.shared_dirty, 0); | 
|  | 489 |  | 
|  | 490 | EXPECT_EQ(vmas[0].usage.swap, 0); | 
|  | 491 | EXPECT_EQ(vmas[1].usage.swap, 0); | 
|  | 492 | EXPECT_EQ(vmas[2].usage.swap, 0); | 
|  | 493 | EXPECT_EQ(vmas[3].usage.swap, 0); | 
|  | 494 | EXPECT_EQ(vmas[4].usage.swap, 0); | 
|  | 495 | EXPECT_EQ(vmas[5].usage.swap, 0); | 
|  | 496 |  | 
|  | 497 | EXPECT_EQ(vmas[0].usage.swap_pss, 0); | 
|  | 498 | EXPECT_EQ(vmas[1].usage.swap_pss, 0); | 
|  | 499 | EXPECT_EQ(vmas[2].usage.swap_pss, 0); | 
|  | 500 | EXPECT_EQ(vmas[3].usage.swap_pss, 0); | 
|  | 501 | EXPECT_EQ(vmas[4].usage.swap_pss, 0); | 
|  | 502 | EXPECT_EQ(vmas[5].usage.swap_pss, 0); | 
|  | 503 | } | 
|  | 504 |  | 
|  | 505 | TEST(TestProcMemInfo, SmapsReturnTest) { | 
|  | 506 | ProcMemInfo proc_mem(pid); | 
|  | 507 | auto vmas = proc_mem.Smaps(); | 
|  | 508 | EXPECT_FALSE(vmas.empty()); | 
|  | 509 | } | 
|  | 510 |  | 
|  | 511 | TEST(TestProcMemInfo, SmapsTest) { | 
|  | 512 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 513 | std::string path = ::android::base::StringPrintf("%s/testdata1/smaps_short", exec_dir.c_str()); | 
|  | 514 | ProcMemInfo proc_mem(pid); | 
|  | 515 | auto vmas = proc_mem.Smaps(path); | 
|  | 516 |  | 
|  | 517 | ASSERT_FALSE(vmas.empty()); | 
| Sandeep Patil | 002f02e | 2019-01-13 19:39:46 -0800 | [diff] [blame] | 518 | // We should get a total of 6 vmas | 
|  | 519 | ASSERT_EQ(vmas.size(), 6); | 
| Sandeep Patil | 82a48b1 | 2019-01-01 16:04:04 -0800 | [diff] [blame] | 520 |  | 
|  | 521 | // Expect values to be equal to what we have in testdata1/smaps_short | 
|  | 522 | // Check for sizes first | 
|  | 523 | ASSERT_EQ(vmas[0].usage.vss, 32768); | 
|  | 524 | EXPECT_EQ(vmas[1].usage.vss, 11204); | 
|  | 525 | EXPECT_EQ(vmas[2].usage.vss, 16896); | 
|  | 526 | EXPECT_EQ(vmas[3].usage.vss, 260); | 
|  | 527 | EXPECT_EQ(vmas[4].usage.vss, 6060); | 
|  | 528 | EXPECT_EQ(vmas[5].usage.vss, 4); | 
|  | 529 |  | 
|  | 530 | // Check for names | 
|  | 531 | EXPECT_EQ(vmas[0].name, "[anon:dalvik-zygote-jit-code-cache]"); | 
|  | 532 | EXPECT_EQ(vmas[1].name, "/system/framework/x86_64/boot-framework.art"); | 
|  | 533 | EXPECT_EQ(vmas[2].name, "[anon:libc_malloc]"); | 
|  | 534 | EXPECT_EQ(vmas[3].name, "/system/priv-app/SettingsProvider/oat/x86_64/SettingsProvider.odex"); | 
|  | 535 | EXPECT_EQ(vmas[4].name, "/system/lib64/libhwui.so"); | 
|  | 536 | EXPECT_EQ(vmas[5].name, "[vsyscall]"); | 
|  | 537 |  | 
|  | 538 | EXPECT_EQ(vmas[0].usage.rss, 2048); | 
|  | 539 | EXPECT_EQ(vmas[1].usage.rss, 11188); | 
|  | 540 | EXPECT_EQ(vmas[2].usage.rss, 15272); | 
|  | 541 | EXPECT_EQ(vmas[3].usage.rss, 260); | 
|  | 542 | EXPECT_EQ(vmas[4].usage.rss, 4132); | 
|  | 543 | EXPECT_EQ(vmas[5].usage.rss, 0); | 
|  | 544 |  | 
|  | 545 | EXPECT_EQ(vmas[0].usage.pss, 113); | 
|  | 546 | EXPECT_EQ(vmas[1].usage.pss, 2200); | 
|  | 547 | EXPECT_EQ(vmas[2].usage.pss, 15272); | 
|  | 548 | EXPECT_EQ(vmas[3].usage.pss, 260); | 
|  | 549 | EXPECT_EQ(vmas[4].usage.pss, 1274); | 
|  | 550 | EXPECT_EQ(vmas[5].usage.pss, 0); | 
|  | 551 |  | 
|  | 552 | EXPECT_EQ(vmas[0].usage.uss, 0); | 
|  | 553 | EXPECT_EQ(vmas[1].usage.uss, 1660); | 
|  | 554 | EXPECT_EQ(vmas[2].usage.uss, 15272); | 
|  | 555 | EXPECT_EQ(vmas[3].usage.uss, 260); | 
|  | 556 | EXPECT_EQ(vmas[4].usage.uss, 0); | 
|  | 557 | EXPECT_EQ(vmas[5].usage.uss, 0); | 
|  | 558 |  | 
|  | 559 | EXPECT_EQ(vmas[0].usage.private_clean, 0); | 
|  | 560 | EXPECT_EQ(vmas[1].usage.private_clean, 0); | 
|  | 561 | EXPECT_EQ(vmas[2].usage.private_clean, 0); | 
|  | 562 | EXPECT_EQ(vmas[3].usage.private_clean, 260); | 
|  | 563 | EXPECT_EQ(vmas[4].usage.private_clean, 0); | 
|  | 564 | EXPECT_EQ(vmas[5].usage.private_clean, 0); | 
|  | 565 |  | 
|  | 566 | EXPECT_EQ(vmas[0].usage.private_dirty, 0); | 
|  | 567 | EXPECT_EQ(vmas[1].usage.private_dirty, 1660); | 
|  | 568 | EXPECT_EQ(vmas[2].usage.private_dirty, 15272); | 
|  | 569 | EXPECT_EQ(vmas[3].usage.private_dirty, 0); | 
|  | 570 | EXPECT_EQ(vmas[4].usage.private_dirty, 0); | 
|  | 571 | EXPECT_EQ(vmas[5].usage.private_dirty, 0); | 
|  | 572 |  | 
|  | 573 | EXPECT_EQ(vmas[0].usage.shared_clean, 0); | 
|  | 574 | EXPECT_EQ(vmas[1].usage.shared_clean, 80); | 
|  | 575 | EXPECT_EQ(vmas[2].usage.shared_clean, 0); | 
|  | 576 | EXPECT_EQ(vmas[3].usage.shared_clean, 0); | 
|  | 577 | EXPECT_EQ(vmas[4].usage.shared_clean, 4132); | 
|  | 578 | EXPECT_EQ(vmas[5].usage.shared_clean, 0); | 
|  | 579 |  | 
|  | 580 | EXPECT_EQ(vmas[0].usage.shared_dirty, 2048); | 
|  | 581 | EXPECT_EQ(vmas[1].usage.shared_dirty, 9448); | 
|  | 582 | EXPECT_EQ(vmas[2].usage.shared_dirty, 0); | 
|  | 583 | EXPECT_EQ(vmas[3].usage.shared_dirty, 0); | 
|  | 584 | EXPECT_EQ(vmas[4].usage.shared_dirty, 0); | 
|  | 585 | EXPECT_EQ(vmas[5].usage.shared_dirty, 0); | 
|  | 586 |  | 
|  | 587 | EXPECT_EQ(vmas[0].usage.swap, 0); | 
|  | 588 | EXPECT_EQ(vmas[1].usage.swap, 0); | 
|  | 589 | EXPECT_EQ(vmas[2].usage.swap, 0); | 
|  | 590 | EXPECT_EQ(vmas[3].usage.swap, 0); | 
|  | 591 | EXPECT_EQ(vmas[4].usage.swap, 0); | 
|  | 592 | EXPECT_EQ(vmas[5].usage.swap, 0); | 
|  | 593 |  | 
|  | 594 | EXPECT_EQ(vmas[0].usage.swap_pss, 0); | 
|  | 595 | EXPECT_EQ(vmas[1].usage.swap_pss, 0); | 
|  | 596 | EXPECT_EQ(vmas[2].usage.swap_pss, 0); | 
|  | 597 | EXPECT_EQ(vmas[3].usage.swap_pss, 0); | 
|  | 598 | EXPECT_EQ(vmas[4].usage.swap_pss, 0); | 
|  | 599 | EXPECT_EQ(vmas[5].usage.swap_pss, 0); | 
|  | 600 | } | 
|  | 601 |  | 
| Sandeep Patil | 549feab | 2018-11-19 11:38:40 -0800 | [diff] [blame] | 602 | TEST(ValidateProcMemInfoFlags, TestPageFlags1) { | 
|  | 603 | // Create proc object using libpagemap | 
|  | 604 | pm_kernel_t* ker; | 
|  | 605 | ASSERT_EQ(0, pm_kernel_create(&ker)); | 
|  | 606 | pm_process_t* proc; | 
|  | 607 | ASSERT_EQ(0, pm_process_create(ker, pid, &proc)); | 
|  | 608 |  | 
|  | 609 | // count swapbacked pages using libpagemap | 
|  | 610 | pm_memusage_t proc_usage; | 
|  | 611 | pm_memusage_zero(&proc_usage); | 
|  | 612 | ASSERT_EQ(0, pm_process_usage_flags(proc, &proc_usage, (1 << KPF_SWAPBACKED), | 
|  | 613 | (1 << KPF_SWAPBACKED))); | 
|  | 614 |  | 
|  | 615 | // Create ProcMemInfo that counts swapbacked pages | 
|  | 616 | ProcMemInfo proc_mem(pid, false, (1 << KPF_SWAPBACKED), (1 << KPF_SWAPBACKED)); | 
|  | 617 |  | 
|  | 618 | EXPECT_EQ(proc_usage.vss, proc_mem.Usage().vss); | 
|  | 619 | EXPECT_EQ(proc_usage.rss, proc_mem.Usage().rss); | 
|  | 620 | EXPECT_EQ(proc_usage.pss, proc_mem.Usage().pss); | 
|  | 621 | EXPECT_EQ(proc_usage.uss, proc_mem.Usage().uss); | 
|  | 622 |  | 
|  | 623 | pm_process_destroy(proc); | 
|  | 624 | pm_kernel_destroy(ker); | 
|  | 625 | } | 
|  | 626 |  | 
|  | 627 | TEST(ValidateProcMemInfoFlags, TestPageFlags2) { | 
|  | 628 | // Create proc object using libpagemap | 
|  | 629 | pm_kernel_t* ker; | 
|  | 630 | ASSERT_EQ(0, pm_kernel_create(&ker)); | 
|  | 631 | pm_process_t* proc; | 
|  | 632 | ASSERT_EQ(0, pm_process_create(ker, pid, &proc)); | 
|  | 633 |  | 
|  | 634 | // count non-swapbacked pages using libpagemap | 
|  | 635 | pm_memusage_t proc_usage; | 
|  | 636 | pm_memusage_zero(&proc_usage); | 
|  | 637 | ASSERT_EQ(0, pm_process_usage_flags(proc, &proc_usage, (1 << KPF_SWAPBACKED), 0)); | 
|  | 638 |  | 
|  | 639 | // Create ProcMemInfo that counts non-swapbacked pages | 
|  | 640 | ProcMemInfo proc_mem(pid, false, 0, (1 << KPF_SWAPBACKED)); | 
|  | 641 |  | 
|  | 642 | EXPECT_EQ(proc_usage.vss, proc_mem.Usage().vss); | 
|  | 643 | EXPECT_EQ(proc_usage.rss, proc_mem.Usage().rss); | 
|  | 644 | EXPECT_EQ(proc_usage.pss, proc_mem.Usage().pss); | 
|  | 645 | EXPECT_EQ(proc_usage.uss, proc_mem.Usage().uss); | 
|  | 646 |  | 
|  | 647 | pm_process_destroy(proc); | 
|  | 648 | pm_kernel_destroy(ker); | 
|  | 649 | } | 
|  | 650 |  | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 651 | TEST(SysMemInfoParser, TestSysMemInfoFile) { | 
|  | 652 | std::string meminfo = R"meminfo(MemTotal:        3019740 kB | 
|  | 653 | MemFree:         1809728 kB | 
|  | 654 | MemAvailable:    2546560 kB | 
|  | 655 | Buffers:           54736 kB | 
|  | 656 | Cached:           776052 kB | 
|  | 657 | SwapCached:            0 kB | 
|  | 658 | Active:           445856 kB | 
|  | 659 | Inactive:         459092 kB | 
|  | 660 | Active(anon):      78492 kB | 
|  | 661 | Inactive(anon):     2240 kB | 
|  | 662 | Active(file):     367364 kB | 
|  | 663 | Inactive(file):   456852 kB | 
|  | 664 | Unevictable:        3096 kB | 
|  | 665 | Mlocked:            3096 kB | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 666 | SwapTotal:         32768 kB | 
|  | 667 | SwapFree:           4096 kB | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 668 | Dirty:                32 kB | 
|  | 669 | Writeback:             0 kB | 
|  | 670 | AnonPages:         74988 kB | 
|  | 671 | Mapped:            62624 kB | 
|  | 672 | Shmem:              4020 kB | 
|  | 673 | Slab:              86464 kB | 
|  | 674 | SReclaimable:      44432 kB | 
|  | 675 | SUnreclaim:        42032 kB | 
|  | 676 | KernelStack:        4880 kB | 
|  | 677 | PageTables:         2900 kB | 
|  | 678 | NFS_Unstable:          0 kB | 
|  | 679 | Bounce:                0 kB | 
|  | 680 | WritebackTmp:          0 kB | 
|  | 681 | CommitLimit:     1509868 kB | 
|  | 682 | Committed_AS:      80296 kB | 
|  | 683 | VmallocTotal:   263061440 kB | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 684 | VmallocUsed:       65536 kB | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 685 | VmallocChunk:          0 kB | 
|  | 686 | AnonHugePages:      6144 kB | 
|  | 687 | ShmemHugePages:        0 kB | 
|  | 688 | ShmemPmdMapped:        0 kB | 
|  | 689 | CmaTotal:         131072 kB | 
|  | 690 | CmaFree:          130380 kB | 
|  | 691 | HugePages_Total:       0 | 
|  | 692 | HugePages_Free:        0 | 
|  | 693 | HugePages_Rsvd:        0 | 
|  | 694 | HugePages_Surp:        0 | 
|  | 695 | Hugepagesize:       2048 kB)meminfo"; | 
|  | 696 |  | 
|  | 697 | TemporaryFile tf; | 
|  | 698 | ASSERT_TRUE(tf.fd != -1); | 
|  | 699 | ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd)); | 
|  | 700 |  | 
|  | 701 | SysMemInfo mi; | 
|  | 702 | ASSERT_TRUE(mi.ReadMemInfo(tf.path)); | 
|  | 703 | EXPECT_EQ(mi.mem_total_kb(), 3019740); | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 704 | EXPECT_EQ(mi.mem_free_kb(), 1809728); | 
|  | 705 | EXPECT_EQ(mi.mem_buffers_kb(), 54736); | 
|  | 706 | EXPECT_EQ(mi.mem_cached_kb(), 776052); | 
|  | 707 | EXPECT_EQ(mi.mem_shmem_kb(), 4020); | 
|  | 708 | EXPECT_EQ(mi.mem_slab_kb(), 86464); | 
|  | 709 | EXPECT_EQ(mi.mem_slab_reclaimable_kb(), 44432); | 
|  | 710 | EXPECT_EQ(mi.mem_slab_unreclaimable_kb(), 42032); | 
|  | 711 | EXPECT_EQ(mi.mem_swap_kb(), 32768); | 
|  | 712 | EXPECT_EQ(mi.mem_swap_free_kb(), 4096); | 
|  | 713 | EXPECT_EQ(mi.mem_mapped_kb(), 62624); | 
|  | 714 | EXPECT_EQ(mi.mem_vmalloc_used_kb(), 65536); | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 715 | EXPECT_EQ(mi.mem_page_tables_kb(), 2900); | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 716 | EXPECT_EQ(mi.mem_kernel_stack_kb(), 4880); | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 717 | } | 
|  | 718 |  | 
|  | 719 | TEST(SysMemInfoParser, TestEmptyFile) { | 
|  | 720 | TemporaryFile tf; | 
|  | 721 | std::string empty_string = ""; | 
|  | 722 | ASSERT_TRUE(tf.fd != -1); | 
|  | 723 | ASSERT_TRUE(::android::base::WriteStringToFd(empty_string, tf.fd)); | 
|  | 724 |  | 
|  | 725 | SysMemInfo mi; | 
|  | 726 | EXPECT_TRUE(mi.ReadMemInfo(tf.path)); | 
|  | 727 | EXPECT_EQ(mi.mem_total_kb(), 0); | 
|  | 728 | } | 
|  | 729 |  | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 730 | TEST(SysMemInfoParser, TestZramTotal) { | 
| Sandeep Patil | 70fa72d | 2018-11-09 19:18:29 -0800 | [diff] [blame] | 731 | std::string exec_dir = ::android::base::GetExecutableDirectory(); | 
|  | 732 |  | 
|  | 733 | SysMemInfo mi; | 
|  | 734 | std::string zram_mmstat_dir = exec_dir + "/testdata1/"; | 
|  | 735 | EXPECT_EQ(mi.mem_zram_kb(zram_mmstat_dir), 30504); | 
|  | 736 |  | 
|  | 737 | std::string zram_memused_dir = exec_dir + "/testdata2/"; | 
|  | 738 | EXPECT_EQ(mi.mem_zram_kb(zram_memused_dir), 30504); | 
|  | 739 | } | 
|  | 740 |  | 
| Sandeep Patil | 2f0b6eb | 2018-12-11 09:28:38 -0800 | [diff] [blame] | 741 | enum { | 
|  | 742 | MEMINFO_TOTAL, | 
|  | 743 | MEMINFO_FREE, | 
|  | 744 | MEMINFO_BUFFERS, | 
|  | 745 | MEMINFO_CACHED, | 
|  | 746 | MEMINFO_SHMEM, | 
|  | 747 | MEMINFO_SLAB, | 
|  | 748 | MEMINFO_SLAB_RECLAIMABLE, | 
|  | 749 | MEMINFO_SLAB_UNRECLAIMABLE, | 
|  | 750 | MEMINFO_SWAP_TOTAL, | 
|  | 751 | MEMINFO_SWAP_FREE, | 
|  | 752 | MEMINFO_ZRAM_TOTAL, | 
|  | 753 | MEMINFO_MAPPED, | 
|  | 754 | MEMINFO_VMALLOC_USED, | 
|  | 755 | MEMINFO_PAGE_TABLES, | 
|  | 756 | MEMINFO_KERNEL_STACK, | 
|  | 757 | MEMINFO_COUNT | 
|  | 758 | }; | 
|  | 759 |  | 
|  | 760 | TEST(SysMemInfoParser, TestZramWithTags) { | 
|  | 761 | std::string meminfo = R"meminfo(MemTotal:        3019740 kB | 
|  | 762 | MemFree:         1809728 kB | 
|  | 763 | MemAvailable:    2546560 kB | 
|  | 764 | Buffers:           54736 kB | 
|  | 765 | Cached:           776052 kB | 
|  | 766 | SwapCached:            0 kB | 
|  | 767 | Active:           445856 kB | 
|  | 768 | Inactive:         459092 kB | 
|  | 769 | Active(anon):      78492 kB | 
|  | 770 | Inactive(anon):     2240 kB | 
|  | 771 | Active(file):     367364 kB | 
|  | 772 | Inactive(file):   456852 kB | 
|  | 773 | Unevictable:        3096 kB | 
|  | 774 | Mlocked:            3096 kB | 
|  | 775 | SwapTotal:         32768 kB | 
|  | 776 | SwapFree:           4096 kB | 
|  | 777 | Dirty:                32 kB | 
|  | 778 | Writeback:             0 kB | 
|  | 779 | AnonPages:         74988 kB | 
|  | 780 | Mapped:            62624 kB | 
|  | 781 | Shmem:              4020 kB | 
|  | 782 | Slab:              86464 kB | 
|  | 783 | SReclaimable:      44432 kB | 
|  | 784 | SUnreclaim:        42032 kB | 
|  | 785 | KernelStack:        4880 kB | 
|  | 786 | PageTables:         2900 kB | 
|  | 787 | NFS_Unstable:          0 kB | 
|  | 788 | Bounce:                0 kB | 
|  | 789 | WritebackTmp:          0 kB | 
|  | 790 | CommitLimit:     1509868 kB | 
|  | 791 | Committed_AS:      80296 kB | 
|  | 792 | VmallocTotal:   263061440 kB | 
|  | 793 | VmallocUsed:       65536 kB | 
|  | 794 | VmallocChunk:          0 kB | 
|  | 795 | AnonHugePages:      6144 kB | 
|  | 796 | ShmemHugePages:        0 kB | 
|  | 797 | ShmemPmdMapped:        0 kB | 
|  | 798 | CmaTotal:         131072 kB | 
|  | 799 | CmaFree:          130380 kB | 
|  | 800 | HugePages_Total:       0 | 
|  | 801 | HugePages_Free:        0 | 
|  | 802 | HugePages_Rsvd:        0 | 
|  | 803 | HugePages_Surp:        0 | 
|  | 804 | Hugepagesize:       2048 kB)meminfo"; | 
|  | 805 |  | 
|  | 806 | TemporaryFile tf; | 
|  | 807 | ASSERT_TRUE(tf.fd != -1); | 
|  | 808 | ASSERT_TRUE(::android::base::WriteStringToFd(meminfo, tf.fd)); | 
|  | 809 | std::string file = std::string(tf.path); | 
|  | 810 | std::vector<uint64_t> mem(MEMINFO_COUNT); | 
|  | 811 | std::vector<std::string> tags(SysMemInfo::kDefaultSysMemInfoTags); | 
|  | 812 | auto it = tags.begin(); | 
|  | 813 | tags.insert(it + MEMINFO_ZRAM_TOTAL, "Zram:"); | 
|  | 814 | SysMemInfo mi; | 
|  | 815 |  | 
|  | 816 | // Read system memory info | 
|  | 817 | EXPECT_TRUE(mi.ReadMemInfo(tags, &mem, file)); | 
|  | 818 |  | 
|  | 819 | EXPECT_EQ(mem[MEMINFO_TOTAL], 3019740); | 
|  | 820 | EXPECT_EQ(mem[MEMINFO_FREE], 1809728); | 
|  | 821 | EXPECT_EQ(mem[MEMINFO_BUFFERS], 54736); | 
|  | 822 | EXPECT_EQ(mem[MEMINFO_CACHED], 776052); | 
|  | 823 | EXPECT_EQ(mem[MEMINFO_SHMEM], 4020); | 
|  | 824 | EXPECT_EQ(mem[MEMINFO_SLAB], 86464); | 
|  | 825 | EXPECT_EQ(mem[MEMINFO_SLAB_RECLAIMABLE], 44432); | 
|  | 826 | EXPECT_EQ(mem[MEMINFO_SLAB_UNRECLAIMABLE], 42032); | 
|  | 827 | EXPECT_EQ(mem[MEMINFO_SWAP_TOTAL], 32768); | 
|  | 828 | EXPECT_EQ(mem[MEMINFO_SWAP_FREE], 4096); | 
|  | 829 | EXPECT_EQ(mem[MEMINFO_MAPPED], 62624); | 
|  | 830 | EXPECT_EQ(mem[MEMINFO_VMALLOC_USED], 65536); | 
|  | 831 | EXPECT_EQ(mem[MEMINFO_PAGE_TABLES], 2900); | 
|  | 832 | EXPECT_EQ(mem[MEMINFO_KERNEL_STACK], 4880); | 
|  | 833 | } | 
|  | 834 |  | 
| Sandeep Patil | c24f1e3 | 2018-12-29 14:34:20 -0800 | [diff] [blame] | 835 | TEST(SysMemInfoParser, TestVmallocInfoNoMemory) { | 
|  | 836 | std::string vmallocinfo = | 
|  | 837 | R"vmallocinfo(0x0000000000000000-0x0000000000000000   69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap | 
|  | 838 | 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=b220000 ioremap | 
|  | 839 | 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap | 
|  | 840 | 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap)vmallocinfo"; | 
|  | 841 |  | 
|  | 842 | TemporaryFile tf; | 
|  | 843 | ASSERT_TRUE(tf.fd != -1); | 
|  | 844 | ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); | 
|  | 845 | std::string file = std::string(tf.path); | 
|  | 846 |  | 
|  | 847 | SysMemInfo smi; | 
|  | 848 | EXPECT_EQ(smi.ReadVmallocInfo(file), 0); | 
|  | 849 | } | 
|  | 850 |  | 
|  | 851 | TEST(SysMemInfoParser, TestVmallocInfoKernel) { | 
|  | 852 | std::string vmallocinfo = | 
|  | 853 | R"vmallocinfo(0x0000000000000000-0x0000000000000000    8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc)vmallocinfo"; | 
|  | 854 |  | 
|  | 855 | TemporaryFile tf; | 
|  | 856 | ASSERT_TRUE(tf.fd != -1); | 
|  | 857 | ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); | 
|  | 858 | std::string file = std::string(tf.path); | 
|  | 859 |  | 
|  | 860 | SysMemInfo smi; | 
|  | 861 | EXPECT_EQ(smi.ReadVmallocInfo(file), getpagesize()); | 
|  | 862 | } | 
|  | 863 |  | 
|  | 864 | TEST(SysMemInfoParser, TestVmallocInfoModule) { | 
|  | 865 | std::string vmallocinfo = | 
|  | 866 | R"vmallocinfo(0x0000000000000000-0x0000000000000000   28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo"; | 
|  | 867 |  | 
|  | 868 | TemporaryFile tf; | 
|  | 869 | ASSERT_TRUE(tf.fd != -1); | 
|  | 870 | ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); | 
|  | 871 | std::string file = std::string(tf.path); | 
|  | 872 |  | 
|  | 873 | SysMemInfo smi; | 
|  | 874 | EXPECT_EQ(smi.ReadVmallocInfo(file), 6 * getpagesize()); | 
|  | 875 | } | 
|  | 876 |  | 
|  | 877 | TEST(SysMemInfoParser, TestVmallocInfoAll) { | 
|  | 878 | std::string vmallocinfo = | 
|  | 879 | R"vmallocinfo(0x0000000000000000-0x0000000000000000   69632 of_iomap+0x78/0xb0 phys=17a00000 ioremap | 
|  | 880 | 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=b220000 ioremap | 
|  | 881 | 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17c90000 ioremap | 
|  | 882 | 0x0000000000000000-0x0000000000000000    8192 of_iomap+0x78/0xb0 phys=17ca0000 ioremap | 
|  | 883 | 0x0000000000000000-0x0000000000000000    8192 drm_property_create_blob+0x44/0xec pages=1 vmalloc | 
|  | 884 | 0x0000000000000000-0x0000000000000000   28672 pktlog_alloc_buf+0xc4/0x15c [wlan] pages=6 vmalloc)vmallocinfo"; | 
|  | 885 |  | 
|  | 886 | TemporaryFile tf; | 
|  | 887 | ASSERT_TRUE(tf.fd != -1); | 
|  | 888 | ASSERT_TRUE(::android::base::WriteStringToFd(vmallocinfo, tf.fd)); | 
|  | 889 | std::string file = std::string(tf.path); | 
|  | 890 |  | 
|  | 891 | SysMemInfo smi; | 
|  | 892 | EXPECT_EQ(smi.ReadVmallocInfo(file), 7 * getpagesize()); | 
|  | 893 | } | 
|  | 894 |  | 
| Sandeep Patil | 54d8721 | 2018-08-29 17:10:47 -0700 | [diff] [blame] | 895 | int main(int argc, char** argv) { | 
|  | 896 | ::testing::InitGoogleTest(&argc, argv); | 
|  | 897 | if (argc <= 1) { | 
|  | 898 | cerr << "Pid of a permanently sleeping process must be provided." << endl; | 
|  | 899 | exit(EXIT_FAILURE); | 
|  | 900 | } | 
|  | 901 | ::android::base::InitLogging(argv, android::base::StderrLogger); | 
|  | 902 | pid = std::stoi(std::string(argv[1])); | 
|  | 903 | return RUN_ALL_TESTS(); | 
|  | 904 | } |