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

Side by Side Diff: content/public/test/navigation_simulator.cc

Issue 2698393002: Allow asynchronous deferral in NavigationSimulator (Closed)
Patch Set: engedy/clamy review Created 3 years, 9 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
« no previous file with comments | « content/public/test/navigation_simulator.h ('k') | content/test/BUILD.gn » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/public/test/navigation_simulator.h" 5 #include "content/public/test/navigation_simulator.h"
6 6
7 #include "base/bind.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/run_loop.h"
7 #include "content/browser/frame_host/navigation_handle_impl.h" 10 #include "content/browser/frame_host/navigation_handle_impl.h"
8 #include "content/browser/frame_host/navigation_request.h" 11 #include "content/browser/frame_host/navigation_request.h"
9 #include "content/common/frame_messages.h" 12 #include "content/common/frame_messages.h"
10 #include "content/public/browser/navigation_throttle.h" 13 #include "content/public/browser/navigation_throttle.h"
11 #include "content/public/browser/web_contents.h" 14 #include "content/public/browser/web_contents.h"
12 #include "content/public/common/browser_side_navigation_policy.h" 15 #include "content/public/common/browser_side_navigation_policy.h"
13 #include "content/test/test_navigation_url_loader.h" 16 #include "content/test/test_navigation_url_loader.h"
14 #include "content/test/test_render_frame_host.h" 17 #include "content/test/test_render_frame_host.h"
15 #include "net/base/load_flags.h" 18 #include "net/base/load_flags.h"
16 #include "net/url_request/redirect_info.h" 19 #include "net/url_request/redirect_info.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 common_params.referrer = referrer_; 119 common_params.referrer = referrer_;
117 common_params.transition = transition_; 120 common_params.transition = transition_;
118 common_params.navigation_type = 121 common_params.navigation_type =
119 PageTransitionCoreTypeIs(transition_, ui::PAGE_TRANSITION_RELOAD) 122 PageTransitionCoreTypeIs(transition_, ui::PAGE_TRANSITION_RELOAD)
120 ? FrameMsg_Navigate_Type::RELOAD 123 ? FrameMsg_Navigate_Type::RELOAD
121 : FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT; 124 : FrameMsg_Navigate_Type::DIFFERENT_DOCUMENT;
122 render_frame_host_->OnMessageReceived(FrameHostMsg_BeginNavigation( 125 render_frame_host_->OnMessageReceived(FrameHostMsg_BeginNavigation(
123 render_frame_host_->GetRoutingID(), common_params, begin_params)); 126 render_frame_host_->GetRoutingID(), common_params, begin_params));
124 NavigationRequest* request = 127 NavigationRequest* request =
125 render_frame_host_->frame_tree_node()->navigation_request(); 128 render_frame_host_->frame_tree_node()->navigation_request();
126 DCHECK(request); 129
130 // The request failed synchronously.
131 if (!request)
132 return;
127 DCHECK_EQ(handle_, request->navigation_handle()); 133 DCHECK_EQ(handle_, request->navigation_handle());
128 } else { 134 } else {
129 render_frame_host_->OnMessageReceived( 135 render_frame_host_->OnMessageReceived(
130 FrameHostMsg_DidStartLoading(render_frame_host_->GetRoutingID(), true)); 136 FrameHostMsg_DidStartLoading(render_frame_host_->GetRoutingID(), true));
131 render_frame_host_->OnMessageReceived(FrameHostMsg_DidStartProvisionalLoad( 137 render_frame_host_->OnMessageReceived(FrameHostMsg_DidStartProvisionalLoad(
132 render_frame_host_->GetRoutingID(), navigation_url_, 138 render_frame_host_->GetRoutingID(), navigation_url_,
133 std::vector<GURL>(), base::TimeTicks::Now())); 139 std::vector<GURL>(), base::TimeTicks::Now()));
134 DCHECK_EQ(handle_, render_frame_host_->navigation_handle()); 140 DCHECK_EQ(handle_, render_frame_host_->navigation_handle());
135 handle_->WillStartRequest( 141 handle_->WillStartRequest(
136 "GET", scoped_refptr<content::ResourceRequestBodyImpl>(), referrer_, 142 "GET", scoped_refptr<content::ResourceRequestBodyImpl>(), referrer_,
137 true /* user_gesture */, transition_, false /* is_external_protocol */, 143 true /* user_gesture */, transition_, false /* is_external_protocol */,
138 REQUEST_CONTEXT_TYPE_LOCATION, 144 REQUEST_CONTEXT_TYPE_LOCATION,
139 blink::WebMixedContentContextType::NotMixedContent, 145 blink::WebMixedContentContextType::NotMixedContent,
140 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>()); 146 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>());
141 } 147 }
142 148
143 CHECK(handle_); 149 CHECK(handle_);
144 150 WaitForThrottleChecksComplete();
145 // Make sure all NavigationThrottles have run.
146 // TODO(clamy): provide a non auto-advance mode if needed.
147 while (handle_->state_for_testing() == NavigationHandleImpl::DEFERRING_START)
148 handle_->Resume();
149 151
150 CHECK_EQ(1, num_did_start_navigation_called_); 152 CHECK_EQ(1, num_did_start_navigation_called_);
151 CHECK_EQ(1, num_will_start_request_called_); 153 if (GetLastThrottleCheckResult() == NavigationThrottle::PROCEED) {
154 CHECK_EQ(1, num_will_start_request_called_);
155 } else {
156 // TODO(clamy): Add error handling code based on the
157 // NavigationThrottleCheckResult here and in other methods.
158 state_ = FAILED;
159 }
152 } 160 }
153 161
154 void NavigationSimulator::Redirect(const GURL& new_url) { 162 void NavigationSimulator::Redirect(const GURL& new_url) {
155 CHECK(state_ <= STARTED) << "NavigationSimulator::Redirect should be " 163 CHECK(state_ <= STARTED) << "NavigationSimulator::Redirect should be "
156 "called before Fail or Commit"; 164 "called before Fail or Commit";
157 CHECK_EQ(0, num_did_finish_navigation_called_) 165 CHECK_EQ(0, num_did_finish_navigation_called_)
158 << "NavigationSimulator::Redirect cannot be called after the " 166 << "NavigationSimulator::Redirect cannot be called after the "
159 "navigation has finished"; 167 "navigation has finished";
160 168
161 if (state_ == INITIALIZATION) 169 if (state_ == INITIALIZATION)
162 Start(); 170 Start();
163 171
164 navigation_url_ = new_url; 172 navigation_url_ = new_url;
165 173
166 int previous_num_will_redirect_request_called = 174 int previous_num_will_redirect_request_called =
167 num_will_redirect_request_called_; 175 num_will_redirect_request_called_;
168 int previous_did_redirect_navigation_called = 176 int previous_did_redirect_navigation_called =
169 num_did_redirect_navigation_called_; 177 num_did_redirect_navigation_called_;
170 178
179 PrepareCompleteCallbackOnHandle();
171 if (IsBrowserSideNavigationEnabled()) { 180 if (IsBrowserSideNavigationEnabled()) {
172 NavigationRequest* request = 181 NavigationRequest* request =
173 render_frame_host_->frame_tree_node()->navigation_request(); 182 render_frame_host_->frame_tree_node()->navigation_request();
174 TestNavigationURLLoader* url_loader = 183 TestNavigationURLLoader* url_loader =
175 static_cast<TestNavigationURLLoader*>(request->loader_for_testing()); 184 static_cast<TestNavigationURLLoader*>(request->loader_for_testing());
176 CHECK(url_loader); 185 CHECK(url_loader);
177 186
178 net::RedirectInfo redirect_info; 187 net::RedirectInfo redirect_info;
179 redirect_info.status_code = 302; 188 redirect_info.status_code = 302;
180 redirect_info.new_method = "GET"; 189 redirect_info.new_method = "GET";
181 redirect_info.new_url = new_url; 190 redirect_info.new_url = new_url;
182 redirect_info.new_first_party_for_cookies = new_url; 191 redirect_info.new_first_party_for_cookies = new_url;
183 redirect_info.new_referrer = referrer_.url.spec(); 192 redirect_info.new_referrer = referrer_.url.spec();
184 redirect_info.new_referrer_policy = 193 redirect_info.new_referrer_policy =
185 Referrer::ReferrerPolicyForUrlRequest(referrer_); 194 Referrer::ReferrerPolicyForUrlRequest(referrer_);
186 195
187 url_loader->CallOnRequestRedirected( 196 url_loader->CallOnRequestRedirected(
188 redirect_info, scoped_refptr<ResourceResponse>(new ResourceResponse)); 197 redirect_info, scoped_refptr<ResourceResponse>(new ResourceResponse));
189 } else { 198 } else {
190 handle_->WillRedirectRequest( 199 handle_->WillRedirectRequest(
191 new_url, "GET", referrer_.url, false /* is_external_protocol */, 200 new_url, "GET", referrer_.url, false /* is_external_protocol */,
192 scoped_refptr<net::HttpResponseHeaders>(), 201 scoped_refptr<net::HttpResponseHeaders>(),
193 net::HttpResponseInfo::ConnectionInfo(), 202 net::HttpResponseInfo::ConnectionInfo(),
194 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>()); 203 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>());
195 } 204 }
196 205
197 // Make sure all NavigationThrottles have run. 206 WaitForThrottleChecksComplete();
198 // TODO(clamy): provide a non auto-advance mode if needed. 207
199 while (handle_->state_for_testing() == 208 if (GetLastThrottleCheckResult() == NavigationThrottle::PROCEED) {
200 NavigationHandleImpl::DEFERRING_REDIRECT) { 209 CHECK_EQ(previous_num_will_redirect_request_called + 1,
201 handle_->Resume(); 210 num_will_redirect_request_called_);
211 CHECK_EQ(previous_did_redirect_navigation_called + 1,
212 num_did_redirect_navigation_called_);
213 } else {
214 state_ = FAILED;
202 } 215 }
203
204 CHECK_EQ(previous_num_will_redirect_request_called + 1,
205 num_will_redirect_request_called_);
206 CHECK_EQ(previous_did_redirect_navigation_called + 1,
207 num_did_redirect_navigation_called_);
208 } 216 }
209 217
210 void NavigationSimulator::Commit() { 218 void NavigationSimulator::Commit() {
211 CHECK_LE(state_, STARTED) << "NavigationSimulator::Commit can only be " 219 CHECK_LE(state_, STARTED) << "NavigationSimulator::Commit can only be "
212 "called once, and cannot be called after " 220 "called once, and cannot be called after "
213 "NavigationSimulator::Fail"; 221 "NavigationSimulator::Fail";
214 CHECK_EQ(0, num_did_finish_navigation_called_) 222 CHECK_EQ(0, num_did_finish_navigation_called_)
215 << "NavigationSimulator::Commit cannot be called after the " 223 << "NavigationSimulator::Commit cannot be called after the "
216 "navigation has finished"; 224 "navigation has finished";
217 225
218 if (state_ == INITIALIZATION) 226 if (state_ == INITIALIZATION)
219 Start(); 227 Start();
220 228
229 PrepareCompleteCallbackOnHandle();
221 if (IsBrowserSideNavigationEnabled() && 230 if (IsBrowserSideNavigationEnabled() &&
222 render_frame_host_->frame_tree_node()->navigation_request()) { 231 render_frame_host_->frame_tree_node()->navigation_request()) {
223 render_frame_host_->PrepareForCommit(); 232 render_frame_host_->PrepareForCommit();
224 } 233 }
225 234
226 // Call NavigationHandle::WillProcessResponse if needed. 235 // Call NavigationHandle::WillProcessResponse if needed.
227 if (handle_->state_for_testing() < 236 // Note that the handle's state can be CANCELING if a throttle cancelled it
228 NavigationHandleImpl::WILL_PROCESS_RESPONSE) { 237 // synchronously in PrepareForCommit.
238 if (handle_->state_for_testing() < NavigationHandleImpl::CANCELING) {
229 handle_->WillProcessResponse( 239 handle_->WillProcessResponse(
230 render_frame_host_, scoped_refptr<net::HttpResponseHeaders>(), 240 render_frame_host_, scoped_refptr<net::HttpResponseHeaders>(),
231 net::HttpResponseInfo::ConnectionInfo(), SSLStatus(), GlobalRequestID(), 241 net::HttpResponseInfo::ConnectionInfo(), SSLStatus(), GlobalRequestID(),
232 false /* should_replace_current_entry */, false /* is_download */, 242 false /* should_replace_current_entry */, false /* is_download */,
233 false /* is_stream */, base::Closure(), 243 false /* is_stream */, base::Closure(),
234 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>()); 244 base::Callback<void(NavigationThrottle::ThrottleCheckResult)>());
235 } 245 }
236 246
237 // Make sure all NavigationThrottles have run. 247 WaitForThrottleChecksComplete();
238 // TODO(clamy): provide a non auto-advance mode if needed. 248
239 while (handle_->state_for_testing() == 249 if (GetLastThrottleCheckResult() != NavigationThrottle::PROCEED) {
240 NavigationHandleImpl::DEFERRING_RESPONSE) { 250 state_ = FAILED;
241 handle_->Resume(); 251 return;
242 } 252 }
243 253
244 CHECK_EQ(1, num_will_process_response_called_); 254 CHECK_EQ(1, num_will_process_response_called_);
245 CHECK_EQ(1, num_ready_to_commit_called_); 255 CHECK_EQ(1, num_ready_to_commit_called_);
246 256
247 // Update the RenderFrameHost now that we know which RenderFrameHost will 257 // Update the RenderFrameHost now that we know which RenderFrameHost will
248 // commit the navigation. 258 // commit the navigation.
249 TestRenderFrameHost* new_render_frame_host = 259 TestRenderFrameHost* new_render_frame_host =
250 static_cast<TestRenderFrameHost*>(handle_->GetRenderFrameHost()); 260 static_cast<TestRenderFrameHost*>(handle_->GetRenderFrameHost());
251 if (!IsBrowserSideNavigationEnabled() && 261 if (!IsBrowserSideNavigationEnabled() &&
(...skipping 187 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 << "The transition cannot be set after the navigation has started"; 449 << "The transition cannot be set after the navigation has started";
440 transition_ = transition; 450 transition_ = transition;
441 } 451 }
442 452
443 void NavigationSimulator::SetReferrer(const Referrer& referrer) { 453 void NavigationSimulator::SetReferrer(const Referrer& referrer) {
444 CHECK_LE(state_, STARTED) << "The referrer cannot be set after the " 454 CHECK_LE(state_, STARTED) << "The referrer cannot be set after the "
445 "navigation has committed or has failed"; 455 "navigation has committed or has failed";
446 referrer_ = referrer; 456 referrer_ = referrer;
447 } 457 }
448 458
459 NavigationThrottle::ThrottleCheckResult
460 NavigationSimulator::GetLastThrottleCheckResult() {
461 return last_throttle_check_result_.value();
462 }
463
449 void NavigationSimulator::DidStartNavigation( 464 void NavigationSimulator::DidStartNavigation(
450 NavigationHandle* navigation_handle) { 465 NavigationHandle* navigation_handle) {
451 // Check if this navigation is the one we're simulating. 466 // Check if this navigation is the one we're simulating.
452 if (handle_) 467 if (handle_)
453 return; 468 return;
454 469
455 if (navigation_handle->GetURL() != navigation_url_) 470 if (navigation_handle->GetURL() != navigation_url_)
456 return; 471 return;
457 472
458 NavigationHandleImpl* handle = 473 NavigationHandleImpl* handle =
459 static_cast<NavigationHandleImpl*>(navigation_handle); 474 static_cast<NavigationHandleImpl*>(navigation_handle);
460 475
461 if (handle->frame_tree_node() != render_frame_host_->frame_tree_node()) 476 if (handle->frame_tree_node() != render_frame_host_->frame_tree_node())
462 return; 477 return;
463 478
464 handle_ = handle; 479 handle_ = handle;
465 480
466 num_did_start_navigation_called_++; 481 num_did_start_navigation_called_++;
467 482
468 // Add a throttle to count NavigationThrottle calls count. 483 // Add a throttle to count NavigationThrottle calls count.
469 handle->RegisterThrottleForTesting( 484 handle->RegisterThrottleForTesting(
470 base::MakeUnique<NavigationThrottleCallbackRunner>( 485 base::MakeUnique<NavigationThrottleCallbackRunner>(
471 handle, 486 handle,
472 base::Bind(&NavigationSimulator::OnWillStartRequest, 487 base::Bind(&NavigationSimulator::OnWillStartRequest,
473 weak_factory_.GetWeakPtr()), 488 weak_factory_.GetWeakPtr()),
474 base::Bind(&NavigationSimulator::OnWillRedirectRequest, 489 base::Bind(&NavigationSimulator::OnWillRedirectRequest,
475 weak_factory_.GetWeakPtr()), 490 weak_factory_.GetWeakPtr()),
476 base::Bind(&NavigationSimulator::OnWillProcessResponse, 491 base::Bind(&NavigationSimulator::OnWillProcessResponse,
477 weak_factory_.GetWeakPtr()))); 492 weak_factory_.GetWeakPtr())));
493
494 PrepareCompleteCallbackOnHandle();
478 } 495 }
479 496
480 void NavigationSimulator::DidRedirectNavigation( 497 void NavigationSimulator::DidRedirectNavigation(
481 NavigationHandle* navigation_handle) { 498 NavigationHandle* navigation_handle) {
482 if (navigation_handle == handle_) 499 if (navigation_handle == handle_)
483 num_did_redirect_navigation_called_++; 500 num_did_redirect_navigation_called_++;
484 } 501 }
485 502
486 void NavigationSimulator::ReadyToCommitNavigation( 503 void NavigationSimulator::ReadyToCommitNavigation(
487 NavigationHandle* navigation_handle) { 504 NavigationHandle* navigation_handle) {
(...skipping 12 matching lines...) Expand all
500 } 517 }
501 518
502 void NavigationSimulator::OnWillRedirectRequest() { 519 void NavigationSimulator::OnWillRedirectRequest() {
503 num_will_redirect_request_called_++; 520 num_will_redirect_request_called_++;
504 } 521 }
505 522
506 void NavigationSimulator::OnWillProcessResponse() { 523 void NavigationSimulator::OnWillProcessResponse() {
507 num_will_process_response_called_++; 524 num_will_process_response_called_++;
508 } 525 }
509 526
527 void NavigationSimulator::WaitForThrottleChecksComplete() {
528 // If last_throttle_check_result_ is set, then throttle checks completed
529 // synchronously.
530 if (last_throttle_check_result_)
531 return;
532
533 base::RunLoop run_loop;
534 throttle_checks_wait_closure_ = run_loop.QuitClosure();
535 run_loop.Run();
536 throttle_checks_wait_closure_.Reset();
537 }
538
539 void NavigationSimulator::OnThrottleChecksComplete(
540 NavigationThrottle::ThrottleCheckResult result) {
541 DCHECK(!last_throttle_check_result_);
542 last_throttle_check_result_ = result;
543 if (throttle_checks_wait_closure_)
544 throttle_checks_wait_closure_.Run();
545 }
546
547 void NavigationSimulator::PrepareCompleteCallbackOnHandle() {
548 last_throttle_check_result_.reset();
549 handle_->set_complete_callback_for_testing(
550 base::Bind(&NavigationSimulator::OnThrottleChecksComplete,
551 weak_factory_.GetWeakPtr()));
552 }
553
510 } // namespace content 554 } // namespace content
OLDNEW
« no previous file with comments | « content/public/test/navigation_simulator.h ('k') | content/test/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698