Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(255)

Side by Side Diff: net/quic/iovector_test.cc

Issue 2193073003: Move shared files in net/quic/ into net/quic/core/ (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: io_thread_unittest.cc Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/quic/iovector.cc ('k') | net/quic/proto/cached_network_parameters.proto » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 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/quic/iovector.h"
6
7 #include <string.h>
8
9 #include <memory>
10 #include <string>
11
12 #include "net/test/gtest_util.h"
13 #include "testing/gtest/include/gtest/gtest.h"
14
15 using std::string;
16
17 namespace net {
18 namespace test {
19 namespace {
20
21 const char* const test_data[] = {
22 "test string 1, a medium size one.", "test string2",
23 "test string 3, a looooooooooooong loooooooooooooooong string"};
24
25 TEST(IOVectorTest, CopyConstructor) {
26 IOVector iov1;
27 for (size_t i = 0; i < arraysize(test_data); ++i) {
28 iov1.Append(const_cast<char*>(test_data[i]), strlen(test_data[i]));
29 }
30 IOVector iov2 = iov1;
31 EXPECT_EQ(iov2.Size(), iov1.Size());
32 for (size_t i = 0; i < iov2.Size(); ++i) {
33 EXPECT_TRUE(iov2.iovec()[i].iov_base == iov1.iovec()[i].iov_base);
34 EXPECT_EQ(iov2.iovec()[i].iov_len, iov1.iovec()[i].iov_len);
35 }
36 EXPECT_EQ(iov2.TotalBufferSize(), iov1.TotalBufferSize());
37 }
38
39 TEST(IOVectorTest, AssignmentOperator) {
40 IOVector iov1;
41 for (size_t i = 0; i < arraysize(test_data); ++i) {
42 iov1.Append(const_cast<char*>(test_data[i]), strlen(test_data[i]));
43 }
44 IOVector iov2;
45 iov2.Append(const_cast<char*>("ephemeral string"), 16);
46 // The following assignment results in a shallow copy;
47 // both IOVectors point to the same underlying data.
48 iov2 = iov1;
49 EXPECT_EQ(iov2.Size(), iov1.Size());
50 for (size_t i = 0; i < iov2.Size(); ++i) {
51 EXPECT_TRUE(iov2.iovec()[i].iov_base == iov1.iovec()[i].iov_base);
52 EXPECT_EQ(iov2.iovec()[i].iov_len, iov1.iovec()[i].iov_len);
53 }
54 EXPECT_EQ(iov2.TotalBufferSize(), iov1.TotalBufferSize());
55 }
56
57 TEST(IOVectorTest, Append) {
58 IOVector iov;
59 int length = 0;
60 const struct iovec* iov2 = iov.iovec();
61
62 ASSERT_EQ(0u, iov.Size());
63 ASSERT_TRUE(iov2 == nullptr);
64 for (size_t i = 0; i < arraysize(test_data); ++i) {
65 const int str_len = strlen(test_data[i]);
66 const int append_len = str_len / 2;
67 // This should append a new block.
68 iov.Append(const_cast<char*>(test_data[i]), append_len);
69 length += append_len;
70 ASSERT_EQ(i + 1, static_cast<size_t>(iov.Size()));
71 ASSERT_TRUE(iov.LastBlockEnd() == test_data[i] + append_len);
72 // This should just lengthen the existing block.
73 iov.Append(const_cast<char*>(test_data[i] + append_len),
74 str_len - append_len);
75 length += (str_len - append_len);
76 ASSERT_EQ(i + 1, static_cast<size_t>(iov.Size()));
77 ASSERT_TRUE(iov.LastBlockEnd() == test_data[i] + str_len);
78 }
79
80 iov2 = iov.iovec();
81 ASSERT_TRUE(iov2 != nullptr);
82 for (size_t i = 0; i < iov.Size(); ++i) {
83 ASSERT_TRUE(test_data[i] == iov2[i].iov_base);
84 ASSERT_EQ(strlen(test_data[i]), iov2[i].iov_len);
85 }
86 }
87
88 TEST(IOVectorTest, AppendIovec) {
89 IOVector iov;
90 const struct iovec test_iov[] = {{const_cast<char*>("foo"), 3},
91 {const_cast<char*>("bar"), 3},
92 {const_cast<char*>("buzzzz"), 6}};
93 iov.AppendIovec(test_iov, arraysize(test_iov));
94 for (size_t i = 0; i < arraysize(test_iov); ++i) {
95 EXPECT_EQ(test_iov[i].iov_base, iov.iovec()[i].iov_base);
96 EXPECT_EQ(test_iov[i].iov_len, iov.iovec()[i].iov_len);
97 }
98
99 // Test AppendIovecAtMostBytes.
100 iov.Clear();
101 // Stop in the middle of a block.
102 EXPECT_EQ(5u, iov.AppendIovecAtMostBytes(test_iov, arraysize(test_iov), 5));
103 EXPECT_EQ(5u, iov.TotalBufferSize());
104 iov.Append(static_cast<char*>(test_iov[1].iov_base) + 2, 1);
105 // Make sure the boundary case, where max_bytes == size of block also works.
106 EXPECT_EQ(6u, iov.AppendIovecAtMostBytes(&test_iov[2], 1, 6));
107 ASSERT_LE(arraysize(test_iov), static_cast<size_t>(iov.Size()));
108 for (size_t i = 0; i < arraysize(test_iov); ++i) {
109 EXPECT_EQ(test_iov[i].iov_base, iov.iovec()[i].iov_base);
110 EXPECT_EQ(test_iov[i].iov_len, iov.iovec()[i].iov_len);
111 }
112 }
113
114 TEST(IOVectorTest, ConsumeHalfBlocks) {
115 IOVector iov;
116 int length = 0;
117
118 for (size_t i = 0; i < arraysize(test_data); ++i) {
119 const int str_len = strlen(test_data[i]);
120 iov.Append(const_cast<char*>(test_data[i]), str_len);
121 length += str_len;
122 }
123 const char* endp = iov.LastBlockEnd();
124 for (size_t i = 0; i < arraysize(test_data); ++i) {
125 const struct iovec* iov2 = iov.iovec();
126 const size_t str_len = strlen(test_data[i]);
127 size_t tmp = str_len / 2;
128
129 ASSERT_TRUE(iov2 != nullptr);
130 ASSERT_TRUE(iov2[0].iov_base == test_data[i]);
131 ASSERT_EQ(str_len, iov2[0].iov_len);
132
133 // Consume half of the first block.
134 size_t consumed = iov.Consume(tmp);
135 ASSERT_EQ(tmp, consumed);
136 ASSERT_EQ(arraysize(test_data) - i, static_cast<size_t>(iov.Size()));
137 iov2 = iov.iovec();
138 ASSERT_TRUE(iov2 != nullptr);
139 ASSERT_TRUE(iov2[0].iov_base == test_data[i] + tmp);
140 ASSERT_EQ(iov2[0].iov_len, str_len - tmp);
141
142 // Consume the rest of the first block.
143 consumed = iov.Consume(str_len - tmp);
144 ASSERT_EQ(str_len - tmp, consumed);
145 ASSERT_EQ(arraysize(test_data) - i - 1, static_cast<size_t>(iov.Size()));
146 iov2 = iov.iovec();
147 if (iov.Size() > 0) {
148 ASSERT_TRUE(iov2 != nullptr);
149 ASSERT_TRUE(iov.LastBlockEnd() == endp);
150 } else {
151 ASSERT_TRUE(iov2 == nullptr);
152 ASSERT_TRUE(iov.LastBlockEnd() == nullptr);
153 }
154 }
155 }
156
157 TEST(IOVectorTest, ConsumeTwoAndHalfBlocks) {
158 IOVector iov;
159 int length = 0;
160
161 for (size_t i = 0; i < arraysize(test_data); ++i) {
162 const int str_len = strlen(test_data[i]);
163 iov.Append(const_cast<char*>(test_data[i]), str_len);
164 length += str_len;
165 }
166 const size_t last_len = strlen(test_data[arraysize(test_data) - 1]);
167 const size_t half_len = last_len / 2;
168
169 const char* endp = iov.LastBlockEnd();
170 size_t consumed = iov.Consume(length - half_len);
171 ASSERT_EQ(length - half_len, consumed);
172 const struct iovec* iov2 = iov.iovec();
173 ASSERT_TRUE(iov2 != nullptr);
174 ASSERT_EQ(1u, iov.Size());
175 ASSERT_TRUE(iov2[0].iov_base ==
176 test_data[arraysize(test_data) - 1] + last_len - half_len);
177 ASSERT_EQ(half_len, iov2[0].iov_len);
178 ASSERT_TRUE(iov.LastBlockEnd() == endp);
179
180 consumed = iov.Consume(half_len);
181 ASSERT_EQ(half_len, consumed);
182 iov2 = iov.iovec();
183 ASSERT_EQ(0u, iov.Size());
184 ASSERT_TRUE(iov2 == nullptr);
185 ASSERT_TRUE(iov.LastBlockEnd() == nullptr);
186 }
187
188 TEST(IOVectorTest, ConsumeTooMuch) {
189 IOVector iov;
190 int length = 0;
191
192 for (size_t i = 0; i < arraysize(test_data); ++i) {
193 const int str_len = strlen(test_data[i]);
194 iov.Append(const_cast<char*>(test_data[i]), str_len);
195 length += str_len;
196 }
197
198 int consumed = 0;
199 EXPECT_DFATAL({ consumed = iov.Consume(length + 1); },
200 "Attempting to consume 1 non-existent bytes.");
201 ASSERT_EQ(length, consumed);
202 const struct iovec* iov2 = iov.iovec();
203 ASSERT_EQ(0u, iov.Size());
204 ASSERT_TRUE(iov2 == nullptr);
205 ASSERT_TRUE(iov.LastBlockEnd() == nullptr);
206 }
207
208 TEST(IOVectorTest, ConsumeAndCopyHalfBlocks) {
209 IOVector iov;
210 int length = 0;
211
212 for (size_t i = 0; i < arraysize(test_data); ++i) {
213 const int str_len = strlen(test_data[i]);
214 iov.Append(const_cast<char*>(test_data[i]), str_len);
215 length += str_len;
216 }
217 const char* endp = iov.LastBlockEnd();
218 for (size_t i = 0; i < arraysize(test_data); ++i) {
219 const struct iovec* iov2 = iov.iovec();
220 const size_t str_len = strlen(test_data[i]);
221 size_t tmp = str_len / 2;
222
223 ASSERT_TRUE(iov2 != nullptr);
224 ASSERT_TRUE(iov2[0].iov_base == test_data[i]);
225 ASSERT_EQ(str_len, iov2[0].iov_len);
226
227 // Consume half of the first block.
228 std::unique_ptr<char[]> buffer(new char[str_len]);
229 size_t consumed = iov.ConsumeAndCopy(tmp, buffer.get());
230 EXPECT_EQ(0, memcmp(test_data[i], buffer.get(), tmp));
231 ASSERT_EQ(tmp, consumed);
232 ASSERT_EQ(arraysize(test_data) - i, static_cast<size_t>(iov.Size()));
233 iov2 = iov.iovec();
234 ASSERT_TRUE(iov2 != nullptr);
235 ASSERT_TRUE(iov2[0].iov_base == test_data[i] + tmp);
236 ASSERT_EQ(iov2[0].iov_len, str_len - tmp);
237
238 // Consume the rest of the first block.
239 consumed = iov.ConsumeAndCopy(str_len - tmp, buffer.get());
240 ASSERT_EQ(str_len - tmp, consumed);
241 ASSERT_EQ(arraysize(test_data) - i - 1, static_cast<size_t>(iov.Size()));
242 iov2 = iov.iovec();
243 if (iov.Size() > 0) {
244 ASSERT_TRUE(iov2 != nullptr);
245 ASSERT_TRUE(iov.LastBlockEnd() == endp);
246 } else {
247 ASSERT_TRUE(iov2 == nullptr);
248 ASSERT_TRUE(iov.LastBlockEnd() == nullptr);
249 }
250 }
251 }
252
253 TEST(IOVectorTest, ConsumeAndCopyTwoAndHalfBlocks) {
254 IOVector iov;
255 size_t length = 0;
256
257 for (size_t i = 0; i < arraysize(test_data); ++i) {
258 const int str_len = strlen(test_data[i]);
259 iov.Append(const_cast<char*>(test_data[i]), str_len);
260 length += str_len;
261 }
262 const size_t last_len = strlen(test_data[arraysize(test_data) - 1]);
263 const size_t half_len = last_len / 2;
264
265 const char* endp = iov.LastBlockEnd();
266 std::unique_ptr<char[]> buffer(new char[length]);
267 size_t consumed = iov.ConsumeAndCopy(length - half_len, buffer.get());
268 ASSERT_EQ(length - half_len, consumed);
269 const struct iovec* iov2 = iov.iovec();
270 ASSERT_TRUE(iov2 != nullptr);
271 ASSERT_EQ(1u, iov.Size());
272 ASSERT_TRUE(iov2[0].iov_base ==
273 test_data[arraysize(test_data) - 1] + last_len - half_len);
274 ASSERT_EQ(half_len, iov2[0].iov_len);
275 ASSERT_TRUE(iov.LastBlockEnd() == endp);
276
277 consumed = iov.Consume(half_len);
278 ASSERT_EQ(half_len, consumed);
279 iov2 = iov.iovec();
280 ASSERT_EQ(0u, iov.Size());
281 ASSERT_TRUE(iov2 == nullptr);
282 ASSERT_TRUE(iov.LastBlockEnd() == nullptr);
283 }
284
285 TEST(IOVectorTest, ConsumeAndCopyTooMuch) {
286 IOVector iov;
287 int length = 0;
288
289 for (size_t i = 0; i < arraysize(test_data); ++i) {
290 const int str_len = strlen(test_data[i]);
291 iov.Append(const_cast<char*>(test_data[i]), str_len);
292 length += str_len;
293 }
294
295 int consumed = 0;
296 std::unique_ptr<char[]> buffer(new char[length + 1]);
297 EXPECT_DFATAL({ consumed = iov.ConsumeAndCopy(length + 1, buffer.get()); },
298 "Attempting to consume 1 non-existent bytes.");
299 ASSERT_EQ(length, consumed);
300 const struct iovec* iov2 = iov.iovec();
301 ASSERT_EQ(0u, iov.Size());
302 ASSERT_TRUE(iov2 == nullptr);
303 ASSERT_TRUE(iov.LastBlockEnd() == nullptr);
304 }
305
306 TEST(IOVectorTest, Clear) {
307 IOVector iov;
308 int length = 0;
309
310 for (size_t i = 0; i < arraysize(test_data); ++i) {
311 const int str_len = strlen(test_data[i]);
312 iov.Append(const_cast<char*>(test_data[i]), str_len);
313 length += str_len;
314 }
315 const struct iovec* iov2 = iov.iovec();
316 ASSERT_TRUE(iov2 != nullptr);
317 ASSERT_EQ(arraysize(test_data), static_cast<size_t>(iov.Size()));
318
319 iov.Clear();
320 iov2 = iov.iovec();
321 ASSERT_EQ(0u, iov.Size());
322 ASSERT_TRUE(iov2 == nullptr);
323 }
324
325 TEST(IOVectorTest, Capacity) {
326 IOVector iov;
327 // Note: IOVector merges adjacent Appends() into a single iov.
328 // Therefore, if we expect final size of iov to be 3, we must insure
329 // that the items we are appending are not adjacent. To achieve that
330 // we use use an array (a[1] provides a buffer between a[0] and b[0],
331 // and makes them non-adjacent).
332 char a[2], b[2], c[2];
333 iov.Append(&a[0], 1);
334 iov.Append(&b[0], 1);
335 iov.Append(&c[0], 1);
336 ASSERT_EQ(3u, iov.Size());
337 size_t capacity = iov.Capacity();
338 EXPECT_LE(iov.Size(), capacity);
339 iov.Consume(2);
340 // The capacity should not have changed.
341 EXPECT_EQ(capacity, iov.Capacity());
342 }
343
344 TEST(IOVectorTest, Swap) {
345 IOVector iov1, iov2;
346 // See IOVector merge comment above.
347 char a[2], b[2], c[2], d[2], e[2];
348 iov1.Append(&a[0], 1);
349 iov1.Append(&b[0], 1);
350
351 iov2.Append(&c[0], 1);
352 iov2.Append(&d[0], 1);
353 iov2.Append(&e[0], 1);
354 iov1.Swap(&iov2);
355
356 ASSERT_EQ(3u, iov1.Size());
357 EXPECT_EQ(&c[0], iov1.iovec()[0].iov_base);
358 EXPECT_EQ(1u, iov1.iovec()[0].iov_len);
359 EXPECT_EQ(&d[0], iov1.iovec()[1].iov_base);
360 EXPECT_EQ(1u, iov1.iovec()[1].iov_len);
361 EXPECT_EQ(&e[0], iov1.iovec()[2].iov_base);
362 EXPECT_EQ(1u, iov1.iovec()[2].iov_len);
363
364 ASSERT_EQ(2u, iov2.Size());
365 EXPECT_EQ(&a[0], iov2.iovec()[0].iov_base);
366 EXPECT_EQ(1u, iov2.iovec()[0].iov_len);
367 EXPECT_EQ(&b[0], iov2.iovec()[1].iov_base);
368 EXPECT_EQ(1u, iov2.iovec()[1].iov_len);
369 }
370
371 } // namespace
372 } // namespace test
373 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/iovector.cc ('k') | net/quic/proto/cached_network_parameters.proto » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698