xref: /aosp_15_r20/external/cronet/net/server/http_connection_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2014 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/server/http_connection.h"
6 
7 #include <string>
8 #include <string_view>
9 
10 #include "base/memory/ref_counted.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12 
13 namespace net {
14 namespace {
15 
GetTestString(int size)16 std::string GetTestString(int size) {
17   std::string test_string;
18   for (int i = 0; i < size; ++i) {
19     test_string.push_back('A' + (i % 26));
20   }
21   return test_string;
22 }
23 
TEST(HttpConnectionTest,ReadIOBuffer_SetCapacity)24 TEST(HttpConnectionTest, ReadIOBuffer_SetCapacity) {
25   scoped_refptr<HttpConnection::ReadIOBuffer> buffer =
26       base::MakeRefCounted<HttpConnection::ReadIOBuffer>();
27   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
28             buffer->GetCapacity());
29   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
30             buffer->RemainingCapacity());
31   EXPECT_EQ(0, buffer->GetSize());
32 
33   const int kNewCapacity = HttpConnection::ReadIOBuffer::kInitialBufSize + 128;
34   buffer->SetCapacity(kNewCapacity);
35   EXPECT_EQ(kNewCapacity, buffer->GetCapacity());
36   EXPECT_EQ(kNewCapacity, buffer->RemainingCapacity());
37   EXPECT_EQ(0, buffer->GetSize());
38 }
39 
TEST(HttpConnectionTest,ReadIOBuffer_SetCapacity_WithData)40 TEST(HttpConnectionTest, ReadIOBuffer_SetCapacity_WithData) {
41   scoped_refptr<HttpConnection::ReadIOBuffer> buffer =
42       base::MakeRefCounted<HttpConnection::ReadIOBuffer>();
43   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
44             buffer->GetCapacity());
45   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
46             buffer->RemainingCapacity());
47 
48   // Write arbitrary data up to kInitialBufSize.
49   const std::string kReadData(
50       GetTestString(HttpConnection::ReadIOBuffer::kInitialBufSize));
51   memcpy(buffer->data(), kReadData.data(), kReadData.size());
52   buffer->DidRead(kReadData.size());
53   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
54             buffer->GetCapacity());
55   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize -
56                 static_cast<int>(kReadData.size()),
57             buffer->RemainingCapacity());
58   EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
59   EXPECT_EQ(kReadData,
60             std::string_view(buffer->StartOfBuffer(), buffer->GetSize()));
61 
62   // Check if read data in the buffer is same after SetCapacity().
63   const int kNewCapacity = HttpConnection::ReadIOBuffer::kInitialBufSize + 128;
64   buffer->SetCapacity(kNewCapacity);
65   EXPECT_EQ(kNewCapacity, buffer->GetCapacity());
66   EXPECT_EQ(kNewCapacity - static_cast<int>(kReadData.size()),
67             buffer->RemainingCapacity());
68   EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
69   EXPECT_EQ(kReadData,
70             std::string_view(buffer->StartOfBuffer(), buffer->GetSize()));
71 }
72 
TEST(HttpConnectionTest,ReadIOBuffer_IncreaseCapacity)73 TEST(HttpConnectionTest, ReadIOBuffer_IncreaseCapacity) {
74   scoped_refptr<HttpConnection::ReadIOBuffer> buffer =
75       base::MakeRefCounted<HttpConnection::ReadIOBuffer>();
76   EXPECT_TRUE(buffer->IncreaseCapacity());
77   const int kExpectedInitialBufSize =
78       HttpConnection::ReadIOBuffer::kInitialBufSize *
79       HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor;
80   EXPECT_EQ(kExpectedInitialBufSize, buffer->GetCapacity());
81   EXPECT_EQ(kExpectedInitialBufSize, buffer->RemainingCapacity());
82   EXPECT_EQ(0, buffer->GetSize());
83 
84   // Increase capacity until it fails.
85   while (buffer->IncreaseCapacity());
86   EXPECT_FALSE(buffer->IncreaseCapacity());
87   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
88             buffer->max_buffer_size());
89   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
90             buffer->GetCapacity());
91 
92   // Enlarge capacity limit.
93   buffer->set_max_buffer_size(buffer->max_buffer_size() * 2);
94   EXPECT_TRUE(buffer->IncreaseCapacity());
95   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize *
96                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
97             buffer->GetCapacity());
98 
99   // Shrink capacity limit. It doesn't change capacity itself.
100   buffer->set_max_buffer_size(
101       HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize / 2);
102   EXPECT_FALSE(buffer->IncreaseCapacity());
103   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize *
104                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
105             buffer->GetCapacity());
106 }
107 
TEST(HttpConnectionTest,ReadIOBuffer_IncreaseCapacity_WithData)108 TEST(HttpConnectionTest, ReadIOBuffer_IncreaseCapacity_WithData) {
109   scoped_refptr<HttpConnection::ReadIOBuffer> buffer =
110       base::MakeRefCounted<HttpConnection::ReadIOBuffer>();
111   EXPECT_TRUE(buffer->IncreaseCapacity());
112   const int kExpectedInitialBufSize =
113       HttpConnection::ReadIOBuffer::kInitialBufSize *
114       HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor;
115   EXPECT_EQ(kExpectedInitialBufSize, buffer->GetCapacity());
116   EXPECT_EQ(kExpectedInitialBufSize, buffer->RemainingCapacity());
117   EXPECT_EQ(0, buffer->GetSize());
118 
119   // Write arbitrary data up to kExpectedInitialBufSize.
120   std::string kReadData(GetTestString(kExpectedInitialBufSize));
121   memcpy(buffer->data(), kReadData.data(), kReadData.size());
122   buffer->DidRead(kReadData.size());
123   EXPECT_EQ(kExpectedInitialBufSize, buffer->GetCapacity());
124   EXPECT_EQ(kExpectedInitialBufSize - static_cast<int>(kReadData.size()),
125             buffer->RemainingCapacity());
126   EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
127   EXPECT_EQ(kReadData,
128             std::string_view(buffer->StartOfBuffer(), buffer->GetSize()));
129 
130   // Increase capacity until it fails and check if read data in the buffer is
131   // same.
132   while (buffer->IncreaseCapacity());
133   EXPECT_FALSE(buffer->IncreaseCapacity());
134   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
135             buffer->max_buffer_size());
136   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize + 0,
137             buffer->GetCapacity());
138   EXPECT_EQ(HttpConnection::ReadIOBuffer::kDefaultMaxBufferSize -
139                 static_cast<int>(kReadData.size()),
140             buffer->RemainingCapacity());
141   EXPECT_EQ(static_cast<int>(kReadData.size()), buffer->GetSize());
142   EXPECT_EQ(kReadData,
143             std::string_view(buffer->StartOfBuffer(), buffer->GetSize()));
144 }
145 
TEST(HttpConnectionTest,ReadIOBuffer_DidRead_DidConsume)146 TEST(HttpConnectionTest, ReadIOBuffer_DidRead_DidConsume) {
147   scoped_refptr<HttpConnection::ReadIOBuffer> buffer =
148       base::MakeRefCounted<HttpConnection::ReadIOBuffer>();
149   const char* start_of_buffer = buffer->StartOfBuffer();
150   EXPECT_EQ(start_of_buffer, buffer->data());
151 
152   // Read data.
153   const int kReadLength = 128;
154   const std::string kReadData(GetTestString(kReadLength));
155   memcpy(buffer->data(), kReadData.data(), kReadLength);
156   buffer->DidRead(kReadLength);
157   // No change in total capacity.
158   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize + 0,
159             buffer->GetCapacity());
160   // Change in unused capacity because of read data.
161   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize - kReadLength,
162             buffer->RemainingCapacity());
163   EXPECT_EQ(kReadLength, buffer->GetSize());
164   // No change in start pointers of read data.
165   EXPECT_EQ(start_of_buffer, buffer->StartOfBuffer());
166   // Change in start pointer of unused buffer.
167   EXPECT_EQ(start_of_buffer + kReadLength, buffer->data());
168   // Test read data.
169   EXPECT_EQ(kReadData, std::string(buffer->StartOfBuffer(), buffer->GetSize()));
170 
171   // Consume data partially.
172   const int kConsumedLength = 32;
173   ASSERT_LT(kConsumedLength, kReadLength);
174   buffer->DidConsume(kConsumedLength);
175   // Capacity reduced because read data was too small comparing to capacity.
176   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
177                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
178             buffer->GetCapacity());
179   // Change in unused capacity because of read data.
180   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
181                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor -
182                 kReadLength + kConsumedLength,
183             buffer->RemainingCapacity());
184   // Change in read size.
185   EXPECT_EQ(kReadLength - kConsumedLength, buffer->GetSize());
186   // Start data could be changed even when capacity is reduced.
187   start_of_buffer = buffer->StartOfBuffer();
188   // Change in start pointer of unused buffer.
189   EXPECT_EQ(start_of_buffer + kReadLength - kConsumedLength, buffer->data());
190   // Change in read data.
191   EXPECT_EQ(kReadData.substr(kConsumedLength),
192             std::string(buffer->StartOfBuffer(), buffer->GetSize()));
193 
194   // Read more data.
195   const int kReadLength2 = 64;
196   buffer->DidRead(kReadLength2);
197   // No change in total capacity.
198   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
199                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
200             buffer->GetCapacity());
201   // Change in unused capacity because of read data.
202   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
203                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor -
204                 kReadLength + kConsumedLength - kReadLength2,
205             buffer->RemainingCapacity());
206   // Change in read size
207   EXPECT_EQ(kReadLength - kConsumedLength + kReadLength2, buffer->GetSize());
208   // No change in start pointer of read part.
209   EXPECT_EQ(start_of_buffer, buffer->StartOfBuffer());
210   // Change in start pointer of unused buffer.
211   EXPECT_EQ(start_of_buffer + kReadLength - kConsumedLength + kReadLength2,
212             buffer->data());
213 
214   // Consume data fully.
215   buffer->DidConsume(kReadLength - kConsumedLength + kReadLength2);
216   // Capacity reduced again because read data was too small.
217   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
218                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor /
219                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
220             buffer->GetCapacity());
221   EXPECT_EQ(HttpConnection::ReadIOBuffer::kInitialBufSize /
222                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor /
223                 HttpConnection::ReadIOBuffer::kCapacityIncreaseFactor,
224             buffer->RemainingCapacity());
225   // All reverts to initial because no data is left.
226   EXPECT_EQ(0, buffer->GetSize());
227   // Start data could be changed even when capacity is reduced.
228   start_of_buffer = buffer->StartOfBuffer();
229   EXPECT_EQ(start_of_buffer, buffer->data());
230 }
231 
TEST(HttpConnectionTest,QueuedWriteIOBuffer_Append_DidConsume)232 TEST(HttpConnectionTest, QueuedWriteIOBuffer_Append_DidConsume) {
233   scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer =
234       base::MakeRefCounted<HttpConnection::QueuedWriteIOBuffer>();
235   EXPECT_TRUE(buffer->IsEmpty());
236   EXPECT_EQ(0, buffer->GetSizeToWrite());
237   EXPECT_EQ(0, buffer->total_size());
238 
239   const std::string kData("data to write");
240   EXPECT_TRUE(buffer->Append(kData));
241   EXPECT_FALSE(buffer->IsEmpty());
242   EXPECT_EQ(static_cast<int>(kData.size()), buffer->GetSizeToWrite());
243   EXPECT_EQ(static_cast<int>(kData.size()), buffer->total_size());
244   // First data to write is same to kData.
245   EXPECT_EQ(kData, std::string_view(buffer->data(), buffer->GetSizeToWrite()));
246 
247   const std::string kData2("more data to write");
248   EXPECT_TRUE(buffer->Append(kData2));
249   EXPECT_FALSE(buffer->IsEmpty());
250   // No change in size to write.
251   EXPECT_EQ(static_cast<int>(kData.size()), buffer->GetSizeToWrite());
252   // Change in total size.
253   EXPECT_EQ(static_cast<int>(kData.size() + kData2.size()),
254             buffer->total_size());
255   // First data to write has not been changed. Same to kData.
256   EXPECT_EQ(kData, std::string_view(buffer->data(), buffer->GetSizeToWrite()));
257 
258   // Consume data partially.
259   const int kConsumedLength = kData.length() - 1;
260   buffer->DidConsume(kConsumedLength);
261   EXPECT_FALSE(buffer->IsEmpty());
262   // Change in size to write.
263   EXPECT_EQ(static_cast<int>(kData.size()) - kConsumedLength,
264             buffer->GetSizeToWrite());
265   // Change in total size.
266   EXPECT_EQ(static_cast<int>(kData.size() + kData2.size()) - kConsumedLength,
267             buffer->total_size());
268   // First data to write has shrinked.
269   EXPECT_EQ(kData.substr(kConsumedLength),
270             std::string_view(buffer->data(), buffer->GetSizeToWrite()));
271 
272   // Consume first data fully.
273   buffer->DidConsume(kData.size() - kConsumedLength);
274   EXPECT_FALSE(buffer->IsEmpty());
275   // Now, size to write is size of data added second.
276   EXPECT_EQ(static_cast<int>(kData2.size()), buffer->GetSizeToWrite());
277   // Change in total size.
278   EXPECT_EQ(static_cast<int>(kData2.size()), buffer->total_size());
279   // First data to write has changed to kData2.
280   EXPECT_EQ(kData2, std::string_view(buffer->data(), buffer->GetSizeToWrite()));
281 
282   // Consume second data fully.
283   buffer->DidConsume(kData2.size());
284   EXPECT_TRUE(buffer->IsEmpty());
285   EXPECT_EQ(0, buffer->GetSizeToWrite());
286   EXPECT_EQ(0, buffer->total_size());
287 }
288 
TEST(HttpConnectionTest,QueuedWriteIOBuffer_TotalSizeLimit)289 TEST(HttpConnectionTest, QueuedWriteIOBuffer_TotalSizeLimit) {
290   scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer =
291       base::MakeRefCounted<HttpConnection::QueuedWriteIOBuffer>();
292   EXPECT_EQ(HttpConnection::QueuedWriteIOBuffer::kDefaultMaxBufferSize + 0,
293             buffer->max_buffer_size());
294 
295   // Set total size limit very small.
296   buffer->set_max_buffer_size(10);
297 
298   const int kDataLength = 4;
299   const std::string kData(kDataLength, 'd');
300   EXPECT_TRUE(buffer->Append(kData));
301   EXPECT_EQ(kDataLength, buffer->total_size());
302   EXPECT_TRUE(buffer->Append(kData));
303   EXPECT_EQ(kDataLength * 2, buffer->total_size());
304 
305   // Cannot append more data because it exceeds the limit.
306   EXPECT_FALSE(buffer->Append(kData));
307   EXPECT_EQ(kDataLength * 2, buffer->total_size());
308 
309   // Consume data partially.
310   const int kConsumedLength = 2;
311   buffer->DidConsume(kConsumedLength);
312   EXPECT_EQ(kDataLength * 2 - kConsumedLength, buffer->total_size());
313 
314   // Can add more data.
315   EXPECT_TRUE(buffer->Append(kData));
316   EXPECT_EQ(kDataLength * 3 - kConsumedLength, buffer->total_size());
317 
318   // Cannot append more data because it exceeds the limit.
319   EXPECT_FALSE(buffer->Append(kData));
320   EXPECT_EQ(kDataLength * 3 - kConsumedLength, buffer->total_size());
321 
322   // Enlarge limit.
323   buffer->set_max_buffer_size(20);
324   // Can add more data.
325   EXPECT_TRUE(buffer->Append(kData));
326   EXPECT_EQ(kDataLength * 4 - kConsumedLength, buffer->total_size());
327 }
328 
TEST(HttpConnectionTest,QueuedWriteIOBuffer_DataPointerStability)329 TEST(HttpConnectionTest, QueuedWriteIOBuffer_DataPointerStability) {
330   // This is a regression test that makes sure that QueuedWriteIOBuffer deals
331   // with base::queue's semantics differences vs. std::queue right, and still
332   // makes sure our data() pointers are stable.
333   scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer =
334       base::MakeRefCounted<HttpConnection::QueuedWriteIOBuffer>();
335 
336   // We append a short string to make it fit within any short string
337   // optimization, so that if the underlying queue moves the std::string,
338   // the data should change.
339   buffer->Append("abcdefgh");
340 
341   // Read part of it, to make sure this handles the case of data() pointing
342   // to something other than start of string right.
343   buffer->DidConsume(3);
344   const char* old_data = buffer->data();
345   EXPECT_EQ("defgh", std::string_view(buffer->data(), 5));
346 
347   // Now append a whole bunch of other things to make the underlying queue
348   // grow, and likely need to move stuff around in memory.
349   for (int i = 0; i < 256; ++i)
350     buffer->Append("some other string data");
351 
352   // data() should still be right.
353   EXPECT_EQ("defgh", std::string_view(buffer->data(), 5));
354 
355   // ... it should also be bitwise the same, since the IOBuffer can get passed
356   // to async calls and then have Append's come in.
357   EXPECT_TRUE(buffer->data() == old_data);
358 }
359 
360 }  // namespace
361 }  // namespace net
362