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 "cast/common/public/receiver_info.h"
6
7 #include <cstdio>
8 #include <sstream>
9
10 #include "cast/common/public/testing/discovery_utils.h"
11 #include "discovery/dnssd/public/dns_sd_instance.h"
12 #include "gmock/gmock.h"
13 #include "gtest/gtest.h"
14
15 namespace openscreen {
16 namespace cast {
17 namespace {
18
19 constexpr NetworkInterfaceIndex kNetworkInterface = 0;
20
21 }
22
TEST(ReceiverInfoTests,ConvertValidFromDnsSd)23 TEST(ReceiverInfoTests, ConvertValidFromDnsSd) {
24 std::string instance = "InstanceId";
25 discovery::DnsSdTxtRecord txt = CreateValidTxt();
26 discovery::DnsSdInstanceEndpoint record(
27 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
28 kEndpointV4, kEndpointV6);
29 ErrorOr<ReceiverInfo> info = DnsSdInstanceEndpointToReceiverInfo(record);
30 ASSERT_TRUE(info.is_value()) << info;
31 EXPECT_EQ(info.value().unique_id, kTestUniqueId);
32 EXPECT_TRUE(info.value().v4_address);
33 EXPECT_EQ(info.value().v4_address, kAddressV4);
34 EXPECT_TRUE(info.value().v6_address);
35 EXPECT_EQ(info.value().v6_address, kAddressV6);
36 EXPECT_EQ(info.value().port, kPort);
37 EXPECT_EQ(info.value().unique_id, kTestUniqueId);
38 EXPECT_EQ(info.value().protocol_version, kTestVersion);
39 EXPECT_EQ(info.value().capabilities, kCapabilitiesParsed);
40 EXPECT_EQ(info.value().status, kStatusParsed);
41 EXPECT_EQ(info.value().model_name, kModelName);
42 EXPECT_EQ(info.value().friendly_name, kFriendlyName);
43
44 record = discovery::DnsSdInstanceEndpoint(instance, kCastV2ServiceId,
45 kCastV2DomainId, txt,
46 kNetworkInterface, kEndpointV4);
47 info = DnsSdInstanceEndpointToReceiverInfo(record);
48 ASSERT_TRUE(info.is_value());
49 EXPECT_EQ(info.value().unique_id, kTestUniqueId);
50 EXPECT_TRUE(info.value().v4_address);
51 EXPECT_EQ(info.value().v4_address, kAddressV4);
52 EXPECT_FALSE(info.value().v6_address);
53 EXPECT_EQ(info.value().unique_id, kTestUniqueId);
54 EXPECT_EQ(info.value().protocol_version, kTestVersion);
55 EXPECT_EQ(info.value().capabilities, kCapabilitiesParsed);
56 EXPECT_EQ(info.value().status, kStatusParsed);
57 EXPECT_EQ(info.value().model_name, kModelName);
58 EXPECT_EQ(info.value().friendly_name, kFriendlyName);
59
60 record = discovery::DnsSdInstanceEndpoint(instance, kCastV2ServiceId,
61 kCastV2DomainId, txt,
62 kNetworkInterface, kEndpointV6);
63 info = DnsSdInstanceEndpointToReceiverInfo(record);
64 ASSERT_TRUE(info.is_value());
65 EXPECT_EQ(info.value().unique_id, kTestUniqueId);
66 EXPECT_FALSE(info.value().v4_address);
67 EXPECT_TRUE(info.value().v6_address);
68 EXPECT_EQ(info.value().v6_address, kAddressV6);
69 EXPECT_EQ(info.value().unique_id, kTestUniqueId);
70 EXPECT_EQ(info.value().protocol_version, kTestVersion);
71 EXPECT_EQ(info.value().capabilities, kCapabilitiesParsed);
72 EXPECT_EQ(info.value().status, kStatusParsed);
73 EXPECT_EQ(info.value().model_name, kModelName);
74 EXPECT_EQ(info.value().friendly_name, kFriendlyName);
75 }
76
TEST(ReceiverInfoTests,ConvertInvalidFromDnsSd)77 TEST(ReceiverInfoTests, ConvertInvalidFromDnsSd) {
78 std::string instance = "InstanceId";
79 discovery::DnsSdTxtRecord txt = CreateValidTxt();
80 txt.ClearValue(kUniqueIdKey);
81 discovery::DnsSdInstanceEndpoint record(
82 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
83 kEndpointV4, kEndpointV6);
84 EXPECT_TRUE(DnsSdInstanceEndpointToReceiverInfo(record).is_error());
85
86 txt = CreateValidTxt();
87 txt.ClearValue(kVersionKey);
88 record = discovery::DnsSdInstanceEndpoint(
89 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
90 kEndpointV4, kEndpointV6);
91 EXPECT_TRUE(DnsSdInstanceEndpointToReceiverInfo(record).is_error());
92
93 txt = CreateValidTxt();
94 txt.ClearValue(kCapabilitiesKey);
95 record = discovery::DnsSdInstanceEndpoint(
96 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
97 kEndpointV4, kEndpointV6);
98 EXPECT_TRUE(DnsSdInstanceEndpointToReceiverInfo(record).is_error());
99
100 txt = CreateValidTxt();
101 txt.ClearValue(kStatusKey);
102 record = discovery::DnsSdInstanceEndpoint(
103 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
104 kEndpointV4, kEndpointV6);
105 EXPECT_TRUE(DnsSdInstanceEndpointToReceiverInfo(record).is_error());
106
107 txt = CreateValidTxt();
108 txt.ClearValue(kFriendlyNameKey);
109 record = discovery::DnsSdInstanceEndpoint(
110 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
111 kEndpointV4, kEndpointV6);
112 EXPECT_TRUE(DnsSdInstanceEndpointToReceiverInfo(record).is_error());
113
114 txt = CreateValidTxt();
115 txt.ClearValue(kModelNameKey);
116 record = discovery::DnsSdInstanceEndpoint(
117 instance, kCastV2ServiceId, kCastV2DomainId, txt, kNetworkInterface,
118 kEndpointV4, kEndpointV6);
119 // Note: Model name is an optional field.
120 EXPECT_FALSE(DnsSdInstanceEndpointToReceiverInfo(record).is_error());
121 }
122
TEST(ReceiverInfoTests,ConvertValidToDnsSd)123 TEST(ReceiverInfoTests, ConvertValidToDnsSd) {
124 ReceiverInfo info;
125 info.v4_address = kAddressV4;
126 info.v6_address = kAddressV6;
127 info.port = kPort;
128 info.unique_id = kTestUniqueId;
129 info.protocol_version = kTestVersion;
130 info.capabilities = kCapabilitiesParsed;
131 info.status = kStatusParsed;
132 info.model_name = kModelName;
133 info.friendly_name = kFriendlyName;
134 discovery::DnsSdInstance instance = ReceiverInfoToDnsSdInstance(info);
135 CompareTxtString(instance.txt(), kUniqueIdKey, kTestUniqueId);
136 CompareTxtString(instance.txt(), kCapabilitiesKey, kCapabilitiesString);
137 CompareTxtString(instance.txt(), kModelNameKey, kModelName);
138 CompareTxtString(instance.txt(), kFriendlyNameKey, kFriendlyName);
139 CompareTxtInt(instance.txt(), kVersionKey, kTestVersion);
140 CompareTxtInt(instance.txt(), kStatusKey, kStatus);
141 }
142
TEST(ReceiverInfoTests,ParseReceiverInfoFromRealTXT)143 TEST(ReceiverInfoTests, ParseReceiverInfoFromRealTXT) {
144 constexpr struct {
145 const char* key;
146 const char* value;
147 } kRealTXTForReceiverCastingYoutube[] = {
148 {"bs", "FA99CBBF17D0"},
149 // Note: Includes bits set that are not known:
150 {"ca", "208901"},
151 {"cd", "FED81089FA3FF851CF088AB33AB014C0"},
152 {"fn", u8"⚡ Yurovision® ULTRA™"},
153 {"ic", "/setup/icon.png"},
154 {"id", "4ef522244a5a877f35ddead7d98702e6"},
155 {"md", "Chromecast Ultra"},
156 {"nf", "2"},
157 {"rm", "6342FE65DD269999"},
158 {"rs", "YouTube"},
159 {"st", "1"},
160 {"ve", "05"},
161 };
162
163 discovery::DnsSdTxtRecord txt;
164 for (const auto e : kRealTXTForReceiverCastingYoutube) {
165 ASSERT_TRUE(txt.SetValue(e.key, e.value).ok());
166 }
167 const discovery::DnsSdInstanceEndpoint record(
168 "InstanceId", kCastV2ServiceId, kCastV2DomainId, std::move(txt),
169 kNetworkInterface, kEndpointV4, kEndpointV6);
170
171 const ErrorOr<ReceiverInfo> result =
172 DnsSdInstanceEndpointToReceiverInfo(record);
173 const ReceiverInfo& info = result.value();
174 EXPECT_EQ(info.unique_id, "4ef522244a5a877f35ddead7d98702e6");
175 EXPECT_EQ(info.protocol_version, 5);
176 EXPECT_TRUE(info.capabilities & (kHasVideoOutput | kHasAudioOutput));
177 EXPECT_EQ(info.status, kBusy);
178 EXPECT_EQ(info.model_name, "Chromecast Ultra");
179 EXPECT_EQ(info.friendly_name, u8"⚡ Yurovision® ULTRA™");
180 }
181
182 } // namespace cast
183 } // namespace openscreen
184