blob: 5b7a10c8eea3782f64eb586d26a63e8f0722ab26 [file] [log] [blame]
// Copyright 2018 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 "api/impl/mdns_responder_service.h"
#include <memory>
#include "api/impl/screen_listener_impl.h"
#include "api/impl/testing/fake_mdns_platform_service.h"
#include "api/impl/testing/fake_mdns_responder_adapter.h"
#include "base/make_unique.h"
#include "third_party/googletest/src/googlemock/include/gmock/gmock.h"
#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
namespace openscreen {
namespace {
using ::testing::_;
constexpr char kTestServiceInstance[] = "turtle";
constexpr char kTestServiceName[] = "_foo";
constexpr char kTestServiceProtocol[] = "_udp";
constexpr char kTestHostname[] = "hostname";
constexpr uint16_t kTestPort = 12345;
class FakeMdnsResponderAdapterFactory final
: public MdnsResponderAdapterFactory,
public FakeMdnsResponderAdapter::LifetimeObserver {
public:
~FakeMdnsResponderAdapterFactory() override = default;
std::unique_ptr<mdns::MdnsResponderAdapter> Create() override {
auto mdns = MakeUnique<FakeMdnsResponderAdapter>();
mdns->SetLifetimeObserver(this);
last_mdns_responder_ = mdns.get();
++instances_;
return mdns;
}
void OnDestroyed() override {
last_running_ = last_mdns_responder_->running();
last_registered_services_size_ =
last_mdns_responder_->registered_services().size();
last_mdns_responder_ = nullptr;
}
FakeMdnsResponderAdapter* last_mdns_responder() {
return last_mdns_responder_;
}
int32_t instances() const { return instances_; }
bool last_running() const { return last_running_; }
size_t last_registered_services_size() const {
return last_registered_services_size_;
}
private:
FakeMdnsResponderAdapter* last_mdns_responder_ = nullptr;
int32_t instances_ = 0;
bool last_running_ = false;
size_t last_registered_services_size_ = 0;
};
class MockScreenListenerObserver final : public ScreenListener::Observer {
public:
~MockScreenListenerObserver() override = default;
MOCK_METHOD0(OnStarted, void());
MOCK_METHOD0(OnStopped, void());
MOCK_METHOD0(OnSuspended, void());
MOCK_METHOD0(OnSearching, void());
MOCK_METHOD1(OnScreenAdded, void(const ScreenInfo&));
MOCK_METHOD1(OnScreenChanged, void(const ScreenInfo&));
MOCK_METHOD1(OnScreenRemoved, void(const ScreenInfo&));
MOCK_METHOD0(OnAllScreensRemoved, void());
MOCK_METHOD1(OnError, void(ScreenListenerError));
MOCK_METHOD1(OnMetrics, void(ScreenListener::Metrics));
};
class MockScreenPublisherObserver final : public ScreenPublisher::Observer {
public:
~MockScreenPublisherObserver() override = default;
MOCK_METHOD0(OnStarted, void());
MOCK_METHOD0(OnStopped, void());
MOCK_METHOD0(OnSuspended, void());
MOCK_METHOD1(OnError, void(ScreenPublisherError));
MOCK_METHOD1(OnMetrics, void(ScreenPublisher::Metrics));
};
class MdnsResponderServiceTest : public ::testing::Test {
protected:
void SetUp() override {
auto mdns_responder_factory = MakeUnique<FakeMdnsResponderAdapterFactory>();
mdns_responder_factory_ = mdns_responder_factory.get();
auto platform_service = MakeUnique<FakeMdnsPlatformService>();
fake_platform_service_ = platform_service.get();
fake_platform_service_->set_interfaces(bound_interfaces_);
mdns_service_ = MakeUnique<MdnsResponderService>(
kTestServiceName, kTestServiceProtocol,
std::move(mdns_responder_factory), std::move(platform_service));
screen_listener_ =
MakeUnique<ScreenListenerImpl>(&observer_, mdns_service_.get());
mdns_service_->SetServiceConfig(kTestHostname, kTestServiceInstance,
kTestPort, {}, {{"model", "shifty"}});
screen_publisher_ = MakeUnique<ScreenPublisherImpl>(&publisher_observer_,
mdns_service_.get());
}
MockScreenListenerObserver observer_;
FakeMdnsPlatformService* fake_platform_service_;
FakeMdnsResponderAdapterFactory* mdns_responder_factory_;
std::unique_ptr<MdnsResponderService> mdns_service_;
std::unique_ptr<ScreenListenerImpl> screen_listener_;
MockScreenPublisherObserver publisher_observer_;
std::unique_ptr<ScreenPublisherImpl> screen_publisher_;
platform::UdpSocketPtr default_socket_ =
reinterpret_cast<platform::UdpSocketPtr>(16);
platform::UdpSocketPtr second_socket_ =
reinterpret_cast<platform::UdpSocketPtr>(24);
const uint8_t default_mac_[6] = {0, 11, 22, 33, 44, 55};
const uint8_t second_mac_[6] = {55, 33, 22, 33, 44, 77};
std::vector<MdnsPlatformService::BoundInterface> bound_interfaces_{
MdnsPlatformService::BoundInterface{
platform::InterfaceInfo{1, default_mac_, "eth0",
platform::InterfaceInfo::Type::kEthernet},
platform::IPSubnet{IPAddress{192, 168, 3, 2}, 24}, default_socket_},
MdnsPlatformService::BoundInterface{
platform::InterfaceInfo{2, second_mac_, "eth1",
platform::InterfaceInfo::Type::kEthernet},
platform::IPSubnet{IPAddress{10, 0, 0, 3}, 24}, second_socket_},
};
};
} // namespace
TEST_F(MdnsResponderServiceTest, BasicServiceStates) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
std::string screen_id;
EXPECT_CALL(observer_, OnScreenAdded(_))
.WillOnce(::testing::Invoke([&screen_id](const ScreenInfo& info) {
screen_id = info.screen_id;
EXPECT_EQ(kTestServiceInstance, info.friendly_name);
EXPECT_EQ((IPEndpoint{{192, 168, 3, 7}, kTestPort}), info.v4_endpoint);
EXPECT_FALSE(info.v6_endpoint.address);
}));
mdns_service_->HandleNewEvents({});
mdns_responder->AddAEvent(MakeAEvent(
"gigliorononomicon", IPAddress{192, 168, 3, 8}, default_socket_));
EXPECT_CALL(observer_, OnScreenChanged(_))
.WillOnce(::testing::Invoke([&screen_id](const ScreenInfo& info) {
EXPECT_EQ(screen_id, info.screen_id);
EXPECT_EQ(kTestServiceInstance, info.friendly_name);
EXPECT_EQ((IPEndpoint{{192, 168, 3, 8}, kTestPort}), info.v4_endpoint);
EXPECT_FALSE(info.v6_endpoint.address);
}));
mdns_service_->HandleNewEvents({});
auto ptr_remove = MakePtrEvent(kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, default_socket_);
ptr_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddPtrEvent(std::move(ptr_remove));
EXPECT_CALL(observer_, OnScreenRemoved(_))
.WillOnce(::testing::Invoke([&screen_id](const ScreenInfo& info) {
EXPECT_EQ(screen_id, info.screen_id);
}));
mdns_service_->HandleNewEvents({});
}
TEST_F(MdnsResponderServiceTest, NetworkInterfaceIndex) {
auto second_socket = reinterpret_cast<platform::UdpSocketPtr>(24);
constexpr uint8_t mac[6] = {12, 34, 56, 78, 90};
bound_interfaces_.emplace_back(
platform::InterfaceInfo{2, mac, "wlan0",
platform::InterfaceInfo::Type::kWifi},
platform::IPSubnet{IPAddress{10, 0, 0, 2}, 24}, second_socket);
fake_platform_service_->set_interfaces(bound_interfaces_);
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
second_socket);
EXPECT_CALL(observer_, OnScreenAdded(_))
.WillOnce(::testing::Invoke([](const ScreenInfo& info) {
EXPECT_EQ(2, info.network_interface_index);
}));
mdns_service_->HandleNewEvents({});
}
TEST_F(MdnsResponderServiceTest, SimultaneousFieldChanges) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_));
mdns_service_->HandleNewEvents({});
mdns_responder->AddSrvEvent(
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", 54321, default_socket_));
auto a_remove = MakeAEvent("gigliorononomicon", IPAddress{192, 168, 3, 7},
default_socket_);
a_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddAEvent(std::move(a_remove));
mdns_responder->AddAEvent(MakeAEvent(
"gigliorononomicon", IPAddress{192, 168, 3, 8}, default_socket_));
EXPECT_CALL(observer_, OnScreenChanged(_))
.WillOnce(::testing::Invoke([](const ScreenInfo& info) {
EXPECT_EQ((IPAddress{192, 168, 3, 8}), info.v4_endpoint.address);
EXPECT_EQ(54321, info.v4_endpoint.port);
EXPECT_FALSE(info.v6_endpoint.address);
}));
mdns_service_->HandleNewEvents({});
}
TEST_F(MdnsResponderServiceTest, SimultaneousHostAndAddressChange) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_));
mdns_service_->HandleNewEvents({});
auto srv_remove =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, default_socket_);
srv_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove));
mdns_responder->AddSrvEvent(
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"alpha", kTestPort, default_socket_));
mdns_responder->AddAEvent(MakeAEvent(
"gigliorononomicon", IPAddress{192, 168, 3, 8}, default_socket_));
mdns_responder->AddAEvent(
MakeAEvent("alpha", IPAddress{192, 168, 3, 10}, default_socket_));
EXPECT_CALL(observer_, OnScreenChanged(_))
.WillOnce(::testing::Invoke([](const ScreenInfo& info) {
EXPECT_EQ((IPAddress{192, 168, 3, 10}), info.v4_endpoint.address);
EXPECT_FALSE(info.v6_endpoint.address);
}));
mdns_service_->HandleNewEvents({});
}
TEST_F(MdnsResponderServiceTest, ListenerStateTransitions) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
EXPECT_CALL(observer_, OnSuspended());
screen_listener_->Suspend();
ASSERT_EQ(mdns_responder, mdns_responder_factory_->last_mdns_responder());
EXPECT_FALSE(mdns_responder->running());
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Resume();
ASSERT_EQ(mdns_responder, mdns_responder_factory_->last_mdns_responder());
EXPECT_TRUE(mdns_responder->running());
EXPECT_CALL(observer_, OnStopped());
screen_listener_->Stop();
ASSERT_FALSE(mdns_responder_factory_->last_mdns_responder());
EXPECT_CALL(observer_, OnSuspended());
auto instances = mdns_responder_factory_->instances();
screen_listener_->StartAndSuspend();
EXPECT_EQ(instances + 1, mdns_responder_factory_->instances());
mdns_responder = mdns_responder_factory_->last_mdns_responder();
EXPECT_FALSE(mdns_responder->running());
EXPECT_CALL(observer_, OnStopped());
screen_listener_->Stop();
ASSERT_FALSE(mdns_responder_factory_->last_mdns_responder());
}
TEST_F(MdnsResponderServiceTest, BasicServicePublish) {
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
auto services = mdns_responder->registered_services();
ASSERT_EQ(1u, services.size());
EXPECT_EQ(kTestServiceInstance, services[0].service_instance);
EXPECT_EQ(kTestServiceName, services[0].service_name);
EXPECT_EQ(kTestServiceProtocol, services[0].service_protocol);
auto host_labels = services[0].target_host.GetLabels();
ASSERT_EQ(2u, host_labels.size());
EXPECT_EQ(kTestHostname, host_labels[0]);
EXPECT_EQ("local", host_labels[1]);
EXPECT_EQ(kTestPort, services[0].target_port);
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
EXPECT_FALSE(mdns_responder_factory_->last_mdns_responder());
EXPECT_EQ(0u, mdns_responder_factory_->last_registered_services_size());
}
TEST_F(MdnsResponderServiceTest, PublisherStateTransitions) {
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
EXPECT_EQ(1u, mdns_responder->registered_services().size());
EXPECT_CALL(publisher_observer_, OnSuspended());
screen_publisher_->Suspend();
EXPECT_EQ(0u, mdns_responder->registered_services().size());
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Resume();
EXPECT_EQ(1u, mdns_responder->registered_services().size());
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
EXPECT_EQ(0u, mdns_responder_factory_->last_registered_services_size());
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
EXPECT_EQ(1u, mdns_responder->registered_services().size());
EXPECT_CALL(publisher_observer_, OnSuspended());
screen_publisher_->Suspend();
EXPECT_EQ(0u, mdns_responder->registered_services().size());
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
EXPECT_FALSE(mdns_responder_factory_->last_mdns_responder());
EXPECT_EQ(0u, mdns_responder_factory_->last_registered_services_size());
}
TEST_F(MdnsResponderServiceTest, PublisherObeysInterfaceWhitelist) {
{
mdns_service_->SetServiceConfig(kTestHostname, kTestServiceInstance,
kTestPort, {}, {{"model", "shifty"}});
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(2u, interfaces.size());
EXPECT_EQ(default_socket_, interfaces[0].socket);
EXPECT_EQ(second_socket_, interfaces[1].socket);
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
}
{
mdns_service_->SetServiceConfig(kTestHostname, kTestServiceInstance,
kTestPort, {1, 2}, {{"model", "shifty"}});
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(2u, interfaces.size());
EXPECT_EQ(default_socket_, interfaces[0].socket);
EXPECT_EQ(second_socket_, interfaces[1].socket);
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
}
{
mdns_service_->SetServiceConfig(kTestHostname, kTestServiceInstance,
kTestPort, {2}, {{"model", "shifty"}});
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(1u, interfaces.size());
EXPECT_EQ(second_socket_, interfaces[0].socket);
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
}
}
TEST_F(MdnsResponderServiceTest, ListenAndPublish) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
{
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(2u, interfaces.size());
EXPECT_EQ(default_socket_, interfaces[0].socket);
EXPECT_EQ(second_socket_, interfaces[1].socket);
}
mdns_service_->SetServiceConfig(kTestHostname, kTestServiceInstance,
kTestPort, {2}, {{"model", "shifty"}});
auto instances = mdns_responder_factory_->instances();
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
EXPECT_EQ(instances, mdns_responder_factory_->instances());
ASSERT_TRUE(mdns_responder->running());
{
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(1u, interfaces.size());
EXPECT_EQ(second_socket_, interfaces[0].socket);
}
EXPECT_CALL(observer_, OnStopped());
screen_listener_->Stop();
ASSERT_TRUE(mdns_responder->running());
EXPECT_EQ(1u, mdns_responder->registered_interfaces().size());
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
EXPECT_FALSE(mdns_responder_factory_->last_mdns_responder());
EXPECT_EQ(0u, mdns_responder_factory_->last_registered_services_size());
}
TEST_F(MdnsResponderServiceTest, PublishAndListen) {
mdns_service_->SetServiceConfig(kTestHostname, kTestServiceInstance,
kTestPort, {2}, {{"model", "shifty"}});
EXPECT_CALL(publisher_observer_, OnStarted());
screen_publisher_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
ASSERT_TRUE(mdns_responder);
ASSERT_TRUE(mdns_responder->running());
{
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(1u, interfaces.size());
EXPECT_EQ(second_socket_, interfaces[0].socket);
}
auto instances = mdns_responder_factory_->instances();
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
EXPECT_EQ(instances, mdns_responder_factory_->instances());
ASSERT_TRUE(mdns_responder->running());
{
auto interfaces = mdns_responder->registered_interfaces();
ASSERT_EQ(1u, interfaces.size());
EXPECT_EQ(second_socket_, interfaces[0].socket);
}
EXPECT_CALL(publisher_observer_, OnStopped());
screen_publisher_->Stop();
ASSERT_TRUE(mdns_responder->running());
EXPECT_EQ(1u, mdns_responder->registered_interfaces().size());
EXPECT_CALL(observer_, OnStopped());
screen_listener_->Stop();
EXPECT_FALSE(mdns_responder_factory_->last_mdns_responder());
EXPECT_EQ(0u, mdns_responder_factory_->last_registered_services_size());
}
TEST_F(MdnsResponderServiceTest, AddressQueryStopped) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_));
mdns_service_->HandleNewEvents({});
auto srv_remove =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, default_socket_);
srv_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove));
EXPECT_CALL(observer_, OnScreenRemoved(_));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_FALSE(mdns_responder->srv_queries_empty());
EXPECT_FALSE(mdns_responder->txt_queries_empty());
EXPECT_TRUE(mdns_responder->a_queries_empty());
EXPECT_TRUE(mdns_responder->aaaa_queries_empty());
}
TEST_F(MdnsResponderServiceTest, AddressQueryRefCount) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
AddEventsForNewService(mdns_responder, "instance-2", kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", 4321,
{"model=shwofty", "id=asdf"},
IPAddress{192, 168, 3, 7}, default_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_)).Times(2);
mdns_service_->HandleNewEvents({});
auto srv_remove =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, default_socket_);
srv_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove));
EXPECT_CALL(observer_, OnScreenRemoved(_));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_FALSE(mdns_responder->srv_queries_empty());
EXPECT_FALSE(mdns_responder->txt_queries_empty());
EXPECT_FALSE(mdns_responder->a_queries_empty());
EXPECT_FALSE(mdns_responder->aaaa_queries_empty());
srv_remove =
MakeSrvEvent("instance-2", kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", 4321, default_socket_);
srv_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove));
EXPECT_CALL(observer_, OnScreenRemoved(_));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_FALSE(mdns_responder->srv_queries_empty());
EXPECT_FALSE(mdns_responder->txt_queries_empty());
EXPECT_TRUE(mdns_responder->a_queries_empty());
EXPECT_TRUE(mdns_responder->aaaa_queries_empty());
}
TEST_F(MdnsResponderServiceTest, ServiceQueriesStoppedSrvFirst) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_));
mdns_service_->HandleNewEvents({});
auto srv_remove =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, default_socket_);
srv_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove));
EXPECT_CALL(observer_, OnScreenRemoved(_));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_FALSE(mdns_responder->srv_queries_empty());
EXPECT_FALSE(mdns_responder->txt_queries_empty());
EXPECT_TRUE(mdns_responder->a_queries_empty());
EXPECT_TRUE(mdns_responder->aaaa_queries_empty());
auto ptr_remove = MakePtrEvent(kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, default_socket_);
ptr_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddPtrEvent(std::move(ptr_remove));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_TRUE(mdns_responder->srv_queries_empty());
EXPECT_TRUE(mdns_responder->txt_queries_empty());
EXPECT_TRUE(mdns_responder->a_queries_empty());
EXPECT_TRUE(mdns_responder->aaaa_queries_empty());
}
TEST_F(MdnsResponderServiceTest, ServiceQueriesStoppedPtrFirst) {
EXPECT_CALL(observer_, OnStarted());
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_));
mdns_service_->HandleNewEvents({});
auto ptr_remove = MakePtrEvent(kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, default_socket_);
ptr_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddPtrEvent(std::move(ptr_remove));
EXPECT_CALL(observer_, OnScreenRemoved(_));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_FALSE(mdns_responder->srv_queries_empty());
EXPECT_FALSE(mdns_responder->txt_queries_empty());
EXPECT_FALSE(mdns_responder->a_queries_empty());
EXPECT_FALSE(mdns_responder->aaaa_queries_empty());
auto srv_remove =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, default_socket_);
srv_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_TRUE(mdns_responder->srv_queries_empty());
EXPECT_TRUE(mdns_responder->txt_queries_empty());
EXPECT_TRUE(mdns_responder->a_queries_empty());
EXPECT_TRUE(mdns_responder->aaaa_queries_empty());
}
TEST_F(MdnsResponderServiceTest, MultipleInterfaceRemove) {
screen_listener_->Start();
auto* mdns_responder = mdns_responder_factory_->last_mdns_responder();
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
default_socket_);
AddEventsForNewService(mdns_responder, kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, "gigliorononomicon", kTestPort,
{"model=shifty", "id=asdf"}, IPAddress{192, 168, 3, 7},
second_socket_);
EXPECT_CALL(observer_, OnScreenAdded(_));
mdns_service_->HandleNewEvents({});
auto srv_remove1 =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, second_socket_);
srv_remove1.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove1));
EXPECT_CALL(observer_, OnScreenChanged(_)).Times(0);
EXPECT_CALL(observer_, OnScreenRemoved(_)).Times(0);
mdns_service_->HandleNewEvents({});
auto srv_remove2 =
MakeSrvEvent(kTestServiceInstance, kTestServiceName, kTestServiceProtocol,
"gigliorononomicon", kTestPort, default_socket_);
srv_remove2.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddSrvEvent(std::move(srv_remove2));
EXPECT_CALL(observer_, OnScreenRemoved(_));
mdns_service_->HandleNewEvents({});
EXPECT_TRUE(mdns_responder->a_queries_empty());
auto ptr_remove = MakePtrEvent(kTestServiceInstance, kTestServiceName,
kTestServiceProtocol, default_socket_);
ptr_remove.header.response_type = mdns::QueryEventHeader::Type::kRemoved;
mdns_responder->AddPtrEvent(std::move(ptr_remove));
mdns_service_->HandleNewEvents({});
EXPECT_FALSE(mdns_responder->ptr_queries_empty());
EXPECT_TRUE(mdns_responder->srv_queries_empty());
EXPECT_TRUE(mdns_responder->txt_queries_empty());
EXPECT_TRUE(mdns_responder->a_queries_empty());
EXPECT_TRUE(mdns_responder->aaaa_queries_empty());
}
} // namespace openscreen