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