blob: 08401a45492b4d1eef6f5ea52894cc91fb0f6885 [file] [log] [blame]
// 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 "cast/common/public/service_info.h"
#include <cstdio>
#include <sstream>
#include "cast/common/public/testing/discovery_utils.h"
#include "discovery/dnssd/public/dns_sd_instance.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace openscreen {
namespace cast {
namespace {
constexpr NetworkInterfaceIndex kNetworkInterface = 0;
}
TEST(ServiceInfoTests, ConvertValidFromDnsSd) {
std::string instance = "InstanceId";
discovery::DnsSdTxtRecord txt = CreateValidTxt();
discovery::DnsSdInstanceEndpoint record(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
ErrorOr<ServiceInfo> info = DnsSdInstanceEndpointToServiceInfo(record);
ASSERT_TRUE(info.is_value()) << info;
EXPECT_EQ(info.value().unique_id, kTestUniqueId);
EXPECT_TRUE(info.value().v4_address);
EXPECT_EQ(info.value().v4_address, kAddressV4);
EXPECT_TRUE(info.value().v6_address);
EXPECT_EQ(info.value().v6_address, kAddressV6);
EXPECT_EQ(info.value().port, kPort);
EXPECT_EQ(info.value().unique_id, kTestUniqueId);
EXPECT_EQ(info.value().protocol_version, kTestVersion);
EXPECT_EQ(info.value().capabilities, kCapabilitiesParsed);
EXPECT_EQ(info.value().status, kStatusParsed);
EXPECT_EQ(info.value().model_name, kModelName);
EXPECT_EQ(info.value().friendly_name, kFriendlyName);
record = discovery::DnsSdInstanceEndpoint(instance, kCastV2ServiceId,
kCastV2DomainId, txt,
kNetworkInterface, kEndpointV4);
info = DnsSdInstanceEndpointToServiceInfo(record);
ASSERT_TRUE(info.is_value());
EXPECT_EQ(info.value().unique_id, kTestUniqueId);
EXPECT_TRUE(info.value().v4_address);
EXPECT_EQ(info.value().v4_address, kAddressV4);
EXPECT_FALSE(info.value().v6_address);
EXPECT_EQ(info.value().unique_id, kTestUniqueId);
EXPECT_EQ(info.value().protocol_version, kTestVersion);
EXPECT_EQ(info.value().capabilities, kCapabilitiesParsed);
EXPECT_EQ(info.value().status, kStatusParsed);
EXPECT_EQ(info.value().model_name, kModelName);
EXPECT_EQ(info.value().friendly_name, kFriendlyName);
record = discovery::DnsSdInstanceEndpoint(instance, kCastV2ServiceId,
kCastV2DomainId, txt,
kNetworkInterface, kEndpointV6);
info = DnsSdInstanceEndpointToServiceInfo(record);
ASSERT_TRUE(info.is_value());
EXPECT_EQ(info.value().unique_id, kTestUniqueId);
EXPECT_FALSE(info.value().v4_address);
EXPECT_TRUE(info.value().v6_address);
EXPECT_EQ(info.value().v6_address, kAddressV6);
EXPECT_EQ(info.value().unique_id, kTestUniqueId);
EXPECT_EQ(info.value().protocol_version, kTestVersion);
EXPECT_EQ(info.value().capabilities, kCapabilitiesParsed);
EXPECT_EQ(info.value().status, kStatusParsed);
EXPECT_EQ(info.value().model_name, kModelName);
EXPECT_EQ(info.value().friendly_name, kFriendlyName);
}
TEST(ServiceInfoTests, ConvertInvalidFromDnsSd) {
std::string instance = "InstanceId";
discovery::DnsSdTxtRecord txt = CreateValidTxt();
txt.ClearValue(kUniqueIdKey);
discovery::DnsSdInstanceEndpoint record(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
EXPECT_TRUE(DnsSdInstanceEndpointToServiceInfo(record).is_error());
txt = CreateValidTxt();
txt.ClearValue(kVersionKey);
record = discovery::DnsSdInstanceEndpoint(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
EXPECT_TRUE(DnsSdInstanceEndpointToServiceInfo(record).is_error());
txt = CreateValidTxt();
txt.ClearValue(kCapabilitiesKey);
record = discovery::DnsSdInstanceEndpoint(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
EXPECT_TRUE(DnsSdInstanceEndpointToServiceInfo(record).is_error());
txt = CreateValidTxt();
txt.ClearValue(kStatusKey);
record = discovery::DnsSdInstanceEndpoint(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
EXPECT_TRUE(DnsSdInstanceEndpointToServiceInfo(record).is_error());
txt = CreateValidTxt();
txt.ClearValue(kFriendlyNameKey);
record = discovery::DnsSdInstanceEndpoint(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
EXPECT_TRUE(DnsSdInstanceEndpointToServiceInfo(record).is_error());
txt = CreateValidTxt();
txt.ClearValue(kModelNameKey);
record = discovery::DnsSdInstanceEndpoint(
instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
kEndpointV4, kEndpointV6);
// Note: Model name is an optional field.
EXPECT_FALSE(DnsSdInstanceEndpointToServiceInfo(record).is_error());
}
TEST(ServiceInfoTests, ConvertValidToDnsSd) {
ServiceInfo info;
info.v4_address = kAddressV4;
info.v6_address = kAddressV6;
info.port = kPort;
info.unique_id = kTestUniqueId;
info.protocol_version = kTestVersion;
info.capabilities = kCapabilitiesParsed;
info.status = kStatusParsed;
info.model_name = kModelName;
info.friendly_name = kFriendlyName;
discovery::DnsSdInstance instance = ServiceInfoToDnsSdInstance(info);
CompareTxtString(instance.txt(), kUniqueIdKey, kTestUniqueId);
CompareTxtString(instance.txt(), kCapabilitiesKey, kCapabilitiesString);
CompareTxtString(instance.txt(), kModelNameKey, kModelName);
CompareTxtString(instance.txt(), kFriendlyNameKey, kFriendlyName);
CompareTxtInt(instance.txt(), kVersionKey, kTestVersion);
CompareTxtInt(instance.txt(), kStatusKey, kStatus);
}
TEST(ServiceInfoTests, ParseServiceInfoFromRealTXT) {
constexpr struct {
const char* key;
const char* value;
} kRealTXTForReceiverCastingYoutube[] = {
{"bs", "FA99CBBF17D0"},
// Note: Includes bits set that are not known:
{"ca", "208901"},
{"cd", "FED81089FA3FF851CF088AB33AB014C0"},
{"fn", u8"⚡ Yurovision® ULTRA™"},
{"ic", "/setup/icon.png"},
{"id", "4ef522244a5a877f35ddead7d98702e6"},
{"md", "Chromecast Ultra"},
{"nf", "2"},
{"rm", "6342FE65DD269999"},
{"rs", "YouTube"},
{"st", "1"},
{"ve", "05"},
};
discovery::DnsSdTxtRecord txt;
for (const auto e : kRealTXTForReceiverCastingYoutube) {
ASSERT_TRUE(txt.SetValue(e.key, e.value).ok());
}
const discovery::DnsSdInstanceEndpoint record(
"InstanceId", kCastV2ServiceId, kCastV2DomainId, std::move(txt),
kNetworkInterface, kEndpointV4, kEndpointV6);
const ErrorOr<ServiceInfo> result =
DnsSdInstanceEndpointToServiceInfo(record);
const ServiceInfo& info = result.value();
EXPECT_EQ(info.unique_id, "4ef522244a5a877f35ddead7d98702e6");
EXPECT_EQ(info.protocol_version, 5);
EXPECT_TRUE(info.capabilities & (kHasVideoOutput | kHasAudioOutput));
EXPECT_EQ(info.status, kBusy);
EXPECT_EQ(info.model_name, "Chromecast Ultra");
EXPECT_EQ(info.friendly_name, u8"⚡ Yurovision® ULTRA™");
}
} // namespace cast
} // namespace openscreen