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/common/quiche_buffer_allocator.h"
6
7 #include "absl/strings/string_view.h"
8 #include "quiche/common/platform/api/quiche_expect_bug.h"
9 #include "quiche/common/platform/api/quiche_test.h"
10 #include "quiche/common/simple_buffer_allocator.h"
11 #include "quiche/common/test_tools/quiche_test_utils.h"
12
13 namespace quiche {
14 namespace test {
15 namespace {
16
TEST(QuicheBuffer,CopyFromEmpty)17 TEST(QuicheBuffer, CopyFromEmpty) {
18 SimpleBufferAllocator allocator;
19 QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "");
20 EXPECT_TRUE(buffer.empty());
21 }
22
TEST(QuicheBuffer,Copy)23 TEST(QuicheBuffer, Copy) {
24 SimpleBufferAllocator allocator;
25 QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "foobar");
26 EXPECT_EQ("foobar", buffer.AsStringView());
27 }
28
TEST(QuicheBuffer,CopyFromIovecZeroBytes)29 TEST(QuicheBuffer, CopyFromIovecZeroBytes) {
30 const int buffer_length = 0;
31
32 SimpleBufferAllocator allocator;
33 QuicheBuffer buffer = QuicheBuffer::CopyFromIovec(
34 &allocator, nullptr,
35 /* iov_count = */ 0, /* iov_offset = */ 0, buffer_length);
36 EXPECT_TRUE(buffer.empty());
37
38 constexpr absl::string_view kData("foobar");
39 iovec iov = MakeIOVector(kData);
40
41 buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov,
42 /* iov_count = */ 1,
43 /* iov_offset = */ 0, buffer_length);
44 EXPECT_TRUE(buffer.empty());
45
46 buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov,
47 /* iov_count = */ 1,
48 /* iov_offset = */ 3, buffer_length);
49 EXPECT_TRUE(buffer.empty());
50 }
51
TEST(QuicheBuffer,CopyFromIovecSimple)52 TEST(QuicheBuffer, CopyFromIovecSimple) {
53 constexpr absl::string_view kData("foobar");
54 iovec iov = MakeIOVector(kData);
55
56 SimpleBufferAllocator allocator;
57 QuicheBuffer buffer =
58 QuicheBuffer::CopyFromIovec(&allocator, &iov,
59 /* iov_count = */ 1, /* iov_offset = */ 0,
60 /* buffer_length = */ 6);
61 EXPECT_EQ("foobar", buffer.AsStringView());
62
63 buffer =
64 QuicheBuffer::CopyFromIovec(&allocator, &iov,
65 /* iov_count = */ 1, /* iov_offset = */ 0,
66 /* buffer_length = */ 3);
67 EXPECT_EQ("foo", buffer.AsStringView());
68
69 buffer =
70 QuicheBuffer::CopyFromIovec(&allocator, &iov,
71 /* iov_count = */ 1, /* iov_offset = */ 3,
72 /* buffer_length = */ 3);
73 EXPECT_EQ("bar", buffer.AsStringView());
74
75 buffer =
76 QuicheBuffer::CopyFromIovec(&allocator, &iov,
77 /* iov_count = */ 1, /* iov_offset = */ 1,
78 /* buffer_length = */ 4);
79 EXPECT_EQ("ooba", buffer.AsStringView());
80 }
81
TEST(QuicheBuffer,CopyFromIovecMultiple)82 TEST(QuicheBuffer, CopyFromIovecMultiple) {
83 constexpr absl::string_view kData1("foo");
84 constexpr absl::string_view kData2("bar");
85 iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
86
87 SimpleBufferAllocator allocator;
88 QuicheBuffer buffer =
89 QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
90 /* iov_count = */ 2, /* iov_offset = */ 0,
91 /* buffer_length = */ 6);
92 EXPECT_EQ("foobar", buffer.AsStringView());
93
94 buffer =
95 QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
96 /* iov_count = */ 2, /* iov_offset = */ 0,
97 /* buffer_length = */ 3);
98 EXPECT_EQ("foo", buffer.AsStringView());
99
100 buffer =
101 QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
102 /* iov_count = */ 2, /* iov_offset = */ 3,
103 /* buffer_length = */ 3);
104 EXPECT_EQ("bar", buffer.AsStringView());
105
106 buffer =
107 QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
108 /* iov_count = */ 2, /* iov_offset = */ 1,
109 /* buffer_length = */ 4);
110 EXPECT_EQ("ooba", buffer.AsStringView());
111 }
112
TEST(QuicheBuffer,CopyFromIovecOffsetTooLarge)113 TEST(QuicheBuffer, CopyFromIovecOffsetTooLarge) {
114 constexpr absl::string_view kData1("foo");
115 constexpr absl::string_view kData2("bar");
116 iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
117
118 SimpleBufferAllocator allocator;
119 EXPECT_QUICHE_BUG(
120 QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
121 /* iov_count = */ 2, /* iov_offset = */ 10,
122 /* buffer_length = */ 6),
123 "iov_offset larger than iovec total size");
124 }
125
TEST(QuicheBuffer,CopyFromIovecTooManyBytesRequested)126 TEST(QuicheBuffer, CopyFromIovecTooManyBytesRequested) {
127 constexpr absl::string_view kData1("foo");
128 constexpr absl::string_view kData2("bar");
129 iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)};
130
131 SimpleBufferAllocator allocator;
132 EXPECT_QUICHE_BUG(
133 QuicheBuffer::CopyFromIovec(&allocator, &iov[0],
134 /* iov_count = */ 2, /* iov_offset = */ 2,
135 /* buffer_length = */ 10),
136 R"(iov_offset \+ buffer_length larger than iovec total size)");
137 }
138
139 } // anonymous namespace
140 } // namespace test
141 } // namespace quiche
142