OLD | NEW |
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/browser/loader/mock_resource_loader.h" | 5 #include "content/browser/loader/mock_resource_loader.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 | 8 |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/memory/ref_counted.h" | 10 #include "base/memory/ref_counted.h" |
11 #include "content/browser/loader/resource_controller.h" | 11 #include "content/browser/loader/resource_controller.h" |
12 #include "content/browser/loader/resource_handler.h" | |
13 #include "net/base/io_buffer.h" | 12 #include "net/base/io_buffer.h" |
14 #include "net/url_request/url_request_status.h" | 13 #include "net/url_request/url_request_status.h" |
15 #include "testing/gtest/include/gtest/gtest.h" | 14 #include "testing/gtest/include/gtest/gtest.h" |
16 | 15 |
17 namespace content { | 16 namespace content { |
18 | 17 |
| 18 class MockResourceLoader::TestResourceController : public ResourceController { |
| 19 public: |
| 20 explicit TestResourceController(base::WeakPtr<MockResourceLoader> mock_loader) |
| 21 : mock_loader_(mock_loader) {} |
| 22 ~TestResourceController() override {} |
| 23 |
| 24 void Resume() override { mock_loader_->OnResume(); } |
| 25 |
| 26 void Cancel() override { CancelWithError(net::ERR_ABORTED); } |
| 27 |
| 28 void CancelAndIgnore() override { |
| 29 ADD_FAILURE() << "Unexpected CancelAndIgnore call."; |
| 30 Cancel(); |
| 31 } |
| 32 |
| 33 void CancelWithError(int error_code) override { |
| 34 mock_loader_->OnCancel(error_code); |
| 35 } |
| 36 |
| 37 base::WeakPtr<MockResourceLoader> mock_loader_; |
| 38 }; |
| 39 |
19 MockResourceLoader::MockResourceLoader(ResourceHandler* resource_handler) | 40 MockResourceLoader::MockResourceLoader(ResourceHandler* resource_handler) |
20 : resource_handler_(resource_handler) { | 41 : resource_handler_(resource_handler), weak_factory_(this) { |
21 resource_handler_->SetController(this); | 42 resource_handler_->SetDelegate(this); |
22 } | 43 } |
23 | 44 |
24 MockResourceLoader::~MockResourceLoader() {} | 45 MockResourceLoader::~MockResourceLoader() {} |
25 | 46 |
26 MockResourceLoader::Status MockResourceLoader::OnWillStart(const GURL& url) { | 47 MockResourceLoader::Status MockResourceLoader::OnWillStart(const GURL& url) { |
| 48 EXPECT_FALSE(weak_factory_.HasWeakPtrs()); |
27 EXPECT_EQ(Status::IDLE, status_); | 49 EXPECT_EQ(Status::IDLE, status_); |
| 50 |
28 status_ = Status::CALLING_HANDLER; | 51 status_ = Status::CALLING_HANDLER; |
29 | 52 resource_handler_->OnWillStart(url, base::MakeUnique<TestResourceController>( |
30 bool defer = false; | 53 weak_factory_.GetWeakPtr())); |
31 bool result = resource_handler_->OnWillStart(url, &defer); | 54 if (status_ == Status::CALLING_HANDLER) |
32 // The second case isn't really allowed, but a number of classes do it | |
33 // anyways. | |
34 EXPECT_TRUE(status_ == Status::CALLING_HANDLER || | |
35 (result == false && status_ == Status::CANCELED)); | |
36 if (!result) { | |
37 status_ = Status::CANCELED; | |
38 } else if (defer) { | |
39 status_ = Status::CALLBACK_PENDING; | 55 status_ = Status::CALLBACK_PENDING; |
40 } else { | |
41 status_ = Status::IDLE; | |
42 } | |
43 return status_; | 56 return status_; |
44 } | 57 } |
45 | 58 |
46 MockResourceLoader::Status MockResourceLoader::OnRequestRedirected( | 59 MockResourceLoader::Status MockResourceLoader::OnRequestRedirected( |
47 const net::RedirectInfo& redirect_info, | 60 const net::RedirectInfo& redirect_info, |
48 ResourceResponse* response) { | 61 ResourceResponse* response) { |
| 62 EXPECT_FALSE(weak_factory_.HasWeakPtrs()); |
49 EXPECT_EQ(Status::IDLE, status_); | 63 EXPECT_EQ(Status::IDLE, status_); |
| 64 |
50 status_ = Status::CALLING_HANDLER; | 65 status_ = Status::CALLING_HANDLER; |
51 | 66 resource_handler_->OnRequestRedirected( |
52 bool defer = false; | 67 redirect_info, response, |
53 bool result = | 68 base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr())); |
54 resource_handler_->OnRequestRedirected(redirect_info, response, &defer); | 69 if (status_ == Status::CALLING_HANDLER) |
55 // The second case isn't really allowed, but a number of classes do it | |
56 // anyways. | |
57 EXPECT_TRUE(status_ == Status::CALLING_HANDLER || | |
58 (result == false && status_ == Status::CANCELED)); | |
59 if (!result) { | |
60 status_ = Status::CANCELED; | |
61 } else if (defer) { | |
62 status_ = Status::CALLBACK_PENDING; | 70 status_ = Status::CALLBACK_PENDING; |
63 } else { | |
64 status_ = Status::IDLE; | |
65 } | |
66 return status_; | 71 return status_; |
67 } | 72 } |
68 | 73 |
69 MockResourceLoader::Status MockResourceLoader::OnResponseStarted( | 74 MockResourceLoader::Status MockResourceLoader::OnResponseStarted( |
70 ResourceResponse* response) { | 75 ResourceResponse* response) { |
| 76 EXPECT_FALSE(weak_factory_.HasWeakPtrs()); |
71 EXPECT_EQ(Status::IDLE, status_); | 77 EXPECT_EQ(Status::IDLE, status_); |
| 78 |
72 status_ = Status::CALLING_HANDLER; | 79 status_ = Status::CALLING_HANDLER; |
73 | 80 resource_handler_->OnResponseStarted( |
74 bool defer = false; | 81 response, |
75 bool result = resource_handler_->OnResponseStarted(response, &defer); | 82 base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr())); |
76 // The second case isn't really allowed, but a number of classes do it | 83 if (status_ == Status::CALLING_HANDLER) |
77 // anyways. | |
78 EXPECT_TRUE(status_ == Status::CALLING_HANDLER || | |
79 (result == false && status_ == Status::CANCELED)); | |
80 if (!result) { | |
81 status_ = Status::CANCELED; | |
82 } else if (defer) { | |
83 status_ = Status::CALLBACK_PENDING; | 84 status_ = Status::CALLBACK_PENDING; |
84 } else { | |
85 status_ = Status::IDLE; | |
86 } | |
87 return status_; | 85 return status_; |
88 } | 86 } |
89 | 87 |
90 MockResourceLoader::Status MockResourceLoader::OnWillRead(int min_size) { | 88 MockResourceLoader::Status MockResourceLoader::OnWillRead(int min_size) { |
| 89 EXPECT_FALSE(weak_factory_.HasWeakPtrs()); |
91 EXPECT_EQ(Status::IDLE, status_); | 90 EXPECT_EQ(Status::IDLE, status_); |
| 91 |
92 status_ = Status::CALLING_HANDLER; | 92 status_ = Status::CALLING_HANDLER; |
93 | |
94 scoped_refptr<net::IOBuffer> buf; | 93 scoped_refptr<net::IOBuffer> buf; |
95 int buf_size; | 94 int buf_size; |
96 bool result = resource_handler_->OnWillRead(&buf, &buf_size, min_size); | 95 bool result = resource_handler_->OnWillRead(&buf, &buf_size, min_size); |
97 // The second case isn't really allowed, but a number of classes do it | 96 // The second case isn't really allowed, but a number of classes do it |
98 // anyways. | 97 // anyways. |
99 EXPECT_TRUE(status_ == Status::CALLING_HANDLER || | 98 EXPECT_TRUE(status_ == Status::CALLING_HANDLER || |
100 (result == false && status_ == Status::CANCELED)); | 99 (result == false && status_ == Status::CANCELED)); |
101 if (!result) { | 100 if (!result) { |
102 status_ = Status::CANCELED; | 101 status_ = Status::CANCELED; |
103 } else { | 102 } else { |
104 EXPECT_LE(min_size, buf_size); | 103 EXPECT_LE(min_size, buf_size); |
105 status_ = Status::IDLE; | 104 status_ = Status::IDLE; |
106 } | 105 } |
107 return status_; | 106 return status_; |
108 }; | 107 }; |
109 | 108 |
110 MockResourceLoader::Status MockResourceLoader::OnReadCompleted(int bytes_read) { | 109 MockResourceLoader::Status MockResourceLoader::OnReadCompleted(int bytes_read) { |
| 110 EXPECT_FALSE(weak_factory_.HasWeakPtrs()); |
111 EXPECT_EQ(Status::IDLE, status_); | 111 EXPECT_EQ(Status::IDLE, status_); |
| 112 |
112 status_ = Status::CALLING_HANDLER; | 113 status_ = Status::CALLING_HANDLER; |
113 | 114 resource_handler_->OnReadCompleted( |
114 bool defer = false; | 115 bytes_read, |
115 bool result = resource_handler_->OnReadCompleted(bytes_read, &defer); | 116 base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr())); |
116 // The second case isn't really allowed, but a number of classes do it | 117 if (status_ == Status::CALLING_HANDLER) |
117 // anyways. | |
118 EXPECT_TRUE(status_ == Status::CALLING_HANDLER || | |
119 (result == false && status_ == Status::CANCELED)); | |
120 if (!result) { | |
121 status_ = Status::CANCELED; | |
122 } else if (defer) { | |
123 status_ = Status::CALLBACK_PENDING; | 118 status_ = Status::CALLBACK_PENDING; |
124 } else { | |
125 status_ = Status::IDLE; | |
126 } | |
127 return status_; | 119 return status_; |
128 } | 120 } |
129 | 121 |
130 MockResourceLoader::Status MockResourceLoader::OnResponseCompleted( | 122 MockResourceLoader::Status MockResourceLoader::OnResponseCompleted( |
131 const net::URLRequestStatus& status) { | 123 const net::URLRequestStatus& status) { |
| 124 EXPECT_FALSE(weak_factory_.HasWeakPtrs()); |
132 // This should only happen while the ResourceLoader is idle or the request was | 125 // This should only happen while the ResourceLoader is idle or the request was |
133 // canceled. | 126 // canceled. |
134 EXPECT_TRUE(status_ == Status::IDLE || | 127 EXPECT_TRUE(status_ == Status::IDLE || |
135 (!status.is_success() && status_ == Status::CANCELED && | 128 (!status.is_success() && status_ == Status::CANCELED && |
136 error_code_ == status.error())); | 129 error_code_ == status.error())); |
137 | 130 |
138 status_ = Status::CALLING_HANDLER; | 131 status_ = Status::CALLING_HANDLER; |
139 | 132 resource_handler_->OnResponseCompleted( |
140 bool defer = false; | 133 status, |
141 resource_handler_->OnResponseCompleted(status, &defer); | 134 base::MakeUnique<TestResourceController>(weak_factory_.GetWeakPtr())); |
142 EXPECT_EQ(Status::CALLING_HANDLER, status_); | 135 if (status_ == Status::CALLING_HANDLER) |
143 if (defer) { | |
144 status_ = Status::CALLBACK_PENDING; | 136 status_ = Status::CALLBACK_PENDING; |
145 } else { | 137 EXPECT_NE(Status::CANCELED, status_); |
146 status_ = Status::IDLE; | |
147 } | |
148 return status_; | 138 return status_; |
149 } | 139 } |
150 | 140 |
151 void MockResourceLoader::Cancel() { | 141 void MockResourceLoader::OutOfBandCancel(int error_code, bool tell_renderer) { |
152 CancelWithError(net::ERR_ABORTED); | 142 // Shouldn't be called in-band. |
| 143 EXPECT_NE(Status::CALLING_HANDLER, status_); |
| 144 |
| 145 status_ = Status::CANCELED; |
| 146 canceled_out_of_band_ = true; |
| 147 |
| 148 // To mimic real behavior, keep old error, in the case of double-cancel. |
| 149 if (error_code_ == net::OK) |
| 150 error_code_ = error_code; |
153 } | 151 } |
154 | 152 |
155 void MockResourceLoader::CancelAndIgnore() { | 153 void MockResourceLoader::OnCancel(int error_code) { |
156 NOTREACHED(); | 154 // It's currently allowed to be canceled in-band after being cancelled |
157 } | 155 // out-of-band, so do nothing, unless the status is no longer CANCELED, which |
158 | 156 // which case, OnResponseCompleted has already been called, and cancels aren't |
159 void MockResourceLoader::CancelWithError(int error_code) { | 157 // expected then. |
160 EXPECT_LT(error_code, 0); | 158 // TODO(mmenke): Make CancelOutOfBand synchronously destroy the |
161 // Ignore double cancels. Classes shouldn't be doing this, as | 159 // ResourceLoader. |
162 // ResourceLoader doesn't really support it, but they do anywways. :( | 160 if (canceled_out_of_band_ && status_ == Status::CANCELED) |
163 // TODO(mmenke): Remove this check. | |
164 if (error_code_ != net::OK) | |
165 return; | 161 return; |
166 | 162 |
167 // ResourceLoader really expects canceled not to be called synchronously, but | 163 EXPECT_LT(error_code, 0); |
168 // a lot of code does it, so allow it. | |
169 // TODO(mmenke): Remove CALLING_HANDLER. | |
170 EXPECT_TRUE(status_ == Status::CALLBACK_PENDING || | 164 EXPECT_TRUE(status_ == Status::CALLBACK_PENDING || |
171 status_ == Status::CALLING_HANDLER || status_ == Status::IDLE); | 165 status_ == Status::CALLING_HANDLER); |
| 166 |
172 status_ = Status::CANCELED; | 167 status_ = Status::CANCELED; |
173 error_code_ = error_code; | 168 error_code_ = error_code; |
174 } | 169 } |
175 | 170 |
176 void MockResourceLoader::Resume() { | 171 void MockResourceLoader::OnResume() { |
177 EXPECT_EQ(Status::CALLBACK_PENDING, status_); | 172 EXPECT_TRUE(status_ == Status::CALLBACK_PENDING || |
| 173 status_ == Status::CALLING_HANDLER); |
| 174 |
178 status_ = Status::IDLE; | 175 status_ = Status::IDLE; |
179 } | 176 } |
180 | 177 |
181 } // namespace content | 178 } // namespace content |
OLD | NEW |