// 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/mdns/mdns_probe.h" #include #include #include "discovery/common/config.h" #include "discovery/mdns/mdns_probe_manager.h" #include "discovery/mdns/mdns_querier.h" #include "discovery/mdns/mdns_random.h" #include "discovery/mdns/mdns_receiver.h" #include "discovery/mdns/mdns_sender.h" #include "gmock/gmock.h" #include "gtest/gtest.h" #include "platform/test/fake_clock.h" #include "platform/test/fake_task_runner.h" #include "platform/test/fake_udp_socket.h" using testing::_; using testing::Invoke; using testing::Return; using testing::StrictMock; namespace openscreen { namespace discovery { class MockMdnsSender : public MdnsSender { public: explicit MockMdnsSender(UdpSocket* socket) : MdnsSender(socket) {} MOCK_METHOD1(SendMulticast, Error(const MdnsMessage& message)); MOCK_METHOD2(SendMessage, Error(const MdnsMessage& message, const IPEndpoint& endpoint)); }; class MockObserver : public MdnsProbeImpl::Observer { public: MOCK_METHOD1(OnProbeSuccess, void(MdnsProbe*)); MOCK_METHOD1(OnProbeFailure, void(MdnsProbe*)); }; class MdnsProbeTests : public testing::Test { public: MdnsProbeTests() : clock_(Clock::now()), task_runner_(&clock_), socket_(&task_runner_), sender_(&socket_), receiver_(config_) { EXPECT_EQ(task_runner_.delayed_task_count(), 0); probe_ = CreateProbe(); EXPECT_EQ(task_runner_.delayed_task_count(), 1); } protected: std::unique_ptr CreateProbe() { return std::make_unique(&sender_, &receiver_, &random_, &task_runner_, FakeClock::now, &observer_, name_, address_v4_); } MdnsMessage CreateMessage(const DomainName& domain) { MdnsMessage message(0, MessageType::Response); SrvRecordRdata rdata(0, 0, 80, domain); MdnsRecord record(std::move(domain), DnsType::kSRV, DnsClass::kIN, RecordType::kUnique, std::chrono::seconds(1), std::move(rdata)); message.AddAnswer(record); return message; } void OnMessageReceived(const MdnsMessage& message) { probe_->OnMessageReceived(message); } Config config_; FakeClock clock_; FakeTaskRunner task_runner_; FakeUdpSocket socket_; StrictMock sender_; MdnsReceiver receiver_; MdnsRandom random_; StrictMock observer_; std::unique_ptr probe_; const DomainName name_{"test", "_googlecast", "_tcp", "local"}; const DomainName name2_{"test2", "_googlecast", "_tcp", "local"}; const IPAddress address_v4_{192, 168, 0, 0}; const IPEndpoint endpoint_v4_{address_v4_, 80}; }; TEST_F(MdnsProbeTests, TestNoCancelationFlow) { EXPECT_CALL(sender_, SendMulticast(_)); clock_.Advance(kDelayBetweenProbeQueries); EXPECT_EQ(task_runner_.delayed_task_count(), 1); testing::Mock::VerifyAndClearExpectations(&sender_); EXPECT_CALL(sender_, SendMulticast(_)); clock_.Advance(kDelayBetweenProbeQueries); EXPECT_EQ(task_runner_.delayed_task_count(), 1); testing::Mock::VerifyAndClearExpectations(&sender_); EXPECT_CALL(sender_, SendMulticast(_)); clock_.Advance(kDelayBetweenProbeQueries); EXPECT_EQ(task_runner_.delayed_task_count(), 1); testing::Mock::VerifyAndClearExpectations(&sender_); EXPECT_CALL(observer_, OnProbeSuccess(probe_.get())).Times(1); clock_.Advance(kDelayBetweenProbeQueries); EXPECT_EQ(task_runner_.delayed_task_count(), 0); } TEST_F(MdnsProbeTests, CancelationWhenMatchingMessageReceived) { EXPECT_CALL(observer_, OnProbeFailure(probe_.get())).Times(1); OnMessageReceived(CreateMessage(name_)); } TEST_F(MdnsProbeTests, TestNoCancelationOnUnrelatedMessages) { OnMessageReceived(CreateMessage(name2_)); EXPECT_CALL(sender_, SendMulticast(_)); clock_.Advance(kDelayBetweenProbeQueries); EXPECT_EQ(task_runner_.delayed_task_count(), 1); testing::Mock::VerifyAndClearExpectations(&sender_); } } // namespace discovery } // namespace openscreen