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