blob: 55f89e4c2c0473c706cf14f9eab7a35264e3b397 [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 "chrome/browser/extensions/updater/extension_update_client_base_browsertest.h"
#include "base/bind.h"
#include "base/path_service.h"
#include "base/run_loop.h"
#include "base/task/post_task.h"
#include "base/test/scoped_feature_list.h"
#include "chrome/browser/chrome_browser_main.h"
#include "chrome/browser/chrome_browser_main_extra_parts.h"
#include "chrome/browser/extensions/browsertest_util.h"
#include "components/update_client/protocol_handler.h"
#include "components/update_client/url_loader_post_interceptor.h"
#include "content/public/browser/browser_context.h"
#include "extensions/browser/updater/update_service.h"
#include "extensions/browser/updater/update_service_factory.h"
#include "extensions/common/extension_features.h"
#include "net/url_request/test_url_request_interceptor.h"
namespace extensions {
namespace {
using ConfigFactoryCallback =
ExtensionUpdateClientBaseTest::ConfigFactoryCallback;
class TestChromeUpdateClientConfig
: public extensions::ChromeUpdateClientConfig {
public:
TestChromeUpdateClientConfig(content::BrowserContext* context,
bool use_JSON,
const std::vector<GURL>& update_url,
const std::vector<GURL>& ping_url)
: extensions::ChromeUpdateClientConfig(context),
use_JSON_(use_JSON),
update_url_(update_url),
ping_url_(ping_url) {}
// Overrides for update_client::Configurator.
std::vector<GURL> UpdateUrl() const final { return update_url_; }
std::vector<GURL> PingUrl() const final { return ping_url_; }
bool EnabledCupSigning() const final { return false; }
std::unique_ptr<update_client::ProtocolHandlerFactory>
GetProtocolHandlerFactory() const final {
if (use_JSON_)
return std::make_unique<update_client::ProtocolHandlerFactoryJSON>();
return std::make_unique<update_client::ProtocolHandlerFactoryXml>();
}
protected:
~TestChromeUpdateClientConfig() override = default;
private:
bool use_JSON_ = false;
std::vector<GURL> update_url_;
std::vector<GURL> ping_url_;
DISALLOW_COPY_AND_ASSIGN(TestChromeUpdateClientConfig);
};
// This class implements a simple Chrome extra part that is used to
// set up the network interceptors in the test class. This would allow us to
// reliably inject the network interceptors before the browser starts running.
class TestChromeBrowserMainExtraParts : public ChromeBrowserMainExtraParts {
public:
explicit TestChromeBrowserMainExtraParts(ExtensionUpdateClientBaseTest* test)
: test_(test) {}
~TestChromeBrowserMainExtraParts() override {}
// ChromeBrowserMainExtraParts:
void PreProfileInit() override { test_->SetUpNetworkInterceptors(); }
private:
ExtensionUpdateClientBaseTest* test_;
DISALLOW_COPY_AND_ASSIGN(TestChromeBrowserMainExtraParts);
};
class UpdateClientCompleteEventWaiter
: public update_client::UpdateClient::Observer {
public:
using UpdateClientEvents = update_client::UpdateClient::Observer::Events;
explicit UpdateClientCompleteEventWaiter(const std::string& id)
: id_(id), event_(UpdateClientEvents::COMPONENT_UPDATE_ERROR) {}
~UpdateClientCompleteEventWaiter() override {}
void OnEvent(update_client::UpdateClient::Observer::Events event,
const std::string& id) final {
if (id_ == id && (event == UpdateClientEvents::COMPONENT_UPDATED ||
event == UpdateClientEvents::COMPONENT_NOT_UPDATED ||
event == UpdateClientEvents::COMPONENT_UPDATE_ERROR)) {
event_ = event;
run_loop_.Quit();
}
}
UpdateClientEvents Wait() {
run_loop_.Run();
return event_;
}
private:
const std::string id_;
UpdateClientEvents event_;
base::RunLoop run_loop_;
DISALLOW_COPY_AND_ASSIGN(UpdateClientCompleteEventWaiter);
};
} // namespace
ExtensionUpdateClientBaseTest::ExtensionUpdateClientBaseTest(bool use_JSON)
: https_server_for_update_(net::EmbeddedTestServer::TYPE_HTTPS),
https_server_for_ping_(net::EmbeddedTestServer::TYPE_HTTPS),
use_JSON_(use_JSON) {}
ExtensionUpdateClientBaseTest::~ExtensionUpdateClientBaseTest() {}
std::vector<GURL> ExtensionUpdateClientBaseTest::GetUpdateUrls() const {
return {https_server_for_update_.GetURL("/updatehost/service/update")};
}
std::vector<GURL> ExtensionUpdateClientBaseTest::GetPingUrls() const {
return {https_server_for_ping_.GetURL("/pinghost/service/ping")};
}
ConfigFactoryCallback
ExtensionUpdateClientBaseTest::ChromeUpdateClientConfigFactory() const {
return base::BindRepeating(
[](const std::vector<GURL>& update_url, const std::vector<GURL>& ping_url,
bool use_JSON, content::BrowserContext* context)
-> scoped_refptr<ChromeUpdateClientConfig> {
return base::MakeRefCounted<TestChromeUpdateClientConfig>(
context, use_JSON, update_url, ping_url);
},
GetUpdateUrls(), GetPingUrls(), use_JSON_);
}
void ExtensionUpdateClientBaseTest::SetUp() {
ASSERT_TRUE(https_server_for_update_.InitializeAndListen());
ASSERT_TRUE(https_server_for_ping_.InitializeAndListen());
scoped_feature_list_.InitAndEnableFeature(
extensions_features::kNewExtensionUpdaterService);
ChromeUpdateClientConfig::SetChromeUpdateClientConfigFactoryForTesting(
ChromeUpdateClientConfigFactory());
ExtensionBrowserTest::SetUp();
}
void ExtensionUpdateClientBaseTest::CreatedBrowserMainParts(
content::BrowserMainParts* parts) {
ExtensionBrowserTest::CreatedBrowserMainParts(parts);
static_cast<ChromeBrowserMainParts*>(parts)->AddParts(
new TestChromeBrowserMainExtraParts(this));
}
void ExtensionUpdateClientBaseTest::SetUpOnMainThread() {
ExtensionBrowserTest::SetUpOnMainThread();
extensions::browsertest_util::CreateAndInitializeLocalCache();
update_service_ =
extensions::UpdateServiceFactory::GetForBrowserContext(profile());
ASSERT_TRUE(update_service_);
}
void ExtensionUpdateClientBaseTest::TearDownOnMainThread() {
get_interceptor_.reset();
}
void ExtensionUpdateClientBaseTest::SetUpNetworkInterceptors() {
const auto update_urls = GetUpdateUrls();
ASSERT_TRUE(!update_urls.empty());
const GURL update_url = update_urls.front();
update_interceptor_ =
std::make_unique<update_client::URLLoaderPostInterceptor>(
update_urls, &https_server_for_update_);
https_server_for_update_.StartAcceptingConnections();
const auto ping_urls = GetPingUrls();
ASSERT_TRUE(!ping_urls.empty());
const GURL ping_url = ping_urls.front();
ping_interceptor_ = std::make_unique<update_client::URLLoaderPostInterceptor>(
ping_urls, &https_server_for_ping_);
https_server_for_ping_.StartAcceptingConnections();
get_interceptor_ =
std::make_unique<content::URLLoaderInterceptor>(base::BindRepeating(
&ExtensionUpdateClientBaseTest::OnRequest, base::Unretained(this)));
}
update_client::UpdateClient::Observer::Events
ExtensionUpdateClientBaseTest::WaitOnComponentUpdaterCompleteEvent(
const std::string& id) {
UpdateClientCompleteEventWaiter waiter(id);
update_service_->AddUpdateClientObserver(&waiter);
auto event = waiter.Wait();
update_service_->RemoveUpdateClientObserver(&waiter);
return event;
}
bool ExtensionUpdateClientBaseTest::OnRequest(
content::URLLoaderInterceptor::RequestParams* params) {
if (params->url_request.url.host() != "localhost")
return false;
get_interceptor_count_++;
return callback_ && callback_.Run(params);
}
} // namespace extensions