| // Copyright 2022 The Chromium Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style license that can be | |
| // found in the LICENSE file. | |
| #include "quiche/common/quiche_buffer_allocator.h" | |
| #include "absl/strings/string_view.h" | |
| #include "quiche/common/platform/api/quiche_expect_bug.h" | |
| #include "quiche/common/platform/api/quiche_test.h" | |
| #include "quiche/common/simple_buffer_allocator.h" | |
| #include "quiche/common/test_tools/quiche_test_utils.h" | |
| namespace quiche { | |
| namespace test { | |
| namespace { | |
| TEST(QuicheBuffer, CopyFromEmpty) { | |
| SimpleBufferAllocator allocator; | |
| QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, ""); | |
| EXPECT_TRUE(buffer.empty()); | |
| } | |
| TEST(QuicheBuffer, Copy) { | |
| SimpleBufferAllocator allocator; | |
| QuicheBuffer buffer = QuicheBuffer::Copy(&allocator, "foobar"); | |
| EXPECT_EQ("foobar", buffer.AsStringView()); | |
| } | |
| TEST(QuicheBuffer, CopyFromIovecZeroBytes) { | |
| const int buffer_length = 0; | |
| SimpleBufferAllocator allocator; | |
| QuicheBuffer buffer = QuicheBuffer::CopyFromIovec( | |
| &allocator, nullptr, | |
| /* iov_count = */ 0, /* iov_offset = */ 0, buffer_length); | |
| EXPECT_TRUE(buffer.empty()); | |
| constexpr absl::string_view kData("foobar"); | |
| iovec iov = MakeIOVector(kData); | |
| buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov, | |
| /* iov_count = */ 1, | |
| /* iov_offset = */ 0, buffer_length); | |
| EXPECT_TRUE(buffer.empty()); | |
| buffer = QuicheBuffer::CopyFromIovec(&allocator, &iov, | |
| /* iov_count = */ 1, | |
| /* iov_offset = */ 3, buffer_length); | |
| EXPECT_TRUE(buffer.empty()); | |
| } | |
| TEST(QuicheBuffer, CopyFromIovecSimple) { | |
| constexpr absl::string_view kData("foobar"); | |
| iovec iov = MakeIOVector(kData); | |
| SimpleBufferAllocator allocator; | |
| QuicheBuffer buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov, | |
| /* iov_count = */ 1, /* iov_offset = */ 0, | |
| /* buffer_length = */ 6); | |
| EXPECT_EQ("foobar", buffer.AsStringView()); | |
| buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov, | |
| /* iov_count = */ 1, /* iov_offset = */ 0, | |
| /* buffer_length = */ 3); | |
| EXPECT_EQ("foo", buffer.AsStringView()); | |
| buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov, | |
| /* iov_count = */ 1, /* iov_offset = */ 3, | |
| /* buffer_length = */ 3); | |
| EXPECT_EQ("bar", buffer.AsStringView()); | |
| buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov, | |
| /* iov_count = */ 1, /* iov_offset = */ 1, | |
| /* buffer_length = */ 4); | |
| EXPECT_EQ("ooba", buffer.AsStringView()); | |
| } | |
| TEST(QuicheBuffer, CopyFromIovecMultiple) { | |
| constexpr absl::string_view kData1("foo"); | |
| constexpr absl::string_view kData2("bar"); | |
| iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)}; | |
| SimpleBufferAllocator allocator; | |
| QuicheBuffer buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov[0], | |
| /* iov_count = */ 2, /* iov_offset = */ 0, | |
| /* buffer_length = */ 6); | |
| EXPECT_EQ("foobar", buffer.AsStringView()); | |
| buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov[0], | |
| /* iov_count = */ 2, /* iov_offset = */ 0, | |
| /* buffer_length = */ 3); | |
| EXPECT_EQ("foo", buffer.AsStringView()); | |
| buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov[0], | |
| /* iov_count = */ 2, /* iov_offset = */ 3, | |
| /* buffer_length = */ 3); | |
| EXPECT_EQ("bar", buffer.AsStringView()); | |
| buffer = | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov[0], | |
| /* iov_count = */ 2, /* iov_offset = */ 1, | |
| /* buffer_length = */ 4); | |
| EXPECT_EQ("ooba", buffer.AsStringView()); | |
| } | |
| TEST(QuicheBuffer, CopyFromIovecOffsetTooLarge) { | |
| constexpr absl::string_view kData1("foo"); | |
| constexpr absl::string_view kData2("bar"); | |
| iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)}; | |
| SimpleBufferAllocator allocator; | |
| EXPECT_QUICHE_BUG( | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov[0], | |
| /* iov_count = */ 2, /* iov_offset = */ 10, | |
| /* buffer_length = */ 6), | |
| "iov_offset larger than iovec total size"); | |
| } | |
| TEST(QuicheBuffer, CopyFromIovecTooManyBytesRequested) { | |
| constexpr absl::string_view kData1("foo"); | |
| constexpr absl::string_view kData2("bar"); | |
| iovec iov[] = {MakeIOVector(kData1), MakeIOVector(kData2)}; | |
| SimpleBufferAllocator allocator; | |
| EXPECT_QUICHE_BUG( | |
| QuicheBuffer::CopyFromIovec(&allocator, &iov[0], | |
| /* iov_count = */ 2, /* iov_offset = */ 2, | |
| /* buffer_length = */ 10), | |
| R"(iov_offset \+ buffer_length larger than iovec total size)"); | |
| } | |
| } // anonymous namespace | |
| } // namespace test | |
| } // namespace quiche |