You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
299 lines
12 KiB
299 lines
12 KiB
// Copyright 2019 The Chromium Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
|
|
#include "discovery/dnssd/impl/conversion_layer.h"
|
|
|
|
#include <algorithm>
|
|
#include <chrono>
|
|
#include <vector>
|
|
|
|
#include "discovery/dnssd/impl/instance_key.h"
|
|
#include "discovery/dnssd/impl/service_key.h"
|
|
#include "discovery/dnssd/testing/fake_dns_record_factory.h"
|
|
#include "discovery/mdns/testing/mdns_test_util.h"
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
|
|
namespace openscreen {
|
|
namespace discovery {
|
|
|
|
// TXT Conversions.
|
|
TEST(DnsSdConversionLayerTest, TestCreateTxtEmpty) {
|
|
TxtRecordRdata txt = MakeTxtRecord({});
|
|
ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
|
|
EXPECT_TRUE(record.is_value());
|
|
EXPECT_TRUE(record.value().IsEmpty());
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, TestCreateTxtOnlyEmptyString) {
|
|
TxtRecordRdata txt;
|
|
ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
|
|
EXPECT_TRUE(record.is_value());
|
|
EXPECT_TRUE(record.value().IsEmpty());
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, TestCreateTxtValidKeyValue) {
|
|
TxtRecordRdata txt = MakeTxtRecord({"name=value"});
|
|
ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
|
|
ASSERT_TRUE(record.is_value());
|
|
ASSERT_TRUE(record.value().GetValue("name").is_value());
|
|
|
|
// EXPECT_STREQ is causing memory leaks
|
|
std::string expected = "value";
|
|
ASSERT_TRUE(record.value().GetValue("name").is_value());
|
|
const std::vector<uint8_t>& value = record.value().GetValue("name").value();
|
|
ASSERT_EQ(value.size(), expected.size());
|
|
for (size_t i = 0; i < expected.size(); i++) {
|
|
EXPECT_EQ(expected[i], value[i]);
|
|
}
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, TestCreateTxtInvalidKeyValue) {
|
|
TxtRecordRdata txt = MakeTxtRecord({"=value"});
|
|
ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
|
|
EXPECT_TRUE(record.is_error());
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, TestCreateTxtValidBool) {
|
|
TxtRecordRdata txt = MakeTxtRecord({"name"});
|
|
ErrorOr<DnsSdTxtRecord> record = CreateFromDnsTxt(txt);
|
|
ASSERT_TRUE(record.is_value());
|
|
ASSERT_TRUE(record.value().GetFlag("name").is_value());
|
|
EXPECT_TRUE(record.value().GetFlag("name").value());
|
|
}
|
|
|
|
// Get*QueryInfo methods.
|
|
TEST(DnsSdConversionLayerTest, GetInstanceQueryInfoTest) {
|
|
InstanceKey key{"instance.Id", "_service-id._udp", "192.168.0.0"};
|
|
DnsQueryInfo query = GetInstanceQueryInfo(key);
|
|
EXPECT_EQ(query.dns_type, DnsType::kANY);
|
|
EXPECT_EQ(query.dns_class, DnsClass::kANY);
|
|
ASSERT_EQ(query.name.labels().size(), size_t{7});
|
|
EXPECT_EQ(query.name.labels()[0], "instance.Id");
|
|
EXPECT_EQ(query.name.labels()[1], "_service-id");
|
|
EXPECT_EQ(query.name.labels()[2], "_udp");
|
|
EXPECT_EQ(query.name.labels()[3], "192");
|
|
EXPECT_EQ(query.name.labels()[4], "168");
|
|
EXPECT_EQ(query.name.labels()[5], "0");
|
|
EXPECT_EQ(query.name.labels()[6], "0");
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetPtrQueryInfoTest) {
|
|
ServiceKey key{"_service-id._udp", "192.168.0.0"};
|
|
DnsQueryInfo query = GetPtrQueryInfo(key);
|
|
EXPECT_EQ(query.dns_type, DnsType::kPTR);
|
|
EXPECT_EQ(query.dns_class, DnsClass::kANY);
|
|
ASSERT_EQ(query.name.labels().size(), size_t{6});
|
|
EXPECT_EQ(query.name.labels()[0], "_service-id");
|
|
EXPECT_EQ(query.name.labels()[1], "_udp");
|
|
EXPECT_EQ(query.name.labels()[2], "192");
|
|
EXPECT_EQ(query.name.labels()[3], "168");
|
|
EXPECT_EQ(query.name.labels()[4], "0");
|
|
EXPECT_EQ(query.name.labels()[5], "0");
|
|
}
|
|
|
|
// GetDnsRecords tests.
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsPtr) {
|
|
DnsSdTxtRecord txt;
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
|
|
FakeDnsRecordFactory::kPortNum},
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kPTR;
|
|
});
|
|
ASSERT_NE(it, records.end());
|
|
|
|
EXPECT_EQ(it->dns_class(), DnsClass::kIN);
|
|
EXPECT_EQ(it->record_type(), RecordType::kShared);
|
|
EXPECT_EQ(it->name().labels().size(), size_t{3});
|
|
EXPECT_EQ(it->name().labels()[0],
|
|
FakeDnsRecordFactory::kServiceNameServicePart);
|
|
EXPECT_EQ(it->name().labels()[1],
|
|
FakeDnsRecordFactory::kServiceNameProtocolPart);
|
|
EXPECT_EQ(it->name().labels()[2], FakeDnsRecordFactory::kDomainName);
|
|
|
|
const auto& rdata = absl::get<PtrRecordRdata>(it->rdata());
|
|
EXPECT_EQ(rdata.ptr_domain().labels().size(), size_t{4});
|
|
EXPECT_EQ(rdata.ptr_domain().labels()[0],
|
|
FakeDnsRecordFactory::kInstanceName);
|
|
EXPECT_EQ(rdata.ptr_domain().labels()[1],
|
|
FakeDnsRecordFactory::kServiceNameServicePart);
|
|
EXPECT_EQ(rdata.ptr_domain().labels()[2],
|
|
FakeDnsRecordFactory::kServiceNameProtocolPart);
|
|
EXPECT_EQ(rdata.ptr_domain().labels()[3], FakeDnsRecordFactory::kDomainName);
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsSrv) {
|
|
DnsSdTxtRecord txt;
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
|
|
FakeDnsRecordFactory::kPortNum},
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kSRV;
|
|
});
|
|
ASSERT_NE(it, records.end());
|
|
|
|
EXPECT_EQ(it->dns_class(), DnsClass::kIN);
|
|
EXPECT_EQ(it->record_type(), RecordType::kUnique);
|
|
EXPECT_EQ(it->name().labels().size(), size_t{4});
|
|
EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
|
|
EXPECT_EQ(it->name().labels()[1],
|
|
FakeDnsRecordFactory::kServiceNameServicePart);
|
|
EXPECT_EQ(it->name().labels()[2],
|
|
FakeDnsRecordFactory::kServiceNameProtocolPart);
|
|
EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
|
|
|
|
const auto& rdata = absl::get<SrvRecordRdata>(it->rdata());
|
|
EXPECT_EQ(rdata.priority(), 0);
|
|
EXPECT_EQ(rdata.weight(), 0);
|
|
EXPECT_EQ(rdata.port(), FakeDnsRecordFactory::kPortNum);
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsAPresent) {
|
|
DnsSdTxtRecord txt;
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
|
|
FakeDnsRecordFactory::kPortNum},
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kA;
|
|
});
|
|
ASSERT_NE(it, records.end());
|
|
|
|
EXPECT_EQ(it->dns_class(), DnsClass::kIN);
|
|
EXPECT_EQ(it->record_type(), RecordType::kUnique);
|
|
EXPECT_EQ(it->name().labels().size(), size_t{4});
|
|
EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
|
|
EXPECT_EQ(it->name().labels()[1],
|
|
FakeDnsRecordFactory::kServiceNameServicePart);
|
|
EXPECT_EQ(it->name().labels()[2],
|
|
FakeDnsRecordFactory::kServiceNameProtocolPart);
|
|
EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
|
|
|
|
const auto& rdata = absl::get<ARecordRdata>(it->rdata());
|
|
EXPECT_EQ(rdata.ipv4_address(),
|
|
IPAddress(FakeDnsRecordFactory::kV4AddressOctets));
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsANotPresent) {
|
|
DnsSdTxtRecord txt;
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kA;
|
|
});
|
|
EXPECT_EQ(it, records.end());
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsAAAAPresent) {
|
|
DnsSdTxtRecord txt;
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
|
|
FakeDnsRecordFactory::kPortNum},
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kAAAA;
|
|
});
|
|
ASSERT_NE(it, records.end());
|
|
|
|
EXPECT_EQ(it->dns_class(), DnsClass::kIN);
|
|
EXPECT_EQ(it->record_type(), RecordType::kUnique);
|
|
EXPECT_EQ(it->name().labels().size(), size_t{4});
|
|
EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
|
|
EXPECT_EQ(it->name().labels()[1],
|
|
FakeDnsRecordFactory::kServiceNameServicePart);
|
|
EXPECT_EQ(it->name().labels()[2],
|
|
FakeDnsRecordFactory::kServiceNameProtocolPart);
|
|
EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
|
|
|
|
const auto& rdata = absl::get<AAAARecordRdata>(it->rdata());
|
|
EXPECT_EQ(rdata.ipv6_address(),
|
|
IPAddress(FakeDnsRecordFactory::kV6AddressHextets));
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsAAAANotPresent) {
|
|
DnsSdTxtRecord txt;
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kAAAA;
|
|
});
|
|
EXPECT_EQ(it, records.end());
|
|
}
|
|
|
|
TEST(DnsSdConversionLayerTest, GetDnsRecordsTxt) {
|
|
DnsSdTxtRecord txt;
|
|
std::vector<uint8_t> value{'v', 'a', 'l', 'u', 'e'};
|
|
txt.SetValue("name", value);
|
|
txt.SetFlag("boolean", true);
|
|
DnsSdInstanceEndpoint instance_endpoint(
|
|
FakeDnsRecordFactory::kInstanceName, FakeDnsRecordFactory::kServiceName,
|
|
FakeDnsRecordFactory::kDomainName, txt, 0,
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV4AddressOctets),
|
|
FakeDnsRecordFactory::kPortNum},
|
|
IPEndpoint{IPAddress(FakeDnsRecordFactory::kV6AddressHextets),
|
|
FakeDnsRecordFactory::kPortNum});
|
|
std::vector<MdnsRecord> records = GetDnsRecords(instance_endpoint);
|
|
auto it = std::find_if(records.begin(), records.end(),
|
|
[](const MdnsRecord& record) {
|
|
return record.dns_type() == DnsType::kTXT;
|
|
});
|
|
ASSERT_NE(it, records.end());
|
|
|
|
EXPECT_EQ(it->dns_class(), DnsClass::kIN);
|
|
EXPECT_EQ(it->record_type(), RecordType::kUnique);
|
|
EXPECT_EQ(it->name().labels().size(), size_t{4});
|
|
EXPECT_EQ(it->name().labels()[0], FakeDnsRecordFactory::kInstanceName);
|
|
EXPECT_EQ(it->name().labels()[1],
|
|
FakeDnsRecordFactory::kServiceNameServicePart);
|
|
EXPECT_EQ(it->name().labels()[2],
|
|
FakeDnsRecordFactory::kServiceNameProtocolPart);
|
|
EXPECT_EQ(it->name().labels()[3], FakeDnsRecordFactory::kDomainName);
|
|
|
|
const auto& rdata = absl::get<TxtRecordRdata>(it->rdata());
|
|
EXPECT_EQ(rdata.texts().size(), size_t{2});
|
|
|
|
auto it2 =
|
|
std::find(rdata.texts().begin(), rdata.texts().end(), "name=value");
|
|
EXPECT_NE(it2, rdata.texts().end());
|
|
|
|
it2 = std::find(rdata.texts().begin(), rdata.texts().end(), "boolean");
|
|
EXPECT_NE(it2, rdata.texts().end());
|
|
}
|
|
|
|
} // namespace discovery
|
|
} // namespace openscreen
|