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 #include "net_stats_client.h"
22
23 using namespace testing::ext;
24
25 namespace {
26 const std::string DEFAULT_TEST_PATH("/data/local/tmp/");
27 const std::string DEFAULT_NET_PATH("/proc/net/xt_qtaguid/stats");
28 constexpr uint32_t BUF_SIZE = 4 * 1024 * 1024;
29
30 std::string g_path;
31
32 struct NetDetails {
33 uint64_t tx;
34 uint64_t rx;
35 std::string type;
36 };
37
38 struct TestElement {
39 int32_t pid;
40 int32_t uid;
41 uint64_t tx;
42 uint64_t rx;
43 std::vector<NetDetails> details;
44 };
45
46 TestElement g_expectBegin = {9553, 10194, 0, 0};
47 TestElement g_expectEnd = {9553, 10194, 27085, 751549, {{27085, 751549, std::string("wlan0")}}};
48
49 std::string GetFullPath(std::string path);
50
51 class NetworkPluginTest : public ::testing::Test {
52 public:
53 static void SetUpTestCase();
54
TearDownTestCase()55 static void TearDownTestCase()
56 {
57 if (access(g_path.c_str(), F_OK) == 0) {
58 std::string str = "rm -rf " + GetFullPath(DEFAULT_TEST_PATH) + "utresources";
59 system(str.c_str());
60 }
61 }
SetUp()62 void SetUp() {}
TearDown()63 void TearDown() {}
64 };
65
Getexepath()66 string Getexepath()
67 {
68 char buf[PATH_MAX] = "";
69 std::string path = "/proc/self/exe";
70 size_t rslt = readlink(path.c_str(), buf, sizeof(buf));
71 if (rslt < 0 || (rslt >= sizeof(buf))) {
72 return "";
73 }
74 buf[rslt] = '\0';
75 for (int i = rslt; i >= 0; i--) {
76 if (buf[i] == '/') {
77 buf[i + 1] = '\0';
78 break;
79 }
80 }
81 return buf;
82 }
83
SetConfig(std::vector<int> pidList,NetworkConfig & config)84 bool SetConfig(std::vector<int> pidList, NetworkConfig& config)
85 {
86 CHECK_TRUE(pidList.size() > 0, false, "ut: %s failed!\n", __func__);
87
88 for (size_t i = 0; i < pidList.size(); i++) {
89 config.add_pid(pidList.at(i));
90 }
91 return true;
92 }
93
PluginStub(NetworkPlugin & plugin,NetworkDatas & networkData,NetworkConfig & config)94 bool PluginStub(NetworkPlugin& plugin, NetworkDatas& networkData, NetworkConfig& config)
95 {
96 // serialize
97 int configSize = config.ByteSizeLong();
98 std::vector<uint8_t> configData(configSize);
99 int ret = config.SerializeToArray(configData.data(), configData.size());
100
101 // start
102 ret = plugin.Start(configData.data(), configSize);
103 CHECK_TRUE(ret == 0, false, "ut: start failed!\n");
104
105 // report
106 std::vector<uint8_t> bufferData(BUF_SIZE);
107 ret = plugin.Report(bufferData.data(), bufferData.size());
108 if (ret > 0) {
109 networkData.ParseFromArray(bufferData.data(), ret);
110 return true;
111 }
112
113 return false;
114 }
115
GetFullPath(std::string path)116 std::string GetFullPath(std::string path)
117 {
118 if (path.size() > 0 && path[0] != '/') {
119 return Getexepath() + path;
120 }
121 return path;
122 }
123
SetUpTestCase()124 void NetworkPluginTest::SetUpTestCase()
125 {
126 g_path = GetFullPath(DEFAULT_TEST_PATH);
127 EXPECT_NE("", g_path);
128 g_path += "utresources";
129 }
130
131 /**
132 * @tc.name: network plugin
133 * @tc.desc: Test whether the utresource path exists.
134 * @tc.type: FUNC
135 */
136 HWTEST_F(NetworkPluginTest, Testpath, TestSize.Level1)
137 {
138 EXPECT_NE(g_path, "");
139 }
140
141 /**
142 * @tc.name: network plugin
143 * @tc.desc: No network data for specific pid.
144 * @tc.type: FUNC
145 */
146 HWTEST_F(NetworkPluginTest, TestNetworkDataNull, TestSize.Level1)
147 {
148 NetworkPlugin plugin;
149 NetworkDatas networkData;
150 plugin.setPathForTest(g_path + std::string("/begin"));
151
152 std::vector<int> pidList = {g_expectBegin.pid};
153 NetworkConfig config;
154 EXPECT_TRUE(SetConfig(pidList, config));
155 ASSERT_TRUE(PluginStub(plugin, networkData, config));
156
157 for (uint32_t i = 0; i < pidList.size(); ++i) {
158 EXPECT_EQ(g_expectBegin.uid, plugin.GetUid(pidList[i]));
159 EXPECT_EQ(g_expectBegin.rx, networkData.mutable_networkinfo(i)->rx_bytes());
160 EXPECT_EQ(g_expectBegin.tx, networkData.mutable_networkinfo(i)->tx_bytes());
161 int index = networkData.mutable_networkinfo(i)->details_size();
162 EXPECT_EQ(index, 0);
163 }
164
165 // stop
166 plugin.Stop();
167 }
168
169 /**
170 * @tc.name: network plugin
171 * @tc.desc: get network data for specific pid.
172 * @tc.type: FUNC
173 */
174 HWTEST_F(NetworkPluginTest, TestGetNetworkData, TestSize.Level1)
175 {
176 NetworkPlugin plugin;
177 NetworkDatas networkData;
178 plugin.setPathForTest(g_path + std::string("/end"));
179
180 std::vector<int> pidList = {g_expectEnd.pid};
181 NetworkConfig config;
182 EXPECT_TRUE(SetConfig(pidList, config));
183 ASSERT_TRUE(PluginStub(plugin, networkData, config));
184
185 for (uint32_t i = 0; i < pidList.size(); ++i) {
186 EXPECT_EQ(g_expectEnd.uid, plugin.GetUid(pidList[i]));
187 EXPECT_EQ(g_expectEnd.rx, networkData.mutable_networkinfo(i)->rx_bytes());
188 EXPECT_EQ(g_expectEnd.tx, networkData.mutable_networkinfo(i)->tx_bytes());
189 int index = networkData.mutable_networkinfo(i)->details_size();
190 EXPECT_EQ(index, 1);
191 for (int j = 0; j < index; ++j) {
192 EXPECT_EQ(g_expectEnd.details[j].tx, networkData.mutable_networkinfo(i)->mutable_details(j)->tx_bytes());
193 EXPECT_EQ(g_expectEnd.details[j].rx, networkData.mutable_networkinfo(i)->mutable_details(j)->rx_bytes());
194 EXPECT_EQ(g_expectEnd.details[j].type, networkData.mutable_networkinfo(i)->mutable_details(j)->type());
195 }
196 }
197
198 // stop
199 plugin.Stop();
200 }
201
202 /**
203 * @tc.name: network plugin
204 * @tc.desc: test the ParseFromArray fail of plugin start
205 * @tc.type: FUNC
206 */
207 HWTEST_F(NetworkPluginTest, TestParseFromArrayOfPluginStart, TestSize.Level1)
208 {
209 NetworkPlugin plugin;
210 NetworkConfig config;
211 int32_t pid = 1;
212
213 // set config
214 config.add_pid(pid);
215
216 // serialize
217 int size = config.ByteSizeLong();
218 ASSERT_GT(size, 0);
219 std::vector<uint8_t> configData(size);
220 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
221
222 // start
223 EXPECT_NE(plugin.Start(configData.data(), size - 1), 0);
224 }
225
WriteFunc(WriterStruct * writer,const void * data,size_t size)226 long WriteFunc(WriterStruct* writer, const void* data, size_t size)
227 {
228 if (writer == nullptr || data == nullptr || size <= 0) {
229 return -1;
230 }
231 return 0;
232 }
233
FlushFunc(WriterStruct * writer)234 bool FlushFunc(WriterStruct* writer)
235 {
236 if (writer == nullptr) {
237 return false;
238 }
239 return true;
240 }
241
242 /**
243 * @tc.name: network plugin
244 * @tc.desc: test register
245 * @tc.type: FUNC
246 */
247 HWTEST_F(NetworkPluginTest, TestRegister, TestSize.Level1)
248 {
249 std::string path = std::string("libnetworkplugin.z.so");
250 void* handle = dlopen(path.c_str(), RTLD_LAZY);
251 EXPECT_NE(handle, nullptr);
252 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
253 EXPECT_NE(plugin, nullptr);
254 EXPECT_STREQ(plugin->name, "network-plugin");
255
256 // set config
257 NetworkConfig config;
258 int32_t pid = 1;
259 config.add_pid(pid);
260 int size = config.ByteSizeLong();
261 ASSERT_GT(size, 0);
262 std::vector<uint8_t> configData(size);
263 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
264
265 // test framework process
266 WriterStruct writer = {WriteFunc, FlushFunc};
267 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
268 EXPECT_EQ(plugin->callbacks->onRegisterWriterStruct(&writer), 0);
269 }
270
271 /**
272 * @tc.name: network plugin
273 * @tc.desc: Framework test
274 * @tc.type: FUNC
275 */
276 HWTEST_F(NetworkPluginTest, TestFramework, TestSize.Level1)
277 {
278 std::string path = std::string("libnetworkplugin.z.so");
279 void* handle = dlopen(path.c_str(), RTLD_LAZY);
280 EXPECT_NE(handle, nullptr);
281 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
282 EXPECT_NE(plugin, nullptr);
283 EXPECT_STREQ(plugin->name, "network-plugin");
284
285 // set config
286 NetworkConfig config;
287 int32_t pid = 1;
288 config.add_pid(pid);
289 int size = config.ByteSizeLong();
290 ASSERT_GT(size, 0);
291 std::vector<uint8_t> configData(size);
292 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
293
294 // test framework process
295 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
296 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
297 if (access(DEFAULT_NET_PATH.c_str(), F_OK) != 0) {
298 EXPECT_LT(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
299 } else {
300 EXPECT_EQ(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
301 }
302 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
303 }
304
305 /**
306 * @tc.name: network plugin
307 * @tc.desc: systemdata test
308 * @tc.type: FUNC
309 */
310 HWTEST_F(NetworkPluginTest, TestSystemData, TestSize.Level1)
311 {
312 std::string path = std::string("libnetworkplugin.z.so");
313 void* handle = dlopen(path.c_str(), RTLD_LAZY);
314 EXPECT_NE(handle, nullptr);
315 PluginModuleStruct* plugin = reinterpret_cast<PluginModuleStruct*>(dlsym(handle, "g_pluginModule"));
316
317 // set config
318 NetworkConfig config;
319 std::string test_file = "/data/local/tmp/utresources/begin/proc/net/xt_qtaguid/stats";
320 config.set_test_file(test_file);
321 int size = config.ByteSizeLong();
322 ASSERT_GT(size, 0);
323 std::vector<uint8_t> configData(size);
324 ASSERT_GT(config.SerializeToArray(configData.data(), configData.size()), 0);
325
326 // systemdata test
327 std::vector<uint8_t> dataBuffer(plugin->resultBufferSizeHint);
328 EXPECT_EQ(plugin->callbacks->onPluginSessionStart(configData.data(), configData.size()), 0);
329 EXPECT_GT(plugin->callbacks->onPluginReportResult(dataBuffer.data(), dataBuffer.size()), 0);
330 EXPECT_EQ(plugin->callbacks->onPluginSessionStop(), 0);
331 }
332
333 /**
334 * @tc.name: network plugin
335 * @tc.desc: start test with single pid
336 * @tc.type: FUNC
337 */
338 HWTEST_F(NetworkPluginTest, TestStart1, TestSize.Level1)
339 {
340 NetworkPlugin plugin;
341 NetworkConfig config;
342 config.set_single_pid(-1);
343 int configSize = config.ByteSizeLong();
344 std::vector<uint8_t> configData(configSize);
345 int ret = config.SerializeToArray(configData.data(), configData.size());
346 ret = plugin.Start(configData.data(), configSize);
347 EXPECT_EQ(ret, -1);
348 plugin.Stop();
349 }
350
351 /**
352 * @tc.name: network plugin
353 * @tc.desc: start test with startup process name
354 * @tc.type: FUNC
355 */
356 HWTEST_F(NetworkPluginTest, TestStart2, TestSize.Level1)
357 {
358 NetworkPlugin plugin;
359 NetworkConfig config;
360 config.set_startup_process_name("");
361 int configSize = config.ByteSizeLong();
362 std::vector<uint8_t> configData(configSize);
363 int ret = config.SerializeToArray(configData.data(), configData.size());
364 ret = plugin.Start(configData.data(), configSize);
365 EXPECT_GE(ret, -1);
366 plugin.Stop();
367 }
368
369 /**
370 * @tc.name: network plugin
371 * @tc.desc: start test with restart process name
372 * @tc.type: FUNC
373 */
374 HWTEST_F(NetworkPluginTest, TestStart3, TestSize.Level1)
375 {
376 NetworkPlugin plugin;
377 NetworkConfig config;
378 config.set_restart_process_name("");
379 int configSize = config.ByteSizeLong();
380 std::vector<uint8_t> configData(configSize);
381 int ret = config.SerializeToArray(configData.data(), configData.size());
382 ret = plugin.Start(configData.data(), configSize);
383 EXPECT_GE(ret, -1);
384 plugin.Stop();
385 }
386
387 /**
388 * @tc.name: network plugin
389 * @tc.desc: GetBundleNameByPid test
390 * @tc.type: FUNC
391 */
392 HWTEST_F(NetworkPluginTest, TestGetBundleNameByPid, TestSize.Level1)
393 {
394 NetworkPlugin plugin;
395 std::string processName = plugin.GetBundleNameByPid(1);
396 EXPECT_EQ(processName, "/bin/init");
397 }
398
399 /**
400 * @tc.name: network plugin
401 * @tc.desc: GetUidByConfiguredBundleName test
402 * @tc.type: FUNC
403 */
404 HWTEST_F(NetworkPluginTest, TestGetUidByConfiguredBundleName, TestSize.Level1)
405 {
406 NetworkPlugin plugin;
407 EXPECT_EQ(plugin.GetUidByConfiguredBundleName(""), -1);
408 }
409
410 /**
411 * @tc.name: network plugin
412 * @tc.desc: WriteNetFlowData test
413 * @tc.type: FUNC
414 */
415 HWTEST_F(NetworkPluginTest, TestWriteNetFlowData, TestSize.Level1)
416 {
417 NetworkPlugin plugin;
418 NetworkFlowData dataProto;
419 ASSERT_FALSE(plugin.WriteNetFlowData(dataProto));
420 }
421
422 /**
423 * @tc.name: network plugin
424 * @tc.desc: Screen by uid test multiple iface
425 * @tc.type: FUNC
426 */
427 HWTEST_F(NetworkPluginTest, TestScreen1, TestSize.Level1)
428 {
429 NetworkPlugin plugin;
430 plugin.setSingleUid(1);
431 NetFlowData data;
432 std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos;
433 plugin.ScreenNetworkStatByUid(infos, data);
434 OHOS::NetManagerStandard::NetStatsInfo info1;
435 info1.uid_ = 1;
436 info1.iface_ = "wlan0";
437 info1.rxBytes_ = 1;
438 info1.txBytes_ = 1;
439 info1.rxPackets_ = 1;
440 info1.txPackets_ = 1;
441 infos.push_back(info1);
442 OHOS::NetManagerStandard::NetStatsInfo info2;
443 info2.uid_ = 1;
444 info2.iface_ = "rmnet0";
445 info2.rxBytes_ = 2;
446 info2.txBytes_ = 2;
447 info2.rxPackets_ = 2;
448 info2.txPackets_ = 2;
449 infos.push_back(info2);
450 plugin.ScreenNetworkStatByUid(infos, data);
451 EXPECT_EQ(data.rxBytes, 3);
452 EXPECT_EQ(data.txBytes, 3);
453 EXPECT_EQ(data.rxPackets, 3);
454 EXPECT_EQ(data.txPackets, 3);
455 EXPECT_EQ(data.details.size(), 2);
456 }
457
458 /**
459 * @tc.name: network plugin
460 * @tc.desc: Screen by uid test with multiple uid
461 * @tc.type: FUNC
462 */
463 HWTEST_F(NetworkPluginTest, TestScreen2, TestSize.Level1)
464 {
465 NetworkPlugin plugin;
466 plugin.setSingleUid(1);
467 NetFlowData data;
468 std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos;
469 plugin.ScreenNetworkStatByUid(infos, data);
470 OHOS::NetManagerStandard::NetStatsInfo info1;
471 info1.uid_ = 1;
472 info1.iface_ = "wlan0";
473 info1.rxBytes_ = 1;
474 info1.txBytes_ = 1;
475 info1.rxPackets_ = 1;
476 info1.txPackets_ = 1;
477 infos.push_back(info1);
478 OHOS::NetManagerStandard::NetStatsInfo info2;
479 info2.uid_ = 2;
480 info2.iface_ = "rmnet0";
481 info2.rxBytes_ = 2;
482 info2.txBytes_ = 2;
483 info2.rxPackets_ = 2;
484 info2.txPackets_ = 2;
485 infos.push_back(info2);
486 plugin.ScreenNetworkStatByUid(infos, data);
487 EXPECT_EQ(data.rxBytes, 1);
488 EXPECT_EQ(data.txBytes, 1);
489 EXPECT_EQ(data.rxPackets, 1);
490 EXPECT_EQ(data.txPackets, 1);
491 EXPECT_EQ(data.details.size(), 1);
492 }
493
494 /**
495 * @tc.name: network plugin
496 * @tc.desc: retain all test with multiple iface
497 * @tc.type: FUNC
498 */
499 HWTEST_F(NetworkPluginTest, TestScreen3, TestSize.Level1)
500 {
501 NetworkPlugin plugin;
502 plugin.setSingleUid(1);
503 NetFlowData data;
504 std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos;
505 plugin.RetainAllNetworkStat(infos, data);
506 OHOS::NetManagerStandard::NetStatsInfo info1;
507 info1.uid_ = 1;
508 info1.iface_ = "wlan0";
509 info1.rxBytes_ = 1;
510 info1.txBytes_ = 1;
511 info1.rxPackets_ = 1;
512 info1.txPackets_ = 1;
513 infos.push_back(info1);
514 OHOS::NetManagerStandard::NetStatsInfo info2;
515 info2.uid_ = 1;
516 info2.iface_ = "rmnet0";
517 info2.rxBytes_ = 2;
518 info2.txBytes_ = 2;
519 info2.rxPackets_ = 2;
520 info2.txPackets_ = 2;
521 infos.push_back(info2);
522 plugin.RetainAllNetworkStat(infos, data);
523 EXPECT_EQ(data.rxBytes, 3);
524 EXPECT_EQ(data.txBytes, 3);
525 EXPECT_EQ(data.rxPackets, 3);
526 EXPECT_EQ(data.txPackets, 3);
527 EXPECT_EQ(data.details.size(), 2);
528 }
529
530 /**
531 * @tc.name: network plugin
532 * @tc.desc: retain all test with multiple uid
533 * @tc.type: FUNC
534 */
535 HWTEST_F(NetworkPluginTest, TestScreen4, TestSize.Level1)
536 {
537 NetworkPlugin plugin;
538 plugin.setSingleUid(1);
539 NetFlowData data;
540 std::vector<OHOS::NetManagerStandard::NetStatsInfo> infos;
541 plugin.RetainAllNetworkStat(infos, data);
542 OHOS::NetManagerStandard::NetStatsInfo info1;
543 info1.uid_ = 1;
544 info1.iface_ = "wlan0";
545 info1.rxBytes_ = 1;
546 info1.txBytes_ = 1;
547 info1.rxPackets_ = 1;
548 info1.txPackets_ = 1;
549 infos.push_back(info1);
550 OHOS::NetManagerStandard::NetStatsInfo info2;
551 info2.uid_ = 2;
552 info2.iface_ = "rmnet0";
553 info2.rxBytes_ = 2;
554 info2.txBytes_ = 2;
555 info2.rxPackets_ = 2;
556 info2.txPackets_ = 2;
557 infos.push_back(info2);
558 plugin.RetainAllNetworkStat(infos, data);
559 EXPECT_EQ(data.rxBytes, 3);
560 EXPECT_EQ(data.txBytes, 3);
561 EXPECT_EQ(data.rxPackets, 3);
562 EXPECT_EQ(data.txPackets, 3);
563 EXPECT_EQ(data.details.size(), 2);
564 }
565 } // namespace
566