| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 #ifndef NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_ | 5 #ifndef NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_ |
| 6 #define NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_ | 6 #define NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_ |
| 7 #pragma once | 7 #pragma once |
| 8 | 8 |
| 9 #include "net/http/http_transaction.h" | 9 #include "net/http/http_transaction.h" |
| 10 | 10 |
| 11 #include <algorithm> | |
| 12 #include <string> | 11 #include <string> |
| 13 | 12 |
| 14 #include "base/callback.h" | 13 #include "base/callback.h" |
| 15 #include "base/compiler_specific.h" | 14 #include "base/compiler_specific.h" |
| 16 #include "base/message_loop.h" | |
| 17 #include "base/string16.h" | 15 #include "base/string16.h" |
| 18 #include "base/string_util.h" | |
| 19 #include "base/stringprintf.h" | |
| 20 #include "net/base/io_buffer.h" | 16 #include "net/base/io_buffer.h" |
| 21 #include "net/base/load_flags.h" | 17 #include "net/base/load_flags.h" |
| 22 #include "net/base/net_errors.h" | 18 #include "net/base/net_errors.h" |
| 23 #include "net/base/test_completion_callback.h" | 19 #include "net/base/test_completion_callback.h" |
| 24 #include "net/disk_cache/disk_cache.h" | 20 #include "net/disk_cache/disk_cache.h" |
| 25 #include "net/http/http_cache.h" | 21 #include "net/http/http_cache.h" |
| 26 #include "net/http/http_request_info.h" | 22 #include "net/http/http_request_info.h" |
| 27 #include "net/http/http_response_headers.h" | 23 #include "net/http/http_response_headers.h" |
| 28 #include "net/http/http_response_info.h" | 24 #include "net/http/http_response_info.h" |
| 29 | 25 |
| 26 namespace net { |
| 27 class IOBuffer; |
| 28 } |
| 29 |
| 30 //----------------------------------------------------------------------------- | 30 //----------------------------------------------------------------------------- |
| 31 // mock transaction data | 31 // mock transaction data |
| 32 | 32 |
| 33 // these flags may be combined to form the test_mode field | 33 // these flags may be combined to form the test_mode field |
| 34 enum { | 34 enum { |
| 35 TEST_MODE_NORMAL = 0, | 35 TEST_MODE_NORMAL = 0, |
| 36 TEST_MODE_SYNC_NET_START = 1 << 0, | 36 TEST_MODE_SYNC_NET_START = 1 << 0, |
| 37 TEST_MODE_SYNC_NET_READ = 1 << 1, | 37 TEST_MODE_SYNC_NET_READ = 1 << 1, |
| 38 TEST_MODE_SYNC_CACHE_START = 1 << 2, | 38 TEST_MODE_SYNC_CACHE_START = 1 << 2, |
| 39 TEST_MODE_SYNC_CACHE_READ = 1 << 3, | 39 TEST_MODE_SYNC_CACHE_READ = 1 << 3, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 90 ~ScopedMockTransaction() { | 90 ~ScopedMockTransaction() { |
| 91 RemoveMockTransaction(this); | 91 RemoveMockTransaction(this); |
| 92 } | 92 } |
| 93 }; | 93 }; |
| 94 | 94 |
| 95 //----------------------------------------------------------------------------- | 95 //----------------------------------------------------------------------------- |
| 96 // mock http request | 96 // mock http request |
| 97 | 97 |
| 98 class MockHttpRequest : public net::HttpRequestInfo { | 98 class MockHttpRequest : public net::HttpRequestInfo { |
| 99 public: | 99 public: |
| 100 explicit MockHttpRequest(const MockTransaction& t) { | 100 explicit MockHttpRequest(const MockTransaction& t); |
| 101 url = GURL(t.url); | |
| 102 method = t.method; | |
| 103 extra_headers.AddHeadersFromString(t.request_headers); | |
| 104 load_flags = t.load_flags; | |
| 105 } | |
| 106 }; | 101 }; |
| 107 | 102 |
| 108 //----------------------------------------------------------------------------- | 103 //----------------------------------------------------------------------------- |
| 109 // use this class to test completely consuming a transaction | 104 // use this class to test completely consuming a transaction |
| 110 | 105 |
| 111 class TestTransactionConsumer : public CallbackRunner< Tuple1<int> > { | 106 class TestTransactionConsumer : public CallbackRunner< Tuple1<int> > { |
| 112 public: | 107 public: |
| 113 explicit TestTransactionConsumer(net::HttpTransactionFactory* factory) | 108 explicit TestTransactionConsumer(net::HttpTransactionFactory* factory); |
| 114 : state_(IDLE), | 109 virtual ~TestTransactionConsumer(); |
| 115 trans_(NULL), | |
| 116 error_(net::OK) { | |
| 117 // Disregard the error code. | |
| 118 factory->CreateTransaction(&trans_); | |
| 119 ++quit_counter_; | |
| 120 } | |
| 121 | |
| 122 ~TestTransactionConsumer() { | |
| 123 } | |
| 124 | 110 |
| 125 void Start(const net::HttpRequestInfo* request, | 111 void Start(const net::HttpRequestInfo* request, |
| 126 const net::BoundNetLog& net_log) { | 112 const net::BoundNetLog& net_log); |
| 127 state_ = STARTING; | |
| 128 int result = trans_->Start(request, this, net_log); | |
| 129 if (result != net::ERR_IO_PENDING) | |
| 130 DidStart(result); | |
| 131 } | |
| 132 | 113 |
| 133 bool is_done() const { return state_ == DONE; } | 114 bool is_done() const { return state_ == DONE; } |
| 134 int error() const { return error_; } | 115 int error() const { return error_; } |
| 135 | 116 |
| 136 const net::HttpResponseInfo* response_info() const { | 117 const net::HttpResponseInfo* response_info() const { |
| 137 return trans_->GetResponseInfo(); | 118 return trans_->GetResponseInfo(); |
| 138 } | 119 } |
| 139 const std::string& content() const { return content_; } | 120 const std::string& content() const { return content_; } |
| 140 | 121 |
| 141 private: | 122 private: |
| 142 // Callback implementation: | |
| 143 virtual void RunWithParams(const Tuple1<int>& params) { | |
| 144 int result = params.a; | |
| 145 switch (state_) { | |
| 146 case STARTING: | |
| 147 DidStart(result); | |
| 148 break; | |
| 149 case READING: | |
| 150 DidRead(result); | |
| 151 break; | |
| 152 default: | |
| 153 NOTREACHED(); | |
| 154 } | |
| 155 } | |
| 156 | |
| 157 void DidStart(int result) { | |
| 158 if (result != net::OK) { | |
| 159 DidFinish(result); | |
| 160 } else { | |
| 161 Read(); | |
| 162 } | |
| 163 } | |
| 164 | |
| 165 void DidRead(int result) { | |
| 166 if (result <= 0) { | |
| 167 DidFinish(result); | |
| 168 } else { | |
| 169 content_.append(read_buf_->data(), result); | |
| 170 Read(); | |
| 171 } | |
| 172 } | |
| 173 | |
| 174 void DidFinish(int result) { | |
| 175 state_ = DONE; | |
| 176 error_ = result; | |
| 177 if (--quit_counter_ == 0) | |
| 178 MessageLoop::current()->Quit(); | |
| 179 } | |
| 180 | |
| 181 void Read() { | |
| 182 state_ = READING; | |
| 183 read_buf_ = new net::IOBuffer(1024); | |
| 184 int result = trans_->Read(read_buf_, 1024, this); | |
| 185 if (result != net::ERR_IO_PENDING) | |
| 186 DidRead(result); | |
| 187 } | |
| 188 | |
| 189 enum State { | 123 enum State { |
| 190 IDLE, | 124 IDLE, |
| 191 STARTING, | 125 STARTING, |
| 192 READING, | 126 READING, |
| 193 DONE | 127 DONE |
| 194 } state_; | 128 }; |
| 195 | 129 |
| 130 void DidStart(int result); |
| 131 void DidRead(int result); |
| 132 void DidFinish(int result); |
| 133 void Read(); |
| 134 |
| 135 // Callback implementation: |
| 136 virtual void RunWithParams(const Tuple1<int>& params); |
| 137 |
| 138 State state_; |
| 196 scoped_ptr<net::HttpTransaction> trans_; | 139 scoped_ptr<net::HttpTransaction> trans_; |
| 197 std::string content_; | 140 std::string content_; |
| 198 scoped_refptr<net::IOBuffer> read_buf_; | 141 scoped_refptr<net::IOBuffer> read_buf_; |
| 199 int error_; | 142 int error_; |
| 200 | 143 |
| 201 static int quit_counter_; | 144 static int quit_counter_; |
| 202 }; | 145 }; |
| 203 | 146 |
| 204 //----------------------------------------------------------------------------- | 147 //----------------------------------------------------------------------------- |
| 205 // mock network layer | 148 // mock network layer |
| 206 | 149 |
| 207 // This transaction class inspects the available set of mock transactions to | 150 // This transaction class inspects the available set of mock transactions to |
| 208 // find data for the request URL. It supports IO operations that complete | 151 // find data for the request URL. It supports IO operations that complete |
| 209 // synchronously or asynchronously to help exercise different code paths in the | 152 // synchronously or asynchronously to help exercise different code paths in the |
| 210 // HttpCache implementation. | 153 // HttpCache implementation. |
| 211 class MockNetworkTransaction : public net::HttpTransaction { | 154 class MockNetworkTransaction : public net::HttpTransaction { |
| 212 public: | 155 public: |
| 213 MockNetworkTransaction() : | 156 MockNetworkTransaction(); |
| 214 ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)), data_cursor_(0) { | 157 virtual ~MockNetworkTransaction(); |
| 215 } | |
| 216 | 158 |
| 217 virtual int Start(const net::HttpRequestInfo* request, | 159 virtual int Start(const net::HttpRequestInfo* request, |
| 218 net::CompletionCallback* callback, | 160 net::CompletionCallback* callback, |
| 219 const net::BoundNetLog& net_log) { | 161 const net::BoundNetLog& net_log); |
| 220 const MockTransaction* t = FindMockTransaction(request->url); | |
| 221 if (!t) | |
| 222 return net::ERR_FAILED; | |
| 223 | 162 |
| 224 std::string resp_status = t->status; | 163 virtual int RestartIgnoringLastError(net::CompletionCallback* callback); |
| 225 std::string resp_headers = t->response_headers; | |
| 226 std::string resp_data = t->data; | |
| 227 if (t->handler) | |
| 228 (t->handler)(request, &resp_status, &resp_headers, &resp_data); | |
| 229 | |
| 230 std::string header_data = base::StringPrintf( | |
| 231 "%s\n%s\n", resp_status.c_str(), resp_headers.c_str()); | |
| 232 std::replace(header_data.begin(), header_data.end(), '\n', '\0'); | |
| 233 | |
| 234 response_.request_time = base::Time::Now(); | |
| 235 if (!t->request_time.is_null()) | |
| 236 response_.request_time = t->request_time; | |
| 237 | |
| 238 response_.was_cached = false; | |
| 239 | |
| 240 response_.response_time = base::Time::Now(); | |
| 241 if (!t->response_time.is_null()) | |
| 242 response_.response_time = t->response_time; | |
| 243 | |
| 244 response_.headers = new net::HttpResponseHeaders(header_data); | |
| 245 response_.ssl_info.cert_status = t->cert_status; | |
| 246 data_ = resp_data; | |
| 247 test_mode_ = t->test_mode; | |
| 248 | |
| 249 if (test_mode_ & TEST_MODE_SYNC_NET_START) | |
| 250 return net::OK; | |
| 251 | |
| 252 CallbackLater(callback, net::OK); | |
| 253 return net::ERR_IO_PENDING; | |
| 254 } | |
| 255 | |
| 256 virtual int RestartIgnoringLastError(net::CompletionCallback* callback) { | |
| 257 return net::ERR_FAILED; | |
| 258 } | |
| 259 | 164 |
| 260 virtual int RestartWithCertificate(net::X509Certificate* client_cert, | 165 virtual int RestartWithCertificate(net::X509Certificate* client_cert, |
| 261 net::CompletionCallback* callback) { | 166 net::CompletionCallback* callback); |
| 262 return net::ERR_FAILED; | |
| 263 } | |
| 264 | 167 |
| 265 virtual int RestartWithAuth(const string16& username, | 168 virtual int RestartWithAuth(const string16& username, |
| 266 const string16& password, | 169 const string16& password, |
| 267 net::CompletionCallback* callback) { | 170 net::CompletionCallback* callback); |
| 268 return net::ERR_FAILED; | |
| 269 } | |
| 270 | 171 |
| 271 virtual bool IsReadyToRestartForAuth() { | 172 virtual bool IsReadyToRestartForAuth(); |
| 272 return false; | |
| 273 } | |
| 274 | 173 |
| 275 virtual int Read(net::IOBuffer* buf, int buf_len, | 174 virtual int Read(net::IOBuffer* buf, int buf_len, |
| 276 net::CompletionCallback* callback) { | 175 net::CompletionCallback* callback); |
| 277 int data_len = static_cast<int>(data_.size()); | |
| 278 int num = std::min(buf_len, data_len - data_cursor_); | |
| 279 if (num) { | |
| 280 memcpy(buf->data(), data_.data() + data_cursor_, num); | |
| 281 data_cursor_ += num; | |
| 282 } | |
| 283 if (test_mode_ & TEST_MODE_SYNC_NET_READ) | |
| 284 return num; | |
| 285 | 176 |
| 286 CallbackLater(callback, num); | 177 virtual void StopCaching(); |
| 287 return net::ERR_IO_PENDING; | |
| 288 } | |
| 289 | 178 |
| 290 virtual void StopCaching() {} | 179 virtual const net::HttpResponseInfo* GetResponseInfo() const; |
| 291 | 180 |
| 292 virtual const net::HttpResponseInfo* GetResponseInfo() const { | 181 virtual net::LoadState GetLoadState() const; |
| 293 return &response_; | |
| 294 } | |
| 295 | 182 |
| 296 virtual net::LoadState GetLoadState() const { | 183 virtual uint64 GetUploadProgress() const; |
| 297 if (data_cursor_) | |
| 298 return net::LOAD_STATE_READING_RESPONSE; | |
| 299 return net::LOAD_STATE_IDLE; | |
| 300 } | |
| 301 | |
| 302 virtual uint64 GetUploadProgress() const { | |
| 303 return 0; | |
| 304 } | |
| 305 | 184 |
| 306 private: | 185 private: |
| 307 void CallbackLater(net::CompletionCallback* callback, int result) { | 186 void CallbackLater(net::CompletionCallback* callback, int result); |
| 308 MessageLoop::current()->PostTask(FROM_HERE, task_factory_.NewRunnableMethod( | 187 void RunCallback(net::CompletionCallback* callback, int result); |
| 309 &MockNetworkTransaction::RunCallback, callback, result)); | |
| 310 } | |
| 311 void RunCallback(net::CompletionCallback* callback, int result) { | |
| 312 callback->Run(result); | |
| 313 } | |
| 314 | 188 |
| 315 ScopedRunnableMethodFactory<MockNetworkTransaction> task_factory_; | 189 ScopedRunnableMethodFactory<MockNetworkTransaction> task_factory_; |
| 316 net::HttpResponseInfo response_; | 190 net::HttpResponseInfo response_; |
| 317 std::string data_; | 191 std::string data_; |
| 318 int data_cursor_; | 192 int data_cursor_; |
| 319 int test_mode_; | 193 int test_mode_; |
| 320 }; | 194 }; |
| 321 | 195 |
| 322 class MockNetworkLayer : public net::HttpTransactionFactory { | 196 class MockNetworkLayer : public net::HttpTransactionFactory { |
| 323 public: | 197 public: |
| 324 MockNetworkLayer() : transaction_count_(0) { | 198 MockNetworkLayer(); |
| 325 } | 199 virtual ~MockNetworkLayer(); |
| 326 | |
| 327 virtual int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans) { | |
| 328 transaction_count_++; | |
| 329 trans->reset(new MockNetworkTransaction()); | |
| 330 return net::OK; | |
| 331 } | |
| 332 | |
| 333 virtual net::HttpCache* GetCache() { | |
| 334 return NULL; | |
| 335 } | |
| 336 | |
| 337 virtual net::HttpNetworkSession* GetSession() { | |
| 338 return NULL; | |
| 339 } | |
| 340 | |
| 341 virtual void Suspend(bool suspend) {} | |
| 342 | 200 |
| 343 int transaction_count() const { return transaction_count_; } | 201 int transaction_count() const { return transaction_count_; } |
| 344 | 202 |
| 203 // net::HttpTransactionFactory: |
| 204 virtual int CreateTransaction(scoped_ptr<net::HttpTransaction>* trans); |
| 205 virtual net::HttpCache* GetCache(); |
| 206 virtual net::HttpNetworkSession* GetSession(); |
| 207 virtual void Suspend(bool suspend); |
| 208 |
| 345 private: | 209 private: |
| 346 int transaction_count_; | 210 int transaction_count_; |
| 347 }; | 211 }; |
| 348 | 212 |
| 349 | |
| 350 //----------------------------------------------------------------------------- | 213 //----------------------------------------------------------------------------- |
| 351 // helpers | 214 // helpers |
| 352 | 215 |
| 353 // read the transaction completely | 216 // read the transaction completely |
| 354 int ReadTransaction(net::HttpTransaction* trans, std::string* result); | 217 int ReadTransaction(net::HttpTransaction* trans, std::string* result); |
| 355 | 218 |
| 356 #endif // NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_ | 219 #endif // NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_ |
| OLD | NEW |