OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "net/http/http_transaction_unittest.h" | 5 #include "net/http/http_transaction_unittest.h" |
6 | 6 |
7 #include "base/hash_tables.h" | 7 #include <algorithm> |
| 8 |
8 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
9 #include "base/string_util.h" | 10 #include "base/string_util.h" |
10 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
11 #include "net/base/load_flags.h" | 12 #include "net/base/load_flags.h" |
12 #include "net/disk_cache/disk_cache.h" | 13 #include "net/disk_cache/disk_cache.h" |
13 #include "net/http/http_cache.h" | 14 #include "net/http/http_cache.h" |
14 #include "net/http/http_request_info.h" | 15 #include "net/http/http_request_info.h" |
15 #include "net/http/http_response_info.h" | 16 #include "net/http/http_response_info.h" |
16 #include "net/http/http_transaction.h" | 17 #include "net/http/http_transaction.h" |
17 #include "testing/gtest/include/gtest/gtest.h" | 18 #include "testing/gtest/include/gtest/gtest.h" |
18 | 19 |
| 20 namespace { |
| 21 typedef base::hash_map<std::string, const MockTransaction*> MockTransactionMap; |
| 22 static MockTransactionMap mock_transactions; |
| 23 } // namespace |
| 24 |
19 //----------------------------------------------------------------------------- | 25 //----------------------------------------------------------------------------- |
20 // mock transaction data | 26 // mock transaction data |
21 | 27 |
22 const MockTransaction kSimpleGET_Transaction = { | 28 const MockTransaction kSimpleGET_Transaction = { |
23 "http://www.google.com/", | 29 "http://www.google.com/", |
24 "GET", | 30 "GET", |
25 base::Time(), | 31 base::Time(), |
26 "", | 32 "", |
27 net::LOAD_NORMAL, | 33 net::LOAD_NORMAL, |
28 "HTTP/1.1 200 OK", | 34 "HTTP/1.1 200 OK", |
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
97 }; | 103 }; |
98 | 104 |
99 static const MockTransaction* const kBuiltinMockTransactions[] = { | 105 static const MockTransaction* const kBuiltinMockTransactions[] = { |
100 &kSimpleGET_Transaction, | 106 &kSimpleGET_Transaction, |
101 &kSimplePOST_Transaction, | 107 &kSimplePOST_Transaction, |
102 &kTypicalGET_Transaction, | 108 &kTypicalGET_Transaction, |
103 &kETagGET_Transaction, | 109 &kETagGET_Transaction, |
104 &kRangeGET_Transaction | 110 &kRangeGET_Transaction |
105 }; | 111 }; |
106 | 112 |
107 typedef base::hash_map<std::string, const MockTransaction*> | |
108 MockTransactionMap; | |
109 static MockTransactionMap mock_transactions; | |
110 | |
111 void AddMockTransaction(const MockTransaction* trans) { | |
112 mock_transactions[GURL(trans->url).spec()] = trans; | |
113 } | |
114 | |
115 void RemoveMockTransaction(const MockTransaction* trans) { | |
116 mock_transactions.erase(GURL(trans->url).spec()); | |
117 } | |
118 | |
119 const MockTransaction* FindMockTransaction(const GURL& url) { | 113 const MockTransaction* FindMockTransaction(const GURL& url) { |
120 // look for overrides: | 114 // look for overrides: |
121 MockTransactionMap::const_iterator it = mock_transactions.find(url.spec()); | 115 MockTransactionMap::const_iterator it = mock_transactions.find(url.spec()); |
122 if (it != mock_transactions.end()) | 116 if (it != mock_transactions.end()) |
123 return it->second; | 117 return it->second; |
124 | 118 |
125 // look for builtins: | 119 // look for builtins: |
126 for (size_t i = 0; i < arraysize(kBuiltinMockTransactions); ++i) { | 120 for (size_t i = 0; i < arraysize(kBuiltinMockTransactions); ++i) { |
127 if (url == GURL(kBuiltinMockTransactions[i]->url)) | 121 if (url == GURL(kBuiltinMockTransactions[i]->url)) |
128 return kBuiltinMockTransactions[i]; | 122 return kBuiltinMockTransactions[i]; |
129 } | 123 } |
130 return NULL; | 124 return NULL; |
131 } | 125 } |
132 | 126 |
| 127 void AddMockTransaction(const MockTransaction* trans) { |
| 128 mock_transactions[GURL(trans->url).spec()] = trans; |
| 129 } |
| 130 |
| 131 void RemoveMockTransaction(const MockTransaction* trans) { |
| 132 mock_transactions.erase(GURL(trans->url).spec()); |
| 133 } |
| 134 |
| 135 MockHttpRequest::MockHttpRequest(const MockTransaction& t) { |
| 136 url = GURL(t.url); |
| 137 method = t.method; |
| 138 extra_headers.AddHeadersFromString(t.request_headers); |
| 139 load_flags = t.load_flags; |
| 140 } |
133 | 141 |
134 //----------------------------------------------------------------------------- | 142 //----------------------------------------------------------------------------- |
135 | 143 |
136 // static | 144 // static |
137 int TestTransactionConsumer::quit_counter_ = 0; | 145 int TestTransactionConsumer::quit_counter_ = 0; |
138 | 146 |
| 147 TestTransactionConsumer::TestTransactionConsumer( |
| 148 net::HttpTransactionFactory* factory) |
| 149 : state_(IDLE), |
| 150 trans_(NULL), |
| 151 error_(net::OK) { |
| 152 // Disregard the error code. |
| 153 factory->CreateTransaction(&trans_); |
| 154 ++quit_counter_; |
| 155 } |
| 156 |
| 157 TestTransactionConsumer::~TestTransactionConsumer() { |
| 158 } |
| 159 |
| 160 void TestTransactionConsumer::Start(const net::HttpRequestInfo* request, |
| 161 const net::BoundNetLog& net_log) { |
| 162 state_ = STARTING; |
| 163 int result = trans_->Start(request, this, net_log); |
| 164 if (result != net::ERR_IO_PENDING) |
| 165 DidStart(result); |
| 166 } |
| 167 |
| 168 void TestTransactionConsumer::DidStart(int result) { |
| 169 if (result != net::OK) { |
| 170 DidFinish(result); |
| 171 } else { |
| 172 Read(); |
| 173 } |
| 174 } |
| 175 |
| 176 void TestTransactionConsumer::DidRead(int result) { |
| 177 if (result <= 0) { |
| 178 DidFinish(result); |
| 179 } else { |
| 180 content_.append(read_buf_->data(), result); |
| 181 Read(); |
| 182 } |
| 183 } |
| 184 |
| 185 void TestTransactionConsumer::DidFinish(int result) { |
| 186 state_ = DONE; |
| 187 error_ = result; |
| 188 if (--quit_counter_ == 0) |
| 189 MessageLoop::current()->Quit(); |
| 190 } |
| 191 |
| 192 void TestTransactionConsumer::Read() { |
| 193 state_ = READING; |
| 194 read_buf_ = new net::IOBuffer(1024); |
| 195 int result = trans_->Read(read_buf_, 1024, this); |
| 196 if (result != net::ERR_IO_PENDING) |
| 197 DidRead(result); |
| 198 } |
| 199 |
| 200 void TestTransactionConsumer::RunWithParams(const Tuple1<int>& params) { |
| 201 int result = params.a; |
| 202 switch (state_) { |
| 203 case STARTING: |
| 204 DidStart(result); |
| 205 break; |
| 206 case READING: |
| 207 DidRead(result); |
| 208 break; |
| 209 default: |
| 210 NOTREACHED(); |
| 211 } |
| 212 } |
| 213 |
| 214 |
| 215 MockNetworkTransaction::MockNetworkTransaction() : |
| 216 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), data_cursor_(0) { |
| 217 } |
| 218 |
| 219 MockNetworkTransaction::~MockNetworkTransaction() {} |
| 220 |
| 221 int MockNetworkTransaction::Start(const net::HttpRequestInfo* request, |
| 222 net::CompletionCallback* callback, |
| 223 const net::BoundNetLog& net_log) { |
| 224 const MockTransaction* t = FindMockTransaction(request->url); |
| 225 if (!t) |
| 226 return net::ERR_FAILED; |
| 227 |
| 228 std::string resp_status = t->status; |
| 229 std::string resp_headers = t->response_headers; |
| 230 std::string resp_data = t->data; |
| 231 if (t->handler) |
| 232 (t->handler)(request, &resp_status, &resp_headers, &resp_data); |
| 233 |
| 234 std::string header_data = base::StringPrintf( |
| 235 "%s\n%s\n", resp_status.c_str(), resp_headers.c_str()); |
| 236 std::replace(header_data.begin(), header_data.end(), '\n', '\0'); |
| 237 |
| 238 response_.request_time = base::Time::Now(); |
| 239 if (!t->request_time.is_null()) |
| 240 response_.request_time = t->request_time; |
| 241 |
| 242 response_.was_cached = false; |
| 243 |
| 244 response_.response_time = base::Time::Now(); |
| 245 if (!t->response_time.is_null()) |
| 246 response_.response_time = t->response_time; |
| 247 |
| 248 response_.headers = new net::HttpResponseHeaders(header_data); |
| 249 response_.ssl_info.cert_status = t->cert_status; |
| 250 data_ = resp_data; |
| 251 test_mode_ = t->test_mode; |
| 252 |
| 253 if (test_mode_ & TEST_MODE_SYNC_NET_START) |
| 254 return net::OK; |
| 255 |
| 256 CallbackLater(callback, net::OK); |
| 257 return net::ERR_IO_PENDING; |
| 258 } |
| 259 |
| 260 int MockNetworkTransaction::RestartIgnoringLastError( |
| 261 net::CompletionCallback* callback) { |
| 262 return net::ERR_FAILED; |
| 263 } |
| 264 |
| 265 int MockNetworkTransaction::RestartWithCertificate( |
| 266 net::X509Certificate* client_cert, |
| 267 net::CompletionCallback* callback) { |
| 268 return net::ERR_FAILED; |
| 269 } |
| 270 |
| 271 int MockNetworkTransaction::RestartWithAuth(const string16& username, |
| 272 const string16& password, |
| 273 net::CompletionCallback* callback) { |
| 274 return net::ERR_FAILED; |
| 275 } |
| 276 |
| 277 bool MockNetworkTransaction::IsReadyToRestartForAuth() { |
| 278 return false; |
| 279 } |
| 280 |
| 281 int MockNetworkTransaction::Read(net::IOBuffer* buf, int buf_len, |
| 282 net::CompletionCallback* callback) { |
| 283 int data_len = static_cast<int>(data_.size()); |
| 284 int num = std::min(buf_len, data_len - data_cursor_); |
| 285 if (num) { |
| 286 memcpy(buf->data(), data_.data() + data_cursor_, num); |
| 287 data_cursor_ += num; |
| 288 } |
| 289 if (test_mode_ & TEST_MODE_SYNC_NET_READ) |
| 290 return num; |
| 291 |
| 292 CallbackLater(callback, num); |
| 293 return net::ERR_IO_PENDING; |
| 294 } |
| 295 |
| 296 void MockNetworkTransaction::StopCaching() {} |
| 297 |
| 298 const net::HttpResponseInfo* MockNetworkTransaction::GetResponseInfo() const { |
| 299 return &response_; |
| 300 } |
| 301 |
| 302 net::LoadState MockNetworkTransaction::GetLoadState() const { |
| 303 if (data_cursor_) |
| 304 return net::LOAD_STATE_READING_RESPONSE; |
| 305 return net::LOAD_STATE_IDLE; |
| 306 } |
| 307 |
| 308 uint64 MockNetworkTransaction::GetUploadProgress() const { |
| 309 return 0; |
| 310 } |
| 311 |
| 312 void MockNetworkTransaction::CallbackLater(net::CompletionCallback* callback, |
| 313 int result) { |
| 314 MessageLoop::current()->PostTask(FROM_HERE, task_factory_.NewRunnableMethod( |
| 315 &MockNetworkTransaction::RunCallback, callback, result)); |
| 316 } |
| 317 |
| 318 void MockNetworkTransaction::RunCallback(net::CompletionCallback* callback, |
| 319 int result) { |
| 320 callback->Run(result); |
| 321 } |
| 322 |
| 323 MockNetworkLayer::MockNetworkLayer() : transaction_count_(0) {} |
| 324 |
| 325 MockNetworkLayer::~MockNetworkLayer() {} |
| 326 |
| 327 int MockNetworkLayer::CreateTransaction( |
| 328 scoped_ptr<net::HttpTransaction>* trans) { |
| 329 transaction_count_++; |
| 330 trans->reset(new MockNetworkTransaction()); |
| 331 return net::OK; |
| 332 } |
| 333 |
| 334 net::HttpCache* MockNetworkLayer::GetCache() { |
| 335 return NULL; |
| 336 } |
| 337 |
| 338 net::HttpNetworkSession* MockNetworkLayer::GetSession() { |
| 339 return NULL; |
| 340 } |
| 341 |
| 342 void MockNetworkLayer::Suspend(bool suspend) {} |
139 | 343 |
140 //----------------------------------------------------------------------------- | 344 //----------------------------------------------------------------------------- |
141 // helpers | 345 // helpers |
142 | 346 |
143 int ReadTransaction(net::HttpTransaction* trans, std::string* result) { | 347 int ReadTransaction(net::HttpTransaction* trans, std::string* result) { |
144 int rv; | 348 int rv; |
145 | 349 |
146 TestCompletionCallback callback; | 350 TestCompletionCallback callback; |
147 | 351 |
148 std::string content; | 352 std::string content; |
149 do { | 353 do { |
150 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); | 354 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256)); |
151 rv = trans->Read(buf, 256, &callback); | 355 rv = trans->Read(buf, 256, &callback); |
152 if (rv == net::ERR_IO_PENDING) | 356 if (rv == net::ERR_IO_PENDING) |
153 rv = callback.WaitForResult(); | 357 rv = callback.WaitForResult(); |
154 if (rv > 0) { | 358 if (rv > 0) { |
155 content.append(buf->data(), rv); | 359 content.append(buf->data(), rv); |
156 } else if (rv < 0) { | 360 } else if (rv < 0) { |
157 return rv; | 361 return rv; |
158 } | 362 } |
159 } while (rv > 0); | 363 } while (rv > 0); |
160 | 364 |
161 result->swap(content); | 365 result->swap(content); |
162 return net::OK; | 366 return net::OK; |
163 } | 367 } |
OLD | NEW |