Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Unified Diff: ios/chrome/browser/browser_state/test_chrome_browser_state.cc

Issue 1664823003: Upstream ChromeBrowserState sub-classes. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Address comments Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: ios/chrome/browser/browser_state/test_chrome_browser_state.cc
diff --git a/ios/chrome/browser/browser_state/test_chrome_browser_state.cc b/ios/chrome/browser/browser_state/test_chrome_browser_state.cc
new file mode 100644
index 0000000000000000000000000000000000000000..236bf2b94d11cc279760d1a2ea66c2957b4c2cc2
--- /dev/null
+++ b/ios/chrome/browser/browser_state/test_chrome_browser_state.cc
@@ -0,0 +1,426 @@
+// Copyright 2013 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 "ios/chrome/browser/browser_state/test_chrome_browser_state.h"
+
+#include <utility>
+
+#include "base/base_paths.h"
+#include "base/files/file_util.h"
+#include "base/logging.h"
+#include "base/macros.h"
+#include "base/message_loop/message_loop.h"
+#include "base/path_service.h"
+#include "base/run_loop.h"
+#include "base/thread_task_runner_handle.h"
+#include "components/bookmarks/browser/bookmark_model.h"
+#include "components/bookmarks/common/bookmark_constants.h"
+#include "components/history/core/browser/history_constants.h"
+#include "components/history/core/browser/history_database_params.h"
+#include "components/history/core/browser/history_service.h"
+#include "components/history/core/browser/top_sites.h"
+#include "components/history/core/browser/visit_delegate.h"
+#include "components/history/ios/browser/history_database_helper.h"
+#include "components/keyed_service/core/service_access_type.h"
+#include "components/keyed_service/ios/browser_state_dependency_manager.h"
+#include "components/syncable_prefs/pref_service_syncable.h"
+#include "components/syncable_prefs/testing_pref_service_syncable.h"
+#include "components/user_prefs/user_prefs.h"
+#include "components/webdata_services/web_data_service_wrapper.h"
+#include "ios/chrome/browser/application_context.h"
+#include "ios/chrome/browser/autocomplete/in_memory_url_index_factory.h"
+#include "ios/chrome/browser/bookmarks/bookmark_client_impl.h"
+#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h"
+#include "ios/chrome/browser/browser_state/browser_state_keyed_service_factories.h"
+#include "ios/chrome/browser/history/history_client_impl.h"
+#include "ios/chrome/browser/history/history_service_factory.h"
+#include "ios/chrome/browser/history/top_sites_factory.h"
+#include "ios/chrome/browser/history/web_history_service_factory.h"
+#include "ios/chrome/browser/pref_names.h"
+#include "ios/chrome/browser/prefs/browser_prefs.h"
+#include "ios/chrome/browser/prefs/ios_chrome_pref_service_factory.h"
+#include "ios/chrome/browser/sync/glue/sync_start_util.h"
+#include "ios/chrome/browser/web_data_service_factory.h"
+#include "ios/public/provider/chrome/browser/chrome_browser_provider.h"
+#include "ios/web/public/web_thread.h"
+#include "net/url_request/url_request_test_util.h"
+
+namespace {
+scoped_ptr<KeyedService> BuildHistoryService(web::BrowserState* context) {
+ ios::ChromeBrowserState* browser_state =
+ ios::ChromeBrowserState::FromBrowserState(context);
+ return make_scoped_ptr(new history::HistoryService(
+ make_scoped_ptr(new HistoryClientImpl(
+ ios::BookmarkModelFactory::GetForBrowserState(browser_state))),
+ nullptr));
+}
+
+scoped_ptr<KeyedService> BuildBookmarkModel(web::BrowserState* context) {
+ ios::ChromeBrowserState* browser_state =
+ ios::ChromeBrowserState::FromBrowserState(context);
+ scoped_ptr<bookmarks::BookmarkModel> bookmark_model(
+ new bookmarks::BookmarkModel(
+ make_scoped_ptr(new BookmarkClientImpl(browser_state))));
+ bookmark_model->Load(
+ browser_state->GetPrefs(),
+ browser_state->GetPrefs()->GetString(prefs::kAcceptLanguages),
+ browser_state->GetStatePath(), browser_state->GetIOTaskRunner(),
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::UI));
+ return std::move(bookmark_model);
+}
+
+void NotReachedErrorCallback(WebDataServiceWrapper::ErrorType error_type,
+ sql::InitStatus status) {
+ NOTREACHED();
+}
+
+scoped_ptr<KeyedService> BuildWebDataService(web::BrowserState* context) {
+ const base::FilePath& browser_state_path = context->GetStatePath();
+ return make_scoped_ptr(new WebDataServiceWrapper(
+ browser_state_path, GetApplicationContext()->GetApplicationLocale(),
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::UI),
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::DB),
+ ios::sync_start_util::GetFlareForSyncableService(browser_state_path),
+ &NotReachedErrorCallback));
+}
+
+base::FilePath CreateTempBrowserStateDir(base::ScopedTempDir* temp_dir) {
+ DCHECK(temp_dir);
+ if (!temp_dir->CreateUniqueTempDir()) {
+ // Fallback logic in case we fail to create unique temporary directory.
+ LOG(ERROR) << "Failed to create unique temporary directory.";
+ base::FilePath system_tmp_dir;
+ bool success = PathService::Get(base::DIR_TEMP, &system_tmp_dir);
+
+ // We're severly screwed if we can't get the system temporary
+ // directory. Die now to avoid writing to the filesystem root
+ // or other bad places.
+ CHECK(success);
+
+ base::FilePath fallback_dir(
+ system_tmp_dir.Append(FILE_PATH_LITERAL("TestChromeBrowserStatePath")));
+ base::DeleteFile(fallback_dir, true);
+ base::CreateDirectory(fallback_dir);
+ if (!temp_dir->Set(fallback_dir)) {
+ // That shouldn't happen, but if it does, try to recover.
+ LOG(ERROR) << "Failed to use a fallback temporary directory.";
+
+ // We're screwed if this fails, see CHECK above.
+ CHECK(temp_dir->Set(system_tmp_dir));
+ }
+ }
+ return temp_dir->path();
+}
+} // namespace
+
+TestChromeBrowserState::TestChromeBrowserState(
+ TestChromeBrowserState* original_browser_state)
+ : testing_prefs_(nullptr),
+ otr_browser_state_(nullptr),
+ original_browser_state_(original_browser_state) {
+ // Not calling Init() here as the bi-directional link between original and
+ // off-the-record TestChromeBrowserState must be established before this
+ // method can be called.
+ DCHECK(original_browser_state_);
+}
+
+TestChromeBrowserState::TestChromeBrowserState(
+ const base::FilePath& path,
+ scoped_ptr<syncable_prefs::PrefServiceSyncable> prefs,
+ const TestingFactories& testing_factories,
+ const RefcountedTestingFactories& refcounted_testing_factories)
+ : state_path_(path),
+ prefs_(std::move(prefs)),
+ testing_prefs_(nullptr),
+ otr_browser_state_(nullptr),
+ original_browser_state_(nullptr) {
+ Init();
+
+ for (const auto& pair : testing_factories) {
+ pair.first->SetTestingFactory(this, pair.second);
+ }
+
+ for (const auto& pair : refcounted_testing_factories) {
+ pair.first->SetTestingFactory(this, pair.second);
+ }
+}
+
+TestChromeBrowserState::~TestChromeBrowserState() {
+ // If this TestChromeBrowserState owns an incognito TestChromeBrowserState,
+ // tear it down first.
+ otr_browser_state_.reset();
+
+ BrowserStateDependencyManager::GetInstance()->DestroyBrowserStateServices(
+ this);
+}
+
+void TestChromeBrowserState::Init() {
+ // If threads have been initialized, we should be on the UI thread.
+ DCHECK(!web::WebThread::IsThreadInitialized(web::WebThread::UI) ||
+ web::WebThread::CurrentlyOn(web::WebThread::UI));
+
+ if (state_path_.empty())
+ state_path_ = CreateTempBrowserStateDir(&temp_dir_);
+
+ if (IsOffTheRecord())
+ state_path_ = state_path_.Append(FILE_PATH_LITERAL("OTR"));
+
+ if (!base::PathExists(state_path_))
+ base::CreateDirectory(state_path_);
+
+ // Normally this would happen during browser startup, but for tests we need to
+ // trigger creation of BrowserState-related services.
+ EnsureBrowserStateKeyedServiceFactoriesBuilt();
+ if (ios::GetChromeBrowserProvider())
+ ios::GetChromeBrowserProvider()->AssertBrowserContextKeyedFactoriesBuilt();
+
+ if (prefs_) {
+ // If user passed a custom PrefServiceSyncable, then leave |testing_prefs_|
+ // unset as it is not possible to determine its type.
+ } else if (IsOffTheRecord()) {
+ // This leaves |testing_prefs_| unset as CreateIncognitoBrowserStatePrefs()
+ // does not return a TestingPrefServiceSyncable.
+ DCHECK(original_browser_state_);
+ prefs_ =
+ CreateIncognitoBrowserStatePrefs(original_browser_state_->prefs_.get());
+ } else {
+ testing_prefs_ = new syncable_prefs::TestingPrefServiceSyncable();
+ RegisterBrowserStatePrefs(testing_prefs_->registry());
+ prefs_.reset(testing_prefs_);
+ }
+ user_prefs::UserPrefs::Set(this, prefs_.get());
+
+ // Prefs for incognito TestChromeBrowserState are set in
+ // CreateIncognitoBrowserStatePrefs().
+ if (!IsOffTheRecord()) {
+ user_prefs::PrefRegistrySyncable* pref_registry =
+ static_cast<user_prefs::PrefRegistrySyncable*>(
+ prefs_->DeprecatedGetPrefRegistry());
+ BrowserStateDependencyManager::GetInstance()
+ ->RegisterBrowserStatePrefsForServices(this, pref_registry);
+ }
+
+ BrowserStateDependencyManager::GetInstance()
+ ->CreateBrowserStateServicesForTest(this);
+}
+
+bool TestChromeBrowserState::IsOffTheRecord() const {
+ return original_browser_state_ != nullptr;
+}
+
+base::FilePath TestChromeBrowserState::GetStatePath() const {
+ if (!IsOffTheRecord())
+ return state_path_;
+
+ base::FilePath otr_stash_state_path =
+ state_path_.Append(FILE_PATH_LITERAL("OTR"));
+ if (!base::PathExists(otr_stash_state_path))
+ base::CreateDirectory(otr_stash_state_path);
+ return otr_stash_state_path;
+}
+
+scoped_refptr<base::SequencedTaskRunner>
+TestChromeBrowserState::GetIOTaskRunner() {
+ return base::MessageLoop::current()->task_runner();
+}
+
+ios::ChromeBrowserState*
+TestChromeBrowserState::GetOriginalChromeBrowserState() {
+ if (IsOffTheRecord())
+ return original_browser_state_;
+ return this;
+}
+
+bool TestChromeBrowserState::HasOffTheRecordChromeBrowserState() const {
+ return otr_browser_state_ != nullptr;
+}
+
+ios::ChromeBrowserState*
+TestChromeBrowserState::GetOffTheRecordChromeBrowserState() {
+ if (IsOffTheRecord())
+ return this;
+
+ if (!otr_browser_state_) {
+ otr_browser_state_.reset(new TestChromeBrowserState(this));
+ otr_browser_state_->Init();
+ }
+
+ return otr_browser_state_.get();
+}
+
+PrefProxyConfigTracker* TestChromeBrowserState::GetProxyConfigTracker() {
+ return nullptr;
+}
+
+net::SSLConfigService* TestChromeBrowserState::GetSSLConfigService() {
+ return nullptr;
+}
+
+PrefService* TestChromeBrowserState::GetPrefs() {
+ return prefs_.get();
+}
+
+PrefService* TestChromeBrowserState::GetOffTheRecordPrefs() {
+ return nullptr;
+}
+
+ChromeBrowserStateIOData* TestChromeBrowserState::GetIOData() {
+ return nullptr;
+}
+
+void TestChromeBrowserState::ClearNetworkingHistorySince(
+ base::Time time,
+ const base::Closure& completion) {
+ if (!completion.is_null())
+ completion.Run();
+}
+
+net::URLRequestContextGetter* TestChromeBrowserState::CreateRequestContext(
+ ProtocolHandlerMap* protocol_handlers,
+ URLRequestInterceptorScopedVector request_interceptors) {
+ return new net::TestURLRequestContextGetter(
+ web::WebThread::GetTaskRunnerForThread(web::WebThread::IO));
+}
+
+net::URLRequestContextGetter*
+TestChromeBrowserState::CreateIsolatedRequestContext(
+ const base::FilePath& partition_path) {
+ return nullptr;
+}
+
+TestChromeBrowserState* TestChromeBrowserState::AsTestChromeBrowserState() {
+ return this;
+}
+
+void TestChromeBrowserState::CreateWebDataService() {
+ ignore_result(
+ ios::WebDataServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ this, &BuildWebDataService));
+
+ // Wait a bit after creating the WebDataService to allow the initialisation
+ // to complete (otherwise the TestChromeBrowserState may be destroyed before
+ // initialisation of the database is complete which leads to SQL init errors).
+ base::RunLoop run_loop;
+ run_loop.RunUntilIdle();
+}
+
+void TestChromeBrowserState::CreateBookmarkModel(bool delete_file) {
+ if (delete_file) {
+ base::DeleteFile(GetOriginalChromeBrowserState()->GetStatePath().Append(
+ bookmarks::kBookmarksFileName),
+ false /* recursive */);
+ }
+ ignore_result(
+ ios::BookmarkModelFactory::GetInstance()->SetTestingFactoryAndUse(
+ this, &BuildBookmarkModel));
+}
+
+bool TestChromeBrowserState::CreateHistoryService(bool delete_file) {
+ // Ensure that no HistoryService exists before creating a new one.
+ DestroyHistoryService();
+
+ if (delete_file) {
+ base::FilePath path =
+ GetOriginalChromeBrowserState()->GetStatePath().Append(
+ history::kHistoryFilename);
+ if (!base::DeleteFile(path, false) && base::PathExists(path))
+ return false;
+ }
+
+ // Create and initialize the HistoryService, but destroy it if the init fails.
+ history::HistoryService* history_service =
+ static_cast<history::HistoryService*>(
+ ios::HistoryServiceFactory::GetInstance()->SetTestingFactoryAndUse(
+ this, &BuildHistoryService));
+ if (!history_service->Init(
+ GetPrefs()->GetString(prefs::kAcceptLanguages),
+ history::HistoryDatabaseParamsForPath(
+ GetOriginalChromeBrowserState()->GetStatePath()))) {
+ ios::HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr);
+ return false;
+ }
+
+ // Some tests expect that CreateHistoryService() will also make the
+ // InMemoryURLIndex available.
+ ios::InMemoryURLIndexFactory::GetInstance()->SetTestingFactory(
+ this, ios::InMemoryURLIndexFactory::GetDefaultFactory());
+ // Disable WebHistoryService by default, since it makes network requests.
+ ios::WebHistoryServiceFactory::GetInstance()->SetTestingFactory(this,
+ nullptr);
+
+ return true;
+}
+
+void TestChromeBrowserState::DestroyHistoryService() {
+ history::HistoryService* history_service =
+ ios::HistoryServiceFactory::GetInstance()->GetForBrowserStateIfExists(
+ this, ServiceAccessType::EXPLICIT_ACCESS);
+ if (!history_service)
+ return;
+
+ history_service->ClearCachedDataForContextID(0);
+ history_service->SetOnBackendDestroyTask(
+ base::MessageLoop::QuitWhenIdleClosure());
+ history_service->Shutdown();
+ history_service = nullptr;
+
+ // Resetting the testing factory force the destruction of the current
+ // HistoryService instance associated with the TestChromeBrowserState.
+ ios::HistoryServiceFactory::GetInstance()->SetTestingFactory(this, nullptr);
+
+ // Wait for the backend class to terminate before deleting the files and
+ // moving to the next test. Note: if this never terminates, somebody is
+ // probably leaking a reference to the history backend, so it never calls
+ // our destroy task.
+ base::MessageLoop::current()->Run();
+
+ // Make sure we don't have any event pending that could disrupt the next
+ // test.
+ base::ThreadTaskRunnerHandle::Get()->PostTask(
+ FROM_HERE, base::MessageLoop::QuitWhenIdleClosure());
+ base::MessageLoop::current()->Run();
+}
+
+syncable_prefs::TestingPrefServiceSyncable*
+TestChromeBrowserState::GetTestingPrefService() {
+ DCHECK(prefs_);
+ DCHECK(testing_prefs_);
+ return testing_prefs_;
+}
+
+TestChromeBrowserState::Builder::Builder() : build_called_(false) {}
+
+TestChromeBrowserState::Builder::~Builder() {}
+
+void TestChromeBrowserState::Builder::AddTestingFactory(
+ BrowserStateKeyedServiceFactory* service_factory,
+ BrowserStateKeyedServiceFactory::TestingFactoryFunction cb) {
+ DCHECK(!build_called_);
+ testing_factories_.push_back(std::make_pair(service_factory, cb));
+}
+
+void TestChromeBrowserState::Builder::AddTestingFactory(
+ RefcountedBrowserStateKeyedServiceFactory* service_factory,
+ RefcountedBrowserStateKeyedServiceFactory::TestingFactoryFunction cb) {
+ DCHECK(!build_called_);
+ refcounted_testing_factories_.push_back(std::make_pair(service_factory, cb));
+}
+
+void TestChromeBrowserState::Builder::SetPath(const base::FilePath& path) {
+ DCHECK(!build_called_);
+ state_path_ = path;
+}
+
+void TestChromeBrowserState::Builder::SetPrefService(
+ scoped_ptr<syncable_prefs::PrefServiceSyncable> prefs) {
+ DCHECK(!build_called_);
+ pref_service_ = std::move(prefs);
+}
+
+scoped_ptr<TestChromeBrowserState> TestChromeBrowserState::Builder::Build() {
+ DCHECK(!build_called_);
+ return make_scoped_ptr(new TestChromeBrowserState(
+ state_path_, std::move(pref_service_), testing_factories_,
+ refcounted_testing_factories_));
+}

Powered by Google App Engine
This is Rietveld 408576698