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