1 // Copyright 2018 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "osp/impl/testing/fake_mdns_responder_adapter.h"
6 
7 #include "gtest/gtest.h"
8 
9 namespace openscreen {
10 namespace osp {
11 
12 namespace {
13 
14 constexpr char kTestServiceInstance[] = "turtle";
15 constexpr char kTestServiceName[] = "_foo";
16 constexpr char kTestServiceProtocol[] = "_udp";
17 
18 UdpSocket* const kDefaultSocket =
19     reinterpret_cast<UdpSocket*>(static_cast<uintptr_t>(8));
20 UdpSocket* const kSecondSocket =
21     reinterpret_cast<UdpSocket*>(static_cast<uintptr_t>(32));
22 
23 }  // namespace
24 
TEST(FakeMdnsResponderAdapterTest,AQueries)25 TEST(FakeMdnsResponderAdapterTest, AQueries) {
26   FakeMdnsResponderAdapter mdns_responder;
27 
28   mdns_responder.Init();
29   ASSERT_TRUE(mdns_responder.running());
30   auto event = MakeAEvent("alpha", IPAddress{1, 2, 3, 4}, kDefaultSocket);
31   auto domain_name = event.domain_name;
32   mdns_responder.AddAEvent(std::move(event));
33 
34   auto a_events = mdns_responder.TakeAResponses();
35   EXPECT_TRUE(a_events.empty());
36 
37   auto result = mdns_responder.StartAQuery(kDefaultSocket, domain_name);
38   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
39 
40   a_events = mdns_responder.TakeAResponses();
41   ASSERT_EQ(1u, a_events.size());
42   EXPECT_EQ(domain_name, a_events[0].domain_name);
43   EXPECT_EQ((IPAddress{1, 2, 3, 4}), a_events[0].address);
44 
45   result = mdns_responder.StopAQuery(kDefaultSocket, domain_name);
46   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
47 
48   mdns_responder.Close();
49   ASSERT_FALSE(mdns_responder.running());
50 
51   mdns_responder.AddAEvent(
52       MakeAEvent("alpha", IPAddress{1, 2, 3, 4}, kDefaultSocket));
53   result = mdns_responder.StartAQuery(kDefaultSocket, domain_name);
54   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
55   a_events = mdns_responder.TakeAResponses();
56   EXPECT_TRUE(a_events.empty());
57 }
58 
TEST(FakeMdnsResponderAdapterTest,AaaaQueries)59 TEST(FakeMdnsResponderAdapterTest, AaaaQueries) {
60   FakeMdnsResponderAdapter mdns_responder;
61 
62   mdns_responder.Init();
63   ASSERT_TRUE(mdns_responder.running());
64   auto event = MakeAaaaEvent("alpha", IPAddress{1, 2, 3, 4}, kDefaultSocket);
65   auto domain_name = event.domain_name;
66   mdns_responder.AddAaaaEvent(std::move(event));
67 
68   auto aaaa_events = mdns_responder.TakeAaaaResponses();
69   EXPECT_TRUE(aaaa_events.empty());
70 
71   auto result = mdns_responder.StartAaaaQuery(kDefaultSocket, domain_name);
72   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
73 
74   aaaa_events = mdns_responder.TakeAaaaResponses();
75   ASSERT_EQ(1u, aaaa_events.size());
76   EXPECT_EQ(domain_name, aaaa_events[0].domain_name);
77   EXPECT_EQ((IPAddress{1, 2, 3, 4}), aaaa_events[0].address);
78 
79   result = mdns_responder.StopAaaaQuery(kDefaultSocket, domain_name);
80   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
81 
82   mdns_responder.Close();
83   ASSERT_FALSE(mdns_responder.running());
84 
85   mdns_responder.AddAaaaEvent(
86       MakeAaaaEvent("alpha", IPAddress{1, 2, 3, 4}, kDefaultSocket));
87   result = mdns_responder.StartAaaaQuery(kDefaultSocket, domain_name);
88   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
89   aaaa_events = mdns_responder.TakeAaaaResponses();
90   EXPECT_TRUE(aaaa_events.empty());
91 }
92 
TEST(FakeMdnsResponderAdapterTest,PtrQueries)93 TEST(FakeMdnsResponderAdapterTest, PtrQueries) {
94   const DomainName kTestServiceType{
95       {4, '_', 'f', 'o', 'o', 4, '_', 'u', 'd', 'p', 0}};
96   const DomainName kTestServiceTypeCanon{{4, '_', 'f', 'o', 'o', 4, '_', 'u',
97                                           'd', 'p', 5, 'l', 'o', 'c', 'a', 'l',
98                                           0}};
99 
100   FakeMdnsResponderAdapter mdns_responder;
101 
102   mdns_responder.Init();
103   ASSERT_TRUE(mdns_responder.running());
104   mdns_responder.AddPtrEvent(
105       MakePtrEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
106                    kDefaultSocket));
107 
108   auto ptr_events = mdns_responder.TakePtrResponses();
109   EXPECT_TRUE(ptr_events.empty());
110 
111   auto result = mdns_responder.StartPtrQuery(kDefaultSocket, kTestServiceType);
112   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
113 
114   ptr_events = mdns_responder.TakePtrResponses();
115   ASSERT_EQ(1u, ptr_events.size());
116   auto labels = ptr_events[0].service_instance.GetLabels();
117   EXPECT_EQ(kTestServiceInstance, labels[0]);
118 
119   // TODO(btolsch): qname if PtrEvent gets it.
120   ErrorOr<DomainName> st =
121       DomainName::FromLabels(labels.begin() + 1, labels.end());
122   ASSERT_TRUE(st);
123   EXPECT_EQ(kTestServiceTypeCanon, st.value());
124 
125   result = mdns_responder.StopPtrQuery(kDefaultSocket, kTestServiceType);
126   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
127 
128   mdns_responder.Close();
129   ASSERT_FALSE(mdns_responder.running());
130 
131   mdns_responder.AddPtrEvent(
132       MakePtrEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
133                    kDefaultSocket));
134   result = mdns_responder.StartPtrQuery(kDefaultSocket, kTestServiceType);
135   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
136   ptr_events = mdns_responder.TakePtrResponses();
137   EXPECT_TRUE(ptr_events.empty());
138 }
139 
TEST(FakeMdnsResponderAdapterTest,SrvQueries)140 TEST(FakeMdnsResponderAdapterTest, SrvQueries) {
141   FakeMdnsResponderAdapter mdns_responder;
142 
143   mdns_responder.Init();
144   ASSERT_TRUE(mdns_responder.running());
145 
146   auto event =
147       MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
148                    "alpha", 12345, kDefaultSocket);
149   auto service_instance = event.service_instance;
150   auto domain_name = event.domain_name;
151   mdns_responder.AddSrvEvent(std::move(event));
152 
153   auto srv_events = mdns_responder.TakeSrvResponses();
154   EXPECT_TRUE(srv_events.empty());
155 
156   auto result = mdns_responder.StartSrvQuery(kDefaultSocket, service_instance);
157   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
158 
159   srv_events = mdns_responder.TakeSrvResponses();
160   ASSERT_EQ(1u, srv_events.size());
161   EXPECT_EQ(service_instance, srv_events[0].service_instance);
162   EXPECT_EQ(domain_name, srv_events[0].domain_name);
163   EXPECT_EQ(12345, srv_events[0].port);
164 
165   result = mdns_responder.StopSrvQuery(kDefaultSocket, service_instance);
166   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
167 
168   mdns_responder.Close();
169   ASSERT_FALSE(mdns_responder.running());
170 
171   mdns_responder.AddSrvEvent(
172       MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
173                    "alpha", 12345, kDefaultSocket));
174   result = mdns_responder.StartSrvQuery(kDefaultSocket, service_instance);
175   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
176   srv_events = mdns_responder.TakeSrvResponses();
177   EXPECT_TRUE(srv_events.empty());
178 }
179 
TEST(FakeMdnsResponderAdapterTest,TxtQueries)180 TEST(FakeMdnsResponderAdapterTest, TxtQueries) {
181   FakeMdnsResponderAdapter mdns_responder;
182 
183   mdns_responder.Init();
184   ASSERT_TRUE(mdns_responder.running());
185 
186   const auto txt_lines = std::vector<std::string>{"asdf", "jkl;", "j"};
187   auto event = MakeTxtEvent(kTestServiceInstance, kTestServiceName,
188                             kTestServiceProtocol, txt_lines, kDefaultSocket);
189   auto service_instance = event.service_instance;
190   mdns_responder.AddTxtEvent(std::move(event));
191 
192   auto txt_events = mdns_responder.TakeTxtResponses();
193   EXPECT_TRUE(txt_events.empty());
194 
195   auto result = mdns_responder.StartTxtQuery(kDefaultSocket, service_instance);
196   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
197 
198   txt_events = mdns_responder.TakeTxtResponses();
199   ASSERT_EQ(1u, txt_events.size());
200   EXPECT_EQ(service_instance, txt_events[0].service_instance);
201   EXPECT_EQ(txt_lines, txt_events[0].txt_info);
202 
203   result = mdns_responder.StopTxtQuery(kDefaultSocket, service_instance);
204   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
205 
206   mdns_responder.Close();
207   ASSERT_FALSE(mdns_responder.running());
208 
209   mdns_responder.AddTxtEvent(
210       MakeTxtEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
211                    txt_lines, kDefaultSocket));
212   result = mdns_responder.StartTxtQuery(kDefaultSocket, service_instance);
213   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
214   txt_events = mdns_responder.TakeTxtResponses();
215   EXPECT_TRUE(txt_events.empty());
216 }
217 
TEST(FakeMdnsResponderAdapterTest,RegisterServices)218 TEST(FakeMdnsResponderAdapterTest, RegisterServices) {
219   FakeMdnsResponderAdapter mdns_responder;
220 
221   mdns_responder.Init();
222   ASSERT_TRUE(mdns_responder.running());
223 
224   auto result = mdns_responder.RegisterService(
225       "instance", "name", "proto",
226       DomainName{{1, 'a', 5, 'l', 'o', 'c', 'a', 'l', 0}}, 12345,
227       {{"k1", "asdf"}, {"k2", "jkl"}});
228   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
229   EXPECT_EQ(1u, mdns_responder.registered_services().size());
230 
231   result = mdns_responder.RegisterService(
232       "instance2", "name", "proto",
233       DomainName{{1, 'b', 5, 'l', 'o', 'c', 'a', 'l', 0}}, 12346,
234       {{"k1", "asdf"}, {"k2", "jkl"}});
235   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
236   EXPECT_EQ(2u, mdns_responder.registered_services().size());
237 
238   result = mdns_responder.DeregisterService("instance", "name", "proto");
239   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
240   result = mdns_responder.DeregisterService("instance", "name", "proto");
241   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
242   EXPECT_EQ(1u, mdns_responder.registered_services().size());
243 
244   mdns_responder.Close();
245   ASSERT_FALSE(mdns_responder.running());
246   EXPECT_EQ(0u, mdns_responder.registered_services().size());
247 
248   result = mdns_responder.RegisterService(
249       "instance2", "name", "proto",
250       DomainName{{1, 'b', 5, 'l', 'o', 'c', 'a', 'l', 0}}, 12346,
251       {{"k1", "asdf"}, {"k2", "jkl"}});
252   EXPECT_NE(MdnsResponderErrorCode::kNoError, result);
253   EXPECT_EQ(0u, mdns_responder.registered_services().size());
254 }
255 
TEST(FakeMdnsResponderAdapterTest,RegisterInterfaces)256 TEST(FakeMdnsResponderAdapterTest, RegisterInterfaces) {
257   FakeMdnsResponderAdapter mdns_responder;
258 
259   mdns_responder.Init();
260   ASSERT_TRUE(mdns_responder.running());
261   EXPECT_EQ(0u, mdns_responder.registered_interfaces().size());
262 
263   Error result = mdns_responder.RegisterInterface(InterfaceInfo{}, IPSubnet{},
264                                                   kDefaultSocket);
265   EXPECT_TRUE(result.ok());
266   EXPECT_EQ(1u, mdns_responder.registered_interfaces().size());
267 
268   result = mdns_responder.RegisterInterface(InterfaceInfo{}, IPSubnet{},
269                                             kDefaultSocket);
270   EXPECT_FALSE(result.ok());
271   EXPECT_EQ(1u, mdns_responder.registered_interfaces().size());
272 
273   result = mdns_responder.RegisterInterface(InterfaceInfo{}, IPSubnet{},
274                                             kSecondSocket);
275   EXPECT_TRUE(result.ok());
276   EXPECT_EQ(2u, mdns_responder.registered_interfaces().size());
277 
278   result = mdns_responder.DeregisterInterface(kSecondSocket);
279   EXPECT_TRUE(result.ok());
280   EXPECT_EQ(1u, mdns_responder.registered_interfaces().size());
281   result = mdns_responder.DeregisterInterface(kSecondSocket);
282   EXPECT_FALSE(result.ok());
283   EXPECT_EQ(1u, mdns_responder.registered_interfaces().size());
284 
285   mdns_responder.Close();
286   ASSERT_FALSE(mdns_responder.running());
287   EXPECT_EQ(0u, mdns_responder.registered_interfaces().size());
288 
289   result = mdns_responder.RegisterInterface(InterfaceInfo{}, IPSubnet{},
290                                             kDefaultSocket);
291   EXPECT_FALSE(result.ok());
292   EXPECT_EQ(0u, mdns_responder.registered_interfaces().size());
293 }
294 
TEST(FakeMdnsResponderAdapterTest,UpdateTxtData)295 TEST(FakeMdnsResponderAdapterTest, UpdateTxtData) {
296   FakeMdnsResponderAdapter mdns_responder;
297 
298   mdns_responder.Init();
299   ASSERT_TRUE(mdns_responder.running());
300 
301   const std::map<std::string, std::string> txt_data1{{"k1", "asdf"},
302                                                      {"k2", "jkl"}};
303   auto result = mdns_responder.RegisterService(
304       "instance", "name", "proto",
305       DomainName{{1, 'a', 5, 'l', 'o', 'c', 'a', 'l', 0}}, 12345, txt_data1);
306   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
307   ASSERT_EQ(1u, mdns_responder.registered_services().size());
308   EXPECT_EQ(txt_data1, mdns_responder.registered_services()[0].txt_data);
309 
310   const std::map<std::string, std::string> txt_data2{
311       {"k1", "monkey"}, {"k2", "panda"}, {"k3", "turtle"}, {"k4", "rhino"}};
312   result = mdns_responder.UpdateTxtData("instance", "name", "proto", txt_data2);
313   EXPECT_EQ(MdnsResponderErrorCode::kNoError, result);
314   ASSERT_EQ(1u, mdns_responder.registered_services().size());
315   EXPECT_EQ(txt_data2, mdns_responder.registered_services()[0].txt_data);
316 }
317 
318 }  // namespace osp
319 }  // namespace openscreen
320