1 /*
2 * Copyright (C) 2023-2024 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 <gtest/gtest.h>
17 #include <thread>
18
19 #ifdef GTEST_API_
20 #define private public
21 #define protected public
22 #endif
23
24 #include "mdns_client.h"
25 #include "mdns_client_resume.h"
26 #include "mdns_common.h"
27 #include "mdns_event_stub.h"
28 #include "mock_i_discovery_callback_test.h"
29 #include "netmgr_ext_log_wrapper.h"
30 #include "refbase.h"
31
32 namespace OHOS {
33 namespace NetManagerStandard {
34 using namespace testing::ext;
35
36 constexpr int DEMO_PORT = 12345;
37 constexpr int TIME_ONE_MS = 1;
38 constexpr int TIME_TWO_MS = 2;
39 constexpr int TIME_FOUR_MS = 4;
40 constexpr int TIME_FIVE_MS = 5;
41 constexpr const char *DEMO_NAME = "ala";
42 constexpr const char *DEMO_TYPE = "_hellomdns._tcp";
43
44 static const TxtRecord g_txt{{"key", {'v', 'a', 'l', 'u', 'e'}}, {"null", {'\0'}}};
45
46 enum class EventType {
47 UNKNOWN,
48 REGISTER,
49 FOUND,
50 LOST,
51 RESOLVE,
52 };
53
54 std::mutex g_mtx;
55 std::condition_variable g_cv;
56 int g_register = 0;
57 int g_found = 0;
58 int g_lost = 0;
59 int g_resolve = 0;
60
61 class MDnsTestRegistrationCallback : public RegistrationCallbackStub {
62 public:
MDnsTestRegistrationCallback(const MDnsServiceInfo & info)63 explicit MDnsTestRegistrationCallback(const MDnsServiceInfo &info) : expected_(info) {}
64 virtual ~MDnsTestRegistrationCallback() = default;
HandleRegister(const MDnsServiceInfo & info,int32_t retCode)65 void HandleRegister(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleUnRegister(const MDnsServiceInfo & info,int32_t retCode)66 void HandleUnRegister(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleRegisterResult(const MDnsServiceInfo & info,int32_t retCode)67 void HandleRegisterResult(const MDnsServiceInfo &info, int32_t retCode) override
68 {
69 g_mtx.lock();
70 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
71 std::cerr << "registered instance " << info.name + MDNS_DOMAIN_SPLITER_STR + info.type << "\n";
72 EXPECT_EQ(expected_.name, info.name);
73 EXPECT_EQ(expected_.type, info.type);
74 EXPECT_EQ(expected_.port, info.port);
75 g_register++;
76 g_mtx.unlock();
77 g_cv.notify_one();
78 }
79 MDnsServiceInfo expected_;
80 };
81
82 class MDnsTestDiscoveryCallback : public DiscoveryCallbackStub {
83 public:
MDnsTestDiscoveryCallback(const std::vector<MDnsServiceInfo> & info)84 explicit MDnsTestDiscoveryCallback(const std::vector<MDnsServiceInfo> &info) : expected_(info) {}
85 virtual ~MDnsTestDiscoveryCallback() = default;
HandleStartDiscover(const MDnsServiceInfo & info,int32_t retCode)86 void HandleStartDiscover(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleStopDiscover(const MDnsServiceInfo & info,int32_t retCode)87 void HandleStopDiscover(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleServiceFound(const MDnsServiceInfo & info,int32_t retCode)88 void HandleServiceFound(const MDnsServiceInfo &info, int32_t retCode) override
89 {
90 g_mtx.lock();
91 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
92 std::cerr << "found instance " << info.name + MDNS_DOMAIN_SPLITER_STR + info.type << "\n";
93 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
94 [&](auto const &x) { return x.name == info.name; }) != expected_.end());
95 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
96 [&](auto const &x) { return x.type == info.type; }) != expected_.end());
97 g_found++;
98 g_mtx.unlock();
99 g_cv.notify_one();
100 }
101
HandleServiceLost(const MDnsServiceInfo & info,int32_t retCode)102 void HandleServiceLost(const MDnsServiceInfo &info, int32_t retCode) override
103 {
104 g_mtx.lock();
105 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
106 std::cerr << "lost instance " << info.name + MDNS_DOMAIN_SPLITER_STR + info.type << "\n";
107 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
108 [&](auto const &x) { return x.name == info.name; }) != expected_.end());
109 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
110 [&](auto const &x) { return x.type == info.type; }) != expected_.end());
111 g_lost++;
112 g_mtx.unlock();
113 g_cv.notify_one();
114 }
115 std::vector<MDnsServiceInfo> expected_;
116 };
117
118 class MDnsTestResolveCallback : public ResolveCallbackStub {
119 public:
MDnsTestResolveCallback(const MDnsServiceInfo & info)120 explicit MDnsTestResolveCallback(const MDnsServiceInfo &info) : expected_(info) {}
121 virtual ~MDnsTestResolveCallback() = default;
HandleResolveResult(const MDnsServiceInfo & info,int32_t retCode)122 void HandleResolveResult(const MDnsServiceInfo &info, int32_t retCode) override
123 {
124 g_mtx.lock();
125 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
126 std::cerr << "resolved instance " << info.addr + MDNS_HOSTPORT_SPLITER_STR + std::to_string(info.port) << "\n";
127 EXPECT_EQ(expected_.name, info.name);
128 EXPECT_EQ(expected_.type, info.type);
129 EXPECT_EQ(expected_.port, info.port);
130 EXPECT_EQ(expected_.txtRecord, info.txtRecord);
131 g_resolve++;
132 g_mtx.unlock();
133 g_cv.notify_one();
134 }
135 MDnsServiceInfo expected_;
136 };
137
138 class MDnsClientResumeTest : public testing::Test {
139 public:
140 static void SetUpTestCase();
141 static void TearDownTestCase();
142 void SetUp() override;
143 void TearDown() override;
144 };
145
SetUpTestCase()146 void MDnsClientResumeTest::SetUpTestCase() {}
147
TearDownTestCase()148 void MDnsClientResumeTest::TearDownTestCase() {}
149
SetUp()150 void MDnsClientResumeTest::SetUp() {}
151
TearDown()152 void MDnsClientResumeTest::TearDown() {}
153
154 class MDnsClientTest : public testing::Test {
155 public:
156 static void SetUpTestCase();
157 static void TearDownTestCase();
158 void SetUp() override;
159 void TearDown() override;
160 };
161
SetUpTestCase()162 void MDnsClientTest::SetUpTestCase() {}
163
TearDownTestCase()164 void MDnsClientTest::TearDownTestCase() {}
165
SetUp()166 void MDnsClientTest::SetUp() {}
167
TearDown()168 void MDnsClientTest::TearDown() {}
169
170 class MDnsServerTest : public testing::Test {
171 public:
172 static void SetUpTestCase();
173 static void TearDownTestCase();
174 void SetUp() override;
175 void TearDown() override;
176 };
177
SetUpTestCase()178 void MDnsServerTest::SetUpTestCase() {}
179
TearDownTestCase()180 void MDnsServerTest::TearDownTestCase() {}
181
SetUp()182 void MDnsServerTest::SetUp() {}
183
TearDown()184 void MDnsServerTest::TearDown() {}
185
186
187 struct MdnsClientTestParams {
188 MDnsServiceInfo info;
189 MDnsServiceInfo infoBack;
190 sptr<MDnsTestRegistrationCallback> registration;
191 sptr<MDnsTestRegistrationCallback> registrationBack;
192 sptr<MDnsTestDiscoveryCallback> discovery;
193 sptr<MDnsTestDiscoveryCallback> discoveryBack;
194 sptr<MDnsTestResolveCallback> resolve;
195 sptr<MDnsTestResolveCallback> resolveBack;
196 };
197
DoTestForMdnsClient(MdnsClientTestParams param)198 void DoTestForMdnsClient(MdnsClientTestParams param)
199 {
200 std::unique_lock<std::mutex> lock(g_mtx);
201 DelayedSingleton<MDnsClient>::GetInstance()->RegisterService(param.info, param.registration);
202 DelayedSingleton<MDnsClient>::GetInstance()->RegisterService(param.infoBack, param.registrationBack);
203 if (!g_cv.wait_for(lock, std::chrono::seconds(TIME_FIVE_MS), []() { return g_register == TIME_TWO_MS; })) {
204 FAIL();
205 }
206 DelayedSingleton<MDnsClient>::GetInstance()->StartDiscoverService(param.info.type, param.discovery);
207 DelayedSingleton<MDnsClient>::GetInstance()->StartDiscoverService(param.info.type, param.discoveryBack);
208 if (!g_cv.wait_for(lock, std::chrono::seconds(TIME_FIVE_MS), []() { return g_found >= TIME_FOUR_MS; })) {
209 FAIL();
210 }
211 DelayedSingleton<MDnsClient>::GetInstance()->ResolveService(param.info, param.resolve);
212 if (!g_cv.wait_for(lock, std::chrono::seconds(TIME_FIVE_MS), []() { return g_resolve >= TIME_ONE_MS; })) {
213 FAIL();
214 }
215 DelayedSingleton<MDnsClient>::GetInstance()->ResolveService(param.infoBack, param.resolveBack);
216 if (!g_cv.wait_for(lock, std::chrono::seconds(TIME_FIVE_MS), []() { return g_resolve >= TIME_TWO_MS; })) {
217 FAIL();
218 }
219 DelayedSingleton<MDnsClient>::GetInstance()->StopDiscoverService(param.discovery);
220 DelayedSingleton<MDnsClient>::GetInstance()->StopDiscoverService(param.discoveryBack);
221 if (!g_cv.wait_for(lock, std::chrono::seconds(TIME_FIVE_MS), []() { return g_lost >= TIME_ONE_MS; })) {
222 FAIL();
223 }
224 DelayedSingleton<MDnsClient>::GetInstance()->UnRegisterService(param.registration);
225 DelayedSingleton<MDnsClient>::GetInstance()->UnRegisterService(param.registrationBack);
226
227 std::this_thread::sleep_for(std::chrono::seconds(TIME_ONE_MS));
228
229 DelayedSingleton<MDnsClient>::GetInstance()->RestartResume();
230 }
231
232 HWTEST_F(MDnsClientResumeTest, ResumeTest001, TestSize.Level1)
233 {
234 MDnsServiceInfo info;
235 MDnsServiceInfo infoBack;
236 info.name = DEMO_NAME;
237 info.type = DEMO_TYPE;
238 info.port = DEMO_PORT;
239 info.SetAttrMap(g_txt);
240
241 sptr<MDnsTestRegistrationCallback> registration(new (std::nothrow) MDnsTestRegistrationCallback(info));
242 sptr<MDnsTestDiscoveryCallback> discovery(new (std::nothrow) MDnsTestDiscoveryCallback({info, infoBack}));
243 ASSERT_NE(registration, nullptr);
244 ASSERT_NE(discovery, nullptr);
245
246 int32_t ret = MDnsClientResume::GetInstance().SaveRegisterService(info, registration);
247 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
248
249 ret = MDnsClientResume::GetInstance().SaveRegisterService(info, registration);
250 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
251
252 ret = MDnsClientResume::GetInstance().SaveStartDiscoverService(info.type, discovery);
253 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
254
255 ret = MDnsClientResume::GetInstance().SaveStartDiscoverService(info.type, discovery);
256 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
257
258 ret = MDnsClientResume::GetInstance().RemoveRegisterService(registration);
259 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
260
261 ret = MDnsClientResume::GetInstance().RemoveRegisterService(registration);
262 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
263
264 ret = MDnsClientResume::GetInstance().RemoveStopDiscoverService(discovery);
265 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
266
267 ret = MDnsClientResume::GetInstance().RemoveStopDiscoverService(discovery);
268 EXPECT_EQ(ret, NETMANAGER_EXT_SUCCESS);
269
270 RegisterServiceMap *rsm = MDnsClientResume::GetInstance().GetRegisterServiceMap();
271 ASSERT_NE(rsm, nullptr);
272
273 DiscoverServiceMap *dsm = MDnsClientResume::GetInstance().GetStartDiscoverServiceMap();
274 ASSERT_NE(dsm, nullptr);
275 }
276
277 HWTEST_F(MDnsServerTest, ServerTest, TestSize.Level1)
278 {
279 MDnsServiceInfo info;
280 info.name = DEMO_NAME;
281 info.type = DEMO_TYPE;
282 info.port = DEMO_PORT;
283 TxtRecord txt{};
284 info.SetAttrMap(txt);
285 info.SetAttrMap(g_txt);
286 auto retMap = info.GetAttrMap();
287 EXPECT_NE(retMap.size(), 0);
288
289 MessageParcel parcel;
290 auto retMar = info.Marshalling(parcel);
291 EXPECT_EQ(retMar, true);
292
293 auto serviceInfo = info.Unmarshalling(parcel);
294 retMar = info.Marshalling(parcel, serviceInfo);
295 EXPECT_EQ(retMar, true);
296 }
297
298 /**
299 * @tc.name: MDnsCommonTest001
300 * @tc.desc: Test MDnsServerTest
301 * @tc.type: FUNC
302 */
303 HWTEST_F(MDnsServerTest, MDnsCommonTest001, TestSize.Level1)
304 {
305 std::string testStr = "abbcccddddcccbba";
306 for (size_t i = 0; i < testStr.size(); ++i) {
307 EXPECT_TRUE(EndsWith(testStr, testStr.substr(i)));
308 }
309
310 for (size_t i = 0; i < testStr.size(); ++i) {
311 EXPECT_TRUE(StartsWith(testStr, testStr.substr(0, testStr.size() - i)));
312 }
313
314 auto lhs = Split(testStr, 'c');
315 auto rhs = std::vector<std::string_view>{
316 "abb",
317 "dddd",
318 "bba",
319 };
320 EXPECT_EQ(lhs, rhs);
321 }
322
323 /**
324 * @tc.name: MDnsCommonTest002
325 * @tc.desc: Test MDnsServerTest
326 * @tc.type: FUNC
327 */
328 HWTEST_F(MDnsServerTest, MDnsCommonTest002, TestSize.Level1)
329 {
330 constexpr size_t isNameIndex = 1;
331 constexpr size_t isTypeIndex = 2;
332 constexpr size_t isInstanceIndex = 3;
333 constexpr size_t isDomainIndex = 4;
334 std::vector<std::tuple<std::string, bool, bool, bool, bool>> test = {
335 {"abbcccddddcccbba", true, false, false, true },
336 {"", false, false, false, true },
337 {"a.b", false, false, false, true },
338 {"_xxx.tcp", false, false, false, true },
339 {"xxx._tcp", false, false, false, true },
340 {"xxx.yyy", false, false, false, true },
341 {"xxx.yyy", false, false, false, true },
342 {"_xxx._yyy", false, false, false, true },
343 {"hello._ipp._tcp", false, false, true, true },
344 {"_x._y._tcp", false, false, true, true },
345 {"_ipp._tcp", false, true, false, true },
346 {"_http._tcp", false, true, false, true },
347 };
348
349 for (auto line : test) {
350 EXPECT_EQ(IsNameValid(std::get<0>(line)), std::get<isNameIndex>(line));
351 EXPECT_EQ(IsTypeValid(std::get<0>(line)), std::get<isTypeIndex>(line));
352 EXPECT_EQ(IsInstanceValid(std::get<0>(line)), std::get<isInstanceIndex>(line));
353 EXPECT_EQ(IsDomainValid(std::get<0>(line)), std::get<isDomainIndex>(line));
354 }
355
356 EXPECT_TRUE(IsPortValid(22));
357 EXPECT_TRUE(IsPortValid(65535));
358 EXPECT_TRUE(IsPortValid(0));
359 EXPECT_FALSE(IsPortValid(-1));
360 EXPECT_FALSE(IsPortValid(65536));
361 }
362
363 /**
364 * @tc.name: MDnsCommonTest003
365 * @tc.desc: Test MDnsServerTest
366 * @tc.type: FUNC
367 */
368 HWTEST_F(MDnsServerTest, MDnsCommonTest003, TestSize.Level1)
369 {
370 std::string instance = "hello._ipp._tcp";
371 std::string instance1 = "_x._y._tcp";
372 std::string name;
373 std::string type;
374 ExtractNameAndType(instance, name, type);
375 EXPECT_EQ(name, "hello");
376 EXPECT_EQ(type, "_ipp._tcp");
377
378 ExtractNameAndType(instance1, name, type);
379 EXPECT_EQ(name, "_x");
380 EXPECT_EQ(type, "_y._tcp");
381 }
382
383 HWTEST_F(MDnsServerTest, MDnsServerBranchTest001, TestSize.Level1)
384 {
385 std::string serviceType = "test";
386 sptr<IDiscoveryCallback> callback = new (std::nothrow) MockIDiscoveryCallbackTest();
387 EXPECT_TRUE(callback != nullptr);
388 if (callback == nullptr) {
389 return;
390 }
391 auto ret = DelayedSingleton<MDnsClient>::GetInstance()->StartDiscoverService(serviceType, callback);
392 EXPECT_EQ(ret, NET_MDNS_ERR_ILLEGAL_ARGUMENT);
393
394 ret = DelayedSingleton<MDnsClient>::GetInstance()->StopDiscoverService(callback);
395 EXPECT_EQ(ret, NET_MDNS_ERR_CALLBACK_NOT_FOUND);
396
397 callback = nullptr;
398 ret = DelayedSingleton<MDnsClient>::GetInstance()->StartDiscoverService(serviceType, callback);
399 EXPECT_EQ(ret, NET_MDNS_ERR_ILLEGAL_ARGUMENT);
400
401 ret = DelayedSingleton<MDnsClient>::GetInstance()->StopDiscoverService(callback);
402 EXPECT_EQ(ret, NET_MDNS_ERR_ILLEGAL_ARGUMENT);
403 }
404 } // namespace NetManagerStandard
405 } // namespace OHOS