| Index: chrome/browser/media/router/discovery/dial/device_description_service_unittest.cc
|
| diff --git a/chrome/browser/media/router/discovery/dial/device_description_service_unittest.cc b/chrome/browser/media/router/discovery/dial/device_description_service_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b58a67dab321abf07cdb5d7475500fa690fccacf
|
| --- /dev/null
|
| +++ b/chrome/browser/media/router/discovery/dial/device_description_service_unittest.cc
|
| @@ -0,0 +1,328 @@
|
| +// Copyright 2017 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 "chrome/browser/media/router/discovery/dial/device_description_service.h"
|
| +
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/test/mock_callback.h"
|
| +#include "chrome/browser/media/router/discovery/dial/device_description_fetcher.h"
|
| +#include "chrome/browser/media/router/discovery/dial/dial_device_data.h"
|
| +#include "chrome/browser/media/router/discovery/dial/parsed_dial_device_description.h"
|
| +#include "chrome/browser/media/router/discovery/dial/safe_dial_device_description_parser.h"
|
| +#include "chrome/test/base/testing_profile.h"
|
| +#include "content/public/test/test_browser_thread_bundle.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using ::testing::_;
|
| +using ::testing::Return;
|
| +using ::testing::SaveArg;
|
| +
|
| +// Create Test Data
|
| +namespace {
|
| +
|
| +media_router::DialDeviceData CreateDialDeviceData(int num) {
|
| + media_router::DialDeviceData device_data(
|
| + base::StringPrintf("Device id %d", num),
|
| + GURL(base::StringPrintf("http://192.168.1.%d/dd.xml", num)),
|
| + base::Time::Now());
|
| + device_data.set_label(base::StringPrintf("Device label %d", num));
|
| + return device_data;
|
| +}
|
| +
|
| +media_router::DialDeviceDescriptionData CreateDialDeviceDescriptionData(
|
| + int num) {
|
| + return media_router::DialDeviceDescriptionData(
|
| + "", GURL(base::StringPrintf("http://192.168.1.%d/apps", num)));
|
| +}
|
| +
|
| +chrome::mojom::DialDeviceDescriptionPtr CreateDialDeviceDescriptionPtr(
|
| + int num) {
|
| + chrome::mojom::DialDeviceDescriptionPtr description_ptr =
|
| + chrome::mojom::DialDeviceDescription::New();
|
| + description_ptr->friendly_name = base::StringPrintf("Friendly name %d", num);
|
| + description_ptr->model_name = base::StringPrintf("Model name %d", num);
|
| + description_ptr->unique_id = base::StringPrintf("Unique ID %d", num);
|
| + return description_ptr;
|
| +}
|
| +
|
| +media_router::ParsedDialDeviceDescription CreateParsedDialDeviceDescription(
|
| + int num) {
|
| + media_router::ParsedDialDeviceDescription description_data;
|
| + description_data.app_url =
|
| + GURL(base::StringPrintf("http://192.168.1.%d/apps", num));
|
| + description_data.friendly_name = base::StringPrintf("Friendly name %d", num);
|
| + description_data.model_name = base::StringPrintf("Model name %d", num);
|
| + description_data.unique_id = base::StringPrintf("Unique ID %d", num);
|
| + return description_data;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace media_router {
|
| +
|
| +class TestSafeDialDeviceDescriptionParser
|
| + : public SafeDialDeviceDescriptionParser {
|
| + public:
|
| + ~TestSafeDialDeviceDescriptionParser() override {}
|
| +
|
| + MOCK_METHOD2(Start,
|
| + void(const std::string& xml_text,
|
| + const DeviceDescriptionCallback& callback));
|
| +};
|
| +
|
| +class TestDeviceDescriptionService : public DeviceDescriptionService {
|
| + public:
|
| + TestDeviceDescriptionService(
|
| + const DeviceDescriptionParseSuccessCallback& success_cb,
|
| + const DeviceDescriptionParseErrorCallback& error_cb)
|
| + : DeviceDescriptionService(success_cb, error_cb) {}
|
| +
|
| + MOCK_METHOD0(CreateSafeParser, SafeDialDeviceDescriptionParser*());
|
| +};
|
| +
|
| +class DeviceDescriptionServiceTest : public ::testing::Test {
|
| + public:
|
| + DeviceDescriptionServiceTest()
|
| + : device_description_service_(mock_success_cb_.Get(),
|
| + mock_error_cb_.Get()),
|
| + fetcher_map_(
|
| + device_description_service_.device_description_fetcher_map_),
|
| + description_cache_(device_description_service_.description_cache_),
|
| + thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
|
| +
|
| + TestDeviceDescriptionService* device_description_service() {
|
| + return &device_description_service_;
|
| + }
|
| +
|
| + void AddToCache(const std::string& device_label,
|
| + const ParsedDialDeviceDescription& description_data,
|
| + bool expired) {
|
| + DeviceDescriptionService::CacheEntry cache_entry;
|
| + cache_entry.expire_time = base::Time::Now();
|
| + if (!expired)
|
| + cache_entry.expire_time += base::TimeDelta::FromHours(12);
|
| + cache_entry.description_data = description_data;
|
| + description_cache_[device_label] = cache_entry;
|
| + }
|
| +
|
| + void SetTestParser(
|
| + std::unique_ptr<TestSafeDialDeviceDescriptionParser> test_parser) {
|
| + if (device_description_service_.parser_)
|
| + return;
|
| + device_description_service_.parser_ = std::move(test_parser);
|
| + }
|
| +
|
| + void OnDeviceDescriptionFetchComplete(int num) {
|
| + auto device_data = CreateDialDeviceData(num);
|
| + auto description_response_data = CreateDialDeviceDescriptionData(num);
|
| + auto parsed_description_data = CreateParsedDialDeviceDescription(num);
|
| +
|
| + EXPECT_CALL(mock_success_cb_, Run(device_data, parsed_description_data));
|
| +
|
| + device_description_service_.OnDeviceDescriptionFetchComplete(
|
| + device_data, description_response_data);
|
| + device_description_service_.OnParsedDeviceDescription(
|
| + device_data, description_response_data.app_url,
|
| + CreateDialDeviceDescriptionPtr(num));
|
| + }
|
| +
|
| + void TestOnParsedDeviceDescription(
|
| + chrome::mojom::DialDeviceDescriptionPtr description_ptr,
|
| + const std::string& error_message) {
|
| + GURL app_url("http://192.168.1.1/apps");
|
| + auto device_data = CreateDialDeviceData(1);
|
| + auto description_data = CreateParsedDialDeviceDescription(1);
|
| +
|
| + if (!error_message.empty()) {
|
| + EXPECT_CALL(mock_error_cb_, Run(device_data, error_message));
|
| + } else {
|
| + EXPECT_CALL(mock_success_cb_, Run(device_data, description_data));
|
| + }
|
| + device_description_service()->OnParsedDeviceDescription(
|
| + device_data, app_url, std::move(description_ptr));
|
| + }
|
| +
|
| + protected:
|
| + base::MockCallback<
|
| + DeviceDescriptionService::DeviceDescriptionParseSuccessCallback>
|
| + mock_success_cb_;
|
| + base::MockCallback<
|
| + DeviceDescriptionService::DeviceDescriptionParseErrorCallback>
|
| + mock_error_cb_;
|
| +
|
| + TestDeviceDescriptionService device_description_service_;
|
| + std::map<std::string, std::unique_ptr<DeviceDescriptionFetcher>>&
|
| + fetcher_map_;
|
| + std::map<std::string, DeviceDescriptionService::CacheEntry>&
|
| + description_cache_;
|
| +
|
| + const content::TestBrowserThreadBundle thread_bundle_;
|
| + TestingProfile profile_;
|
| +};
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest, TestGetDeviceDescriptionFromCache) {
|
| + auto device_data = CreateDialDeviceData(1);
|
| + auto description_data = CreateParsedDialDeviceDescription(1);
|
| + EXPECT_CALL(mock_success_cb_, Run(device_data, description_data));
|
| +
|
| + AddToCache(device_data.label(), description_data, false /* expired */);
|
| +
|
| + std::vector<DialDeviceData> devices = {device_data};
|
| + device_description_service()->GetDeviceDescriptions(devices, nullptr);
|
| +}
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest, TestGetDeviceDescriptionFetchURL) {
|
| + DialDeviceData device_data = CreateDialDeviceData(1);
|
| + std::vector<DialDeviceData> devices = {device_data};
|
| +
|
| + // Create Fetcher
|
| + EXPECT_TRUE(fetcher_map_.empty());
|
| + device_description_service()->GetDeviceDescriptions(
|
| + devices, profile_.GetRequestContext());
|
| + EXPECT_EQ(size_t(1), fetcher_map_.size());
|
| +
|
| + // Remove fetcher and create safe parser
|
| + auto test_parser = base::MakeUnique<TestSafeDialDeviceDescriptionParser>();
|
| + EXPECT_CALL(*test_parser, Start(_, _));
|
| +
|
| + SetTestParser(std::move(test_parser));
|
| + OnDeviceDescriptionFetchComplete(1);
|
| +}
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest, TestGetDeviceDescriptionFetchURLError) {
|
| + DialDeviceData device_data = CreateDialDeviceData(1);
|
| + std::vector<DialDeviceData> devices;
|
| + devices.push_back(device_data);
|
| +
|
| + // Create Fetcher
|
| + EXPECT_TRUE(fetcher_map_.empty());
|
| + device_description_service()->GetDeviceDescriptions(
|
| + devices, profile_.GetRequestContext());
|
| + EXPECT_EQ(size_t(1), fetcher_map_.size());
|
| +
|
| + EXPECT_CALL(mock_error_cb_, Run(device_data, ""));
|
| +
|
| + device_description_service()->OnDeviceDescriptionFetchError(device_data, "");
|
| + EXPECT_TRUE(fetcher_map_.empty());
|
| +}
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest,
|
| + TestGetDeviceDescriptionRemoveOutDatedFetchers) {
|
| + DialDeviceData device_data_1 = CreateDialDeviceData(1);
|
| + DialDeviceData device_data_2 = CreateDialDeviceData(2);
|
| + DialDeviceData device_data_3 = CreateDialDeviceData(3);
|
| +
|
| + std::vector<DialDeviceData> devices;
|
| + devices.push_back(device_data_1);
|
| + devices.push_back(device_data_2);
|
| +
|
| + // insert fetchers
|
| + device_description_service()->GetDeviceDescriptions(
|
| + devices, profile_.GetRequestContext());
|
| +
|
| + // Keep fetchers non exist in current device list and remove fetchers with
|
| + // different description url.
|
| + GURL new_url_2 = GURL("http://example.com");
|
| + device_data_2.set_device_description_url(new_url_2);
|
| +
|
| + devices.clear();
|
| + devices.push_back(device_data_2);
|
| + devices.push_back(device_data_3);
|
| + device_description_service()->GetDeviceDescriptions(
|
| + devices, profile_.GetRequestContext());
|
| +
|
| + EXPECT_EQ(size_t(3), fetcher_map_.size());
|
| +
|
| + auto* description_fetcher = fetcher_map_[device_data_2.label()].get();
|
| + EXPECT_EQ(new_url_2, description_fetcher->device_description_url());
|
| +
|
| + EXPECT_CALL(mock_error_cb_, Run(_, _)).Times(3);
|
| + device_description_service()->OnDeviceDescriptionFetchError(device_data_1,
|
| + "");
|
| + device_description_service()->OnDeviceDescriptionFetchError(device_data_2,
|
| + "");
|
| + device_description_service()->OnDeviceDescriptionFetchError(device_data_3,
|
| + "");
|
| +}
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest, TestCleanUpCacheEntries) {
|
| + DialDeviceData device_data_1 = CreateDialDeviceData(1);
|
| + DialDeviceData device_data_2 = CreateDialDeviceData(2);
|
| + DialDeviceData device_data_3 = CreateDialDeviceData(3);
|
| +
|
| + AddToCache(device_data_1.label(), ParsedDialDeviceDescription(),
|
| + true /* expired */);
|
| + AddToCache(device_data_2.label(), ParsedDialDeviceDescription(),
|
| + true /* expired */);
|
| + AddToCache(device_data_3.label(), ParsedDialDeviceDescription(),
|
| + false /* expired */);
|
| +
|
| + device_description_service_.CleanUpCacheEntries();
|
| + EXPECT_EQ(size_t(1), description_cache_.size());
|
| + EXPECT_TRUE(base::ContainsKey(description_cache_, device_data_3.label()));
|
| +
|
| + AddToCache(device_data_3.label(), ParsedDialDeviceDescription(),
|
| + true /* expired*/);
|
| + device_description_service_.CleanUpCacheEntries();
|
| + EXPECT_TRUE(description_cache_.empty());
|
| +}
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest, TestOnParsedDeviceDescription) {
|
| + GURL app_url("http://192.168.1.1/apps");
|
| + DialDeviceData device_data = CreateDialDeviceData(1);
|
| +
|
| + // null_ptr
|
| + std::string error_message = "Failed to parse device description XML";
|
| + TestOnParsedDeviceDescription(nullptr, error_message);
|
| +
|
| + // Empty field
|
| + error_message = "Failed to process fetch result";
|
| + TestOnParsedDeviceDescription(chrome::mojom::DialDeviceDescription::New(),
|
| + error_message);
|
| +
|
| + // Valid device description ptr and put in cache
|
| + auto description_ptr = CreateDialDeviceDescriptionPtr(1);
|
| + TestOnParsedDeviceDescription(std::move(description_ptr), "");
|
| + EXPECT_EQ(size_t(1), description_cache_.size());
|
| +
|
| + // Valid device description ptr and skip cache.
|
| + size_t cache_num = 256;
|
| + for (size_t i = 0; i < cache_num; i++) {
|
| + AddToCache(std::to_string(i), ParsedDialDeviceDescription(),
|
| + false /* expired */);
|
| + }
|
| +
|
| + EXPECT_EQ(size_t(cache_num + 1), description_cache_.size());
|
| + description_ptr = CreateDialDeviceDescriptionPtr(1);
|
| + TestOnParsedDeviceDescription(std::move(description_ptr), "");
|
| + EXPECT_EQ(size_t(cache_num + 1), description_cache_.size());
|
| +}
|
| +
|
| +TEST_F(DeviceDescriptionServiceTest, TestSafeParserProperlyCreated) {
|
| + DialDeviceData device_data_1 = CreateDialDeviceData(1);
|
| + DialDeviceData device_data_2 = CreateDialDeviceData(2);
|
| + DialDeviceData device_data_3 = CreateDialDeviceData(3);
|
| +
|
| + std::vector<DialDeviceData> devices = {device_data_1, device_data_2,
|
| + device_data_3};
|
| +
|
| + // insert fetchers
|
| + device_description_service()->GetDeviceDescriptions(
|
| + devices, profile_.GetRequestContext());
|
| + auto test_parser = base::MakeUnique<TestSafeDialDeviceDescriptionParser>();
|
| + EXPECT_CALL(*test_parser, Start(_, _)).Times(3);
|
| +
|
| + EXPECT_FALSE(device_description_service()->parser_);
|
| + SetTestParser(std::move(test_parser));
|
| + OnDeviceDescriptionFetchComplete(1);
|
| +
|
| + EXPECT_TRUE(device_description_service()->parser_);
|
| + OnDeviceDescriptionFetchComplete(2);
|
| + OnDeviceDescriptionFetchComplete(3);
|
| +
|
| + EXPECT_FALSE(device_description_service()->parser_);
|
| +}
|
| +
|
| +} // namespace media_router
|
|
|