1 /* 2 * Copyright (C) 2016 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 #define LOG_TAG "memtrack_hidl_hal_test" 18 #include <android-base/logging.h> 19 #include <android-base/unique_fd.h> 20 21 #include <android/hardware/memtrack/1.0/IMemtrack.h> 22 23 #include <VtsHalHidlTargetTestBase.h> 24 25 #include <fcntl.h> 26 #include <algorithm> 27 #include <vector> 28 29 using ::android::hardware::memtrack::V1_0::IMemtrack; 30 using ::android::hardware::memtrack::V1_0::MemtrackRecord; 31 using ::android::hardware::memtrack::V1_0::MemtrackFlag; 32 using ::android::hardware::memtrack::V1_0::MemtrackType; 33 using ::android::hardware::memtrack::V1_0::MemtrackStatus; 34 using ::android::hardware::hidl_vec; 35 using ::android::hardware::Return; 36 using ::android::sp; 37 using ::android::base::unique_fd; 38 using std::vector; 39 using std::count_if; 40 41 class MemtrackHidlTest : public ::testing::VtsHalHidlTargetTestBase { 42 public: 43 virtual void SetUp() override { 44 memtrack = ::testing::VtsHalHidlTargetTestBase::getService<IMemtrack>(); 45 ASSERT_NE(memtrack, nullptr); 46 } 47 48 virtual void TearDown() override {} 49 50 sp<IMemtrack> memtrack; 51 }; 52 53 /* Returns true if flags contains at least min, and no more than max, 54 * of the flags in flagSet. Returns false otherwise. 55 */ 56 bool rightFlagCount(uint32_t flags, vector<MemtrackFlag> flagSet, uint32_t min, 57 uint32_t max) { 58 uint32_t count = 59 count_if(flagSet.begin(), flagSet.end(), 60 [&](MemtrackFlag f) { return flags & (uint32_t)f; }); 61 return (min <= count && count <= max); 62 } 63 64 /* Returns true when passed a valid, defined status, false otherwise. 65 */ 66 bool validStatus(MemtrackStatus s) { 67 vector<MemtrackStatus> statusVec = { 68 MemtrackStatus::SUCCESS, MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED, 69 MemtrackStatus::TYPE_NOT_SUPPORTED}; 70 return std::find(statusVec.begin(), statusVec.end(), s) != statusVec.end(); 71 } 72 73 auto generate_cb(MemtrackStatus *s, hidl_vec<MemtrackRecord> *v) { 74 return [=](MemtrackStatus status, hidl_vec<MemtrackRecord> vec) { 75 *s = status; 76 *v = vec; 77 }; 78 } 79 80 /* Sanity check results when getMemory() is passed a negative PID 81 */ 82 TEST_F(MemtrackHidlTest, BadPidTest) { 83 MemtrackStatus s; 84 hidl_vec<MemtrackRecord> v; 85 auto cb = generate_cb(&s, &v); 86 for (uint32_t i = 0; i < static_cast<uint32_t>(MemtrackType::NUM_TYPES); 87 i++) { 88 Return<void> ret = 89 memtrack->getMemory(-1, static_cast<MemtrackType>(i), cb); 90 ASSERT_TRUE(ret.isOk()); 91 ASSERT_TRUE(validStatus(s)); 92 } 93 } 94 95 /* Sanity check results when getMemory() is passed a bad memory usage type 96 */ 97 TEST_F(MemtrackHidlTest, BadTypeTest) { 98 MemtrackStatus s; 99 hidl_vec<MemtrackRecord> v; 100 auto cb = generate_cb(&s, &v); 101 Return<void> ret = memtrack->getMemory(getpid(), MemtrackType::NUM_TYPES, cb); 102 ASSERT_TRUE(ret.isOk()); 103 ASSERT_TRUE(validStatus(s)); 104 } 105 106 /* Call memtrack on this process and check that the results are reasonable 107 * for all memory types, including valid flag combinations for every 108 * MemtrackRecord returned. 109 */ 110 TEST_F(MemtrackHidlTest, GetMemoryTest) { 111 /* Opening this device causes the kernel to provide memtrack with memory 112 * info for this process. 113 */ 114 unique_fd fd(open("/dev/kgsl-3d0", O_RDWR)); 115 116 MemtrackStatus s; 117 hidl_vec<MemtrackRecord> v; 118 auto cb = generate_cb(&s, &v); 119 uint32_t unsupportedCount = 0; 120 for (uint32_t i = 0; i < static_cast<uint32_t>(MemtrackType::NUM_TYPES); 121 i++) { 122 Return<void> ret = 123 memtrack->getMemory(getpid(), static_cast<MemtrackType>(i), cb); 124 ASSERT_TRUE(ret.isOk()); 125 126 switch (s) { 127 case MemtrackStatus::MEMORY_TRACKING_NOT_SUPPORTED: 128 unsupportedCount++; 129 break; 130 case MemtrackStatus::TYPE_NOT_SUPPORTED: 131 break; 132 case MemtrackStatus::SUCCESS: { 133 for (uint32_t j = 0; j < v.size(); j++) { 134 // Enforce flag constraints 135 vector<MemtrackFlag> smapFlags = {MemtrackFlag::SMAPS_ACCOUNTED, 136 MemtrackFlag::SMAPS_UNACCOUNTED}; 137 EXPECT_TRUE(rightFlagCount(v[j].flags, smapFlags, 1, 1)); 138 vector<MemtrackFlag> shareFlags = {MemtrackFlag::SHARED, 139 MemtrackFlag::SHARED_PSS, 140 MemtrackFlag::PRIVATE}; 141 EXPECT_TRUE(rightFlagCount(v[j].flags, shareFlags, 0, 1)); 142 vector<MemtrackFlag> systemFlags = {MemtrackFlag::SYSTEM, 143 MemtrackFlag::DEDICATED}; 144 EXPECT_TRUE(rightFlagCount(v[j].flags, systemFlags, 0, 1)); 145 vector<MemtrackFlag> secureFlags = {MemtrackFlag::SECURE, 146 MemtrackFlag::NONSECURE}; 147 EXPECT_TRUE(rightFlagCount(v[j].flags, secureFlags, 0, 1)); 148 } 149 break; 150 } 151 default: 152 FAIL(); 153 } 154 } 155 // If tracking is not supported this should be returned for all types. 156 ASSERT_TRUE(unsupportedCount == 0 || 157 unsupportedCount == 158 static_cast<uint32_t>(MemtrackType::NUM_TYPES)); 159 } 160 161 int main(int argc, char **argv) { 162 ::testing::InitGoogleTest(&argc, argv); 163 int status = RUN_ALL_TESTS(); 164 LOG(INFO) << "Test result = " << status; 165 return status; 166 } 167