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

Side by Side Diff: chrome/browser/prerender/prerender_test_utils.cc

Issue 2309443002: NoState Prefetch: Refactor prerender_browsertests.cc (Closed)
Patch Set: Remove unnecessary diff Created 4 years, 3 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 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 "chrome/browser/prerender/prerender_test_utils.h"
6
7 #include "base/command_line.h"
8 #include "chrome/browser/prerender/prerender_manager.h"
9 #include "chrome/browser/prerender/prerender_manager_factory.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/renderer_host/chrome_resource_dispatcher_host_delegate. h"
12 #include "chrome/browser/safe_browsing/local_database_manager.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/tabs/tab_strip_model.h"
15 #include "chrome/common/pref_names.h"
16 #include "components/prefs/pref_service.h"
17 #include "content/public/browser/notification_details.h"
18 #include "content/public/browser/notification_source.h"
19 #include "content/public/browser/notification_types.h"
20 #include "content/public/browser/render_view_host.h"
21 #include "content/public/common/content_switches.h"
22 #include "content/public/common/url_constants.h"
23 #include "content/public/test/ppapi_test_utils.h"
24 #include "ppapi/shared_impl/ppapi_switches.h"
25 #include "testing/gtest/include/gtest/gtest.h"
26
27 using content::BrowserThread;
28 using content::RenderViewHost;
29
30 namespace prerender {
31
32 namespace test_utils {
33
34 namespace {
droger 2016/09/02 14:33:54 nit: blank line after this. I believe the recomme
mattcary 2016/09/02 15:02:07 Done.
35 // Wrapper over URLRequestMockHTTPJob that exposes extra callbacks.
36 class MockHTTPJob : public net::URLRequestMockHTTPJob {
37 public:
38 MockHTTPJob(net::URLRequest* request,
39 net::NetworkDelegate* delegate,
40 const base::FilePath& file)
41 : net::URLRequestMockHTTPJob(
42 request,
43 delegate,
44 file,
45 BrowserThread::GetBlockingPool()->GetTaskRunnerWithShutdownBehavior(
46 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)) {}
47
48 void set_start_callback(const base::Closure& start_callback) {
49 start_callback_ = start_callback;
50 }
51
52 void Start() override {
53 if (!start_callback_.is_null())
54 start_callback_.Run();
55 net::URLRequestMockHTTPJob::Start();
56 }
57
58 private:
59 ~MockHTTPJob() override {}
60
61 base::Closure start_callback_;
62 };
63
64 // Protocol handler which counts the number of requests that start.
65 class CountingInterceptor : public net::URLRequestInterceptor {
66 public:
67 CountingInterceptor(const base::FilePath& file,
68 const base::WeakPtr<RequestCounter>& counter)
69 : file_(file), counter_(counter), weak_factory_(this) {}
70 ~CountingInterceptor() override {}
71
72 net::URLRequestJob* MaybeInterceptRequest(
73 net::URLRequest* request,
74 net::NetworkDelegate* network_delegate) const override {
75 MockHTTPJob* job = new MockHTTPJob(request, network_delegate, file_);
76 job->set_start_callback(base::Bind(&CountingInterceptor::RequestStarted,
77 weak_factory_.GetWeakPtr()));
78 return job;
79 }
80
81 void RequestStarted() {
82 content::BrowserThread::PostTask(
83 content::BrowserThread::UI, FROM_HERE,
84 base::Bind(&RequestCounter::RequestStarted, counter_));
85 }
86
87 private:
88 base::FilePath file_;
89 base::WeakPtr<RequestCounter> counter_;
90 mutable base::WeakPtrFactory<CountingInterceptor> weak_factory_;
91 };
92
93 // An ExternalProtocolHandler that blocks everything and asserts it never is
94 // called.
95 class NeverRunsExternalProtocolHandlerDelegate
96 : public ExternalProtocolHandler::Delegate {
97 public:
98 scoped_refptr<shell_integration::DefaultProtocolClientWorker>
99 CreateShellWorker(
100 const shell_integration::DefaultWebClientWorkerCallback& callback,
101 const std::string& protocol) override {
102 NOTREACHED();
103 // This will crash, but it shouldn't get this far with BlockState::BLOCK
104 // anyway.
105 return nullptr;
106 }
107
108 ExternalProtocolHandler::BlockState GetBlockState(
109 const std::string& scheme) override {
110 // Block everything and fail the test.
111 ADD_FAILURE();
112 return ExternalProtocolHandler::BLOCK;
113 }
114
115 void BlockRequest() override {}
116
117 void RunExternalProtocolDialog(const GURL& url,
118 int render_process_host_id,
119 int routing_id,
120 ui::PageTransition page_transition,
121 bool has_user_gesture) override {
122 NOTREACHED();
123 }
124
125 void LaunchUrlWithoutSecurityCheck(const GURL& url) override { NOTREACHED(); }
126
127 void FinishedProcessingCheck() override { NOTREACHED(); }
128 };
129
130 } // namespace
131
132 RequestCounter::RequestCounter() : count_(0), expected_count_(-1) {}
133
134 RequestCounter::~RequestCounter() {}
135
136 void RequestCounter::RequestStarted() {
137 count_++;
138 if (loop_ && count_ == expected_count_)
139 loop_->Quit();
140 }
141
142 void RequestCounter::WaitForCount(int expected_count) {
143 ASSERT_TRUE(!loop_);
144 ASSERT_EQ(-1, expected_count_);
145 if (count_ < expected_count) {
146 expected_count_ = expected_count;
147 loop_.reset(new base::RunLoop);
148 loop_->Run();
149 expected_count_ = -1;
150 loop_.reset();
151 }
152
153 EXPECT_EQ(expected_count, count_);
154 }
155
156 FakeSafeBrowsingDatabaseManager::FakeSafeBrowsingDatabaseManager() {}
157
158 bool FakeSafeBrowsingDatabaseManager::CheckBrowseUrl(const GURL& gurl,
159 Client* client) {
160 if (bad_urls_.find(gurl.spec()) == bad_urls_.end() ||
161 bad_urls_[gurl.spec()] == safe_browsing::SB_THREAT_TYPE_SAFE) {
162 return true;
163 }
164
165 content::BrowserThread::PostTask(
166 content::BrowserThread::IO, FROM_HERE,
167 base::Bind(&FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone, this,
168 gurl, client));
169 return false;
170 }
171
172 bool FakeSafeBrowsingDatabaseManager::IsSupported() const {
173 return true;
174 }
175
176 bool FakeSafeBrowsingDatabaseManager::ChecksAreAlwaysAsync() const {
177 return false;
178 }
179
180 bool FakeSafeBrowsingDatabaseManager::CanCheckResourceType(
181 content::ResourceType /* resource_type */) const {
182 return true;
183 }
184
185 bool FakeSafeBrowsingDatabaseManager::CheckExtensionIDs(
186 const std::set<std::string>& extension_ids,
187 Client* client) {
188 return true;
189 }
190
191 FakeSafeBrowsingDatabaseManager::~FakeSafeBrowsingDatabaseManager() {}
192
193 void FakeSafeBrowsingDatabaseManager::OnCheckBrowseURLDone(const GURL& gurl,
194 Client* client) {
195 std::vector<safe_browsing::SBThreatType> expected_threats;
196 expected_threats.push_back(safe_browsing::SB_THREAT_TYPE_URL_MALWARE);
197 expected_threats.push_back(safe_browsing::SB_THREAT_TYPE_URL_PHISHING);
198 // TODO(nparker): Replace SafeBrowsingCheck w/ a call to
199 // client->OnCheckBrowseUrlResult()
200 safe_browsing::LocalSafeBrowsingDatabaseManager::SafeBrowsingCheck sb_check(
201 std::vector<GURL>(1, gurl), std::vector<safe_browsing::SBFullHash>(),
202 client, safe_browsing::MALWARE, expected_threats);
203 sb_check.url_results[0] = bad_urls_[gurl.spec()];
204 sb_check.OnSafeBrowsingResult();
205 }
206
207 TestPrerenderContents::TestPrerenderContents(
208 PrerenderManager* prerender_manager,
209 Profile* profile,
210 const GURL& url,
211 const content::Referrer& referrer,
212 Origin origin,
213 FinalStatus expected_final_status)
214 : PrerenderContents(prerender_manager, profile, url, referrer, origin),
215 expected_final_status_(expected_final_status),
216 new_render_view_host_(nullptr),
217 was_hidden_(false),
218 was_shown_(false),
219 should_be_shown_(expected_final_status == FINAL_STATUS_USED),
220 skip_final_checks_(false) {}
221
222 TestPrerenderContents::~TestPrerenderContents() {
223 if (skip_final_checks_)
224 return;
225
226 EXPECT_EQ(expected_final_status_, final_status())
227 << " when testing URL " << prerender_url().path()
228 << " (Expected: " << NameFromFinalStatus(expected_final_status_)
229 << ", Actual: " << NameFromFinalStatus(final_status()) << ")";
230
231 // Prerendering RenderViewHosts should be hidden before the first
232 // navigation, so this should be happen for every PrerenderContents for
233 // which a RenderViewHost is created, regardless of whether or not it's
234 // used.
235 if (new_render_view_host_)
236 EXPECT_TRUE(was_hidden_);
237
238 // A used PrerenderContents will only be destroyed when we swap out
239 // WebContents, at the end of a navigation caused by a call to
240 // NavigateToURLImpl().
241 if (final_status() == FINAL_STATUS_USED)
242 EXPECT_TRUE(new_render_view_host_);
243
244 EXPECT_EQ(should_be_shown_, was_shown_);
245 }
246
247 void TestPrerenderContents::RenderProcessGone(
248 base::TerminationStatus status) {
249 // On quit, it's possible to end up here when render processes are closed
250 // before the PrerenderManager is destroyed. As a result, it's possible to
251 // get either FINAL_STATUS_APP_TERMINATING or FINAL_STATUS_RENDERER_CRASHED
252 // on quit.
253 //
254 // It's also possible for this to be called after we've been notified of
255 // app termination, but before we've been deleted, which is why the second
256 // check is needed.
257 if (expected_final_status_ == FINAL_STATUS_APP_TERMINATING &&
258 final_status() != expected_final_status_) {
259 expected_final_status_ = FINAL_STATUS_RENDERER_CRASHED;
260 }
261
262 PrerenderContents::RenderProcessGone(status);
263 }
264
265 bool TestPrerenderContents::CheckURL(const GURL& url) {
266 // Prevent FINAL_STATUS_UNSUPPORTED_SCHEME when navigating to about:crash in
267 // the PrerenderRendererCrash test.
268 if (url.spec() != content::kChromeUICrashURL)
269 return PrerenderContents::CheckURL(url);
270 return true;
271 }
272
273 void TestPrerenderContents::OnRenderViewHostCreated(
274 RenderViewHost* new_render_view_host) {
275 // Used to make sure the RenderViewHost is hidden and, if used,
276 // subsequently shown.
277 notification_registrar().Add(
278 this, content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED,
279 content::Source<content::RenderWidgetHost>(
280 new_render_view_host->GetWidget()));
281
282 new_render_view_host_ = new_render_view_host;
283
284 PrerenderContents::OnRenderViewHostCreated(new_render_view_host);
285 }
286
287 void TestPrerenderContents::Observe(
288 int type,
289 const content::NotificationSource& source,
290 const content::NotificationDetails& details) {
291 if (type == content::NOTIFICATION_RENDER_WIDGET_VISIBILITY_CHANGED) {
292 EXPECT_EQ(new_render_view_host_->GetWidget(),
293 content::Source<content::RenderWidgetHost>(source).ptr());
294 bool is_visible = *content::Details<bool>(details).ptr();
295
296 if (!is_visible) {
297 was_hidden_ = true;
298 } else if (is_visible && was_hidden_) {
299 // Once hidden, a prerendered RenderViewHost should only be shown after
300 // being removed from the PrerenderContents for display.
301 EXPECT_FALSE(GetRenderViewHost());
302 was_shown_ = true;
303 }
304 return;
305 }
306 PrerenderContents::Observe(type, source, details);
307 }
308
309 TestPrerender::TestPrerender()
310 : contents_(nullptr), number_of_loads_(0), expected_number_of_loads_(0) {}
311
312 TestPrerender::~TestPrerender() {
313 if (contents_)
314 contents_->RemoveObserver(this);
315 }
316
317 void TestPrerender::WaitForLoads(int expected_number_of_loads) {
318 DCHECK(!load_waiter_);
319 DCHECK(!expected_number_of_loads_);
320 if (number_of_loads_ < expected_number_of_loads) {
321 load_waiter_.reset(new base::RunLoop);
322 expected_number_of_loads_ = expected_number_of_loads;
323 load_waiter_->Run();
324 load_waiter_.reset();
325 expected_number_of_loads_ = 0;
326 }
327 EXPECT_LE(expected_number_of_loads, number_of_loads_);
328 }
329
330 void TestPrerender::OnPrerenderCreated(TestPrerenderContents* contents) {
331 DCHECK(!contents_);
332 contents_ = contents;
333 contents_->AddObserver(this);
334 create_loop_.Quit();
335 }
336
337 void TestPrerender::OnPrerenderStart(PrerenderContents* contents) {
338 start_loop_.Quit();
339 }
340
341 void TestPrerender::OnPrerenderStopLoading(PrerenderContents* contents) {
342 number_of_loads_++;
343 if (load_waiter_ && number_of_loads_ >= expected_number_of_loads_)
344 load_waiter_->Quit();
345 }
346
347 void TestPrerender::OnPrerenderStop(PrerenderContents* contents) {
348 DCHECK(contents_);
349 contents_ = nullptr;
350 stop_loop_.Quit();
351 // If there is a WaitForLoads call and it has yet to see the expected number
352 // of loads, stop the loop so the test fails instead of timing out.
353 if (load_waiter_)
354 load_waiter_->Quit();
355 }
356
357 TestPrerenderContentsFactory::TestPrerenderContentsFactory() {}
358
359 TestPrerenderContentsFactory::~TestPrerenderContentsFactory() {
360 EXPECT_TRUE(expected_contents_queue_.empty());
361 }
362
363 std::unique_ptr<TestPrerender>
364 TestPrerenderContentsFactory::ExpectPrerenderContents(
365 FinalStatus final_status) {
366 std::unique_ptr<TestPrerender> handle(new TestPrerender());
367 expected_contents_queue_.push_back(
368 ExpectedContents(final_status, handle->AsWeakPtr()));
369 return handle;
370 }
371
372 PrerenderContents* TestPrerenderContentsFactory::CreatePrerenderContents(
373 PrerenderManager* prerender_manager,
374 Profile* profile,
375 const GURL& url,
376 const content::Referrer& referrer,
377 Origin origin) {
378 ExpectedContents expected;
379 if (!expected_contents_queue_.empty()) {
380 expected = expected_contents_queue_.front();
381 expected_contents_queue_.pop_front();
382 }
383 TestPrerenderContents* contents = new TestPrerenderContents(
384 prerender_manager, profile, url, referrer, origin, expected.final_status);
385 if (expected.handle)
386 expected.handle->OnPrerenderCreated(contents);
387 return contents;
388 }
389
390 TestPrerenderContentsFactory::ExpectedContents::ExpectedContents()
391 : final_status(FINAL_STATUS_MAX) {}
392
393 TestPrerenderContentsFactory::ExpectedContents::ExpectedContents(
394 const ExpectedContents& other) = default;
395
396 TestPrerenderContentsFactory::ExpectedContents::ExpectedContents(
397 FinalStatus final_status,
398 const base::WeakPtr<TestPrerender>& handle)
399 : final_status(final_status), handle(handle) {}
400
401 TestPrerenderContentsFactory::ExpectedContents::~ExpectedContents() {}
402
403 PrerenderInProcessBrowserTest::PrerenderInProcessBrowserTest()
404 : external_protocol_handler_delegate_(
405 base::MakeUnique<NeverRunsExternalProtocolHandlerDelegate>()),
406 safe_browsing_factory_(
407 base::MakeUnique<safe_browsing::TestSafeBrowsingServiceFactory>()),
408 prerender_contents_factory_(nullptr),
409 explicitly_set_browser_(nullptr),
410 autostart_test_server_(true) {}
411
412 PrerenderInProcessBrowserTest::~PrerenderInProcessBrowserTest() {}
413
414 void PrerenderInProcessBrowserTest::SetUpCommandLine(
415 base::CommandLine* command_line) {
416 command_line->AppendSwitch(switches::kEnablePepperTesting);
417 command_line->AppendSwitchASCII(switches::kOverridePluginPowerSaverForTesting,
418 "ignore-list");
419 ASSERT_TRUE(ppapi::RegisterPowerSaverTestPlugin(command_line));
420 }
421
422
423 void PrerenderInProcessBrowserTest::TearDownInProcessBrowserTestFixture() {
424 safe_browsing::SafeBrowsingService::RegisterFactory(nullptr);
425 }
426
427 content::SessionStorageNamespace*
428 PrerenderInProcessBrowserTest::GetSessionStorageNamespace() const {
429 content::WebContents* web_contents = GetActiveWebContents();
430 if (!web_contents)
431 return nullptr;
432 return web_contents->GetController().GetDefaultSessionStorageNamespace();
433 }
434
435 bool PrerenderInProcessBrowserTest::UrlIsInPrerenderManager(
436 const std::string& html_file) const {
437 return UrlIsInPrerenderManager(embedded_test_server()->GetURL(html_file));
438 }
439
440 bool PrerenderInProcessBrowserTest::UrlIsInPrerenderManager(
441 const GURL& url) const {
442 return GetPrerenderManager()->FindPrerenderData(
443 url, GetSessionStorageNamespace()) != nullptr;
444 }
445
446 content::WebContents* PrerenderInProcessBrowserTest::GetActiveWebContents()
447 const {
448 return current_browser()->tab_strip_model()->GetActiveWebContents();
449 }
450
451 PrerenderManager* PrerenderInProcessBrowserTest::GetPrerenderManager() const {
452 return PrerenderManagerFactory::GetForProfile(current_browser()->profile());
453 }
454
455 TestPrerenderContents* PrerenderInProcessBrowserTest::GetPrerenderContentsFor(
456 const GURL& url) const {
457 PrerenderManager::PrerenderData* prerender_data =
458 GetPrerenderManager()->FindPrerenderData(url, nullptr);
459 return static_cast<TestPrerenderContents*>(
460 prerender_data ? prerender_data->contents() : nullptr);
461 }
462
463 void PrerenderInProcessBrowserTest::SetUpInProcessBrowserTestFixture() {
464 safe_browsing_factory_->SetTestDatabaseManager(
465 new test_utils::FakeSafeBrowsingDatabaseManager());
466 safe_browsing::SafeBrowsingService::RegisterFactory(
467 safe_browsing_factory_.get());
468 }
469
470 void PrerenderInProcessBrowserTest::SetUpOnMainThread() {
471 // Increase the memory allowed in a prerendered page above normal settings.
472 // Debug build bots occasionally run against the default limit, and tests
473 // were failing because the prerender was canceled due to memory exhaustion.
474 // http://crbug.com/93076
475 GetPrerenderManager()->mutable_config().max_bytes = 2000 * 1024 * 1024;
476
477 current_browser()->profile()->GetPrefs()->SetBoolean(
478 prefs::kPromptForDownload, false);
479 if (autostart_test_server_)
480 ASSERT_TRUE(embedded_test_server()->Start());
481 ChromeResourceDispatcherHostDelegate::
482 SetExternalProtocolHandlerDelegateForTesting(
483 external_protocol_handler_delegate_.get());
484
485 PrerenderManager* prerender_manager = GetPrerenderManager();
486 ASSERT_TRUE(prerender_manager);
487 prerender_manager->mutable_config().rate_limit_enabled = false;
488 ASSERT_FALSE(prerender_contents_factory_);
489 prerender_contents_factory_ = new TestPrerenderContentsFactory;
490 prerender_manager->SetPrerenderContentsFactoryForTest(
491 prerender_contents_factory_);
492 ASSERT_TRUE(safe_browsing_factory_->test_safe_browsing_service());
493 }
494
495 void CreateCountingInterceptorOnIO(
496 const GURL& url,
497 const base::FilePath& file,
498 const base::WeakPtr<RequestCounter>& counter) {
499 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
500 std::unique_ptr<net::URLRequestInterceptor> request_interceptor(
501 new CountingInterceptor(file, counter));
502 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
503 url, std::move(request_interceptor));
504 }
505
506 void CreateMockInterceptorOnIO(const GURL& url, const base::FilePath& file) {
507 CHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
508 net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
509 url,
510 net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
511 file, content::BrowserThread::GetBlockingPool()));
512 }
513
514 } // namespace test_utils
515
516 } // namespace prerender
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698