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

Unified Diff: content/child/resource_dispatcher_unittest.cc

Issue 2425173003: Deal with canceled requests when flushing deferred messages. (Closed)
Patch Set: Made the is_deferred case a separate if again. Created 4 years, 2 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
« no previous file with comments | « content/child/resource_dispatcher.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: content/child/resource_dispatcher_unittest.cc
diff --git a/content/child/resource_dispatcher_unittest.cc b/content/child/resource_dispatcher_unittest.cc
index a2e457edfc159b77211a719662e9c2e40176a779..c7bedc43c84ff08d59cf7a36d70aedbc757b2813 100644
--- a/content/child/resource_dispatcher_unittest.cc
+++ b/content/child/resource_dispatcher_unittest.cc
@@ -93,6 +93,11 @@ class TestRequestPeer : public RequestPeer {
EXPECT_FALSE(context_->complete);
context_->data.append(data->payload(), data->length());
context_->total_encoded_data_length += data->encoded_data_length();
+
+ if (context_->cancel_on_receive_data) {
+ dispatcher_->Cancel(context_->request_id);
+ context_->cancelled = true;
+ }
}
void OnCompletedRequest(int error_code,
@@ -117,6 +122,7 @@ class TestRequestPeer : public RequestPeer {
int seen_redirects = 0;
bool cancel_on_receive_response = false;
+ bool cancel_on_receive_data = false;
bool received_response = false;
// Data received. If downloading to file, remains empty.
@@ -810,6 +816,113 @@ TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
EXPECT_EQ(0, peer_context.seen_redirects);
}
+// Checks cancelling a request while flushing deferred requests from
+// the FlushDeferredMessages() task.
+TEST_F(ResourceDispatcherTest, CancelWhileFlushingDeferredRequests) {
+ std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
+ TestRequestPeer::Context peer_context;
+ int request_id = StartAsync(std::move(request), NULL, &peer_context);
+
+ // Cancel the request when the data message is handled.
+ peer_context.cancel_on_receive_data = true;
+
+ int id = ConsumeRequestResource();
+ EXPECT_EQ(0u, queued_messages());
+
+ dispatcher()->SetDefersLoading(request_id, true);
+ NotifyReceivedResponse(id);
+ NotifySetDataBuffer(id, strlen(kTestPageContents));
+ NotifyDataReceived(id, kTestPageContents);
+
+ // None of the messages should have been processed yet.
+ EXPECT_EQ("", peer_context.data);
+ EXPECT_FALSE(peer_context.complete);
+ EXPECT_EQ(0u, queued_messages());
+
+ dispatcher()->SetDefersLoading(request_id, false);
+
+ // Make sure that the FlushDeferredMessages() task posted from
+ // SetDefersLoading() is run. It should dispatch all the deferred
+ // messages.
+ base::RunLoop().RunUntilIdle();
+
+ // When the deferred DataReceived is dispatched, the handler will
+ // cancel the request, but the ACK is sent after the handler
+ // returns, so the cancel request ends up before the ACK in the
+ // message queue.
+ ConsumeCancelRequest(id);
+ ConsumeDataReceived_ACK(id);
+
+ // The data was consumed before the handler canceled
+ // the request, so the data should have been received.
+ EXPECT_EQ(kTestPageContents, peer_context.data);
+ EXPECT_FALSE(peer_context.complete);
+ EXPECT_EQ(0u, queued_messages());
+}
+
+// Checks cancelling a request while flushing deferred requests from
+// OnMessageReceived().
+TEST_F(ResourceDispatcherTest,
+ CancelWhileFlushingDeferredRequestsFromOnMessageReceived) {
+ std::unique_ptr<ResourceRequest> request(CreateResourceRequest(false));
+ TestRequestPeer::Context peer_context;
+ int request_id = StartAsync(std::move(request), NULL, &peer_context);
+
+ // Cancel the request when the data message is handled.
+ peer_context.cancel_on_receive_data = true;
+
+ int id = ConsumeRequestResource();
+ EXPECT_EQ(0u, queued_messages());
+
+ dispatcher()->SetDefersLoading(request_id, true);
+ NotifyReceivedResponse(id);
+ NotifySetDataBuffer(id, strlen(kTestPageContents));
+ NotifyDataReceived(id, kTestPageContents);
+
+ // None of the messages should have been processed yet.
+ EXPECT_EQ("", peer_context.data);
+ EXPECT_FALSE(peer_context.complete);
+ EXPECT_EQ(0u, queued_messages());
+
+ dispatcher()->SetDefersLoading(request_id, false);
+
+ // SetDefersLoading() posts a task to run FlushDeferredMessages() to dispatch
+ // the deferred messages. Since the message loop hasn't been run yet the
+ // task hasn't been run either and no IPC-messages should have been
+ // dispatched.
+ EXPECT_EQ("", peer_context.data);
+ EXPECT_FALSE(peer_context.complete);
+ EXPECT_EQ(0u, queued_messages());
+
+ // Calling NotifyRequestComplete() here, before the task from
+ // SetDefersLoading() has been run, triggers the flush in
+ // OnMessageReceived().
+ NotifyRequestComplete(id, strlen(kTestPageContents));
+
+ // When the deferred DataReceived is dispatched, the handler will
+ // cancel the request, but the ACK is sent after the handler
+ // returns, so the cancel request ends up before the ACK in the
+ // message queue.
+ ConsumeCancelRequest(id);
+ ConsumeDataReceived_ACK(id);
+
+ // The data was consumed before the handler canceled
+ // the request, so the data should have been received.
+ EXPECT_EQ(kTestPageContents, peer_context.data);
+ EXPECT_FALSE(peer_context.complete);
+ EXPECT_EQ(0u, queued_messages());
+
+ // Make sure that the FlushDeferredMessages() task posted from
+ // SetDefersLoading() is run. The messages should already have been
+ // flushed above, so it should be a NOOP.
+ base::RunLoop().RunUntilIdle();
+
+ // Check that the task didn't change anything.
+ EXPECT_EQ(kTestPageContents, peer_context.data);
+ EXPECT_FALSE(peer_context.complete);
+ EXPECT_EQ(0u, queued_messages());
+}
+
TEST_F(ResourceDispatcherTest, DownloadToFile) {
std::unique_ptr<ResourceRequest> request(CreateResourceRequest(true));
TestRequestPeer::Context peer_context;
« no previous file with comments | « content/child/resource_dispatcher.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698