679 lines
24 KiB
C++
679 lines
24 KiB
C++
// 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 "osp/impl/presentation/url_availability_requester.h"
|
|
|
|
#include <chrono>
|
|
#include <memory>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "gmock/gmock.h"
|
|
#include "gtest/gtest.h"
|
|
#include "osp/impl/quic/quic_client.h"
|
|
#include "osp/impl/quic/testing/quic_test_support.h"
|
|
#include "osp/msgs/osp_messages.h"
|
|
#include "osp/public/network_service_manager.h"
|
|
#include "osp/public/testing/message_demuxer_test_support.h"
|
|
#include "platform/test/fake_clock.h"
|
|
#include "platform/test/fake_task_runner.h"
|
|
#include "util/osp_logging.h"
|
|
|
|
namespace openscreen {
|
|
namespace osp {
|
|
|
|
using ::testing::_;
|
|
using ::testing::Invoke;
|
|
using ::testing::Mock;
|
|
using ::testing::Test;
|
|
|
|
namespace {
|
|
|
|
class MockReceiverObserver : public ReceiverObserver {
|
|
public:
|
|
~MockReceiverObserver() override = default;
|
|
|
|
MOCK_METHOD2(OnRequestFailed, void(const std::string&, const std::string&));
|
|
MOCK_METHOD2(OnReceiverAvailable,
|
|
void(const std::string&, const std::string&));
|
|
MOCK_METHOD2(OnReceiverUnavailable,
|
|
void(const std::string&, const std::string&));
|
|
};
|
|
|
|
} // namespace
|
|
|
|
class UrlAvailabilityRequesterTest : public Test {
|
|
public:
|
|
UrlAvailabilityRequesterTest() {
|
|
fake_clock_ = std::make_unique<FakeClock>(
|
|
Clock::time_point(std::chrono::milliseconds(1298424)));
|
|
task_runner_ = std::make_unique<FakeTaskRunner>(fake_clock_.get());
|
|
quic_bridge_ =
|
|
std::make_unique<FakeQuicBridge>(task_runner_.get(), FakeClock::now);
|
|
info1_ = {service_id_, friendly_name_, 1, quic_bridge_->kReceiverEndpoint};
|
|
}
|
|
|
|
void SetUp() override {
|
|
NetworkServiceManager::Create(nullptr, nullptr,
|
|
std::move(quic_bridge_->quic_client),
|
|
std::move(quic_bridge_->quic_server));
|
|
availability_watch_ =
|
|
quic_bridge_->receiver_demuxer->SetDefaultMessageTypeWatch(
|
|
msgs::Type::kPresentationUrlAvailabilityRequest, &mock_callback_);
|
|
}
|
|
|
|
void TearDown() override {
|
|
availability_watch_ = MessageDemuxer::MessageWatch();
|
|
NetworkServiceManager::Dispose();
|
|
}
|
|
|
|
protected:
|
|
std::unique_ptr<ProtocolConnection> ExpectIncomingConnection() {
|
|
std::unique_ptr<ProtocolConnection> stream;
|
|
|
|
EXPECT_CALL(quic_bridge_->mock_server_observer, OnIncomingConnectionMock(_))
|
|
.WillOnce(
|
|
Invoke([&stream](std::unique_ptr<ProtocolConnection>& connection) {
|
|
stream = std::move(connection);
|
|
}));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
return stream;
|
|
}
|
|
|
|
void ExpectStreamMessage(MockMessageCallback* mock_callback,
|
|
msgs::PresentationUrlAvailabilityRequest* request) {
|
|
EXPECT_CALL(*mock_callback, OnStreamMessage(_, _, _, _, _, _))
|
|
.WillOnce(
|
|
Invoke([request](uint64_t endpoint_id, uint64_t cid,
|
|
msgs::Type message_type, const uint8_t* buffer,
|
|
size_t buffer_size, Clock::time_point now) {
|
|
ssize_t request_result_size =
|
|
msgs::DecodePresentationUrlAvailabilityRequest(
|
|
buffer, buffer_size, request);
|
|
OSP_DCHECK_GT(request_result_size, 0);
|
|
return request_result_size;
|
|
}));
|
|
}
|
|
|
|
void SendAvailabilityResponse(
|
|
const msgs::PresentationUrlAvailabilityRequest& request,
|
|
std::vector<msgs::UrlAvailability>&& availabilities,
|
|
ProtocolConnection* stream) {
|
|
msgs::PresentationUrlAvailabilityResponse response;
|
|
response.request_id = request.request_id;
|
|
response.url_availabilities = std::move(availabilities);
|
|
msgs::CborEncodeBuffer buffer;
|
|
ssize_t encode_result =
|
|
msgs::EncodePresentationUrlAvailabilityResponse(response, &buffer);
|
|
ASSERT_GT(encode_result, 0);
|
|
stream->Write(buffer.data(), buffer.size());
|
|
}
|
|
|
|
void SendAvailabilityEvent(
|
|
uint64_t watch_id,
|
|
std::vector<msgs::UrlAvailability>&& availabilities,
|
|
ProtocolConnection* stream) {
|
|
msgs::PresentationUrlAvailabilityEvent event;
|
|
event.watch_id = watch_id;
|
|
event.url_availabilities = std::move(availabilities);
|
|
msgs::CborEncodeBuffer buffer;
|
|
ssize_t encode_result =
|
|
msgs::EncodePresentationUrlAvailabilityEvent(event, &buffer);
|
|
ASSERT_GT(encode_result, 0);
|
|
stream->Write(buffer.data(), buffer.size());
|
|
}
|
|
|
|
std::unique_ptr<FakeClock> fake_clock_;
|
|
std::unique_ptr<FakeTaskRunner> task_runner_;
|
|
MockMessageCallback mock_callback_;
|
|
MessageDemuxer::MessageWatch availability_watch_;
|
|
std::unique_ptr<FakeQuicBridge> quic_bridge_;
|
|
UrlAvailabilityRequester listener_{FakeClock::now};
|
|
|
|
std::string url1_{"https://example.com/foo.html"};
|
|
std::string url2_{"https://example.com/bar.html"};
|
|
std::string service_id_{"asdf"};
|
|
std::string friendly_name_{"turtle"};
|
|
ServiceInfo info1_;
|
|
};
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, AvailableObserverFirst) {
|
|
MockReceiverObserver mock_observer;
|
|
listener_.AddObserver({url1_}, &mock_observer);
|
|
|
|
listener_.AddReceiver(info1_);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, AvailableReceiverFirst) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer;
|
|
listener_.AddObserver({url1_}, &mock_observer);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, Unavailable) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer;
|
|
listener_.AddObserver({url1_}, &mock_observer);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, AvailabilityIsCached) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_));
|
|
listener_.AddObserver({url1_}, &mock_observer2);
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, AvailabilityCacheIsTransient) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
listener_.RemoveObserverUrls({url1_}, &mock_observer1);
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
listener_.AddObserver({url1_}, &mock_observer2);
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, PartiallyCachedAnswer) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_));
|
|
listener_.AddObserver({url1_, url2_}, &mock_observer2);
|
|
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url2_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url2_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url2_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, MultipleOverlappingObservers) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_));
|
|
listener_.AddObserver({url1_, url2_}, &mock_observer2);
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url2_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url2_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, RemoveObserverUrls) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
uint64_t url1_watch_id = request.watch_id;
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_));
|
|
listener_.AddObserver({url1_, url2_}, &mock_observer2);
|
|
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url2_}, request.urls);
|
|
|
|
listener_.RemoveObserverUrls({url1_}, &mock_observer1);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url2_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
|
|
SendAvailabilityEvent(
|
|
url1_watch_id,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, RemoveObserver) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
uint64_t url1_watch_id = request.watch_id;
|
|
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_));
|
|
listener_.AddObserver({url1_, url2_}, &mock_observer2);
|
|
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
|
|
uint64_t url2_watch_id = request.watch_id;
|
|
EXPECT_EQ(std::vector<std::string>{url2_}, request.urls);
|
|
|
|
listener_.RemoveObserver(&mock_observer1);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url2_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
|
|
SendAvailabilityEvent(
|
|
url1_watch_id,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
|
|
listener_.RemoveObserver(&mock_observer2);
|
|
|
|
SendAvailabilityEvent(
|
|
url1_watch_id,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
SendAvailabilityEvent(
|
|
url2_watch_id,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(_, service_id_)).Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
Mock::VerifyAndClearExpectations(&mock_observer1);
|
|
Mock::VerifyAndClearExpectations(&mock_observer2);
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, EventUpdate) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_, url2_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ((std::vector<std::string>{url1_, url2_}), request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable,
|
|
msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url2_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(_, service_id_)).Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _)).Times(0);
|
|
SendAvailabilityEvent(
|
|
request.watch_id,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable,
|
|
msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url2_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, RefreshWatches) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(_, service_id_)).Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
fake_clock_->Advance(std::chrono::seconds(60));
|
|
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
listener_.RefreshWatches();
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_));
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, ResponseAfterRemoveObserver) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
listener_.RemoveObserverUrls({url1_}, &mock_observer1);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
listener_.AddObserver({url1_}, &mock_observer2);
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest,
|
|
EmptyCacheAfterRemoveObserverThenReceiver) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ(std::vector<std::string>{url1_}, request.urls);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_));
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
|
|
listener_.RemoveObserverUrls({url1_}, &mock_observer1);
|
|
listener_.RemoveReceiver(info1_);
|
|
MockReceiverObserver mock_observer2;
|
|
EXPECT_CALL(mock_observer2, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer2, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
listener_.AddObserver({url1_}, &mock_observer2);
|
|
}
|
|
|
|
TEST_F(UrlAvailabilityRequesterTest, RemoveObserverInSteps) {
|
|
listener_.AddReceiver(info1_);
|
|
|
|
MockReceiverObserver mock_observer1;
|
|
listener_.AddObserver({url1_, url2_}, &mock_observer1);
|
|
|
|
msgs::PresentationUrlAvailabilityRequest request;
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
std::unique_ptr<ProtocolConnection> stream = ExpectIncomingConnection();
|
|
ASSERT_TRUE(stream);
|
|
|
|
EXPECT_EQ((std::vector<std::string>{url1_, url2_}), request.urls);
|
|
listener_.RemoveObserverUrls({url1_}, &mock_observer1);
|
|
listener_.RemoveObserverUrls({url2_}, &mock_observer1);
|
|
SendAvailabilityResponse(
|
|
request,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kAvailable,
|
|
msgs::UrlAvailability::kAvailable},
|
|
stream.get());
|
|
SendAvailabilityEvent(
|
|
request.watch_id,
|
|
std::vector<msgs::UrlAvailability>{msgs::UrlAvailability::kUnavailable,
|
|
msgs::UrlAvailability::kUnavailable},
|
|
stream.get());
|
|
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url1_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url1_, service_id_))
|
|
.Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverAvailable(url2_, service_id_)).Times(0);
|
|
EXPECT_CALL(mock_observer1, OnReceiverUnavailable(url2_, service_id_))
|
|
.Times(0);
|
|
|
|
// NOTE: This message was generated between the two RemoveObserverUrls calls
|
|
// above. So even though the request is internally cancelled almost
|
|
// immediately, this still went out on the wire.
|
|
ExpectStreamMessage(&mock_callback_, &request);
|
|
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
EXPECT_EQ((std::vector<std::string>{url2_}), request.urls);
|
|
|
|
fake_clock_->Advance(std::chrono::seconds(60));
|
|
|
|
listener_.RefreshWatches();
|
|
EXPECT_CALL(mock_callback_, OnStreamMessage(_, _, _, _, _, _)).Times(0);
|
|
quic_bridge_->RunTasksUntilIdle();
|
|
}
|
|
|
|
} // namespace osp
|
|
} // namespace openscreen
|