blob: 4edba1fddda0fba92e1eb3600f3a9e9030b055ae [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 "discovery/mdns/mdns_probe.h"
#include <memory>
#include <utility>
#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<MdnsProbeImpl> CreateProbe() {
return std::make_unique<MdnsProbeImpl>(&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<MockMdnsSender> sender_;
MdnsReceiver receiver_;
MdnsRandom random_;
StrictMock<MockObserver> observer_;
std::unique_ptr<MdnsProbeImpl> 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