1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_
6#define NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_
7
8#include "net/http/http_transaction.h"
9
10#include <string>
11
12#include "base/callback.h"
13#include "base/compiler_specific.h"
14#include "base/memory/weak_ptr.h"
15#include "base/strings/string16.h"
16#include "net/base/io_buffer.h"
17#include "net/base/load_flags.h"
18#include "net/base/net_errors.h"
19#include "net/base/net_log.h"
20#include "net/base/request_priority.h"
21#include "net/base/test_completion_callback.h"
22#include "net/disk_cache/disk_cache.h"
23#include "net/http/http_cache.h"
24#include "net/http/http_request_info.h"
25#include "net/http/http_response_headers.h"
26#include "net/http/http_response_info.h"
27
28namespace net {
29class HttpRequestHeaders;
30class IOBuffer;
31}
32
33//-----------------------------------------------------------------------------
34// mock transaction data
35
36// these flags may be combined to form the test_mode field
37enum {
38  TEST_MODE_NORMAL = 0,
39  TEST_MODE_SYNC_NET_START = 1 << 0,
40  TEST_MODE_SYNC_NET_READ  = 1 << 1,
41  TEST_MODE_SYNC_CACHE_START = 1 << 2,
42  TEST_MODE_SYNC_CACHE_READ  = 1 << 3,
43  TEST_MODE_SYNC_CACHE_WRITE  = 1 << 4,
44  TEST_MODE_SYNC_ALL = (TEST_MODE_SYNC_NET_START | TEST_MODE_SYNC_NET_READ |
45                        TEST_MODE_SYNC_CACHE_START | TEST_MODE_SYNC_CACHE_READ |
46                        TEST_MODE_SYNC_CACHE_WRITE)
47};
48
49typedef void (*MockTransactionHandler)(const net::HttpRequestInfo* request,
50                                       std::string* response_status,
51                                       std::string* response_headers,
52                                       std::string* response_data);
53
54struct MockTransaction {
55  const char* url;
56  const char* method;
57  // If |request_time| is unspecified, the current time will be used.
58  base::Time request_time;
59  const char* request_headers;
60  int load_flags;
61  const char* status;
62  const char* response_headers;
63  // If |response_time| is unspecified, the current time will be used.
64  base::Time response_time;
65  const char* data;
66  int test_mode;
67  MockTransactionHandler handler;
68  net::CertStatus cert_status;
69  // Value returned by MockNetworkTransaction::Start (potentially
70  // asynchronously if |!(test_mode & TEST_MODE_SYNC_NET_START)|.)
71  net::Error return_code;
72};
73
74extern const MockTransaction kSimpleGET_Transaction;
75extern const MockTransaction kSimplePOST_Transaction;
76extern const MockTransaction kTypicalGET_Transaction;
77extern const MockTransaction kETagGET_Transaction;
78extern const MockTransaction kRangeGET_Transaction;
79
80// returns the mock transaction for the given URL
81const MockTransaction* FindMockTransaction(const GURL& url);
82
83// Add/Remove a mock transaction that can be accessed via FindMockTransaction.
84// There can be only one MockTransaction associated with a given URL.
85void AddMockTransaction(const MockTransaction* trans);
86void RemoveMockTransaction(const MockTransaction* trans);
87
88struct ScopedMockTransaction : MockTransaction {
89  ScopedMockTransaction() {
90    AddMockTransaction(this);
91  }
92  explicit ScopedMockTransaction(const MockTransaction& t)
93      : MockTransaction(t) {
94    AddMockTransaction(this);
95  }
96  ~ScopedMockTransaction() {
97    RemoveMockTransaction(this);
98  }
99};
100
101//-----------------------------------------------------------------------------
102// mock http request
103
104class MockHttpRequest : public net::HttpRequestInfo {
105 public:
106  explicit MockHttpRequest(const MockTransaction& t);
107};
108
109//-----------------------------------------------------------------------------
110// use this class to test completely consuming a transaction
111
112class TestTransactionConsumer {
113 public:
114  TestTransactionConsumer(net::RequestPriority priority,
115                          net::HttpTransactionFactory* factory);
116  virtual ~TestTransactionConsumer();
117
118  void Start(const net::HttpRequestInfo* request,
119             const net::BoundNetLog& net_log);
120
121  bool is_done() const { return state_ == DONE; }
122  int error() const { return error_; }
123
124  const net::HttpResponseInfo* response_info() const {
125    return trans_->GetResponseInfo();
126  }
127  const std::string& content() const { return content_; }
128
129 private:
130  enum State {
131    IDLE,
132    STARTING,
133    READING,
134    DONE
135  };
136
137  void DidStart(int result);
138  void DidRead(int result);
139  void DidFinish(int result);
140  void Read();
141
142  void OnIOComplete(int result);
143
144  State state_;
145  scoped_ptr<net::HttpTransaction> trans_;
146  std::string content_;
147  scoped_refptr<net::IOBuffer> read_buf_;
148  int error_;
149
150  static int quit_counter_;
151};
152
153//-----------------------------------------------------------------------------
154// mock network layer
155
156class MockNetworkLayer;
157
158// This transaction class inspects the available set of mock transactions to
159// find data for the request URL.  It supports IO operations that complete
160// synchronously or asynchronously to help exercise different code paths in the
161// HttpCache implementation.
162class MockNetworkTransaction
163    : public net::HttpTransaction,
164      public base::SupportsWeakPtr<MockNetworkTransaction> {
165 public:
166  MockNetworkTransaction(net::RequestPriority priority,
167                         MockNetworkLayer* factory);
168  virtual ~MockNetworkTransaction();
169
170  virtual int Start(const net::HttpRequestInfo* request,
171                    const net::CompletionCallback& callback,
172                    const net::BoundNetLog& net_log) OVERRIDE;
173
174  virtual int RestartIgnoringLastError(
175      const net::CompletionCallback& callback) OVERRIDE;
176
177  virtual int RestartWithCertificate(
178      net::X509Certificate* client_cert,
179      const net::CompletionCallback& callback) OVERRIDE;
180
181  virtual int RestartWithAuth(
182      const net::AuthCredentials& credentials,
183      const net::CompletionCallback& callback) OVERRIDE;
184
185  virtual bool IsReadyToRestartForAuth() OVERRIDE;
186
187  virtual int Read(net::IOBuffer* buf, int buf_len,
188                   const net::CompletionCallback& callback) OVERRIDE;
189
190  virtual void StopCaching() OVERRIDE;
191
192  virtual bool GetFullRequestHeaders(
193      net::HttpRequestHeaders* headers) const OVERRIDE;
194
195  virtual void DoneReading() OVERRIDE;
196
197  virtual const net::HttpResponseInfo* GetResponseInfo() const OVERRIDE;
198
199  virtual net::LoadState GetLoadState() const OVERRIDE;
200
201  virtual net::UploadProgress GetUploadProgress() const OVERRIDE;
202
203  virtual bool GetLoadTimingInfo(
204      net::LoadTimingInfo* load_timing_info) const OVERRIDE;
205
206  virtual void SetPriority(net::RequestPriority priority) OVERRIDE;
207
208  net::RequestPriority priority() const { return priority_; }
209
210 private:
211  void CallbackLater(const net::CompletionCallback& callback, int result);
212  void RunCallback(const net::CompletionCallback& callback, int result);
213
214  base::WeakPtrFactory<MockNetworkTransaction> weak_factory_;
215  net::HttpResponseInfo response_;
216  std::string data_;
217  int data_cursor_;
218  int test_mode_;
219  net::RequestPriority priority_;
220  base::WeakPtr<MockNetworkLayer> transaction_factory_;
221
222  // NetLog ID of the fake / non-existent underlying socket used by the
223  // connection. Requires Start() be passed a BoundNetLog with a real NetLog to
224  // be initialized.
225  unsigned int socket_log_id_;
226};
227
228class MockNetworkLayer : public net::HttpTransactionFactory,
229                         public base::SupportsWeakPtr<MockNetworkLayer> {
230 public:
231  MockNetworkLayer();
232  virtual ~MockNetworkLayer();
233
234  int transaction_count() const { return transaction_count_; }
235  bool done_reading_called() const { return done_reading_called_; }
236  void TransactionDoneReading();
237
238  // Returns the last priority passed to CreateTransaction, or
239  // DEFAULT_PRIORITY if it hasn't been called yet.
240  net::RequestPriority last_create_transaction_priority() const {
241    return last_create_transaction_priority_;
242  }
243
244  // Returns the last transaction created by
245  // CreateTransaction. Returns a NULL WeakPtr if one has not been
246  // created yet, or the last transaction has been destroyed, or
247  // ClearLastTransaction() has been called and a new transaction
248  // hasn't been created yet.
249  base::WeakPtr<MockNetworkTransaction> last_transaction() {
250    return last_transaction_;
251  }
252
253  // Makes last_transaction() return NULL until the next transaction
254  // is created.
255  void ClearLastTransaction() {
256    last_transaction_.reset();
257  }
258
259  // net::HttpTransactionFactory:
260  virtual int CreateTransaction(
261      net::RequestPriority priority,
262      scoped_ptr<net::HttpTransaction>* trans,
263      net::HttpTransactionDelegate* delegate) OVERRIDE;
264  virtual net::HttpCache* GetCache() OVERRIDE;
265  virtual net::HttpNetworkSession* GetSession() OVERRIDE;
266
267 private:
268  int transaction_count_;
269  bool done_reading_called_;
270  net::RequestPriority last_create_transaction_priority_;
271  base::WeakPtr<MockNetworkTransaction> last_transaction_;
272};
273
274//-----------------------------------------------------------------------------
275// helpers
276
277// read the transaction completely
278int ReadTransaction(net::HttpTransaction* trans, std::string* result);
279
280#endif  // NET_HTTP_HTTP_TRANSACTION_UNITTEST_H_
281