1 /*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 <gtest/gtest.h>
18
19 #include "network_plugin.h"
20 #include "plugin_module_api.h"
21
22 using namespace testing::ext;
23
24 namespace {
25 const std::string DEFAULT_TEST_PATH("/data/local/tmp/");
26 const std::string DEFAULT_NET_PATH("/proc/net/xt_qtaguid/stats");
27 constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
28
29 std::string g_path;
30
31 struct NetDetails {
32 uint64_t tx;
33 uint64_t rx;
34 std::string type;
35 };
36
37 struct TestElement {
38 int32_t pid;
39 int32_t uid;
40 uint64_t tx;
41 uint64_t rx;
42 std::vector<NetDetails> details;
43 };
44
45 TestElement g_expectBegin = {9553, 10194, 0, 0};
46 TestElement g_expectEnd = {9553, 10194, 27085, 751549, {{27085, 751549, std::string("wlan0")}}};
47
48 std::string GetFullPath(std::string path);
49
50 class NetworkPluginTest : public ::testing::Test {
51 public:
52 static void SetUpTestCase();
53
TearDownTestCase()54 static void TearDownTestCase()
55 {
56 if (access(g_path.c_str(), F_OK) == 0) {
57 std::string str = "rm -rf " + GetFullPath(DEFAULT_TEST_PATH) + "utresources";
58 system(str.c_str());
59 }
60 }
SetUp()61 void SetUp() {}
TearDown()62 void TearDown() {}
63 };
64
Getexepath()65 string Getexepath()
66 {
67 char buf[PATH_MAX] = "";
68 std::string path = "/proc/self/exe";
69 size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
70 if (rslt < 0 || (rslt >= sizeof(buf))) {
71 return "";
72 }
73 buf[rslt] = '\0';
74 for (int i = rslt; i >= 0; i--) {
75 if (buf[i] == '/') {
76 buf[i + 1] = '\0';
77 break;
78 }
79 }
80 return buf;
81 }
82
SetConfig(std::vector<int> pidList,NetworkConfig & config)83 bool SetConfig(std::vector<int> pidList, NetworkConfig& config)
84 {
85 CHECK_TRUE(pidList.size() > 0, false, "ut: %s failed!\n", __func__);
86
87 for (size_t i = 0; i < pidList.size(); i++) {
88 config.add_pid(pidList.at(i));
89 }
90 return true;
91 }
92
PluginStub(NetworkPlugin & plugin,NetworkDatas & networkData,NetworkConfig & config)93 bool PluginStub(NetworkPlugin& plugin, NetworkDatas& networkData, NetworkConfig& config)
94 {
95 // serialize
96 int configSize = config.ByteSizeLong();
97 std::vector<uint8_t> configData(configSize);
98 int ret = config.SerializeToArray(configData.data(), configData.size());
99
100 // start
101 ret = plugin.Start(configData.data(), configSize);
102 CHECK_TRUE(ret == 0, false, "ut: start failed!\n");
103
104 // report
105 std::vector<uint8_t> bufferData(BUF_SIZE);
106 ret = plugin.Report(bufferData.data(), bufferData.size());
107 if (ret > 0) {
108 networkData.ParseFromArray(bufferData.data(), ret);
109 return true;
110 }
111
112 return false;
113 }
114
GetFullPath(std::string path)115 std::string GetFullPath(std::string path)
116 {
117 if (path.size() > 0 && path[0] != '/') {
118 return Getexepath() + path;
119 }
120 return path;
121 }
122
SetUpTestCase()123 void NetworkPluginTest::SetUpTestCase()
124 {
125 g_path = GetFullPath(DEFAULT_TEST_PATH);
126 EXPECT_NE("", g_path);
127 g_path += "utresources";
128 }
129
130 /**
131 * @tc.name: network plugin
132 * @tc.desc: Test whether the utresource path exists.
133 * @tc.type: FUNC
134 */
135 HWTEST_F(NetworkPluginTest, Testpath, TestSize.Level1)
136 {
137 EXPECT_NE(g_path, "");
138 }
139
140 /**
141 * @tc.name: network plugin
142 * @tc.desc: No network data for specific pid.
143 * @tc.type: FUNC
144 */
145 HWTEST_F(NetworkPluginTest, TestNetworkDataNull, TestSize.Level1)
146 {
147 NetworkPlugin plugin;
148 NetworkDatas networkData;
149 plugin.setPathForTest(g_path + std::string("/begin"));
150
151 std::vector<int> pidList = {g_expectBegin.pid};
152 NetworkConfig config;
153 EXPECT_TRUE(SetConfig(pidList, config));
154 ASSERT_TRUE(PluginStub(plugin, networkData, config));
155
156 for (uint32_t i = 0; i < pidList.size(); ++i) {
157 EXPECT_EQ(g_expectBegin.uid, plugin.GetUid(pidList[i]));
158 EXPECT_EQ(g_expectBegin.rx, networkData.mutable_networkinfo(i)->rx_bytes());
159 EXPECT_EQ(g_expectBegin.tx, networkData.mutable_networkinfo(i)->tx_bytes());
160 int index = networkData.mutable_networkinfo(i)->details_size();
161 EXPECT_EQ(index, 0);
162 }
163
164 // stop
165 plugin.Stop();
166 }
167
168 /**
169 * @tc.name: network plugin
170 * @tc.desc: get network data for specific pid.
171 * @tc.type: FUNC
172 */
173 HWTEST_F(NetworkPluginTest, TestGetNetworkData, TestSize.Level1)
174 {
175 NetworkPlugin plugin;
176 NetworkDatas networkData;
177 plugin.setPathForTest(g_path + std::string("/end"));
178
179 std::vector<int> pidList = {g_expectEnd.pid};
180 NetworkConfig config;
181 EXPECT_TRUE(SetConfig(pidList, config));
182 ASSERT_TRUE(PluginStub(plugin, networkData, config));
183
184 for (uint32_t i = 0; i < pidList.size(); ++i) {
185 EXPECT_EQ(g_expectEnd.uid, plugin.GetUid(pidList[i]));
186 EXPECT_EQ(g_expectEnd.rx, networkData.mutable_networkinfo(i)->rx_bytes());
187 EXPECT_EQ(g_expectEnd.tx, networkData.mutable_networkinfo(i)->tx_bytes());
188 int index = networkData.mutable_networkinfo(i)->details_size();
189 EXPECT_EQ(index, 1);
190 for (int j = 0; j < index; ++j) {
191 EXPECT_EQ(g_expectEnd.details[j].tx, networkData.mutable_networkinfo(i)->mutable_details(j)->tx_bytes());
192 EXPECT_EQ(g_expectEnd.details[j].rx, networkData.mutable_networkinfo(i)->mutable_details(j)->rx_bytes());
193 EXPECT_EQ(g_expectEnd.details[j].type, networkData.mutable_networkinfo(i)->mutable_details(j)->type());
194 }
195 }
196
197 // stop
198 plugin.Stop();
199 }
200
201 /**
202 * @tc.name: network plugin
203 * @tc.desc: test the ParseFromArray fail of plugin start
204 * @tc.type: FUNC
205 */
206 HWTEST_F(NetworkPluginTest, TestParseFromArrayOfPluginStart, TestSize.Level1)
207 {
208 NetworkPlugin plugin;
209 NetworkConfig config;
210 int32_t pid = 1;
211
212 // set config
213 config.add_pid(pid);
214
215 // serialize
216 int size = config.ByteSizeLong();
217 ASSERT_GT(size, 0);
218 std::vector<uint8_t> configData(size);
219 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
220
221 // start
222 EXPECT_NE(plugin.Start(configData.data(), size - 1), 0);
223 }
224
WriteFunc(WriterStruct * writer,const void * data,size_t size)225 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
226 {
227 if (writer == nullptr || data == nullptr || size <= 0) {
228 return -1;
229 }
230 return 0;
231 }
232
FlushFunc(WriterStruct * writer)233 bool FlushFunc(WriterStruct* writer)
234 {
235 if (writer == nullptr) {
236 return false;
237 }
238 return true;
239 }
240
241 /**
242 * @tc.name: network plugin
243 * @tc.desc: test register
244 * @tc.type: FUNC
245 */
246 HWTEST_F(NetworkPluginTest, TestRegister, TestSize.Level1)
247 {
248 std::string path = std::string("libnetworkplugin.z.so");
249 void* handle = dlopen(path.c_str(), RTLD_LAZY);
250 EXPECT_NE(handle, nullptr);
251 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
252 EXPECT_NE(plugin, nullptr);
253 EXPECT_STREQ(plugin->name, "network-plugin");
254
255 // set config
256 NetworkConfig config;
257 int32_t pid = 1;
258 config.add_pid(pid);
259 int size = config.ByteSizeLong();
260 ASSERT_GT(size, 0);
261 std::vector<uint8_t> configData(size);
262 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
263
264 // test framework process
265 WriterStruct writer = {WriteFunc, FlushFunc};
266 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
267 EXPECT_EQ(plugin->callbacks->onRegisterWriterStruct(&writer), 0);
268 }
269
270 /**
271 * @tc.name: network plugin
272 * @tc.desc: Framework test
273 * @tc.type: FUNC
274 */
275 HWTEST_F(NetworkPluginTest, TestFramework, TestSize.Level1)
276 {
277 std::string path = std::string("libnetworkplugin.z.so");
278 void* handle = dlopen(path.c_str(), RTLD_LAZY);
279 EXPECT_NE(handle, nullptr);
280 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
281 EXPECT_NE(plugin, nullptr);
282 EXPECT_STREQ(plugin->name, "network-plugin");
283
284 // set config
285 NetworkConfig config;
286 int32_t pid = 1;
287 config.add_pid(pid);
288 int size = config.ByteSizeLong();
289 ASSERT_GT(size, 0);
290 std::vector<uint8_t> configData(size);
291 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
292
293 // test framework process
294 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
295 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
296 if (access(DEFAULT_NET_PATH.c_str(), F_OK) != 0) {
297 EXPECT_LT(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
298 } else {
299 EXPECT_EQ(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
300 }
301 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
302 }
303
304 /**
305 * @tc.name: network plugin
306 * @tc.desc: systemdata test
307 * @tc.type: FUNC
308 */
309 HWTEST_F(NetworkPluginTest, TestSystemData, TestSize.Level1)
310 {
311 std::string path = std::string("libnetworkplugin.z.so");
312 void* handle = dlopen(path.c_str(), RTLD_LAZY);
313 EXPECT_NE(handle, nullptr);
314 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
315
316 // set config
317 NetworkConfig config;
318 std::string test_file = "/data/local/tmp/utresources/begin/proc/net/xt_qtaguid/stats";
319 config.set_test_file(test_file);
320 int size = config.ByteSizeLong();
321 ASSERT_GT(size, 0);
322 std::vector<uint8_t> configData(size);
323 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
324
325 // systemdata test
326 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
327 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
328 EXPECT_GT(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
329 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
330 }
331 } // namespace
332