xref: /aosp_15_r20/external/cronet/net/third_party/quiche/src/quiche/balsa/simple_buffer_test.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2022 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 "quiche/balsa/simple_buffer.h"
6 
7 #include <string>
8 
9 #include "absl/strings/string_view.h"
10 #include "quiche/common/platform/api/quiche_expect_bug.h"
11 #include "quiche/common/platform/api/quiche_test.h"
12 
13 namespace quiche {
14 
15 namespace test {
16 
17 namespace {
18 
19 constexpr int kMinimumSimpleBufferSize = 10;
20 
21 // Buffer full of 40 char strings.
22 const char ibuf[] = {
23     "123456789!@#$%^&*()abcdefghijklmnopqrstu"
24     "123456789!@#$%^&*()abcdefghijklmnopqrstu"
25     "123456789!@#$%^&*()abcdefghijklmnopqrstu"
26     "123456789!@#$%^&*()abcdefghijklmnopqrstu"
27     "123456789!@#$%^&*()abcdefghijklmnopqrstu"};
28 
29 }  // namespace
30 
31 class SimpleBufferTest : public QuicheTest {
32  public:
storage(SimpleBuffer & buffer)33   static char* storage(SimpleBuffer& buffer) { return buffer.storage_; }
write_idx(SimpleBuffer & buffer)34   static int write_idx(SimpleBuffer& buffer) { return buffer.write_idx_; }
read_idx(SimpleBuffer & buffer)35   static int read_idx(SimpleBuffer& buffer) { return buffer.read_idx_; }
storage_size(SimpleBuffer & buffer)36   static int storage_size(SimpleBuffer& buffer) { return buffer.storage_size_; }
37 };
38 
39 namespace {
40 
TEST_F(SimpleBufferTest,CreationWithSize)41 TEST_F(SimpleBufferTest, CreationWithSize) {
42   SimpleBuffer buffer1(5);
43   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer1));
44 
45   SimpleBuffer buffer2(25);
46   EXPECT_EQ(25, storage_size(buffer2));
47 }
48 
49 // Make sure that a zero-sized initial buffer does not throw things off.
TEST_F(SimpleBufferTest,CreationWithZeroSize)50 TEST_F(SimpleBufferTest, CreationWithZeroSize) {
51   SimpleBuffer buffer(0);
52   EXPECT_EQ(0, storage_size(buffer));
53   EXPECT_EQ(4, buffer.Write(ibuf, 4));
54   EXPECT_EQ(4, write_idx(buffer));
55   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
56   EXPECT_EQ(4, buffer.ReadableBytes());
57 }
58 
TEST_F(SimpleBufferTest,ReadZeroBytes)59 TEST_F(SimpleBufferTest, ReadZeroBytes) {
60   SimpleBuffer buffer;
61 
62   EXPECT_EQ(0, buffer.Read(nullptr, 0));
63 }
64 
TEST_F(SimpleBufferTest,WriteZeroFromNullptr)65 TEST_F(SimpleBufferTest, WriteZeroFromNullptr) {
66   SimpleBuffer buffer;
67 
68   EXPECT_EQ(0, buffer.Write(nullptr, 0));
69 }
70 
TEST(SimpleBufferExpectBug,ReserveNegativeSize)71 TEST(SimpleBufferExpectBug, ReserveNegativeSize) {
72   SimpleBuffer buffer;
73 
74   EXPECT_QUICHE_BUG(buffer.Reserve(-1), "size must not be negative");
75 }
76 
TEST(SimpleBufferExpectBug,ReadNegativeSize)77 TEST(SimpleBufferExpectBug, ReadNegativeSize) {
78   SimpleBuffer buffer;
79 
80   EXPECT_QUICHE_BUG(buffer.Read(nullptr, -1), "size must not be negative");
81 }
82 
TEST(SimpleBufferExpectBug,WriteNegativeSize)83 TEST(SimpleBufferExpectBug, WriteNegativeSize) {
84   SimpleBuffer buffer;
85 
86   EXPECT_QUICHE_BUG(buffer.Write(nullptr, -1), "size must not be negative");
87 }
88 
TEST_F(SimpleBufferTest,Basics)89 TEST_F(SimpleBufferTest, Basics) {
90   SimpleBuffer buffer;
91 
92   EXPECT_TRUE(buffer.Empty());
93   EXPECT_EQ("", buffer.GetReadableRegion());
94   EXPECT_EQ(0, storage_size(buffer));
95   EXPECT_EQ(0, read_idx(buffer));
96   EXPECT_EQ(0, write_idx(buffer));
97 
98   char* readable_ptr = nullptr;
99   int readable_size = 0;
100   buffer.GetReadablePtr(&readable_ptr, &readable_size);
101   char* writeable_ptr = nullptr;
102   int writable_size = 0;
103   buffer.GetWritablePtr(&writeable_ptr, &writable_size);
104 
105   EXPECT_EQ(storage(buffer), readable_ptr);
106   EXPECT_EQ(0, readable_size);
107   EXPECT_EQ(storage(buffer), writeable_ptr);
108   EXPECT_EQ(0, writable_size);
109   EXPECT_EQ(0, buffer.ReadableBytes());
110 
111   const SimpleBuffer buffer2;
112   EXPECT_EQ(0, buffer2.ReadableBytes());
113 }
114 
TEST_F(SimpleBufferTest,BasicWR)115 TEST_F(SimpleBufferTest, BasicWR) {
116   SimpleBuffer buffer;
117 
118   EXPECT_EQ(4, buffer.Write(ibuf, 4));
119   EXPECT_EQ(0, read_idx(buffer));
120   EXPECT_EQ(4, write_idx(buffer));
121   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
122   EXPECT_EQ(4, buffer.ReadableBytes());
123   EXPECT_EQ("1234", buffer.GetReadableRegion());
124   int bytes_written = 4;
125   EXPECT_TRUE(!buffer.Empty());
126 
127   char* readable_ptr = nullptr;
128   int readable_size = 0;
129   buffer.GetReadablePtr(&readable_ptr, &readable_size);
130   char* writeable_ptr = nullptr;
131   int writable_size = 0;
132   buffer.GetWritablePtr(&writeable_ptr, &writable_size);
133 
134   EXPECT_EQ(storage(buffer), readable_ptr);
135   EXPECT_EQ(4, readable_size);
136   EXPECT_EQ(storage(buffer) + 4, writeable_ptr);
137   EXPECT_EQ(6, writable_size);
138 
139   char obuf[ABSL_ARRAYSIZE(ibuf)];
140   int bytes_read = 0;
141   EXPECT_EQ(4, buffer.Read(obuf + bytes_read, 40));
142   EXPECT_EQ(0, read_idx(buffer));
143   EXPECT_EQ(0, write_idx(buffer));
144   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
145   EXPECT_EQ(0, buffer.ReadableBytes());
146   EXPECT_EQ("", buffer.GetReadableRegion());
147   bytes_read += 4;
148   EXPECT_TRUE(buffer.Empty());
149   buffer.GetReadablePtr(&readable_ptr, &readable_size);
150   buffer.GetWritablePtr(&writeable_ptr, &writable_size);
151   EXPECT_EQ(storage(buffer), readable_ptr);
152   EXPECT_EQ(0, readable_size);
153   EXPECT_EQ(storage(buffer), writeable_ptr);
154   EXPECT_EQ(kMinimumSimpleBufferSize, writable_size);
155 
156   EXPECT_EQ(bytes_written, bytes_read);
157   for (int i = 0; i < bytes_read; ++i) {
158     EXPECT_EQ(obuf[i], ibuf[i]);
159   }
160 
161   // More R/W tests.
162   EXPECT_EQ(10, buffer.Write(ibuf + bytes_written, 10));
163   EXPECT_EQ(0, read_idx(buffer));
164   EXPECT_EQ(10, write_idx(buffer));
165   EXPECT_EQ(10, storage_size(buffer));
166   EXPECT_EQ(10, buffer.ReadableBytes());
167   bytes_written += 10;
168 
169   EXPECT_TRUE(!buffer.Empty());
170 
171   EXPECT_EQ(6, buffer.Read(obuf + bytes_read, 6));
172   EXPECT_EQ(6, read_idx(buffer));
173   EXPECT_EQ(10, write_idx(buffer));
174   EXPECT_EQ(10, storage_size(buffer));
175   EXPECT_EQ(4, buffer.ReadableBytes());
176   bytes_read += 6;
177 
178   EXPECT_TRUE(!buffer.Empty());
179 
180   EXPECT_EQ(4, buffer.Read(obuf + bytes_read, 7));
181   EXPECT_EQ(0, read_idx(buffer));
182   EXPECT_EQ(0, write_idx(buffer));
183   EXPECT_EQ(10, storage_size(buffer));
184   EXPECT_EQ(0, buffer.ReadableBytes());
185   bytes_read += 4;
186 
187   EXPECT_TRUE(buffer.Empty());
188 
189   EXPECT_EQ(bytes_written, bytes_read);
190   for (int i = 0; i < bytes_read; ++i) {
191     EXPECT_EQ(obuf[i], ibuf[i]);
192   }
193 }
194 
TEST_F(SimpleBufferTest,Reserve)195 TEST_F(SimpleBufferTest, Reserve) {
196   SimpleBuffer buffer;
197   EXPECT_EQ(0, storage_size(buffer));
198 
199   buffer.WriteString("foo");
200   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
201 
202   // Reserve by expanding the buffer.
203   buffer.Reserve(kMinimumSimpleBufferSize + 1);
204   EXPECT_EQ(2 * kMinimumSimpleBufferSize, storage_size(buffer));
205 
206   buffer.Clear();
207   buffer.AdvanceWritablePtr(kMinimumSimpleBufferSize);
208   buffer.AdvanceReadablePtr(kMinimumSimpleBufferSize - 2);
209   EXPECT_EQ(kMinimumSimpleBufferSize, write_idx(buffer));
210   EXPECT_EQ(2 * kMinimumSimpleBufferSize, storage_size(buffer));
211 
212   // Reserve by moving data around.  `storage_size` does not change.
213   buffer.Reserve(kMinimumSimpleBufferSize + 1);
214   EXPECT_EQ(2, write_idx(buffer));
215   EXPECT_EQ(2 * kMinimumSimpleBufferSize, storage_size(buffer));
216 }
217 
TEST_F(SimpleBufferTest,Extend)218 TEST_F(SimpleBufferTest, Extend) {
219   SimpleBuffer buffer;
220 
221   // Test a write which should not extend the buffer.
222   EXPECT_EQ(7, buffer.Write(ibuf, 7));
223   EXPECT_EQ(0, read_idx(buffer));
224   EXPECT_EQ(7, write_idx(buffer));
225   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
226   EXPECT_EQ(7, buffer.ReadableBytes());
227   EXPECT_EQ(0, read_idx(buffer));
228   EXPECT_EQ(7, write_idx(buffer));
229   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
230   EXPECT_EQ(7, buffer.ReadableBytes());
231   int bytes_written = 7;
232 
233   // Test a write which should extend the buffer.
234   EXPECT_EQ(4, buffer.Write(ibuf + bytes_written, 4));
235   EXPECT_EQ(0, read_idx(buffer));
236   EXPECT_EQ(11, write_idx(buffer));
237   EXPECT_EQ(20, storage_size(buffer));
238   EXPECT_EQ(11, buffer.ReadableBytes());
239   bytes_written += 4;
240 
241   char obuf[ABSL_ARRAYSIZE(ibuf)];
242   EXPECT_EQ(11, buffer.Read(obuf, 11));
243   EXPECT_EQ(0, read_idx(buffer));
244   EXPECT_EQ(0, write_idx(buffer));
245   EXPECT_EQ(20, storage_size(buffer));
246   EXPECT_EQ(0, read_idx(buffer));
247   EXPECT_EQ(0, write_idx(buffer));
248   EXPECT_EQ(0, buffer.ReadableBytes());
249 
250   const int bytes_read = 11;
251   EXPECT_EQ(bytes_written, bytes_read);
252   for (int i = 0; i < bytes_read; ++i) {
253     EXPECT_EQ(obuf[i], ibuf[i]);
254   }
255 }
256 
TEST_F(SimpleBufferTest,Clear)257 TEST_F(SimpleBufferTest, Clear) {
258   SimpleBuffer buffer;
259 
260   buffer.Clear();
261 
262   EXPECT_EQ(0, read_idx(buffer));
263   EXPECT_EQ(0, write_idx(buffer));
264   EXPECT_EQ(0, storage_size(buffer));
265   EXPECT_EQ(0, buffer.ReadableBytes());
266 
267   buffer.WriteString("foo");
268   buffer.Clear();
269 
270   EXPECT_EQ(0, read_idx(buffer));
271   EXPECT_EQ(0, write_idx(buffer));
272   EXPECT_EQ(kMinimumSimpleBufferSize, storage_size(buffer));
273   EXPECT_EQ(0, buffer.ReadableBytes());
274 }
275 
TEST_F(SimpleBufferTest,LongWrite)276 TEST_F(SimpleBufferTest, LongWrite) {
277   SimpleBuffer buffer;
278 
279   std::string s1 = "HTTP/1.1 500 Service Unavailable";
280   buffer.Write(s1.data(), s1.size());
281   buffer.Write("\r\n", 2);
282   std::string key = "Connection";
283   std::string value = "close";
284   buffer.Write(key.data(), key.size());
285   buffer.Write(": ", 2);
286   buffer.Write(value.data(), value.size());
287   buffer.Write("\r\n", 2);
288   buffer.Write("\r\n", 2);
289   std::string message =
290       "<html><head>\n"
291       "<meta http-equiv=\"content-type\""
292       " content=\"text/html;charset=us-ascii\">\n"
293       "<style><!--\n"
294       "body {font-family: arial,sans-serif}\n"
295       "div.nav {margin-top: 1ex}\n"
296       "div.nav A {font-size: 10pt; font-family: arial,sans-serif}\n"
297       "span.nav {font-size: 10pt; font-family: arial,sans-serif;"
298       " font-weight: bold}\n"
299       "div.nav A,span.big {font-size: 12pt; color: #0000cc}\n"
300       "div.nav A {font-size: 10pt; color: black}\n"
301       "A.l:link {color: #6f6f6f}\n"
302       "A.u:link {color: green}\n"
303       "//--></style>\n"
304       "</head>\n"
305       "<body text=#000000 bgcolor=#ffffff>\n"
306       "<table border=0 cellpadding=2 cellspacing=0 width=100%>"
307       "<tr><td rowspan=3 width=1% nowrap>\n"
308       "<b>"
309       "<font face=times color=#0039b6 size=10>G</font>"
310       "<font face=times color=#c41200 size=10>o</font>"
311       "<font face=times color=#f3c518 size=10>o</font>"
312       "<font face=times color=#0039b6 size=10>g</font>"
313       "<font face=times color=#30a72f size=10>l</font>"
314       "<font face=times color=#c41200 size=10>e</font>"
315       "&nbsp;&nbsp;</b>\n"
316       "<td>&nbsp;</td></tr>\n"
317       "<tr><td bgcolor=#3366cc><font face=arial,sans-serif color=#ffffff>"
318       " <b>Error</b></td></tr>\n"
319       "<tr><td>&nbsp;</td></tr></table>\n"
320       "<blockquote>\n"
321       "<H1> Internal Server Error</H1>\n"
322       " This server was unable to complete the request\n"
323       "<p></blockquote>\n"
324       "<table width=100% cellpadding=0 cellspacing=0>"
325       "<tr><td bgcolor=#3366cc><img alt=\"\" width=1 height=4></td></tr>"
326       "</table>"
327       "</body></html>\n";
328   buffer.Write(message.data(), message.size());
329   const std::string correct_result =
330       "HTTP/1.1 500 Service Unavailable\r\n"
331       "Connection: close\r\n"
332       "\r\n"
333       "<html><head>\n"
334       "<meta http-equiv=\"content-type\""
335       " content=\"text/html;charset=us-ascii\">\n"
336       "<style><!--\n"
337       "body {font-family: arial,sans-serif}\n"
338       "div.nav {margin-top: 1ex}\n"
339       "div.nav A {font-size: 10pt; font-family: arial,sans-serif}\n"
340       "span.nav {font-size: 10pt; font-family: arial,sans-serif;"
341       " font-weight: bold}\n"
342       "div.nav A,span.big {font-size: 12pt; color: #0000cc}\n"
343       "div.nav A {font-size: 10pt; color: black}\n"
344       "A.l:link {color: #6f6f6f}\n"
345       "A.u:link {color: green}\n"
346       "//--></style>\n"
347       "</head>\n"
348       "<body text=#000000 bgcolor=#ffffff>\n"
349       "<table border=0 cellpadding=2 cellspacing=0 width=100%>"
350       "<tr><td rowspan=3 width=1% nowrap>\n"
351       "<b>"
352       "<font face=times color=#0039b6 size=10>G</font>"
353       "<font face=times color=#c41200 size=10>o</font>"
354       "<font face=times color=#f3c518 size=10>o</font>"
355       "<font face=times color=#0039b6 size=10>g</font>"
356       "<font face=times color=#30a72f size=10>l</font>"
357       "<font face=times color=#c41200 size=10>e</font>"
358       "&nbsp;&nbsp;</b>\n"
359       "<td>&nbsp;</td></tr>\n"
360       "<tr><td bgcolor=#3366cc><font face=arial,sans-serif color=#ffffff>"
361       " <b>Error</b></td></tr>\n"
362       "<tr><td>&nbsp;</td></tr></table>\n"
363       "<blockquote>\n"
364       "<H1> Internal Server Error</H1>\n"
365       " This server was unable to complete the request\n"
366       "<p></blockquote>\n"
367       "<table width=100% cellpadding=0 cellspacing=0>"
368       "<tr><td bgcolor=#3366cc><img alt=\"\" width=1 height=4></td></tr>"
369       "</table>"
370       "</body></html>\n";
371   EXPECT_EQ(correct_result, buffer.GetReadableRegion());
372 }
373 
TEST_F(SimpleBufferTest,ReleaseAsSlice)374 TEST_F(SimpleBufferTest, ReleaseAsSlice) {
375   SimpleBuffer buffer;
376 
377   buffer.WriteString("abc");
378   SimpleBuffer::ReleasedBuffer released = buffer.Release();
379   EXPECT_EQ("abc", absl::string_view(released.buffer.get(), released.size));
380 
381   char* readable_ptr = nullptr;
382   int readable_size = 0;
383   buffer.GetReadablePtr(&readable_ptr, &readable_size);
384   EXPECT_EQ(nullptr, readable_ptr);
385   EXPECT_EQ(0, readable_size);
386 
387   buffer.WriteString("def");
388   released = buffer.Release();
389   buffer.GetReadablePtr(&readable_ptr, &readable_size);
390   EXPECT_EQ(nullptr, readable_ptr);
391   EXPECT_EQ(0, readable_size);
392   EXPECT_EQ("def", absl::string_view(released.buffer.get(), released.size));
393 }
394 
TEST_F(SimpleBufferTest,EmptyBufferReleaseAsSlice)395 TEST_F(SimpleBufferTest, EmptyBufferReleaseAsSlice) {
396   SimpleBuffer buffer;
397   char* readable_ptr = nullptr;
398   int readable_size = 0;
399 
400   SimpleBuffer::ReleasedBuffer released = buffer.Release();
401   buffer.GetReadablePtr(&readable_ptr, &readable_size);
402   EXPECT_EQ(nullptr, readable_ptr);
403   EXPECT_EQ(0, readable_size);
404   EXPECT_TRUE(released.buffer == nullptr);
405   EXPECT_EQ(released.size, 0u);
406 }
407 
408 }  // namespace
409 
410 }  // namespace test
411 
412 }  // namespace quiche
413