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