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
53 void SetUp() override {}
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
HWTEST_F(PluginModuleApiTest, ProtoConfigNullAndInvalidSo, TestSize.Level1)127 HWTEST_F(PluginModuleApiTest, ProtoConfigNullAndInvalidSo, TestSize.Level1)
128 {
129 MemoryConfig protoConfig;
130 EXPECT_FALSE(PluginModuleApiTest::MemoryPluginTest(protoConfig, "1111"));
131 }
132
HWTEST_F(PluginModuleApiTest, ProtoConfigNullAndEffectiveSo, TestSize.Level1)133 HWTEST_F(PluginModuleApiTest, ProtoConfigNullAndEffectiveSo, TestSize.Level1)
134 {
135 MemoryConfig protoConfig;
136 EXPECT_TRUE(PluginModuleApiTest::MemoryPluginTest(protoConfig, LIB_PATH));
137 }
138
HWTEST_F(PluginModuleApiTest, ProtoConfigMemAndInvalidSo, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ProtoConfigMemAndEffectiveSo, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ProtoConfigPidAndInvalidSo, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ProtoConfigPidAndEffectiveSo, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, MemoryPluginTreeAndInvalidSo, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, MemoryPluginTreeAndEffectiveSo, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ApiCallInvalidSoAndInvalidStruct, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ApiCallEffectiveSoAndInvalidStruct, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ApiCallInvalidSoAndEffectiveStruct, TestSize.Level1)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
HWTEST_F(PluginModuleApiTest, ApiCallEffectiveSoAndEffectiveStruct, TestSize.Level1)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