• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 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 "discovery/dnssd/impl/conversion_layer.h"
6 
7 #include <algorithm>
8 #include <chrono>
9 #include <vector>
10 
11 #include "discovery/dnssd/impl/instance_key.h"
12 #include "discovery/dnssd/impl/service_key.h"
13 #include "discovery/dnssd/testing/fake_dns_record_factory.h"
14 #include "discovery/mdns/testing/mdns_test_util.h"
15 #include "gmock/gmock.h"
16 #include "gtest/gtest.h"
17 
18 namespace openscreen {
19 namespace discovery {
20 
21 // TXT Conversions.
TEST(DnsSdConversionLayerTest,TestCreateTxtEmpty)22 TEST(DnsSdConversionLayerTest, TestCreateTxtEmpty) {
23   TxtRecordRdata txt = MakeTxtRecord({});
24   ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
25   EXPECT_TRUE(record.is_value());
26   EXPECT_TRUE(record.value().IsEmpty());
27 }
28 
TEST(DnsSdConversionLayerTest,TestCreateTxtOnlyEmptyString)29 TEST(DnsSdConversionLayerTest, TestCreateTxtOnlyEmptyString) {
30   TxtRecordRdata txt;
31   ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
32   EXPECT_TRUE(record.is_value());
33   EXPECT_TRUE(record.value().IsEmpty());
34 }
35 
TEST(DnsSdConversionLayerTest,TestCreateTxtValidKeyValue)36 TEST(DnsSdConversionLayerTest, TestCreateTxtValidKeyValue) {
37   TxtRecordRdata txt = MakeTxtRecord({"name=value"});
38   ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
39   ASSERT_TRUE(record.is_value());
40   ASSERT_TRUE(record.value().GetValue("name").is_value());
41 
42   // EXPECT_STREQ is causing memory leaks
43   std::string expected = "value";
44   ASSERT_TRUE(record.value().GetValue("name").is_value());
45   const std::vector<uint8_t>& value = record.value().GetValue("name").value();
46   ASSERT_EQ(value.size(), expected.size());
47   for (size_t i = 0; i < expected.size(); i++) {
48     EXPECT_EQ(expected[i], value[i]);
49   }
50 }
51 
TEST(DnsSdConversionLayerTest,TestCreateTxtInvalidKeyValue)52 TEST(DnsSdConversionLayerTest, TestCreateTxtInvalidKeyValue) {
53   TxtRecordRdata txt = MakeTxtRecord({"=value"});
54   ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
55   EXPECT_TRUE(record.is_error());
56 }
57 
TEST(DnsSdConversionLayerTest,TestCreateTxtValidBool)58 TEST(DnsSdConversionLayerTest, TestCreateTxtValidBool) {
59   TxtRecordRdata txt = MakeTxtRecord({"name"});
60   ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
61   ASSERT_TRUE(record.is_value());
62   ASSERT_TRUE(record.value().GetFlag("name").is_value());
63   EXPECT_TRUE(record.value().GetFlag("name").value());
64 }
65 
66 // Get*QueryInfo methods.
TEST(DnsSdConversionLayerTest,GetInstanceQueryInfoTest)67 TEST(DnsSdConversionLayerTest, GetInstanceQueryInfoTest) {
68   InstanceKey key{"instance.Id", "_service-id._udp", "192.168.0.0"};
69   DnsQueryInfo query = GetInstanceQueryInfo(key);
70   EXPECT_EQ(query.dns_type, DnsType::kANY);
71   EXPECT_EQ(query.dns_class, DnsClass::kANY);
72   ASSERT_EQ(query.name.labels().size(), size_t{7});
73   EXPECT_EQ(query.name.labels()[0], "instance.Id");
74   EXPECT_EQ(query.name.labels()[1], "_service-id");
75   EXPECT_EQ(query.name.labels()[2], "_udp");
76   EXPECT_EQ(query.name.labels()[3], "192");
77   EXPECT_EQ(query.name.labels()[4], "168");
78   EXPECT_EQ(query.name.labels()[5], "0");
79   EXPECT_EQ(query.name.labels()[6], "0");
80 }
81 
TEST(DnsSdConversionLayerTest,GetPtrQueryInfoTest)82 TEST(DnsSdConversionLayerTest, GetPtrQueryInfoTest) {
83   ServiceKey key{"_service-id._udp", "192.168.0.0"};
84   DnsQueryInfo query = GetPtrQueryInfo(key);
85   EXPECT_EQ(query.dns_type, DnsType::kPTR);
86   EXPECT_EQ(query.dns_class, DnsClass::kANY);
87   ASSERT_EQ(query.name.labels().size(), size_t{6});
88   EXPECT_EQ(query.name.labels()[0], "_service-id");
89   EXPECT_EQ(query.name.labels()[1], "_udp");
90   EXPECT_EQ(query.name.labels()[2], "192");
91   EXPECT_EQ(query.name.labels()[3], "168");
92   EXPECT_EQ(query.name.labels()[4], "0");
93   EXPECT_EQ(query.name.labels()[5], "0");
94 }
95 
96 // GetDnsRecords tests.
TEST(DnsSdConversionLayerTest,GetDnsRecordsPtr)97 TEST(DnsSdConversionLayerTest, GetDnsRecordsPtr) {
98   DnsSdTxtRecord txt;
99   DnsSdInstanceEndpoint instance_endpoint(
100       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
101       FakeDnsRecordFactory::kDomainName, txt, 0,
102       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
103                  FakeDnsRecordFactory::kPortNum},
104       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
105                  FakeDnsRecordFactory::kPortNum});
106   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
107   auto it = std::find_if(records.begin(), records.end(),
108                          [](const MdnsRecord& record) {
109                            return record.dns_type() == DnsType::kPTR;
110                          });
111   ASSERT_NE(it, records.end());
112 
113   EXPECT_EQ(it->dns_class(), DnsClass::kIN);
114   EXPECT_EQ(it->record_type(), RecordType::kShared);
115   EXPECT_EQ(it->name().labels().size(), size_t{3});
116   EXPECT_EQ(it->name().labels()[0],
117             FakeDnsRecordFactory::kServiceNameServicePart);
118   EXPECT_EQ(it->name().labels()[1],
119             FakeDnsRecordFactory::kServiceNameProtocolPart);
120   EXPECT_EQ(it->name().labels()[2], FakeDnsRecordFactory::kDomainName);
121 
122   const auto& rdata = absl::get<PtrRecordRdata>(it->rdata());
123   EXPECT_EQ(rdata.ptr_domain().labels().size(), size_t{4});
124   EXPECT_EQ(rdata.ptr_domain().labels()[0],
125             FakeDnsRecordFactory::kInstanceName);
126   EXPECT_EQ(rdata.ptr_domain().labels()[1],
127             FakeDnsRecordFactory::kServiceNameServicePart);
128   EXPECT_EQ(rdata.ptr_domain().labels()[2],
129             FakeDnsRecordFactory::kServiceNameProtocolPart);
130   EXPECT_EQ(rdata.ptr_domain().labels()[3], FakeDnsRecordFactory::kDomainName);
131 }
132 
TEST(DnsSdConversionLayerTest,GetDnsRecordsSrv)133 TEST(DnsSdConversionLayerTest, GetDnsRecordsSrv) {
134   DnsSdTxtRecord txt;
135   DnsSdInstanceEndpoint instance_endpoint(
136       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
137       FakeDnsRecordFactory::kDomainName, txt, 0,
138       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
139                  FakeDnsRecordFactory::kPortNum},
140       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
141                  FakeDnsRecordFactory::kPortNum});
142   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
143   auto it = std::find_if(records.begin(), records.end(),
144                          [](const MdnsRecord& record) {
145                            return record.dns_type() == DnsType::kSRV;
146                          });
147   ASSERT_NE(it, records.end());
148 
149   EXPECT_EQ(it->dns_class(), DnsClass::kIN);
150   EXPECT_EQ(it->record_type(), RecordType::kUnique);
151   EXPECT_EQ(it->name().labels().size(), size_t{4});
152   EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
153   EXPECT_EQ(it->name().labels()[1],
154             FakeDnsRecordFactory::kServiceNameServicePart);
155   EXPECT_EQ(it->name().labels()[2],
156             FakeDnsRecordFactory::kServiceNameProtocolPart);
157   EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
158 
159   const auto& rdata = absl::get<SrvRecordRdata>(it->rdata());
160   EXPECT_EQ(rdata.priority(), 0);
161   EXPECT_EQ(rdata.weight(), 0);
162   EXPECT_EQ(rdata.port(), FakeDnsRecordFactory::kPortNum);
163 }
164 
TEST(DnsSdConversionLayerTest,GetDnsRecordsAPresent)165 TEST(DnsSdConversionLayerTest, GetDnsRecordsAPresent) {
166   DnsSdTxtRecord txt;
167   DnsSdInstanceEndpoint instance_endpoint(
168       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
169       FakeDnsRecordFactory::kDomainName, txt, 0,
170       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
171                  FakeDnsRecordFactory::kPortNum},
172       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
173                  FakeDnsRecordFactory::kPortNum});
174   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
175   auto it = std::find_if(records.begin(), records.end(),
176                          [](const MdnsRecord& record) {
177                            return record.dns_type() == DnsType::kA;
178                          });
179   ASSERT_NE(it, records.end());
180 
181   EXPECT_EQ(it->dns_class(), DnsClass::kIN);
182   EXPECT_EQ(it->record_type(), RecordType::kUnique);
183   EXPECT_EQ(it->name().labels().size(), size_t{4});
184   EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
185   EXPECT_EQ(it->name().labels()[1],
186             FakeDnsRecordFactory::kServiceNameServicePart);
187   EXPECT_EQ(it->name().labels()[2],
188             FakeDnsRecordFactory::kServiceNameProtocolPart);
189   EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
190 
191   const auto& rdata = absl::get<ARecordRdata>(it->rdata());
192   EXPECT_EQ(rdata.ipv4_address(),
193             IPAddress(FakeDnsRecordFactory::kV4AddressOctets));
194 }
195 
TEST(DnsSdConversionLayerTest,GetDnsRecordsANotPresent)196 TEST(DnsSdConversionLayerTest, GetDnsRecordsANotPresent) {
197   DnsSdTxtRecord txt;
198   DnsSdInstanceEndpoint instance_endpoint(
199       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
200       FakeDnsRecordFactory::kDomainName, txt, 0,
201       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
202                  FakeDnsRecordFactory::kPortNum});
203   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
204   auto it = std::find_if(records.begin(), records.end(),
205                          [](const MdnsRecord& record) {
206                            return record.dns_type() == DnsType::kA;
207                          });
208   EXPECT_EQ(it, records.end());
209 }
210 
TEST(DnsSdConversionLayerTest,GetDnsRecordsAAAAPresent)211 TEST(DnsSdConversionLayerTest, GetDnsRecordsAAAAPresent) {
212   DnsSdTxtRecord txt;
213   DnsSdInstanceEndpoint instance_endpoint(
214       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
215       FakeDnsRecordFactory::kDomainName, txt, 0,
216       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
217                  FakeDnsRecordFactory::kPortNum},
218       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
219                  FakeDnsRecordFactory::kPortNum});
220   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
221   auto it = std::find_if(records.begin(), records.end(),
222                          [](const MdnsRecord& record) {
223                            return record.dns_type() == DnsType::kAAAA;
224                          });
225   ASSERT_NE(it, records.end());
226 
227   EXPECT_EQ(it->dns_class(), DnsClass::kIN);
228   EXPECT_EQ(it->record_type(), RecordType::kUnique);
229   EXPECT_EQ(it->name().labels().size(), size_t{4});
230   EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
231   EXPECT_EQ(it->name().labels()[1],
232             FakeDnsRecordFactory::kServiceNameServicePart);
233   EXPECT_EQ(it->name().labels()[2],
234             FakeDnsRecordFactory::kServiceNameProtocolPart);
235   EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
236 
237   const auto& rdata = absl::get<AAAARecordRdata>(it->rdata());
238   EXPECT_EQ(rdata.ipv6_address(),
239             IPAddress(FakeDnsRecordFactory::kV6AddressHextets));
240 }
241 
TEST(DnsSdConversionLayerTest,GetDnsRecordsAAAANotPresent)242 TEST(DnsSdConversionLayerTest, GetDnsRecordsAAAANotPresent) {
243   DnsSdTxtRecord txt;
244   DnsSdInstanceEndpoint instance_endpoint(
245       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
246       FakeDnsRecordFactory::kDomainName, txt, 0,
247       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
248                  FakeDnsRecordFactory::kPortNum});
249   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
250   auto it = std::find_if(records.begin(), records.end(),
251                          [](const MdnsRecord& record) {
252                            return record.dns_type() == DnsType::kAAAA;
253                          });
254   EXPECT_EQ(it, records.end());
255 }
256 
TEST(DnsSdConversionLayerTest,GetDnsRecordsTxt)257 TEST(DnsSdConversionLayerTest, GetDnsRecordsTxt) {
258   DnsSdTxtRecord txt;
259   std::vector<uint8_t> value{'v', 'a', 'l', 'u', 'e'};
260   txt.SetValue("name", value);
261   txt.SetFlag("boolean", true);
262   DnsSdInstanceEndpoint instance_endpoint(
263       FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
264       FakeDnsRecordFactory::kDomainName, txt, 0,
265       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
266                  FakeDnsRecordFactory::kPortNum},
267       IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
268                  FakeDnsRecordFactory::kPortNum});
269   std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
270   auto it = std::find_if(records.begin(), records.end(),
271                          [](const MdnsRecord& record) {
272                            return record.dns_type() == DnsType::kTXT;
273                          });
274   ASSERT_NE(it, records.end());
275 
276   EXPECT_EQ(it->dns_class(), DnsClass::kIN);
277   EXPECT_EQ(it->record_type(), RecordType::kUnique);
278   EXPECT_EQ(it->name().labels().size(), size_t{4});
279   EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
280   EXPECT_EQ(it->name().labels()[1],
281             FakeDnsRecordFactory::kServiceNameServicePart);
282   EXPECT_EQ(it->name().labels()[2],
283             FakeDnsRecordFactory::kServiceNameProtocolPart);
284   EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
285 
286   const auto& rdata = absl::get<TxtRecordRdata>(it->rdata());
287   EXPECT_EQ(rdata.texts().size(), size_t{2});
288 
289   auto it2 =
290       std::find(rdata.texts().begin(), rdata.texts().end(), "name=value");
291   EXPECT_NE(it2, rdata.texts().end());
292 
293   it2 = std::find(rdata.texts().begin(), rdata.texts().end(), "boolean");
294   EXPECT_NE(it2, rdata.texts().end());
295 }
296 
297 }  // namespace discovery
298 }  // namespace openscreen
299