1*3f982cf4SFabien Sanglard // Copyright 2019 The Chromium Authors. All rights reserved.
2*3f982cf4SFabien Sanglard // Use of this source code is governed by a BSD-style license that can be
3*3f982cf4SFabien Sanglard // found in the LICENSE file.
4*3f982cf4SFabien Sanglard
5*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_responder.h"
6*3f982cf4SFabien Sanglard
7*3f982cf4SFabien Sanglard #include <utility>
8*3f982cf4SFabien Sanglard
9*3f982cf4SFabien Sanglard #include "discovery/common/config.h"
10*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_probe_manager.h"
11*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_random.h"
12*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_receiver.h"
13*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_records.h"
14*3f982cf4SFabien Sanglard #include "discovery/mdns/mdns_sender.h"
15*3f982cf4SFabien Sanglard #include "platform/test/fake_clock.h"
16*3f982cf4SFabien Sanglard #include "platform/test/fake_task_runner.h"
17*3f982cf4SFabien Sanglard #include "platform/test/fake_udp_socket.h"
18*3f982cf4SFabien Sanglard
19*3f982cf4SFabien Sanglard namespace openscreen {
20*3f982cf4SFabien Sanglard namespace discovery {
21*3f982cf4SFabien Sanglard namespace {
22*3f982cf4SFabien Sanglard
23*3f982cf4SFabien Sanglard constexpr Clock::duration kMaximumSharedRecordResponseDelayMs(120 * 1000);
24*3f982cf4SFabien Sanglard
ContainsRecordType(const std::vector<MdnsRecord> & records,DnsType type)25*3f982cf4SFabien Sanglard bool ContainsRecordType(const std::vector<MdnsRecord>& records, DnsType type) {
26*3f982cf4SFabien Sanglard return std::find_if(records.begin(), records.end(),
27*3f982cf4SFabien Sanglard [type](const MdnsRecord& record) {
28*3f982cf4SFabien Sanglard return record.dns_type() == type;
29*3f982cf4SFabien Sanglard }) != records.end();
30*3f982cf4SFabien Sanglard }
31*3f982cf4SFabien Sanglard
CheckSingleNsecRecordType(const MdnsMessage & message,DnsType type)32*3f982cf4SFabien Sanglard void CheckSingleNsecRecordType(const MdnsMessage& message, DnsType type) {
33*3f982cf4SFabien Sanglard ASSERT_EQ(message.answers().size(), size_t{1});
34*3f982cf4SFabien Sanglard const MdnsRecord record = message.answers()[0];
35*3f982cf4SFabien Sanglard
36*3f982cf4SFabien Sanglard ASSERT_EQ(record.dns_type(), DnsType::kNSEC);
37*3f982cf4SFabien Sanglard const NsecRecordRdata& rdata = absl::get<NsecRecordRdata>(record.rdata());
38*3f982cf4SFabien Sanglard
39*3f982cf4SFabien Sanglard ASSERT_EQ(rdata.types().size(), size_t{1});
40*3f982cf4SFabien Sanglard EXPECT_EQ(rdata.types()[0], type);
41*3f982cf4SFabien Sanglard }
42*3f982cf4SFabien Sanglard
CheckPtrDomain(const MdnsRecord & record,const DomainName & domain)43*3f982cf4SFabien Sanglard void CheckPtrDomain(const MdnsRecord& record, const DomainName& domain) {
44*3f982cf4SFabien Sanglard ASSERT_EQ(record.dns_type(), DnsType::kPTR);
45*3f982cf4SFabien Sanglard const PtrRecordRdata& rdata = absl::get<PtrRecordRdata>(record.rdata());
46*3f982cf4SFabien Sanglard
47*3f982cf4SFabien Sanglard EXPECT_EQ(rdata.ptr_domain(), domain);
48*3f982cf4SFabien Sanglard }
49*3f982cf4SFabien Sanglard
ExpectContainsNsecRecordType(const std::vector<MdnsRecord> & records,DnsType type)50*3f982cf4SFabien Sanglard void ExpectContainsNsecRecordType(const std::vector<MdnsRecord>& records,
51*3f982cf4SFabien Sanglard DnsType type) {
52*3f982cf4SFabien Sanglard auto it = std::find_if(
53*3f982cf4SFabien Sanglard records.begin(), records.end(), [type](const MdnsRecord& record) {
54*3f982cf4SFabien Sanglard if (record.dns_type() != DnsType::kNSEC) {
55*3f982cf4SFabien Sanglard return false;
56*3f982cf4SFabien Sanglard }
57*3f982cf4SFabien Sanglard
58*3f982cf4SFabien Sanglard const NsecRecordRdata& rdata =
59*3f982cf4SFabien Sanglard absl::get<NsecRecordRdata>(record.rdata());
60*3f982cf4SFabien Sanglard return rdata.types().size() == 1 && rdata.types()[0] == type;
61*3f982cf4SFabien Sanglard });
62*3f982cf4SFabien Sanglard EXPECT_TRUE(it != records.end());
63*3f982cf4SFabien Sanglard }
64*3f982cf4SFabien Sanglard
65*3f982cf4SFabien Sanglard } // namespace
66*3f982cf4SFabien Sanglard
67*3f982cf4SFabien Sanglard using testing::_;
68*3f982cf4SFabien Sanglard using testing::Args;
69*3f982cf4SFabien Sanglard using testing::Invoke;
70*3f982cf4SFabien Sanglard using testing::Return;
71*3f982cf4SFabien Sanglard using testing::StrictMock;
72*3f982cf4SFabien Sanglard
73*3f982cf4SFabien Sanglard class MockRecordHandler : public MdnsResponder::RecordHandler {
74*3f982cf4SFabien Sanglard public:
AddRecord(MdnsRecord record)75*3f982cf4SFabien Sanglard void AddRecord(MdnsRecord record) { records_.push_back(record); }
76*3f982cf4SFabien Sanglard
77*3f982cf4SFabien Sanglard MOCK_METHOD3(HasRecords, bool(const DomainName&, DnsType, DnsClass));
78*3f982cf4SFabien Sanglard
GetRecords(const DomainName & name,DnsType type,DnsClass clazz)79*3f982cf4SFabien Sanglard std::vector<MdnsRecord::ConstRef> GetRecords(const DomainName& name,
80*3f982cf4SFabien Sanglard DnsType type,
81*3f982cf4SFabien Sanglard DnsClass clazz) override {
82*3f982cf4SFabien Sanglard std::vector<MdnsRecord::ConstRef> records;
83*3f982cf4SFabien Sanglard for (const auto& record : records_) {
84*3f982cf4SFabien Sanglard if (type == DnsType::kANY || record.dns_type() == type) {
85*3f982cf4SFabien Sanglard records.push_back(record);
86*3f982cf4SFabien Sanglard }
87*3f982cf4SFabien Sanglard }
88*3f982cf4SFabien Sanglard
89*3f982cf4SFabien Sanglard return records;
90*3f982cf4SFabien Sanglard }
91*3f982cf4SFabien Sanglard
GetPtrRecords(DnsClass clazz)92*3f982cf4SFabien Sanglard std::vector<MdnsRecord::ConstRef> GetPtrRecords(DnsClass clazz) override {
93*3f982cf4SFabien Sanglard std::vector<MdnsRecord::ConstRef> records;
94*3f982cf4SFabien Sanglard for (const auto& record : records_) {
95*3f982cf4SFabien Sanglard if (record.dns_type() == DnsType::kPTR) {
96*3f982cf4SFabien Sanglard records.push_back(record);
97*3f982cf4SFabien Sanglard }
98*3f982cf4SFabien Sanglard }
99*3f982cf4SFabien Sanglard
100*3f982cf4SFabien Sanglard return records;
101*3f982cf4SFabien Sanglard }
102*3f982cf4SFabien Sanglard
103*3f982cf4SFabien Sanglard private:
104*3f982cf4SFabien Sanglard std::vector<MdnsRecord> records_;
105*3f982cf4SFabien Sanglard };
106*3f982cf4SFabien Sanglard
107*3f982cf4SFabien Sanglard class MockMdnsSender : public MdnsSender {
108*3f982cf4SFabien Sanglard public:
MockMdnsSender(UdpSocket * socket)109*3f982cf4SFabien Sanglard explicit MockMdnsSender(UdpSocket* socket) : MdnsSender(socket) {}
110*3f982cf4SFabien Sanglard
111*3f982cf4SFabien Sanglard MOCK_METHOD1(SendMulticast, Error(const MdnsMessage& message));
112*3f982cf4SFabien Sanglard MOCK_METHOD2(SendMessage,
113*3f982cf4SFabien Sanglard Error(const MdnsMessage& message, const IPEndpoint& endpoint));
114*3f982cf4SFabien Sanglard };
115*3f982cf4SFabien Sanglard
116*3f982cf4SFabien Sanglard class MockProbeManager : public MdnsProbeManager {
117*3f982cf4SFabien Sanglard public:
118*3f982cf4SFabien Sanglard MOCK_CONST_METHOD1(IsDomainClaimed, bool(const DomainName&));
119*3f982cf4SFabien Sanglard MOCK_METHOD2(RespondToProbeQuery,
120*3f982cf4SFabien Sanglard void(const MdnsMessage&, const IPEndpoint&));
121*3f982cf4SFabien Sanglard };
122*3f982cf4SFabien Sanglard
123*3f982cf4SFabien Sanglard class MdnsResponderTest : public testing::Test {
124*3f982cf4SFabien Sanglard public:
MdnsResponderTest()125*3f982cf4SFabien Sanglard MdnsResponderTest()
126*3f982cf4SFabien Sanglard : clock_(Clock::now()),
127*3f982cf4SFabien Sanglard task_runner_(&clock_),
128*3f982cf4SFabien Sanglard socket_(&task_runner_),
129*3f982cf4SFabien Sanglard sender_(&socket_),
130*3f982cf4SFabien Sanglard receiver_(config_),
131*3f982cf4SFabien Sanglard responder_(&record_handler_,
132*3f982cf4SFabien Sanglard &probe_manager_,
133*3f982cf4SFabien Sanglard &sender_,
134*3f982cf4SFabien Sanglard &receiver_,
135*3f982cf4SFabien Sanglard &task_runner_,
136*3f982cf4SFabien Sanglard FakeClock::now,
137*3f982cf4SFabien Sanglard &random_,
138*3f982cf4SFabien Sanglard config_) {}
139*3f982cf4SFabien Sanglard
140*3f982cf4SFabien Sanglard protected:
GetFakePtrRecord(const DomainName & target)141*3f982cf4SFabien Sanglard MdnsRecord GetFakePtrRecord(const DomainName& target) {
142*3f982cf4SFabien Sanglard DomainName name(++target.labels().begin(), target.labels().end());
143*3f982cf4SFabien Sanglard PtrRecordRdata rdata(target);
144*3f982cf4SFabien Sanglard return MdnsRecord(std::move(name), DnsType::kPTR, DnsClass::kIN,
145*3f982cf4SFabien Sanglard RecordType::kUnique, std::chrono::seconds(0), rdata);
146*3f982cf4SFabien Sanglard }
147*3f982cf4SFabien Sanglard
GetFakeSrvRecord(const DomainName & name)148*3f982cf4SFabien Sanglard MdnsRecord GetFakeSrvRecord(const DomainName& name) {
149*3f982cf4SFabien Sanglard SrvRecordRdata rdata(0, 0, 80, name);
150*3f982cf4SFabien Sanglard return MdnsRecord(name, DnsType::kSRV, DnsClass::kIN, RecordType::kUnique,
151*3f982cf4SFabien Sanglard std::chrono::seconds(0), rdata);
152*3f982cf4SFabien Sanglard }
153*3f982cf4SFabien Sanglard
GetFakeTxtRecord(const DomainName & name)154*3f982cf4SFabien Sanglard MdnsRecord GetFakeTxtRecord(const DomainName& name) {
155*3f982cf4SFabien Sanglard TxtRecordRdata rdata;
156*3f982cf4SFabien Sanglard return MdnsRecord(name, DnsType::kTXT, DnsClass::kIN, RecordType::kUnique,
157*3f982cf4SFabien Sanglard std::chrono::seconds(0), rdata);
158*3f982cf4SFabien Sanglard }
159*3f982cf4SFabien Sanglard
GetFakeARecord(const DomainName & name)160*3f982cf4SFabien Sanglard MdnsRecord GetFakeARecord(const DomainName& name) {
161*3f982cf4SFabien Sanglard ARecordRdata rdata(IPAddress(192, 168, 0, 0));
162*3f982cf4SFabien Sanglard return MdnsRecord(name, DnsType::kA, DnsClass::kIN, RecordType::kUnique,
163*3f982cf4SFabien Sanglard std::chrono::seconds(0), rdata);
164*3f982cf4SFabien Sanglard }
165*3f982cf4SFabien Sanglard
GetFakeAAAARecord(const DomainName & name)166*3f982cf4SFabien Sanglard MdnsRecord GetFakeAAAARecord(const DomainName& name) {
167*3f982cf4SFabien Sanglard AAAARecordRdata rdata(IPAddress(1, 2, 3, 4, 5, 6, 7, 8));
168*3f982cf4SFabien Sanglard return MdnsRecord(name, DnsType::kAAAA, DnsClass::kIN, RecordType::kUnique,
169*3f982cf4SFabien Sanglard std::chrono::seconds(0), rdata);
170*3f982cf4SFabien Sanglard }
171*3f982cf4SFabien Sanglard
OnMessageReceived(const MdnsMessage & message,const IPEndpoint & src)172*3f982cf4SFabien Sanglard void OnMessageReceived(const MdnsMessage& message, const IPEndpoint& src) {
173*3f982cf4SFabien Sanglard responder_.OnMessageReceived(message, src);
174*3f982cf4SFabien Sanglard }
175*3f982cf4SFabien Sanglard
QueryForRecordTypeWhenNonePresent(DnsType type)176*3f982cf4SFabien Sanglard void QueryForRecordTypeWhenNonePresent(DnsType type) {
177*3f982cf4SFabien Sanglard MdnsQuestion question(domain_, type, DnsClass::kANY,
178*3f982cf4SFabien Sanglard ResponseType::kMulticast);
179*3f982cf4SFabien Sanglard MdnsMessage message(0, MessageType::Query);
180*3f982cf4SFabien Sanglard message.AddQuestion(question);
181*3f982cf4SFabien Sanglard
182*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
183*3f982cf4SFabien Sanglard .WillOnce([type](const MdnsMessage& msg) -> Error {
184*3f982cf4SFabien Sanglard CheckSingleNsecRecordType(msg, type);
185*3f982cf4SFabien Sanglard return Error::None();
186*3f982cf4SFabien Sanglard });
187*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
188*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
189*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
190*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
191*3f982cf4SFabien Sanglard }
192*3f982cf4SFabien Sanglard
CreateMulticastMdnsQuery(DnsType type)193*3f982cf4SFabien Sanglard MdnsMessage CreateMulticastMdnsQuery(DnsType type) {
194*3f982cf4SFabien Sanglard MdnsQuestion question(domain_, type, DnsClass::kANY,
195*3f982cf4SFabien Sanglard ResponseType::kMulticast);
196*3f982cf4SFabien Sanglard MdnsMessage message(0, MessageType::Query);
197*3f982cf4SFabien Sanglard message.AddQuestion(std::move(question));
198*3f982cf4SFabien Sanglard
199*3f982cf4SFabien Sanglard return message;
200*3f982cf4SFabien Sanglard }
201*3f982cf4SFabien Sanglard
CreateTypeEnumerationQuery()202*3f982cf4SFabien Sanglard MdnsMessage CreateTypeEnumerationQuery() {
203*3f982cf4SFabien Sanglard MdnsQuestion question(type_enumeration_domain_, DnsType::kPTR,
204*3f982cf4SFabien Sanglard DnsClass::kANY, ResponseType::kMulticast);
205*3f982cf4SFabien Sanglard MdnsMessage message(0, MessageType::Query);
206*3f982cf4SFabien Sanglard message.AddQuestion(std::move(question));
207*3f982cf4SFabien Sanglard
208*3f982cf4SFabien Sanglard return message;
209*3f982cf4SFabien Sanglard }
210*3f982cf4SFabien Sanglard
211*3f982cf4SFabien Sanglard const Config config_;
212*3f982cf4SFabien Sanglard FakeClock clock_;
213*3f982cf4SFabien Sanglard FakeTaskRunner task_runner_;
214*3f982cf4SFabien Sanglard FakeUdpSocket socket_;
215*3f982cf4SFabien Sanglard StrictMock<MockMdnsSender> sender_;
216*3f982cf4SFabien Sanglard StrictMock<MockRecordHandler> record_handler_;
217*3f982cf4SFabien Sanglard StrictMock<MockProbeManager> probe_manager_;
218*3f982cf4SFabien Sanglard MdnsReceiver receiver_;
219*3f982cf4SFabien Sanglard MdnsRandom random_;
220*3f982cf4SFabien Sanglard MdnsResponder responder_;
221*3f982cf4SFabien Sanglard
222*3f982cf4SFabien Sanglard DomainName domain_{"instance", "_googlecast", "_tcp", "local"};
223*3f982cf4SFabien Sanglard DomainName type_enumeration_domain_{"_services", "_dns-sd", "_udp", "local"};
224*3f982cf4SFabien Sanglard IPEndpoint endpoint_{IPAddress(192, 168, 0, 0), 80};
225*3f982cf4SFabien Sanglard };
226*3f982cf4SFabien Sanglard
227*3f982cf4SFabien Sanglard // Validate that when records may be sent from multiple receivers, the broadcast
228*3f982cf4SFabien Sanglard // is delayed and it is not delayed otherwise.
TEST_F(MdnsResponderTest,OwnedRecordsSentImmediately)229*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, OwnedRecordsSentImmediately) {
230*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
231*3f982cf4SFabien Sanglard
232*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
233*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
234*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
235*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
236*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(1);
237*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
238*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&sender_);
239*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&record_handler_);
240*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&probe_manager_);
241*3f982cf4SFabien Sanglard
242*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(0);
243*3f982cf4SFabien Sanglard clock_.Advance(Clock::duration(kMaximumSharedRecordResponseDelayMs));
244*3f982cf4SFabien Sanglard }
245*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,NonOwnedRecordsDelayed)246*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, NonOwnedRecordsDelayed) {
247*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
248*3f982cf4SFabien Sanglard
249*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(false));
250*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
251*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
252*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
253*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(0);
254*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
255*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&sender_);
256*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&record_handler_);
257*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&probe_manager_);
258*3f982cf4SFabien Sanglard
259*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(1);
260*3f982cf4SFabien Sanglard clock_.Advance(Clock::duration(kMaximumSharedRecordResponseDelayMs));
261*3f982cf4SFabien Sanglard }
262*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,MultipleQuestionsProcessed)263*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, MultipleQuestionsProcessed) {
264*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
265*3f982cf4SFabien Sanglard MdnsQuestion question2(domain_, DnsType::kANY, DnsClass::kANY,
266*3f982cf4SFabien Sanglard ResponseType::kMulticast);
267*3f982cf4SFabien Sanglard message.AddQuestion(std::move(question2));
268*3f982cf4SFabien Sanglard
269*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_))
270*3f982cf4SFabien Sanglard .WillOnce(Return(true))
271*3f982cf4SFabien Sanglard .WillOnce(Return(false));
272*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
273*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
274*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
275*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(1);
276*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
277*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&sender_);
278*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&record_handler_);
279*3f982cf4SFabien Sanglard testing::Mock::VerifyAndClearExpectations(&probe_manager_);
280*3f982cf4SFabien Sanglard
281*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(1);
282*3f982cf4SFabien Sanglard clock_.Advance(Clock::duration(kMaximumSharedRecordResponseDelayMs));
283*3f982cf4SFabien Sanglard }
284*3f982cf4SFabien Sanglard
285*3f982cf4SFabien Sanglard // Validate that the correct messaging scheme (unicast vs multicast) is used.
TEST_F(MdnsResponderTest,UnicastMessageSentOverUnicast)286*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, UnicastMessageSentOverUnicast) {
287*3f982cf4SFabien Sanglard MdnsQuestion question(domain_, DnsType::kANY, DnsClass::kANY,
288*3f982cf4SFabien Sanglard ResponseType::kUnicast);
289*3f982cf4SFabien Sanglard MdnsMessage message(0, MessageType::Query);
290*3f982cf4SFabien Sanglard message.AddQuestion(question);
291*3f982cf4SFabien Sanglard
292*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
293*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
294*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
295*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
296*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMessage(_, endpoint_)).Times(1);
297*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
298*3f982cf4SFabien Sanglard }
299*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,MulticastMessageSentOverMulticast)300*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, MulticastMessageSentOverMulticast) {
301*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
302*3f982cf4SFabien Sanglard
303*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
304*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
305*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
306*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
307*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_)).Times(1);
308*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
309*3f982cf4SFabien Sanglard }
310*3f982cf4SFabien Sanglard
311*3f982cf4SFabien Sanglard // Validate that records are added as expected based on the query type, and that
312*3f982cf4SFabien Sanglard // additional records are populated as specified in RFC 6762 and 6763.
TEST_F(MdnsResponderTest,AnyQueryResultsAllApplied)313*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, AnyQueryResultsAllApplied) {
314*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
315*3f982cf4SFabien Sanglard
316*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
317*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
318*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
319*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
320*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
321*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
322*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeAAAARecord(domain_));
323*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
324*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
325*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
326*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
327*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{0});
328*3f982cf4SFabien Sanglard
329*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{4});
330*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kSRV));
331*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kTXT));
332*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kA));
333*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kAAAA));
334*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(message.answers(), DnsType::kPTR));
335*3f982cf4SFabien Sanglard return Error::None();
336*3f982cf4SFabien Sanglard });
337*3f982cf4SFabien Sanglard
338*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
339*3f982cf4SFabien Sanglard }
340*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,PtrQueryResultsApplied)341*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, PtrQueryResultsApplied) {
342*3f982cf4SFabien Sanglard DomainName ptr_domain{"_googlecast", "_tcp", "local"};
343*3f982cf4SFabien Sanglard MdnsQuestion question(ptr_domain, DnsType::kPTR, DnsClass::kANY,
344*3f982cf4SFabien Sanglard ResponseType::kMulticast);
345*3f982cf4SFabien Sanglard MdnsMessage message(0, MessageType::Query);
346*3f982cf4SFabien Sanglard message.AddQuestion(question);
347*3f982cf4SFabien Sanglard
348*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
349*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
350*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
351*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
352*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
353*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
354*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
355*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeAAAARecord(domain_));
356*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
357*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
358*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
359*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
360*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{4});
361*3f982cf4SFabien Sanglard
362*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
363*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kPTR));
364*3f982cf4SFabien Sanglard
365*3f982cf4SFabien Sanglard const auto& records = message.additional_records();
366*3f982cf4SFabien Sanglard EXPECT_EQ(records.size(), size_t{4});
367*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kSRV));
368*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kTXT));
369*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kA));
370*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kAAAA));
371*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kPTR));
372*3f982cf4SFabien Sanglard
373*3f982cf4SFabien Sanglard return Error::None();
374*3f982cf4SFabien Sanglard });
375*3f982cf4SFabien Sanglard
376*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
377*3f982cf4SFabien Sanglard }
378*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,SrvQueryResultsApplied)379*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, SrvQueryResultsApplied) {
380*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kSRV);
381*3f982cf4SFabien Sanglard
382*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
383*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
384*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
385*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
386*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
387*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
388*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
389*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeAAAARecord(domain_));
390*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
391*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
392*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
393*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
394*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{2});
395*3f982cf4SFabien Sanglard
396*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
397*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kSRV));
398*3f982cf4SFabien Sanglard
399*3f982cf4SFabien Sanglard const auto& records = message.additional_records();
400*3f982cf4SFabien Sanglard EXPECT_EQ(records.size(), size_t{2});
401*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kA));
402*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kAAAA));
403*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kSRV));
404*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kTXT));
405*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kPTR));
406*3f982cf4SFabien Sanglard
407*3f982cf4SFabien Sanglard return Error::None();
408*3f982cf4SFabien Sanglard });
409*3f982cf4SFabien Sanglard
410*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
411*3f982cf4SFabien Sanglard }
412*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,AQueryResultsApplied)413*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, AQueryResultsApplied) {
414*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kA);
415*3f982cf4SFabien Sanglard
416*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
417*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
418*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
419*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
420*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
421*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
422*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
423*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeAAAARecord(domain_));
424*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
425*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
426*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
427*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
428*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{1});
429*3f982cf4SFabien Sanglard
430*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
431*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kA));
432*3f982cf4SFabien Sanglard
433*3f982cf4SFabien Sanglard const auto& records = message.additional_records();
434*3f982cf4SFabien Sanglard EXPECT_EQ(records.size(), size_t{1});
435*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kAAAA));
436*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kA));
437*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kSRV));
438*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kTXT));
439*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kPTR));
440*3f982cf4SFabien Sanglard
441*3f982cf4SFabien Sanglard return Error::None();
442*3f982cf4SFabien Sanglard });
443*3f982cf4SFabien Sanglard
444*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
445*3f982cf4SFabien Sanglard }
446*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,AAAAQueryResultsApplied)447*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, AAAAQueryResultsApplied) {
448*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kAAAA);
449*3f982cf4SFabien Sanglard
450*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
451*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
452*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
453*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
454*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
455*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
456*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
457*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeAAAARecord(domain_));
458*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
459*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
460*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
461*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
462*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{1});
463*3f982cf4SFabien Sanglard
464*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
465*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kAAAA));
466*3f982cf4SFabien Sanglard
467*3f982cf4SFabien Sanglard const auto& records = message.additional_records();
468*3f982cf4SFabien Sanglard EXPECT_EQ(records.size(), size_t{1});
469*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(records, DnsType::kA));
470*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kAAAA));
471*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kSRV));
472*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kTXT));
473*3f982cf4SFabien Sanglard EXPECT_FALSE(ContainsRecordType(records, DnsType::kPTR));
474*3f982cf4SFabien Sanglard
475*3f982cf4SFabien Sanglard return Error::None();
476*3f982cf4SFabien Sanglard });
477*3f982cf4SFabien Sanglard
478*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
479*3f982cf4SFabien Sanglard }
480*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,MessageOnlySentIfAnswerNotKnown)481*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, MessageOnlySentIfAnswerNotKnown) {
482*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kAAAA);
483*3f982cf4SFabien Sanglard MdnsRecord aaaa_record = GetFakeAAAARecord(domain_);
484*3f982cf4SFabien Sanglard message.AddAnswer(aaaa_record);
485*3f982cf4SFabien Sanglard
486*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
487*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
488*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
489*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
490*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
491*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
492*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
493*3f982cf4SFabien Sanglard record_handler_.AddRecord(aaaa_record);
494*3f982cf4SFabien Sanglard
495*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
496*3f982cf4SFabien Sanglard }
497*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,RecordOnlySentIfNotKnown)498*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, RecordOnlySentIfNotKnown) {
499*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
500*3f982cf4SFabien Sanglard MdnsRecord aaaa_record = GetFakeAAAARecord(domain_);
501*3f982cf4SFabien Sanglard message.AddAnswer(aaaa_record);
502*3f982cf4SFabien Sanglard
503*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
504*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
505*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
506*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
507*3f982cf4SFabien Sanglard record_handler_.AddRecord(aaaa_record);
508*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
509*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
510*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
511*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
512*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{0});
513*3f982cf4SFabien Sanglard
514*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
515*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kA));
516*3f982cf4SFabien Sanglard return Error::None();
517*3f982cf4SFabien Sanglard });
518*3f982cf4SFabien Sanglard
519*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
520*3f982cf4SFabien Sanglard }
521*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,RecordOnlySentIfNotKnownMultiplePackets)522*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, RecordOnlySentIfNotKnownMultiplePackets) {
523*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
524*3f982cf4SFabien Sanglard message.set_truncated();
525*3f982cf4SFabien Sanglard
526*3f982cf4SFabien Sanglard MdnsMessage message2(1, MessageType::Query);
527*3f982cf4SFabien Sanglard MdnsRecord aaaa_record = GetFakeAAAARecord(domain_);
528*3f982cf4SFabien Sanglard message2.AddAnswer(aaaa_record);
529*3f982cf4SFabien Sanglard
530*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
531*3f982cf4SFabien Sanglard OnMessageReceived(message2, endpoint_);
532*3f982cf4SFabien Sanglard
533*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
534*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
535*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
536*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
537*3f982cf4SFabien Sanglard record_handler_.AddRecord(aaaa_record);
538*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
539*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
540*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
541*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
542*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{0});
543*3f982cf4SFabien Sanglard
544*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
545*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kA));
546*3f982cf4SFabien Sanglard return Error::None();
547*3f982cf4SFabien Sanglard });
548*3f982cf4SFabien Sanglard clock_.Advance(std::chrono::seconds(1));
549*3f982cf4SFabien Sanglard }
550*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,RecordOnlySentIfNotKnownMultiplePacketsOutOfOrder)551*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, RecordOnlySentIfNotKnownMultiplePacketsOutOfOrder) {
552*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
553*3f982cf4SFabien Sanglard message.set_truncated();
554*3f982cf4SFabien Sanglard
555*3f982cf4SFabien Sanglard MdnsMessage message2(2, MessageType::Query);
556*3f982cf4SFabien Sanglard MdnsRecord aaaa_record = GetFakeAAAARecord(domain_);
557*3f982cf4SFabien Sanglard message2.AddAnswer(aaaa_record);
558*3f982cf4SFabien Sanglard message2.set_truncated();
559*3f982cf4SFabien Sanglard
560*3f982cf4SFabien Sanglard MdnsMessage message3(3, MessageType::Query);
561*3f982cf4SFabien Sanglard MdnsRecord a_record = GetFakeARecord(domain_);
562*3f982cf4SFabien Sanglard message3.AddAnswer(a_record);
563*3f982cf4SFabien Sanglard
564*3f982cf4SFabien Sanglard OnMessageReceived(message2, endpoint_);
565*3f982cf4SFabien Sanglard OnMessageReceived(message3, endpoint_);
566*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
567*3f982cf4SFabien Sanglard
568*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
569*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
570*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
571*3f982cf4SFabien Sanglard record_handler_.AddRecord(a_record);
572*3f982cf4SFabien Sanglard record_handler_.AddRecord(aaaa_record);
573*3f982cf4SFabien Sanglard record_handler_.AddRecord(aaaa_record);
574*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
575*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
576*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
577*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
578*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
579*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{0});
580*3f982cf4SFabien Sanglard
581*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
582*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kSRV));
583*3f982cf4SFabien Sanglard return Error::None();
584*3f982cf4SFabien Sanglard });
585*3f982cf4SFabien Sanglard clock_.Advance(std::chrono::seconds(1));
586*3f982cf4SFabien Sanglard }
587*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,RecordSentForMultiPacketsSuppressionIfMoreNotFound)588*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, RecordSentForMultiPacketsSuppressionIfMoreNotFound) {
589*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kANY);
590*3f982cf4SFabien Sanglard MdnsRecord aaaa_record = GetFakeAAAARecord(domain_);
591*3f982cf4SFabien Sanglard message.AddAnswer(aaaa_record);
592*3f982cf4SFabien Sanglard message.set_truncated();
593*3f982cf4SFabien Sanglard
594*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
595*3f982cf4SFabien Sanglard
596*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
597*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
598*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
599*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
600*3f982cf4SFabien Sanglard record_handler_.AddRecord(aaaa_record);
601*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
602*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
603*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
604*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
605*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{0});
606*3f982cf4SFabien Sanglard
607*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
608*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kA));
609*3f982cf4SFabien Sanglard return Error::None();
610*3f982cf4SFabien Sanglard });
611*3f982cf4SFabien Sanglard clock_.Advance(std::chrono::seconds(1));
612*3f982cf4SFabien Sanglard }
613*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,RecordNotSentForMultiPacketsSuppressionIfNoQuery)614*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, RecordNotSentForMultiPacketsSuppressionIfNoQuery) {
615*3f982cf4SFabien Sanglard MdnsMessage message(1, MessageType::Query);
616*3f982cf4SFabien Sanglard MdnsRecord aaaa_record = GetFakeAAAARecord(domain_);
617*3f982cf4SFabien Sanglard message.AddAnswer(aaaa_record);
618*3f982cf4SFabien Sanglard
619*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
620*3f982cf4SFabien Sanglard clock_.Advance(std::chrono::seconds(1));
621*3f982cf4SFabien Sanglard }
622*3f982cf4SFabien Sanglard
623*3f982cf4SFabien Sanglard // Validate NSEC records are used correctly.
TEST_F(MdnsResponderTest,QueryForRecordTypesWhenNonePresent)624*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, QueryForRecordTypesWhenNonePresent) {
625*3f982cf4SFabien Sanglard QueryForRecordTypeWhenNonePresent(DnsType::kANY);
626*3f982cf4SFabien Sanglard QueryForRecordTypeWhenNonePresent(DnsType::kSRV);
627*3f982cf4SFabien Sanglard QueryForRecordTypeWhenNonePresent(DnsType::kTXT);
628*3f982cf4SFabien Sanglard QueryForRecordTypeWhenNonePresent(DnsType::kA);
629*3f982cf4SFabien Sanglard QueryForRecordTypeWhenNonePresent(DnsType::kAAAA);
630*3f982cf4SFabien Sanglard }
631*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,AAAAQueryGiveANsec)632*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, AAAAQueryGiveANsec) {
633*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kAAAA);
634*3f982cf4SFabien Sanglard
635*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
636*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
637*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
638*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
639*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
640*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
641*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeAAAARecord(domain_));
642*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
643*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
644*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
645*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
646*3f982cf4SFabien Sanglard
647*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
648*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kAAAA));
649*3f982cf4SFabien Sanglard
650*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{1});
651*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(), DnsType::kA);
652*3f982cf4SFabien Sanglard
653*3f982cf4SFabien Sanglard return Error::None();
654*3f982cf4SFabien Sanglard });
655*3f982cf4SFabien Sanglard
656*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
657*3f982cf4SFabien Sanglard }
658*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,AQueryGiveAAAANsec)659*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, AQueryGiveAAAANsec) {
660*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kA);
661*3f982cf4SFabien Sanglard
662*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
663*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
664*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
665*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
666*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
667*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
668*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
669*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
670*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
671*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
672*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
673*3f982cf4SFabien Sanglard
674*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
675*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kA));
676*3f982cf4SFabien Sanglard
677*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{1});
678*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
679*3f982cf4SFabien Sanglard DnsType::kAAAA);
680*3f982cf4SFabien Sanglard
681*3f982cf4SFabien Sanglard return Error::None();
682*3f982cf4SFabien Sanglard });
683*3f982cf4SFabien Sanglard
684*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
685*3f982cf4SFabien Sanglard }
686*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,SrvQueryGiveCorrectNsecForNoAOrAAAA)687*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, SrvQueryGiveCorrectNsecForNoAOrAAAA) {
688*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kSRV);
689*3f982cf4SFabien Sanglard
690*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
691*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
692*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
693*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
694*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
695*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
696*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
697*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
698*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
699*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
700*3f982cf4SFabien Sanglard
701*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
702*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kSRV));
703*3f982cf4SFabien Sanglard
704*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{2});
705*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(), DnsType::kA);
706*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
707*3f982cf4SFabien Sanglard DnsType::kAAAA);
708*3f982cf4SFabien Sanglard
709*3f982cf4SFabien Sanglard return Error::None();
710*3f982cf4SFabien Sanglard });
711*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
712*3f982cf4SFabien Sanglard }
713*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,SrvQueryGiveCorrectNsec)714*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, SrvQueryGiveCorrectNsec) {
715*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kSRV);
716*3f982cf4SFabien Sanglard
717*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
718*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
719*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
720*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
721*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
722*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
723*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
724*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
725*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
726*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
727*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
728*3f982cf4SFabien Sanglard
729*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
730*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kSRV));
731*3f982cf4SFabien Sanglard
732*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{2});
733*3f982cf4SFabien Sanglard EXPECT_TRUE(
734*3f982cf4SFabien Sanglard ContainsRecordType(message.additional_records(), DnsType::kA));
735*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
736*3f982cf4SFabien Sanglard DnsType::kAAAA);
737*3f982cf4SFabien Sanglard
738*3f982cf4SFabien Sanglard return Error::None();
739*3f982cf4SFabien Sanglard });
740*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
741*3f982cf4SFabien Sanglard }
742*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,PtrQueryGiveCorrectNsecForNoPtrOrSrv)743*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, PtrQueryGiveCorrectNsecForNoPtrOrSrv) {
744*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kPTR);
745*3f982cf4SFabien Sanglard
746*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
747*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
748*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
749*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
750*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
751*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
752*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
753*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
754*3f982cf4SFabien Sanglard
755*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
756*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kPTR));
757*3f982cf4SFabien Sanglard
758*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{2});
759*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
760*3f982cf4SFabien Sanglard DnsType::kTXT);
761*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
762*3f982cf4SFabien Sanglard DnsType::kSRV);
763*3f982cf4SFabien Sanglard
764*3f982cf4SFabien Sanglard return Error::None();
765*3f982cf4SFabien Sanglard });
766*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
767*3f982cf4SFabien Sanglard }
768*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,PtrQueryGiveCorrectNsecForOnlyPtr)769*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, PtrQueryGiveCorrectNsecForOnlyPtr) {
770*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kPTR);
771*3f982cf4SFabien Sanglard
772*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
773*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
774*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
775*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
776*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
777*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
778*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
779*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
780*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
781*3f982cf4SFabien Sanglard
782*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
783*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kPTR));
784*3f982cf4SFabien Sanglard
785*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{2});
786*3f982cf4SFabien Sanglard EXPECT_TRUE(
787*3f982cf4SFabien Sanglard ContainsRecordType(message.additional_records(), DnsType::kTXT));
788*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
789*3f982cf4SFabien Sanglard DnsType::kSRV);
790*3f982cf4SFabien Sanglard
791*3f982cf4SFabien Sanglard return Error::None();
792*3f982cf4SFabien Sanglard });
793*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
794*3f982cf4SFabien Sanglard }
795*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,PtrQueryGiveCorrectNsecForOnlySrv)796*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, PtrQueryGiveCorrectNsecForOnlySrv) {
797*3f982cf4SFabien Sanglard MdnsMessage message = CreateMulticastMdnsQuery(DnsType::kPTR);
798*3f982cf4SFabien Sanglard
799*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(true));
800*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
801*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
802*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakePtrRecord(domain_));
803*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
804*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
805*3f982cf4SFabien Sanglard .WillOnce([](const MdnsMessage& message) -> Error {
806*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
807*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
808*3f982cf4SFabien Sanglard
809*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
810*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kPTR));
811*3f982cf4SFabien Sanglard
812*3f982cf4SFabien Sanglard EXPECT_EQ(message.additional_records().size(), size_t{4});
813*3f982cf4SFabien Sanglard EXPECT_TRUE(
814*3f982cf4SFabien Sanglard ContainsRecordType(message.additional_records(), DnsType::kSRV));
815*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
816*3f982cf4SFabien Sanglard DnsType::kTXT);
817*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(), DnsType::kA);
818*3f982cf4SFabien Sanglard ExpectContainsNsecRecordType(message.additional_records(),
819*3f982cf4SFabien Sanglard DnsType::kAAAA);
820*3f982cf4SFabien Sanglard
821*3f982cf4SFabien Sanglard return Error::None();
822*3f982cf4SFabien Sanglard });
823*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
824*3f982cf4SFabien Sanglard }
825*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,EnumerateAllQuery)826*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, EnumerateAllQuery) {
827*3f982cf4SFabien Sanglard MdnsMessage message = CreateTypeEnumerationQuery();
828*3f982cf4SFabien Sanglard
829*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(false));
830*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
831*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
832*3f982cf4SFabien Sanglard const auto ptr = GetFakePtrRecord(domain_);
833*3f982cf4SFabien Sanglard record_handler_.AddRecord(ptr);
834*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
835*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
836*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
837*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
838*3f982cf4SFabien Sanglard
839*3f982cf4SFabien Sanglard EXPECT_CALL(sender_, SendMulticast(_))
840*3f982cf4SFabien Sanglard .WillOnce([this, &ptr](const MdnsMessage& message) -> Error {
841*3f982cf4SFabien Sanglard EXPECT_EQ(message.questions().size(), size_t{0});
842*3f982cf4SFabien Sanglard EXPECT_EQ(message.authority_records().size(), size_t{0});
843*3f982cf4SFabien Sanglard
844*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers().size(), size_t{1});
845*3f982cf4SFabien Sanglard EXPECT_TRUE(ContainsRecordType(message.answers(), DnsType::kPTR));
846*3f982cf4SFabien Sanglard EXPECT_EQ(message.answers()[0].name(), type_enumeration_domain_);
847*3f982cf4SFabien Sanglard CheckPtrDomain(message.answers()[0], ptr.name());
848*3f982cf4SFabien Sanglard return Error::None();
849*3f982cf4SFabien Sanglard });
850*3f982cf4SFabien Sanglard clock_.Advance(Clock::duration(kMaximumSharedRecordResponseDelayMs));
851*3f982cf4SFabien Sanglard }
852*3f982cf4SFabien Sanglard
TEST_F(MdnsResponderTest,EnumerateAllQueryNoResults)853*3f982cf4SFabien Sanglard TEST_F(MdnsResponderTest, EnumerateAllQueryNoResults) {
854*3f982cf4SFabien Sanglard MdnsMessage message = CreateTypeEnumerationQuery();
855*3f982cf4SFabien Sanglard
856*3f982cf4SFabien Sanglard EXPECT_CALL(probe_manager_, IsDomainClaimed(_)).WillOnce(Return(false));
857*3f982cf4SFabien Sanglard EXPECT_CALL(record_handler_, HasRecords(_, _, _))
858*3f982cf4SFabien Sanglard .WillRepeatedly(Return(true));
859*3f982cf4SFabien Sanglard const auto ptr = GetFakePtrRecord(domain_);
860*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeSrvRecord(domain_));
861*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeTxtRecord(domain_));
862*3f982cf4SFabien Sanglard record_handler_.AddRecord(GetFakeARecord(domain_));
863*3f982cf4SFabien Sanglard OnMessageReceived(message, endpoint_);
864*3f982cf4SFabien Sanglard clock_.Advance(Clock::duration(kMaximumSharedRecordResponseDelayMs));
865*3f982cf4SFabien Sanglard }
866*3f982cf4SFabien Sanglard
867*3f982cf4SFabien Sanglard } // namespace discovery
868*3f982cf4SFabien Sanglard } // namespace openscreen
869