1// Copyright 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "ios/chrome/browser/test/perf_test_with_bvc_ios.h" 6 7#import <UIKit/UIKit.h> 8 9#include "base/files/file_path.h" 10#include "base/strings/sys_string_conversions.h" 11#include "components/bookmarks/test/bookmark_test_helpers.h" 12#include "ios/chrome/browser/autocomplete/autocomplete_classifier_factory.h" 13#include "ios/chrome/browser/bookmarks/bookmark_model_factory.h" 14#include "ios/chrome/browser/browser_state/test_chrome_browser_state_manager.h" 15#import "ios/chrome/browser/main/test_browser.h" 16#include "ios/chrome/browser/search_engines/template_url_service_factory.h" 17#import "ios/chrome/browser/sessions/session_ios.h" 18#include "ios/chrome/browser/sessions/session_restoration_browser_agent.h" 19#import "ios/chrome/browser/sessions/session_service_ios.h" 20#import "ios/chrome/browser/sessions/session_window_ios.h" 21#import "ios/chrome/browser/ui/browser_container/browser_container_view_controller.h" 22#import "ios/chrome/browser/ui/browser_view/browser_view_controller+private.h" 23#import "ios/chrome/browser/ui/browser_view/browser_view_controller.h" 24#import "ios/chrome/browser/ui/browser_view/browser_view_controller_dependency_factory.h" 25#import "ios/chrome/browser/ui/commands/command_dispatcher.h" 26#import "ios/chrome/browser/web/chrome_web_client.h" 27#include "ios/public/provider/chrome/browser/chrome_browser_provider.h" 28 29#if !defined(__has_feature) || !__has_feature(objc_arc) 30#error "This file requires ARC support." 31#endif 32 33// Subclass of PrerenderController so it isn't actually used. Using a mock for 34// this makes cleanup on shutdown simpler, by minimizing the number of profile 35// observers registered with the profiles. The profile observers have to be 36// deallocated before the profiles themselves, but in practice it is very hard 37// to ensure that happens. Also, for performance testing, not having the 38// PrerenderController makes the test far simpler to analyze. 39namespace { 40static GURL emptyGurl_ = GURL("foo", 3, url::Parsed(), false); 41} 42 43PerfTestWithBVC::PerfTestWithBVC(std::string testGroup) 44 : PerfTest(testGroup), 45 slow_teardown_(false), 46 web_client_(std::make_unique<ChromeWebClient>()), 47 provider_(ios::CreateChromeBrowserProvider()), 48 browser_state_manager_( 49 std::make_unique<TestChromeBrowserStateManager>(base::FilePath())), 50 web_state_list_(&web_state_list_delegate_), 51 otr_web_state_list_(&web_state_list_delegate_) {} 52 53PerfTestWithBVC::PerfTestWithBVC(std::string testGroup, 54 std::string firstLabel, 55 std::string averageLabel, 56 bool isWaterfall, 57 bool verbose, 58 bool slowTeardown, 59 int repeat) 60 : PerfTest(testGroup, 61 firstLabel, 62 averageLabel, 63 isWaterfall, 64 verbose, 65 repeat), 66 slow_teardown_(slowTeardown), 67 web_client_(std::make_unique<ChromeWebClient>()), 68 provider_(ios::CreateChromeBrowserProvider()), 69 browser_state_manager_( 70 std::make_unique<TestChromeBrowserStateManager>(base::FilePath())), 71 web_state_list_(&web_state_list_delegate_), 72 otr_web_state_list_(&web_state_list_delegate_) {} 73 74PerfTestWithBVC::~PerfTestWithBVC() {} 75 76void PerfTestWithBVC::SetUp() { 77 PerfTest::SetUp(); 78 79 // Set up the ChromeBrowserState instances. 80 TestChromeBrowserState::Builder test_cbs_builder; 81 test_cbs_builder.AddTestingFactory( 82 ios::TemplateURLServiceFactory::GetInstance(), 83 ios::TemplateURLServiceFactory::GetDefaultFactory()); 84 test_cbs_builder.AddTestingFactory( 85 ios::AutocompleteClassifierFactory::GetInstance(), 86 ios::AutocompleteClassifierFactory::GetDefaultFactory()); 87 chrome_browser_state_ = test_cbs_builder.Build(); 88 chrome_browser_state_->CreateBookmarkModel(false); 89 bookmarks::test::WaitForBookmarkModelToLoad( 90 ios::BookmarkModelFactory::GetForBrowserState( 91 chrome_browser_state_.get())); 92 ASSERT_TRUE(chrome_browser_state_->CreateHistoryService()); 93 94 // Force creation of AutocompleteClassifier instance. 95 ios::AutocompleteClassifierFactory::GetForBrowserState( 96 chrome_browser_state_.get()); 97 98 // Use the session to create a window which will contain the tabs. 99 NSString* state_path = base::SysUTF8ToNSString( 100 chrome_browser_state_->GetStatePath().AsUTF8Unsafe()); 101 SessionIOS* session = 102 [[SessionServiceIOS sharedService] loadSessionFromDirectory:state_path]; 103 DCHECK_EQ(session.sessionWindows.count, 1u); 104 105 browser_ = std::make_unique<TestBrowser>(chrome_browser_state_.get(), 106 &web_state_list_); 107 otr_browser_ = std::make_unique<TestBrowser>( 108 chrome_browser_state_->GetOffTheRecordChromeBrowserState(), 109 &otr_web_state_list_); 110 SessionRestorationBrowserAgent::CreateForBrowser( 111 browser_.get(), [SessionServiceIOS sharedService]); 112 SessionRestorationBrowserAgent::CreateForBrowser( 113 otr_browser_.get(), [SessionServiceIOS sharedService]); 114 SessionRestorationBrowserAgent::FromBrowser(browser_.get()) 115 ->RestoreSessionWindow(session.sessionWindows[0]); 116 SessionRestorationBrowserAgent::FromBrowser(otr_browser_.get()) 117 ->RestoreSessionWindow(session.sessionWindows[0]); 118 119 // Create the browser view controller with its testing factory. 120 bvc_factory_ = [[BrowserViewControllerDependencyFactory alloc] 121 initWithBrowser:browser_.get()]; 122 bvc_ = [[BrowserViewController alloc] 123 initWithBrowser:browser_.get() 124 dependencyFactory:bvc_factory_ 125 browserContainerViewController:[[BrowserContainerViewController alloc] 126 init] 127 dispatcher:browser_->GetCommandDispatcher()]; 128 [bvc_ setActive:YES]; 129 130 // Create a real window to give to the browser view controller. 131 window_ = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 132 [window_ makeKeyAndVisible]; 133 [window_ addSubview:[bvc_ view]]; 134 [[bvc_ view] setFrame:[[UIScreen mainScreen] bounds]]; 135} 136 137void PerfTestWithBVC::TearDown() { 138 browser_.get()->GetWebStateList()->CloseAllWebStates( 139 WebStateList::CLOSE_NO_FLAGS); 140 [[bvc_ view] removeFromSuperview]; 141 142 // Documented example of how to clear out the browser view controller 143 // and its associated data. 144 window_ = nil; 145 [bvc_ shutdown]; 146 bvc_ = nil; 147 bvc_factory_ = nil; 148 149 // The base class |TearDown| method calls the run loop so the 150 // NSAutoreleasePool can drain. This needs to be done before 151 // |chrome_browser_state_| can be cleared. For tests that allocate more 152 // objects, more runloop time may be required. 153 if (slow_teardown_) 154 SpinRunLoop(.5); 155 PerfTest::TearDown(); 156 157 // Before destroying chrome_browser_state_ we need to make sure that no tasks 158 // are left on the ThreadPool since they might depend on it. 159 task_environment_.RunUntilIdle(); 160 161 // The profiles can be deallocated only after the BVC has been deallocated. 162 chrome_browser_state_.reset(); 163} 164