• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2023 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/http/http_transaction_test_util.h"
6 
7 #include <string>
8 #include <string_view>
9 
10 #include "base/test/bind.h"
11 #include "base/test/task_environment.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/test/gtest_util.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 
16 namespace net {
17 
18 namespace {
19 
20 // Default transaction.
21 const MockTransaction kBasicTransaction = {
22     .url = "http://www.example.com/",
23     .method = "GET",
24     .request_time = base::Time(),
25     .request_headers = "",
26     .load_flags = LOAD_NORMAL,
27     .transport_info = TransportInfo(TransportType::kDirect,
28                                     IPEndPoint(IPAddress::IPv4Localhost(), 80),
29                                     /*accept_ch_frame_arg=*/"",
30                                     /*cert_is_issued_by_known_root=*/false,
31                                     kProtoUnknown),
32     .status = "HTTP/1.1 200 OK",
33     .response_headers = "Cache-Control: max-age=10000\n",
34     .response_time = base::Time(),
35     .data = "<html><body>Hello world!</body></html>",
36     .dns_aliases = {},
37     .fps_cache_filter = absl::nullopt,
38     .browser_run_id = absl::nullopt,
39     .test_mode = TEST_MODE_NORMAL,
40     .handler = MockTransactionHandler(),
41     .read_handler = MockTransactionReadHandler(),
42     .cert = nullptr,
43     .cert_status = 0,
44     .ssl_connection_status = 0,
45     .start_return_code = OK,
46     .read_return_code = OK,
47 };
48 const size_t kDefaultBufferSize = 1024;
49 
50 }  // namespace
51 
52 class MockNetworkTransactionTest : public ::testing::Test {
53  public:
MockNetworkTransactionTest()54   MockNetworkTransactionTest()
55       : network_layer_(std::make_unique<MockNetworkLayer>()) {}
56   ~MockNetworkTransactionTest() override = default;
57 
58   MockNetworkTransactionTest(const MockNetworkTransactionTest&) = delete;
59   MockNetworkTransactionTest& operator=(const MockNetworkTransactionTest&) =
60       delete;
61 
62  protected:
CreateNetworkTransaction()63   std::unique_ptr<HttpTransaction> CreateNetworkTransaction() {
64     std::unique_ptr<HttpTransaction> network_transaction;
65     network_layer_->CreateTransaction(DEFAULT_PRIORITY, &network_transaction);
66     return network_transaction;
67   }
68 
RunUntilIdle()69   void RunUntilIdle() { task_environment_.RunUntilIdle(); }
70 
network_layer()71   MockNetworkLayer& network_layer() { return *network_layer_.get(); }
72 
73  private:
74   std::unique_ptr<MockNetworkLayer> network_layer_;
75   base::test::TaskEnvironment task_environment_{
76       base::test::TaskEnvironment::TimeSource::MOCK_TIME};
77 };
78 
TEST_F(MockNetworkTransactionTest,Basic)79 TEST_F(MockNetworkTransactionTest, Basic) {
80   AddMockTransaction(&kBasicTransaction);
81   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
82 
83   auto transaction = CreateNetworkTransaction();
84   TestCompletionCallback start_callback;
85   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
86                                  NetLogWithSource()),
87               test::IsError(ERR_IO_PENDING));
88   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
89 
90   EXPECT_FALSE(transaction->GetResponseInfo()->was_cached);
91   EXPECT_TRUE(transaction->GetResponseInfo()->network_accessed);
92   EXPECT_EQ(kBasicTransaction.transport_info.endpoint,
93             transaction->GetResponseInfo()->remote_endpoint);
94   EXPECT_FALSE(transaction->GetResponseInfo()->was_fetched_via_proxy);
95 
96   scoped_refptr<IOBufferWithSize> buf =
97       base::MakeRefCounted<IOBufferWithSize>(kDefaultBufferSize);
98   TestCompletionCallback read_callback;
99   ASSERT_THAT(
100       transaction->Read(buf.get(), buf->size(), read_callback.callback()),
101       test::IsError(ERR_IO_PENDING));
102   int read_result = read_callback.WaitForResult();
103   ASSERT_THAT(read_result, std::string_view(kBasicTransaction.data).size());
104   EXPECT_EQ(std::string_view(kBasicTransaction.data),
105             std::string_view(buf->data(), read_result));
106 }
107 
TEST_F(MockNetworkTransactionTest,SyncNetStart)108 TEST_F(MockNetworkTransactionTest, SyncNetStart) {
109   MockTransaction new_mock_transaction = kBasicTransaction;
110   new_mock_transaction.test_mode = TEST_MODE_SYNC_NET_START;
111   AddMockTransaction(&new_mock_transaction);
112   HttpRequestInfo request = MockHttpRequest(new_mock_transaction);
113 
114   auto transaction = CreateNetworkTransaction();
115   TestCompletionCallback start_callback;
116   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
117                                  NetLogWithSource()),
118               test::IsError(OK));
119 
120   scoped_refptr<IOBufferWithSize> buf =
121       base::MakeRefCounted<IOBufferWithSize>(kDefaultBufferSize);
122   TestCompletionCallback read_callback;
123   ASSERT_THAT(
124       transaction->Read(buf.get(), buf->size(), read_callback.callback()),
125       test::IsError(ERR_IO_PENDING));
126   int read_result = read_callback.WaitForResult();
127   ASSERT_THAT(read_result, std::string_view(new_mock_transaction.data).size());
128   EXPECT_EQ(std::string_view(new_mock_transaction.data),
129             std::string_view(buf->data(), read_result));
130 }
131 
TEST_F(MockNetworkTransactionTest,AsyncNetStartFailure)132 TEST_F(MockNetworkTransactionTest, AsyncNetStartFailure) {
133   MockTransaction new_mock_transaction = kBasicTransaction;
134   new_mock_transaction.start_return_code = ERR_NETWORK_ACCESS_DENIED;
135   AddMockTransaction(&new_mock_transaction);
136   HttpRequestInfo request = MockHttpRequest(new_mock_transaction);
137 
138   auto transaction = CreateNetworkTransaction();
139   TestCompletionCallback start_callback;
140   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
141                                  NetLogWithSource()),
142               test::IsError(ERR_IO_PENDING));
143   EXPECT_THAT(start_callback.WaitForResult(),
144               test::IsError(ERR_NETWORK_ACCESS_DENIED));
145 }
146 
TEST_F(MockNetworkTransactionTest,SyncNetStartFailure)147 TEST_F(MockNetworkTransactionTest, SyncNetStartFailure) {
148   MockTransaction new_mock_transaction = kBasicTransaction;
149   new_mock_transaction.test_mode = TEST_MODE_SYNC_NET_START;
150   new_mock_transaction.start_return_code = ERR_NETWORK_ACCESS_DENIED;
151   AddMockTransaction(&new_mock_transaction);
152   HttpRequestInfo request = MockHttpRequest(new_mock_transaction);
153 
154   auto transaction = CreateNetworkTransaction();
155   TestCompletionCallback start_callback;
156   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
157                                  NetLogWithSource()),
158               test::IsError(ERR_NETWORK_ACCESS_DENIED));
159 }
160 
TEST_F(MockNetworkTransactionTest,BeforeNetworkStartCallback)161 TEST_F(MockNetworkTransactionTest, BeforeNetworkStartCallback) {
162   AddMockTransaction(&kBasicTransaction);
163   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
164 
165   auto transaction = CreateNetworkTransaction();
166   bool before_network_start_callback_called = false;
167   transaction->SetBeforeNetworkStartCallback(base::BindLambdaForTesting(
168       [&](bool* defer) { before_network_start_callback_called = true; }));
169 
170   TestCompletionCallback start_callback;
171   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
172                                  NetLogWithSource()),
173               test::IsError(ERR_IO_PENDING));
174   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
175   EXPECT_TRUE(before_network_start_callback_called);
176 }
177 
TEST_F(MockNetworkTransactionTest,BeforeNetworkStartCallbackDeferAndResume)178 TEST_F(MockNetworkTransactionTest, BeforeNetworkStartCallbackDeferAndResume) {
179   AddMockTransaction(&kBasicTransaction);
180   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
181 
182   auto transaction = CreateNetworkTransaction();
183   bool before_network_start_callback_called = false;
184   transaction->SetBeforeNetworkStartCallback(
185       base::BindLambdaForTesting([&](bool* defer) {
186         before_network_start_callback_called = true;
187         *defer = true;
188       }));
189 
190   TestCompletionCallback start_callback;
191   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
192                                  NetLogWithSource()),
193               test::IsError(ERR_IO_PENDING));
194   EXPECT_TRUE(before_network_start_callback_called);
195   RunUntilIdle();
196   EXPECT_FALSE(start_callback.have_result());
197   transaction->ResumeNetworkStart();
198   EXPECT_FALSE(start_callback.have_result());
199   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
200 }
201 
TEST_F(MockNetworkTransactionTest,AsyncConnectedCallback)202 TEST_F(MockNetworkTransactionTest, AsyncConnectedCallback) {
203   AddMockTransaction(&kBasicTransaction);
204   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
205 
206   auto transaction = CreateNetworkTransaction();
207   bool connected_callback_called = false;
208   CompletionOnceCallback callback_for_connected_callback;
209   transaction->SetConnectedCallback(base::BindLambdaForTesting(
210       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
211         EXPECT_EQ(kBasicTransaction.transport_info, info);
212         connected_callback_called = true;
213         callback_for_connected_callback = std::move(callback);
214         return ERR_IO_PENDING;
215       }));
216 
217   TestCompletionCallback start_callback;
218   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
219                                  NetLogWithSource()),
220               test::IsError(ERR_IO_PENDING));
221   RunUntilIdle();
222   EXPECT_TRUE(connected_callback_called);
223   EXPECT_FALSE(start_callback.have_result());
224   std::move(callback_for_connected_callback).Run(OK);
225   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
226 }
227 
TEST_F(MockNetworkTransactionTest,AsyncConnectedCallbackFailure)228 TEST_F(MockNetworkTransactionTest, AsyncConnectedCallbackFailure) {
229   AddMockTransaction(&kBasicTransaction);
230   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
231 
232   auto transaction = CreateNetworkTransaction();
233   bool connected_callback_called = false;
234   CompletionOnceCallback callback_for_connected_callback;
235   transaction->SetConnectedCallback(base::BindLambdaForTesting(
236       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
237         EXPECT_EQ(kBasicTransaction.transport_info, info);
238         connected_callback_called = true;
239         callback_for_connected_callback = std::move(callback);
240         return ERR_IO_PENDING;
241       }));
242 
243   TestCompletionCallback start_callback;
244   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
245                                  NetLogWithSource()),
246               test::IsError(ERR_IO_PENDING));
247   RunUntilIdle();
248   EXPECT_TRUE(connected_callback_called);
249   EXPECT_FALSE(start_callback.have_result());
250   std::move(callback_for_connected_callback).Run(ERR_INSUFFICIENT_RESOURCES);
251   EXPECT_THAT(start_callback.WaitForResult(),
252               test::IsError(ERR_INSUFFICIENT_RESOURCES));
253 }
254 
TEST_F(MockNetworkTransactionTest,SyncConnectedCallback)255 TEST_F(MockNetworkTransactionTest, SyncConnectedCallback) {
256   AddMockTransaction(&kBasicTransaction);
257   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
258 
259   auto transaction = CreateNetworkTransaction();
260   bool connected_callback_called = false;
261   transaction->SetConnectedCallback(base::BindLambdaForTesting(
262       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
263         EXPECT_EQ(kBasicTransaction.transport_info, info);
264         connected_callback_called = true;
265         return OK;
266       }));
267 
268   TestCompletionCallback start_callback;
269   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
270                                  NetLogWithSource()),
271               test::IsError(ERR_IO_PENDING));
272   RunUntilIdle();
273   EXPECT_TRUE(connected_callback_called);
274   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
275 }
276 
TEST_F(MockNetworkTransactionTest,SyncConnectedCallbackFailure)277 TEST_F(MockNetworkTransactionTest, SyncConnectedCallbackFailure) {
278   AddMockTransaction(&kBasicTransaction);
279   HttpRequestInfo request = MockHttpRequest(kBasicTransaction);
280 
281   auto transaction = CreateNetworkTransaction();
282   bool connected_callback_called = false;
283   transaction->SetConnectedCallback(base::BindLambdaForTesting(
284       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
285         EXPECT_EQ(kBasicTransaction.transport_info, info);
286         connected_callback_called = true;
287         return ERR_INSUFFICIENT_RESOURCES;
288       }));
289 
290   TestCompletionCallback start_callback;
291   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
292                                  NetLogWithSource()),
293               test::IsError(ERR_IO_PENDING));
294   RunUntilIdle();
295   EXPECT_TRUE(connected_callback_called);
296   EXPECT_THAT(start_callback.WaitForResult(),
297               test::IsError(ERR_INSUFFICIENT_RESOURCES));
298 }
299 
TEST_F(MockNetworkTransactionTest,ModifyRequestHeadersCallback)300 TEST_F(MockNetworkTransactionTest, ModifyRequestHeadersCallback) {
301   const std::string kTestResponseData = "hello";
302   MockTransaction new_mock_transaction = kBasicTransaction;
303   new_mock_transaction.request_headers = "Foo: Bar\r\n";
304 
305   bool transaction_handler_called = false;
306   new_mock_transaction.handler = base::BindLambdaForTesting(
307       [&](const HttpRequestInfo* request, std::string* response_status,
308           std::string* response_headers, std::string* response_data) {
309         EXPECT_EQ("Foo: Bar\r\nHoge: Piyo\r\n\r\n",
310                   request->extra_headers.ToString());
311         *response_data = kTestResponseData;
312         transaction_handler_called = true;
313       });
314   AddMockTransaction(&new_mock_transaction);
315   HttpRequestInfo request = MockHttpRequest(new_mock_transaction);
316 
317   auto transaction = CreateNetworkTransaction();
318   bool modify_request_headers_callback_called_ = false;
319   transaction->SetModifyRequestHeadersCallback(
320       base::BindLambdaForTesting([&](HttpRequestHeaders* request_headers) {
321         modify_request_headers_callback_called_ = true;
322         request_headers->SetHeader("Hoge", "Piyo");
323       }));
324 
325   TestCompletionCallback start_callback;
326   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
327                                  NetLogWithSource()),
328               test::IsError(ERR_IO_PENDING));
329   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
330   EXPECT_TRUE(modify_request_headers_callback_called_);
331   EXPECT_TRUE(transaction_handler_called);
332 
333   scoped_refptr<IOBufferWithSize> buf =
334       base::MakeRefCounted<IOBufferWithSize>(kDefaultBufferSize);
335   TestCompletionCallback read_callback;
336   ASSERT_THAT(
337       transaction->Read(buf.get(), buf->size(), read_callback.callback()),
338       test::IsError(ERR_IO_PENDING));
339   int read_result = read_callback.WaitForResult();
340   ASSERT_THAT(read_result, kTestResponseData.size());
341   EXPECT_EQ(kTestResponseData, std::string_view(buf->data(), read_result));
342 }
343 
TEST_F(MockNetworkTransactionTest,CallbackOrder)344 TEST_F(MockNetworkTransactionTest, CallbackOrder) {
345   const std::string kTestResponseData = "hello";
346   MockTransaction new_mock_transaction = kBasicTransaction;
347   new_mock_transaction.request_headers = "Foo: Bar\r\n";
348 
349   bool before_network_start_callback_called = false;
350   bool connected_callback_called = false;
351   bool modify_request_headers_callback_called_ = false;
352   bool transaction_handler_called = false;
353 
354   new_mock_transaction.handler = base::BindLambdaForTesting(
355       [&](const HttpRequestInfo* request, std::string* response_status,
356           std::string* response_headers, std::string* response_data) {
357         EXPECT_TRUE(before_network_start_callback_called);
358         EXPECT_TRUE(connected_callback_called);
359         EXPECT_TRUE(modify_request_headers_callback_called_);
360         EXPECT_FALSE(transaction_handler_called);
361 
362         *response_data = kTestResponseData;
363         transaction_handler_called = true;
364       });
365 
366   AddMockTransaction(&new_mock_transaction);
367   HttpRequestInfo request = MockHttpRequest(new_mock_transaction);
368 
369   auto transaction = CreateNetworkTransaction();
370   transaction->SetBeforeNetworkStartCallback(
371       base::BindLambdaForTesting([&](bool* defer) {
372         EXPECT_FALSE(before_network_start_callback_called);
373         EXPECT_FALSE(connected_callback_called);
374         EXPECT_FALSE(modify_request_headers_callback_called_);
375         EXPECT_FALSE(transaction_handler_called);
376 
377         before_network_start_callback_called = true;
378         *defer = true;
379       }));
380 
381   CompletionOnceCallback callback_for_connected_callback;
382   transaction->SetConnectedCallback(base::BindLambdaForTesting(
383       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
384         EXPECT_TRUE(before_network_start_callback_called);
385         EXPECT_FALSE(connected_callback_called);
386         EXPECT_FALSE(modify_request_headers_callback_called_);
387         EXPECT_FALSE(transaction_handler_called);
388 
389         connected_callback_called = true;
390         callback_for_connected_callback = std::move(callback);
391         return ERR_IO_PENDING;
392       }));
393 
394   transaction->SetModifyRequestHeadersCallback(
395       base::BindLambdaForTesting([&](HttpRequestHeaders* request_headers) {
396         EXPECT_TRUE(before_network_start_callback_called);
397         EXPECT_TRUE(connected_callback_called);
398         EXPECT_FALSE(modify_request_headers_callback_called_);
399         EXPECT_FALSE(transaction_handler_called);
400 
401         modify_request_headers_callback_called_ = true;
402       }));
403 
404   EXPECT_FALSE(before_network_start_callback_called);
405   TestCompletionCallback start_callback;
406   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
407                                  NetLogWithSource()),
408               test::IsError(ERR_IO_PENDING));
409 
410   EXPECT_TRUE(before_network_start_callback_called);
411 
412   EXPECT_FALSE(connected_callback_called);
413   transaction->ResumeNetworkStart();
414   RunUntilIdle();
415   EXPECT_TRUE(connected_callback_called);
416 
417   EXPECT_FALSE(modify_request_headers_callback_called_);
418   std::move(callback_for_connected_callback).Run(OK);
419   EXPECT_TRUE(modify_request_headers_callback_called_);
420   EXPECT_TRUE(transaction_handler_called);
421 
422   EXPECT_TRUE(start_callback.have_result());
423   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
424 }
425 
426 }  // namespace net
427