• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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