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#include "net/server/http_connection.h"
6
7#include <string>
8
9#include "base/memory/ref_counted.h"
10#include "base/strings/string_piece.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13namespace net {
14namespace {
15
16std::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
24TEST(HttpConnectionTest, ReadIOBuffer_SetCapacity) {
25  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
26      new 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
40TEST(HttpConnectionTest, ReadIOBuffer_SetCapacity_WithData) {
41  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
42      new 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            base::StringPiece(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            base::StringPiece(buffer->StartOfBuffer(), buffer->GetSize()));
71}
72
73TEST(HttpConnectionTest, ReadIOBuffer_IncreaseCapacity) {
74  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
75      new 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
108TEST(HttpConnectionTest, ReadIOBuffer_IncreaseCapacity_WithData) {
109  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
110      new 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            base::StringPiece(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            base::StringPiece(buffer->StartOfBuffer(), buffer->GetSize()));
144}
145
146TEST(HttpConnectionTest, ReadIOBuffer_DidRead_DidConsume) {
147  scoped_refptr<HttpConnection::ReadIOBuffer> buffer(
148      new 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
232TEST(HttpConnectionTest, QueuedWriteIOBuffer_Append_DidConsume) {
233  scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer(
234      new 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, base::StringPiece(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, base::StringPiece(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            base::StringPiece(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,
281            base::StringPiece(buffer->data(), buffer->GetSizeToWrite()));
282
283  // Consume second data fully.
284  buffer->DidConsume(kData2.size());
285  EXPECT_TRUE(buffer->IsEmpty());
286  EXPECT_EQ(0, buffer->GetSizeToWrite());
287  EXPECT_EQ(0, buffer->total_size());
288}
289
290TEST(HttpConnectionTest, QueuedWriteIOBuffer_TotalSizeLimit) {
291  scoped_refptr<HttpConnection::QueuedWriteIOBuffer> buffer(
292      new HttpConnection::QueuedWriteIOBuffer());
293  EXPECT_EQ(HttpConnection::QueuedWriteIOBuffer::kDefaultMaxBufferSize + 0,
294            buffer->max_buffer_size());
295
296  // Set total size limit very small.
297  buffer->set_max_buffer_size(10);
298
299  const int kDataLength = 4;
300  const std::string kData(kDataLength, 'd');
301  EXPECT_TRUE(buffer->Append(kData));
302  EXPECT_EQ(kDataLength, buffer->total_size());
303  EXPECT_TRUE(buffer->Append(kData));
304  EXPECT_EQ(kDataLength * 2, buffer->total_size());
305
306  // Cannot append more data because it exceeds the limit.
307  EXPECT_FALSE(buffer->Append(kData));
308  EXPECT_EQ(kDataLength * 2, buffer->total_size());
309
310  // Consume data partially.
311  const int kConsumedLength = 2;
312  buffer->DidConsume(kConsumedLength);
313  EXPECT_EQ(kDataLength * 2 - kConsumedLength, buffer->total_size());
314
315  // Can add more data.
316  EXPECT_TRUE(buffer->Append(kData));
317  EXPECT_EQ(kDataLength * 3 - kConsumedLength, buffer->total_size());
318
319  // Cannot append more data because it exceeds the limit.
320  EXPECT_FALSE(buffer->Append(kData));
321  EXPECT_EQ(kDataLength * 3 - kConsumedLength, buffer->total_size());
322
323  // Enlarge limit.
324  buffer->set_max_buffer_size(20);
325  // Can add more data.
326  EXPECT_TRUE(buffer->Append(kData));
327  EXPECT_EQ(kDataLength * 4 - kConsumedLength, buffer->total_size());
328}
329
330}  // namespace
331}  // namespace net
332