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 const char *DEMO_NAME = "ala";
33 constexpr const char *DEMO_NAME1 = "ala1";
34 constexpr const char *DEMO_TYPE = "_hellomdns._tcp";
35
36 static const TxtRecord g_txt{{"key", {'v', 'a', 'l', 'u', 'e'}}, {"null", {'\0'}}};
37
38 enum class EventType {
39 UNKNOWN,
40 REGISTER,
41 FOUND,
42 LOST,
43 RESOLVE,
44 };
45
46 std::mutex g_mtx;
47 std::condition_variable g_cv;
48 int g_register = 0;
49 int g_found = 0;
50 int g_lost = 0;
51 int g_resolve = 0;
52
53 class MDnsTestRegistrationCallback : public RegistrationCallbackStub {
54 public:
MDnsTestRegistrationCallback(const MDnsServiceInfo & info)55 explicit MDnsTestRegistrationCallback(const MDnsServiceInfo &info) : expected_(info) {}
56 virtual ~MDnsTestRegistrationCallback() = default;
HandleRegister(const MDnsServiceInfo & info,int32_t retCode)57 void HandleRegister(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleUnRegister(const MDnsServiceInfo & info,int32_t retCode)58 void HandleUnRegister(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleRegisterResult(const MDnsServiceInfo & info,int32_t retCode)59 void HandleRegisterResult(const MDnsServiceInfo &info, int32_t retCode) override
60 {
61 g_mtx.lock();
62 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
63 std::cerr << "registered instance " << info.name + MDNS_DOMAIN_SPLITER_STR + info.type << "\n";
64 EXPECT_EQ(expected_.name, info.name);
65 EXPECT_EQ(expected_.type, info.type);
66 EXPECT_EQ(expected_.port, info.port);
67 g_register++;
68 g_mtx.unlock();
69 g_cv.notify_one();
70 }
71 MDnsServiceInfo expected_;
72 };
73
74 class MDnsTestDiscoveryCallback : public DiscoveryCallbackStub {
75 public:
MDnsTestDiscoveryCallback(const std::vector<MDnsServiceInfo> & info)76 explicit MDnsTestDiscoveryCallback(const std::vector<MDnsServiceInfo> &info) : expected_(info) {}
77 virtual ~MDnsTestDiscoveryCallback() = default;
HandleStartDiscover(const MDnsServiceInfo & info,int32_t retCode)78 void HandleStartDiscover(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleStopDiscover(const MDnsServiceInfo & info,int32_t retCode)79 void HandleStopDiscover(const MDnsServiceInfo &info, int32_t retCode) override {}
HandleServiceFound(const MDnsServiceInfo & info,int32_t retCode)80 void HandleServiceFound(const MDnsServiceInfo &info, int32_t retCode) override
81 {
82 g_mtx.lock();
83 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
84 std::cerr << "found instance " << info.name + MDNS_DOMAIN_SPLITER_STR + info.type << "\n";
85 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
86 [&](auto const &x) { return x.name == info.name; }) != expected_.end());
87 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
88 [&](auto const &x) { return x.type == info.type; }) != expected_.end());
89 g_found++;
90 g_mtx.unlock();
91 g_cv.notify_one();
92 }
93
HandleServiceLost(const MDnsServiceInfo & info,int32_t retCode)94 void HandleServiceLost(const MDnsServiceInfo &info, int32_t retCode) override
95 {
96 g_mtx.lock();
97 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
98 std::cerr << "lost instance " << info.name + MDNS_DOMAIN_SPLITER_STR + info.type << "\n";
99 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
100 [&](auto const &x) { return x.name == info.name; }) != expected_.end());
101 EXPECT_TRUE(std::find_if(expected_.begin(), expected_.end(),
102 [&](auto const &x) { return x.type == info.type; }) != expected_.end());
103 g_lost++;
104 g_mtx.unlock();
105 g_cv.notify_one();
106 }
107 std::vector<MDnsServiceInfo> expected_;
108 };
109
110 class MDnsTestResolveCallback : public ResolveCallbackStub {
111 public:
MDnsTestResolveCallback(const MDnsServiceInfo & info)112 explicit MDnsTestResolveCallback(const MDnsServiceInfo &info) : expected_(info) {}
113 virtual ~MDnsTestResolveCallback() = default;
HandleResolveResult(const MDnsServiceInfo & info,int32_t retCode)114 void HandleResolveResult(const MDnsServiceInfo &info, int32_t retCode) override
115 {
116 g_mtx.lock();
117 EXPECT_EQ(retCode, NETMANAGER_EXT_SUCCESS);
118 std::cerr << "resolved instance " << info.addr + MDNS_HOSTPORT_SPLITER_STR + std::to_string(info.port) << "\n";
119 EXPECT_EQ(expected_.name, info.name);
120 EXPECT_EQ(expected_.type, info.type);
121 EXPECT_EQ(expected_.port, info.port);
122 EXPECT_EQ(expected_.txtRecord, info.txtRecord);
123 g_resolve++;
124 g_mtx.unlock();
125 g_cv.notify_one();
126 }
127 MDnsServiceInfo expected_;
128 };
129
130 class MDnsClientTest : public testing::Test {
131 public:
132 static void SetUpTestCase();
133 static void TearDownTestCase();
134 void SetUp() override;
135 void TearDown() override;
136 };
137
SetUpTestCase()138 void MDnsClientTest::SetUpTestCase() {}
139
TearDownTestCase()140 void MDnsClientTest::TearDownTestCase() {}
141
SetUp()142 void MDnsClientTest::SetUp() {}
143
TearDown()144 void MDnsClientTest::TearDown() {}
145
146 /**
147 * @tc.name: ServiceTest001
148 * @tc.desc: Test mDNS register and found.
149 * @tc.type: FUNC
150 */
151 HWTEST_F(MDnsClientTest, ClientTest001, TestSize.Level1)
152 {
153 MDnsServiceInfo info;
154 MDnsServiceInfo info1;
155 info.name = DEMO_NAME;
156 info.type = DEMO_TYPE;
157 info.port = DEMO_PORT;
158 info.SetAttrMap(g_txt);
159 info1 = info;
160 info1.name = DEMO_NAME1;
161 info1.port = DEMO_PORT1;
162
163 auto client = DelayedSingleton<MDnsClient>::GetInstance();
164 sptr<MDnsTestRegistrationCallback> registration(new (std::nothrow) MDnsTestRegistrationCallback(info));
165 sptr<MDnsTestRegistrationCallback> registration1(new (std::nothrow) MDnsTestRegistrationCallback(info1));
166 sptr<MDnsTestDiscoveryCallback> discovery(new (std::nothrow) MDnsTestDiscoveryCallback({info, info1}));
167 sptr<MDnsTestDiscoveryCallback> discovery1(new (std::nothrow) MDnsTestDiscoveryCallback({info, info1}));
168 sptr<MDnsTestResolveCallback> resolve(new (std::nothrow) MDnsTestResolveCallback(info));
169 sptr<MDnsTestResolveCallback> resolve1(new (std::nothrow) MDnsTestResolveCallback(info1));
170 ASSERT_NE(registration, nullptr);
171 ASSERT_NE(registration1, nullptr);
172 ASSERT_NE(discovery, nullptr);
173 ASSERT_NE(discovery1, nullptr);
174 ASSERT_NE(resolve, nullptr);
175 ASSERT_NE(resolve1, nullptr);
176
177 std::unique_lock<std::mutex> lock(g_mtx);
178
179 client->RegisterService(info, registration);
180 client->RegisterService(info1, registration1);
181
__anonac0976660502() 182 if (!g_cv.wait_for(lock, std::chrono::seconds(5), []() { return g_register == 2; })) {
183 FAIL();
184 }
185
186 client->StartDiscoverService(info.type, discovery);
187 client->StartDiscoverService(info.type, discovery1);
188
__anonac0976660602() 189 if (!g_cv.wait_for(lock, std::chrono::seconds(5), []() { return g_found >= 4; })) {
190 FAIL();
191 }
192
193 client->ResolveService(info, resolve);
__anonac0976660702() 194 if (!g_cv.wait_for(lock, std::chrono::seconds(5), []() { return g_resolve >= 1; })) {
195 FAIL();
196 }
197
198 client->ResolveService(info1, resolve1);
__anonac0976660802() 199 if (!g_cv.wait_for(lock, std::chrono::seconds(5), []() { return g_resolve >= 2; })) {
200 FAIL();
201 }
202
203 client->UnRegisterService(registration);
204 client->UnRegisterService(registration1);
205
__anonac0976660902() 206 if (!g_cv.wait_for(lock, std::chrono::seconds(5), []() { return g_lost >= 4; })) {
207 FAIL();
208 }
209
210 client->StopDiscoverService(discovery);
211 client->StopDiscoverService(discovery1);
212
213 std::this_thread::sleep_for(std::chrono::seconds(1));
214 }
215
216 } // namespace NetManagerStandard
217 } // namespace OHOS