1 /* 2 * Copyright (c) 2021 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include <dlfcn.h> 17 #include <hwext/gtest-ext.h> 18 #include <hwext/gtest-tag.h> 19 #include <iomanip> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <sys/time.h> 24 #include <sys/types.h> 25 #include <time.h> 26 #include <unistd.h> 27 #include <vector> 28 29 #include "logging.h" 30 #include "memory_plugin_config.pb.h" 31 #include "memory_plugin_result.pb.h" 32 #include "plugin_module_api.h" 33 34 using namespace testing::ext; 35 36 #if defined(__i386__) || defined(__x86_64__) 37 const std::string LIB_PATH = const_cast<char*>("./hos/out/hos-arm/clang_x64/devtools/devtools/libmemdataplugin.z.so"); 38 #else 39 const std::string LIB_PATH = const_cast<char*>("/system/lib/libmemdataplugin.z.so"); 40 #endif 41 42 namespace { 43 enum NumType { 44 BIT_WIDTH = 35, 45 MS_S = 1000000, 46 }; 47 48 class PluginModuleApiTest : public ::testing::Test { 49 protected: SetUpTestCase()50 static void SetUpTestCase() {} TearDownTestCase()51 static void TearDownTestCase() {} 52 SetUp()53 void SetUp() override {} TearDown()54 void TearDown() override {} 55 MatchTail(const std::string & name,const char * str)56 bool MatchTail(const std::string& name, const char* str) 57 { 58 int index = name.size() - strlen(str); 59 if (index < 0) { 60 return false; 61 } 62 return strncmp(name.c_str() + index, str, strlen(str)) == 0; 63 } 64 MemoryPluginTest(MemoryConfig & protoConfig,const std::string libPath)65 bool MemoryPluginTest(MemoryConfig& protoConfig, const std::string libPath) 66 { 67 MemoryData memoryData; 68 PluginModuleStruct* memplugin; 69 void* handle; 70 int cnt = 1; 71 uint8_t* dataBuffer; 72 clock_t clockstart, clockend; 73 struct timeval start, end; 74 int timeuse; 75 76 if (!MatchTail(libPath, ".so")) { 77 printf("libPath=%s\r\n", libPath.c_str()); 78 return false; 79 } 80 81 handle = dlopen(libPath.c_str(), RTLD_LAZY); 82 if (handle == nullptr) { 83 HILOG_DEBUG(LOG_CORE, "test:dlopen err:%s.", dlerror()); 84 return false; 85 } 86 87 memplugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule"); 88 dataBuffer = (uint8_t*)malloc(memplugin->resultBufferSizeHint); 89 90 int configlength = protoConfig.ByteSizeLong(); 91 std::vector<uint8_t> config(configlength); 92 protoConfig.SerializeToArray(config.data(), config.size()); 93 94 if (memplugin->callbacks->onPluginSessionStart(config.data(), config.size()) < 0) { 95 HILOG_DEBUG(LOG_CORE, "start failed"); 96 dlclose(handle); 97 free(dataBuffer); 98 return false; 99 } 100 101 clockstart = clock(); 102 gettimeofday(&start, nullptr); 103 104 while (cnt--) { 105 int len = memplugin->callbacks->onPluginReportResult(dataBuffer, memplugin->resultBufferSizeHint); 106 if (len > 0) { 107 memoryData.ParseFromArray(dataBuffer, len); 108 } 109 } 110 111 gettimeofday(&end, nullptr); 112 clockend = clock(); 113 timeuse = MS_S * (end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec; 114 HILOG_DEBUG(LOG_CORE, "clock time=%.3fs, timeofday=%.3fs", (double)(clockend - clockstart) / CLOCKS_PER_SEC, 115 (double)timeuse / MS_S); 116 117 memplugin->callbacks->onPluginSessionStop(); 118 119 memplugin->callbacks->onRegisterWriterStruct(nullptr); 120 121 dlclose(handle); 122 free(dataBuffer); 123 return true; 124 } 125 }; 126 127 HWTEST_F(PluginModuleApiTest, ProtoConfigNullAndInvalidSo, TestSize.Level1) 128 { 129 MemoryConfig protoConfig; 130 EXPECT_FALSE(PluginModuleApiTest::MemoryPluginTest(protoConfig, "1111")); 131 } 132 133 HWTEST_F(PluginModuleApiTest, ProtoConfigNullAndEffectiveSo, TestSize.Level1) 134 { 135 MemoryConfig protoConfig; 136 EXPECT_TRUE(PluginModuleApiTest::MemoryPluginTest(protoConfig, LIB_PATH)); 137 } 138 139 HWTEST_F(PluginModuleApiTest, ProtoConfigMemAndInvalidSo, TestSize.Level1) 140 { 141 MemoryConfig protoConfig; 142 protoConfig.set_report_process_mem_info(true); 143 EXPECT_FALSE(PluginModuleApiTest::MemoryPluginTest(protoConfig, "1111")); 144 } 145 146 HWTEST_F(PluginModuleApiTest, ProtoConfigMemAndEffectiveSo, TestSize.Level1) 147 { 148 MemoryConfig protoConfig; 149 protoConfig.set_report_process_mem_info(true); 150 EXPECT_TRUE(PluginModuleApiTest::MemoryPluginTest(protoConfig, LIB_PATH)); 151 } 152 153 HWTEST_F(PluginModuleApiTest, ProtoConfigPidAndInvalidSo, TestSize.Level1) 154 { 155 MemoryConfig protoConfig; 156 protoConfig.set_report_app_mem_info(true); 157 protoConfig.add_pid(1); 158 EXPECT_FALSE(PluginModuleApiTest::MemoryPluginTest(protoConfig, "1111")); 159 } 160 161 HWTEST_F(PluginModuleApiTest, ProtoConfigPidAndEffectiveSo, TestSize.Level1) 162 { 163 MemoryConfig protoConfig; 164 protoConfig.set_report_app_mem_info(true); 165 protoConfig.add_pid(1); 166 EXPECT_TRUE(PluginModuleApiTest::MemoryPluginTest(protoConfig, LIB_PATH)); 167 } 168 169 HWTEST_F(PluginModuleApiTest, MemoryPluginTreeAndInvalidSo, TestSize.Level1) 170 { 171 MemoryConfig protoConfig; 172 protoConfig.set_report_process_tree(true); 173 EXPECT_FALSE(PluginModuleApiTest::MemoryPluginTest(protoConfig, "1111")); 174 } 175 176 HWTEST_F(PluginModuleApiTest, MemoryPluginTreeAndEffectiveSo, TestSize.Level1) 177 { 178 MemoryConfig protoConfig; 179 protoConfig.set_report_process_tree(true); 180 EXPECT_TRUE(PluginModuleApiTest::MemoryPluginTest(protoConfig, LIB_PATH)); 181 } 182 183 HWTEST_F(PluginModuleApiTest, ApiCallInvalidSoAndInvalidStruct, TestSize.Level1) 184 { 185 PluginModuleStruct memplugin; 186 ASSERT_EQ(memplugin.callbacks->onPluginSessionStart(nullptr, 0), 0); 187 ASSERT_EQ(memplugin.callbacks->onPluginReportResult(nullptr, 0), 0); 188 ASSERT_EQ(memplugin.callbacks->onPluginSessionStop(), 0); 189 ASSERT_EQ(memplugin.callbacks->onRegisterWriterStruct(nullptr), 0); 190 } 191 192 HWTEST_F(PluginModuleApiTest, ApiCallEffectiveSoAndInvalidStruct, TestSize.Level1) 193 { 194 PluginModuleStruct* memplugin; 195 void* handle = dlopen(LIB_PATH.c_str(), RTLD_LAZY); 196 if (handle == nullptr) { 197 HILOG_DEBUG(LOG_CORE, "test:dlopen err:%s.", dlerror()); 198 } 199 memplugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule"); 200 ASSERT_EQ(memplugin->callbacks->onPluginSessionStart(nullptr, 0), 0); 201 ASSERT_EQ(memplugin->callbacks->onPluginReportResult(nullptr, 0), 0); 202 ASSERT_EQ(memplugin->callbacks->onPluginSessionStop(), 0); 203 ASSERT_EQ(memplugin->callbacks->onRegisterWriterStruct(nullptr), 0); 204 } 205 206 HWTEST_F(PluginModuleApiTest, ApiCallInvalidSoAndEffectiveStruct, TestSize.Level1) 207 { 208 PluginModuleStruct memplugin; 209 WriterStruct writer; 210 211 ASSERT_EQ(memplugin.callbacks->onPluginSessionStart(nullptr, 0), 0); 212 ASSERT_EQ(memplugin.callbacks->onPluginSessionStop(), 0); 213 ASSERT_EQ(memplugin.callbacks->onRegisterWriterStruct(&writer), 0); 214 } 215 216 HWTEST_F(PluginModuleApiTest, ApiCallEffectiveSoAndEffectiveStruct, TestSize.Level1) 217 { 218 PluginModuleStruct* memplugin; 219 WriterStruct writer; 220 221 void* handle = dlopen(LIB_PATH.c_str(), RTLD_LAZY); 222 if (handle == nullptr) { 223 HILOG_DEBUG(LOG_CORE, "test:dlopen err:%s.", dlerror()); 224 } 225 memplugin = (PluginModuleStruct*)dlsym(handle, "g_pluginModule"); 226 ASSERT_EQ(memplugin->callbacks->onPluginSessionStart(nullptr, 0), 0); 227 ASSERT_EQ(memplugin->callbacks->onPluginSessionStop(), 0); 228 ASSERT_EQ(memplugin->callbacks->onRegisterWriterStruct(&writer), 0); 229 } 230 } // namespace 231 232