// Copyright 2019 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 "platform/impl/tls_write_buffer.h" #include #include "gmock/gmock.h" #include "gtest/gtest.h" namespace openscreen { namespace { TEST(TlsWriteBufferTest, CheckBasicFunctionality) { TlsWriteBuffer buffer; constexpr size_t write_size = TlsWriteBuffer::kBufferSizeBytes / 2; uint8_t write_buffer[write_size]; std::fill_n(write_buffer, write_size, uint8_t{1}); EXPECT_TRUE(buffer.Push(write_buffer, write_size)); absl::Span readable_data = buffer.GetReadableRegion(); ASSERT_EQ(readable_data.size(), write_size); for (size_t i = 0; i < readable_data.size(); i++) { EXPECT_EQ(readable_data[i], 1); } buffer.Consume(write_size / 2); readable_data = buffer.GetReadableRegion(); ASSERT_EQ(readable_data.size(), write_size / 2); for (size_t i = 0; i < readable_data.size(); i++) { EXPECT_EQ(readable_data[i], 1); } buffer.Consume(write_size / 2); readable_data = buffer.GetReadableRegion(); ASSERT_EQ(readable_data.size(), size_t{0}); // Test that the entire buffer can be used. EXPECT_TRUE(buffer.Push(write_buffer, write_size)); EXPECT_TRUE(buffer.Push(write_buffer, write_size)); // The buffer should be 100% full at this point. Confirm that no more can be // written. EXPECT_FALSE(buffer.Push(write_buffer, write_size)); EXPECT_FALSE(buffer.Push(write_buffer, 1)); } TEST(TlsWriteBufferTest, TestWrapAround) { TlsWriteBuffer buffer; constexpr size_t buffer_size = TlsWriteBuffer::kBufferSizeBytes; uint8_t write_buffer[buffer_size]; std::fill_n(write_buffer, buffer_size, uint8_t{1}); constexpr size_t partial_buffer_size = buffer_size * 3 / 4; EXPECT_TRUE(buffer.Push(write_buffer, partial_buffer_size)); // Buffer contents should now be: |111111111111····| auto region = buffer.GetReadableRegion(); auto* const buffer_begin = region.data(); ASSERT_TRUE(buffer_begin); EXPECT_EQ(region.size(), partial_buffer_size); EXPECT_TRUE(std::all_of(region.begin(), region.end(), [](uint8_t byte) { return byte == 1; })); buffer.Consume(buffer_size / 2); // Buffer contents should now be: |········1111····| region = buffer.GetReadableRegion(); EXPECT_EQ(region.data(), buffer_begin + buffer_size / 2); EXPECT_EQ(region.size(), buffer_size / 4); EXPECT_TRUE(std::all_of(region.begin(), region.end(), [](uint8_t byte) { return byte == 1; })); std::fill_n(write_buffer, buffer_size, uint8_t{2}); EXPECT_TRUE(buffer.Push(write_buffer, buffer_size / 2)); // Buffer contents should now be: |2222····11112222| // Readable region should just be the end part. region = buffer.GetReadableRegion(); EXPECT_EQ(region.data(), buffer_begin + buffer_size / 2); EXPECT_EQ(region.size(), buffer_size / 2); EXPECT_TRUE(std::all_of(region.begin(), region.begin() + buffer_size / 4, [](uint8_t byte) { return byte == 1; })); EXPECT_TRUE(std::all_of(region.begin() + buffer_size / 4, region.end(), [](uint8_t byte) { return byte == 2; })); buffer.Consume(buffer_size / 2); // Buffer contents should now be: |2222············| region = buffer.GetReadableRegion(); EXPECT_EQ(region.data(), buffer_begin); EXPECT_EQ(region.size(), buffer_size / 4); EXPECT_TRUE(std::all_of(region.begin(), region.end(), [](uint8_t byte) { return byte == 2; })); std::fill_n(write_buffer, buffer_size, uint8_t{3}); // The following Push() fails (not enough room). EXPECT_FALSE(buffer.Push(write_buffer, buffer_size)); // Buffer contents should still be: |2222············| EXPECT_TRUE(buffer.Push(write_buffer, buffer_size * 3 / 4)); // Buffer contents should now be: |2222333333333333| EXPECT_FALSE(buffer.Push(write_buffer, buffer_size)); // Not enough room. EXPECT_FALSE(buffer.Push(write_buffer, 1)); // Not enough room. region = buffer.GetReadableRegion(); EXPECT_EQ(region.data(), buffer_begin); EXPECT_EQ(region.size(), buffer_size); EXPECT_TRUE(std::all_of(region.begin(), region.begin() + buffer_size / 4, [](uint8_t byte) { return byte == 2; })); EXPECT_TRUE(std::all_of(region.begin() + buffer_size / 4, region.end(), [](uint8_t byte) { return byte == 3; })); buffer.Consume(buffer_size); // Buffer contents should now be: |················| EXPECT_TRUE(buffer.GetReadableRegion().empty()); } } // namespace } // namespace openscreen