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