xref: /aosp_15_r20/external/cronet/net/http/http_transaction_test_util_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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 = std::nullopt,
38     .browser_run_id = std::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   ScopedMockTransaction mock_transaction(kBasicTransaction);
81   HttpRequestInfo request = MockHttpRequest(mock_transaction);
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(mock_transaction.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(mock_transaction.data).size());
104   EXPECT_EQ(std::string_view(mock_transaction.data),
105             std::string_view(buf->data(), read_result));
106 }
107 
TEST_F(MockNetworkTransactionTest,SyncNetStart)108 TEST_F(MockNetworkTransactionTest, SyncNetStart) {
109   ScopedMockTransaction mock_transaction(kBasicTransaction);
110   mock_transaction.test_mode = TEST_MODE_SYNC_NET_START;
111   HttpRequestInfo request = MockHttpRequest(mock_transaction);
112 
113   auto transaction = CreateNetworkTransaction();
114   TestCompletionCallback start_callback;
115   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
116                                  NetLogWithSource()),
117               test::IsError(OK));
118 
119   scoped_refptr<IOBufferWithSize> buf =
120       base::MakeRefCounted<IOBufferWithSize>(kDefaultBufferSize);
121   TestCompletionCallback read_callback;
122   ASSERT_THAT(
123       transaction->Read(buf.get(), buf->size(), read_callback.callback()),
124       test::IsError(ERR_IO_PENDING));
125   int read_result = read_callback.WaitForResult();
126   ASSERT_THAT(read_result, std::string_view(mock_transaction.data).size());
127   EXPECT_EQ(std::string_view(mock_transaction.data),
128             std::string_view(buf->data(), read_result));
129 }
130 
TEST_F(MockNetworkTransactionTest,AsyncNetStartFailure)131 TEST_F(MockNetworkTransactionTest, AsyncNetStartFailure) {
132   ScopedMockTransaction mock_transaction(kBasicTransaction);
133   mock_transaction.start_return_code = ERR_NETWORK_ACCESS_DENIED;
134   HttpRequestInfo request = MockHttpRequest(mock_transaction);
135 
136   auto transaction = CreateNetworkTransaction();
137   TestCompletionCallback start_callback;
138   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
139                                  NetLogWithSource()),
140               test::IsError(ERR_IO_PENDING));
141   EXPECT_THAT(start_callback.WaitForResult(),
142               test::IsError(ERR_NETWORK_ACCESS_DENIED));
143 }
144 
TEST_F(MockNetworkTransactionTest,SyncNetStartFailure)145 TEST_F(MockNetworkTransactionTest, SyncNetStartFailure) {
146   ScopedMockTransaction mock_transaction(kBasicTransaction);
147   mock_transaction.test_mode = TEST_MODE_SYNC_NET_START;
148   mock_transaction.start_return_code = ERR_NETWORK_ACCESS_DENIED;
149   HttpRequestInfo request = MockHttpRequest(mock_transaction);
150 
151   auto transaction = CreateNetworkTransaction();
152   TestCompletionCallback start_callback;
153   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
154                                  NetLogWithSource()),
155               test::IsError(ERR_NETWORK_ACCESS_DENIED));
156 }
157 
TEST_F(MockNetworkTransactionTest,BeforeNetworkStartCallback)158 TEST_F(MockNetworkTransactionTest, BeforeNetworkStartCallback) {
159   ScopedMockTransaction mock_transaction(kBasicTransaction);
160   HttpRequestInfo request = MockHttpRequest(mock_transaction);
161 
162   auto transaction = CreateNetworkTransaction();
163   bool before_network_start_callback_called = false;
164   transaction->SetBeforeNetworkStartCallback(base::BindLambdaForTesting(
165       [&](bool* defer) { before_network_start_callback_called = true; }));
166 
167   TestCompletionCallback start_callback;
168   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
169                                  NetLogWithSource()),
170               test::IsError(ERR_IO_PENDING));
171   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
172   EXPECT_TRUE(before_network_start_callback_called);
173 }
174 
TEST_F(MockNetworkTransactionTest,BeforeNetworkStartCallbackDeferAndResume)175 TEST_F(MockNetworkTransactionTest, BeforeNetworkStartCallbackDeferAndResume) {
176   ScopedMockTransaction mock_transaction(kBasicTransaction);
177   HttpRequestInfo request = MockHttpRequest(mock_transaction);
178 
179   auto transaction = CreateNetworkTransaction();
180   bool before_network_start_callback_called = false;
181   transaction->SetBeforeNetworkStartCallback(
182       base::BindLambdaForTesting([&](bool* defer) {
183         before_network_start_callback_called = true;
184         *defer = true;
185       }));
186 
187   TestCompletionCallback start_callback;
188   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
189                                  NetLogWithSource()),
190               test::IsError(ERR_IO_PENDING));
191   EXPECT_TRUE(before_network_start_callback_called);
192   RunUntilIdle();
193   EXPECT_FALSE(start_callback.have_result());
194   transaction->ResumeNetworkStart();
195   EXPECT_FALSE(start_callback.have_result());
196   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
197 }
198 
TEST_F(MockNetworkTransactionTest,AsyncConnectedCallback)199 TEST_F(MockNetworkTransactionTest, AsyncConnectedCallback) {
200   ScopedMockTransaction mock_transaction(kBasicTransaction);
201   HttpRequestInfo request = MockHttpRequest(mock_transaction);
202 
203   auto transaction = CreateNetworkTransaction();
204   bool connected_callback_called = false;
205   CompletionOnceCallback callback_for_connected_callback;
206   transaction->SetConnectedCallback(base::BindLambdaForTesting(
207       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
208         EXPECT_EQ(mock_transaction.transport_info, info);
209         connected_callback_called = true;
210         callback_for_connected_callback = std::move(callback);
211         return ERR_IO_PENDING;
212       }));
213 
214   TestCompletionCallback start_callback;
215   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
216                                  NetLogWithSource()),
217               test::IsError(ERR_IO_PENDING));
218   RunUntilIdle();
219   EXPECT_TRUE(connected_callback_called);
220   EXPECT_FALSE(start_callback.have_result());
221   std::move(callback_for_connected_callback).Run(OK);
222   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
223 }
224 
TEST_F(MockNetworkTransactionTest,AsyncConnectedCallbackFailure)225 TEST_F(MockNetworkTransactionTest, AsyncConnectedCallbackFailure) {
226   ScopedMockTransaction mock_transaction(kBasicTransaction);
227   HttpRequestInfo request = MockHttpRequest(mock_transaction);
228 
229   auto transaction = CreateNetworkTransaction();
230   bool connected_callback_called = false;
231   CompletionOnceCallback callback_for_connected_callback;
232   transaction->SetConnectedCallback(base::BindLambdaForTesting(
233       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
234         EXPECT_EQ(mock_transaction.transport_info, info);
235         connected_callback_called = true;
236         callback_for_connected_callback = std::move(callback);
237         return ERR_IO_PENDING;
238       }));
239 
240   TestCompletionCallback start_callback;
241   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
242                                  NetLogWithSource()),
243               test::IsError(ERR_IO_PENDING));
244   RunUntilIdle();
245   EXPECT_TRUE(connected_callback_called);
246   EXPECT_FALSE(start_callback.have_result());
247   std::move(callback_for_connected_callback).Run(ERR_INSUFFICIENT_RESOURCES);
248   EXPECT_THAT(start_callback.WaitForResult(),
249               test::IsError(ERR_INSUFFICIENT_RESOURCES));
250 }
251 
TEST_F(MockNetworkTransactionTest,SyncConnectedCallback)252 TEST_F(MockNetworkTransactionTest, SyncConnectedCallback) {
253   ScopedMockTransaction mock_transaction(kBasicTransaction);
254   HttpRequestInfo request = MockHttpRequest(mock_transaction);
255 
256   auto transaction = CreateNetworkTransaction();
257   bool connected_callback_called = false;
258   transaction->SetConnectedCallback(base::BindLambdaForTesting(
259       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
260         EXPECT_EQ(mock_transaction.transport_info, info);
261         connected_callback_called = true;
262         return OK;
263       }));
264 
265   TestCompletionCallback start_callback;
266   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
267                                  NetLogWithSource()),
268               test::IsError(ERR_IO_PENDING));
269   RunUntilIdle();
270   EXPECT_TRUE(connected_callback_called);
271   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
272 }
273 
TEST_F(MockNetworkTransactionTest,SyncConnectedCallbackFailure)274 TEST_F(MockNetworkTransactionTest, SyncConnectedCallbackFailure) {
275   ScopedMockTransaction mock_transaction(kBasicTransaction);
276   HttpRequestInfo request = MockHttpRequest(mock_transaction);
277 
278   auto transaction = CreateNetworkTransaction();
279   bool connected_callback_called = false;
280   transaction->SetConnectedCallback(base::BindLambdaForTesting(
281       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
282         EXPECT_EQ(mock_transaction.transport_info, info);
283         connected_callback_called = true;
284         return ERR_INSUFFICIENT_RESOURCES;
285       }));
286 
287   TestCompletionCallback start_callback;
288   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
289                                  NetLogWithSource()),
290               test::IsError(ERR_IO_PENDING));
291   RunUntilIdle();
292   EXPECT_TRUE(connected_callback_called);
293   EXPECT_THAT(start_callback.WaitForResult(),
294               test::IsError(ERR_INSUFFICIENT_RESOURCES));
295 }
296 
TEST_F(MockNetworkTransactionTest,ModifyRequestHeadersCallback)297 TEST_F(MockNetworkTransactionTest, ModifyRequestHeadersCallback) {
298   const std::string kTestResponseData = "hello";
299   ScopedMockTransaction mock_transaction(kBasicTransaction);
300   mock_transaction.request_headers = "Foo: Bar\r\n";
301 
302   bool transaction_handler_called = false;
303   mock_transaction.handler = base::BindLambdaForTesting(
304       [&](const HttpRequestInfo* request, std::string* response_status,
305           std::string* response_headers, std::string* response_data) {
306         EXPECT_EQ("Foo: Bar\r\nHoge: Piyo\r\n\r\n",
307                   request->extra_headers.ToString());
308         *response_data = kTestResponseData;
309         transaction_handler_called = true;
310       });
311   HttpRequestInfo request = MockHttpRequest(mock_transaction);
312 
313   auto transaction = CreateNetworkTransaction();
314   bool modify_request_headers_callback_called_ = false;
315   transaction->SetModifyRequestHeadersCallback(
316       base::BindLambdaForTesting([&](HttpRequestHeaders* request_headers) {
317         modify_request_headers_callback_called_ = true;
318         request_headers->SetHeader("Hoge", "Piyo");
319       }));
320 
321   TestCompletionCallback start_callback;
322   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
323                                  NetLogWithSource()),
324               test::IsError(ERR_IO_PENDING));
325   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
326   EXPECT_TRUE(modify_request_headers_callback_called_);
327   EXPECT_TRUE(transaction_handler_called);
328 
329   scoped_refptr<IOBufferWithSize> buf =
330       base::MakeRefCounted<IOBufferWithSize>(kDefaultBufferSize);
331   TestCompletionCallback read_callback;
332   ASSERT_THAT(
333       transaction->Read(buf.get(), buf->size(), read_callback.callback()),
334       test::IsError(ERR_IO_PENDING));
335   int read_result = read_callback.WaitForResult();
336   ASSERT_THAT(read_result, kTestResponseData.size());
337   EXPECT_EQ(kTestResponseData, std::string_view(buf->data(), read_result));
338 }
339 
TEST_F(MockNetworkTransactionTest,CallbackOrder)340 TEST_F(MockNetworkTransactionTest, CallbackOrder) {
341   const std::string kTestResponseData = "hello";
342   ScopedMockTransaction mock_transaction(kBasicTransaction);
343   mock_transaction.request_headers = "Foo: Bar\r\n";
344 
345   bool before_network_start_callback_called = false;
346   bool connected_callback_called = false;
347   bool modify_request_headers_callback_called_ = false;
348   bool transaction_handler_called = false;
349 
350   mock_transaction.handler = base::BindLambdaForTesting(
351       [&](const HttpRequestInfo* request, std::string* response_status,
352           std::string* response_headers, std::string* response_data) {
353         EXPECT_TRUE(before_network_start_callback_called);
354         EXPECT_TRUE(connected_callback_called);
355         EXPECT_TRUE(modify_request_headers_callback_called_);
356         EXPECT_FALSE(transaction_handler_called);
357 
358         *response_data = kTestResponseData;
359         transaction_handler_called = true;
360       });
361 
362   HttpRequestInfo request = MockHttpRequest(mock_transaction);
363 
364   auto transaction = CreateNetworkTransaction();
365   transaction->SetBeforeNetworkStartCallback(
366       base::BindLambdaForTesting([&](bool* defer) {
367         EXPECT_FALSE(before_network_start_callback_called);
368         EXPECT_FALSE(connected_callback_called);
369         EXPECT_FALSE(modify_request_headers_callback_called_);
370         EXPECT_FALSE(transaction_handler_called);
371 
372         before_network_start_callback_called = true;
373         *defer = true;
374       }));
375 
376   CompletionOnceCallback callback_for_connected_callback;
377   transaction->SetConnectedCallback(base::BindLambdaForTesting(
378       [&](const TransportInfo& info, CompletionOnceCallback callback) -> int {
379         EXPECT_TRUE(before_network_start_callback_called);
380         EXPECT_FALSE(connected_callback_called);
381         EXPECT_FALSE(modify_request_headers_callback_called_);
382         EXPECT_FALSE(transaction_handler_called);
383 
384         connected_callback_called = true;
385         callback_for_connected_callback = std::move(callback);
386         return ERR_IO_PENDING;
387       }));
388 
389   transaction->SetModifyRequestHeadersCallback(
390       base::BindLambdaForTesting([&](HttpRequestHeaders* request_headers) {
391         EXPECT_TRUE(before_network_start_callback_called);
392         EXPECT_TRUE(connected_callback_called);
393         EXPECT_FALSE(modify_request_headers_callback_called_);
394         EXPECT_FALSE(transaction_handler_called);
395 
396         modify_request_headers_callback_called_ = true;
397       }));
398 
399   EXPECT_FALSE(before_network_start_callback_called);
400   TestCompletionCallback start_callback;
401   ASSERT_THAT(transaction->Start(&request, start_callback.callback(),
402                                  NetLogWithSource()),
403               test::IsError(ERR_IO_PENDING));
404 
405   EXPECT_TRUE(before_network_start_callback_called);
406 
407   EXPECT_FALSE(connected_callback_called);
408   transaction->ResumeNetworkStart();
409   RunUntilIdle();
410   EXPECT_TRUE(connected_callback_called);
411 
412   EXPECT_FALSE(modify_request_headers_callback_called_);
413   std::move(callback_for_connected_callback).Run(OK);
414   EXPECT_TRUE(modify_request_headers_callback_called_);
415   EXPECT_TRUE(transaction_handler_called);
416 
417   EXPECT_TRUE(start_callback.have_result());
418   EXPECT_THAT(start_callback.WaitForResult(), test::IsError(OK));
419 }
420 
421 }  // namespace net
422