blob: 9a7b12e095a6cbbeed3c669dce980eace61c7c67 [file] [log] [blame]
// Copyright 2022 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "cobalt/xhr/fetch_buffer_pool.h"
#include <vector>
#include "cobalt/script/array_buffer.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cobalt {
namespace xhr {
namespace {
void FillTestData(std::vector<uint8_t>* buffer) {
for (size_t i = 0; i < buffer->size(); ++i) {
buffer->at(i) = static_cast<char>(i);
}
}
void AppendBuffersTo(
const std::vector<script::PreallocatedArrayBufferData>& sources,
std::vector<uint8_t>* destination) {
ASSERT_NE(destination, nullptr);
for (const auto& buffer : sources) {
destination->insert(destination->end(), buffer.data(),
buffer.data() + buffer.byte_length());
}
}
TEST(FetchBufferPoolTest, Empty) {
FetchBufferPool empty_buffer_pool;
EXPECT_EQ(empty_buffer_pool.GetSize(), 0);
std::vector<script::PreallocatedArrayBufferData> buffers;
empty_buffer_pool.ResetAndReturnAsArrayBuffers(false, &buffers);
EXPECT_TRUE(buffers.empty());
empty_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
EXPECT_TRUE(buffers.empty());
empty_buffer_pool.Write(nullptr, 0); // still empty
EXPECT_EQ(empty_buffer_pool.GetSize(), 0);
empty_buffer_pool.ResetAndReturnAsArrayBuffers(false, &buffers);
EXPECT_TRUE(buffers.empty());
empty_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
EXPECT_TRUE(buffers.empty());
}
TEST(FetchBufferPoolTest, SunnyDay) {
FetchBufferPool fetch_buffer_pool;
std::vector<uint8_t> source_buffer(1024 * 1024 + 1023);
FillTestData(&source_buffer);
std::vector<uint8_t> reference_buffer;
for (int i = 0; i < 10; ++i) {
fetch_buffer_pool.Write(source_buffer.data(),
static_cast<int>(source_buffer.size()));
reference_buffer.insert(reference_buffer.end(), source_buffer.begin(),
source_buffer.end());
}
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
ASSERT_FALSE(buffers.empty());
ASSERT_EQ(fetch_buffer_pool.GetSize(), 0);
std::vector<uint8_t> collected_buffer;
AppendBuffersTo(buffers, &collected_buffer);
ASSERT_EQ(collected_buffer, reference_buffer);
}
TEST(FetchBufferPoolTest, Clear) {
FetchBufferPool fetch_buffer_pool;
std::vector<uint8_t> source_buffer(1024);
FillTestData(&source_buffer);
fetch_buffer_pool.Write(source_buffer.data(),
static_cast<int>(source_buffer.size()));
EXPECT_EQ(fetch_buffer_pool.GetSize(), source_buffer.size());
fetch_buffer_pool.Clear();
EXPECT_EQ(fetch_buffer_pool.GetSize(), 0);
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(false, &buffers);
ASSERT_TRUE(buffers.empty());
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
ASSERT_TRUE(buffers.empty());
}
TEST(FetchBufferPoolTest, IncrementalWriteAndRead) {
FetchBufferPool fetch_buffer_pool;
std::vector<uint8_t> source_buffer(4097);
FillTestData(&source_buffer);
std::vector<uint8_t> reference_buffer;
std::vector<uint8_t> collected_buffer;
while (reference_buffer.size() < 1024 * 1024 * 10) {
int bytes_to_write =
static_cast<int>((reference_buffer.size() + 1) % source_buffer.size());
fetch_buffer_pool.Write(source_buffer.data(), bytes_to_write);
reference_buffer.insert(reference_buffer.end(), source_buffer.begin(),
source_buffer.begin() + bytes_to_write);
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(false, &buffers);
ASSERT_FALSE(buffers.empty());
AppendBuffersTo(buffers, &collected_buffer);
}
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
ASSERT_EQ(fetch_buffer_pool.GetSize(), 0);
AppendBuffersTo(buffers, &collected_buffer);
ASSERT_EQ(collected_buffer, reference_buffer);
}
TEST(FetchBufferPoolTest, SingleLargeWrite) {
FetchBufferPool fetch_buffer_pool;
std::vector<uint8_t> large_source_buffer(1024 * 1024 * 16 + 1023);
FillTestData(&large_source_buffer);
{
std::vector<uint8_t> reference_buffer;
std::vector<uint8_t> collected_buffer;
fetch_buffer_pool.Write(large_source_buffer.data(),
static_cast<int>(large_source_buffer.size()));
reference_buffer.insert(reference_buffer.end(), large_source_buffer.begin(),
large_source_buffer.end());
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
ASSERT_FALSE(buffers.empty());
ASSERT_EQ(fetch_buffer_pool.GetSize(), 0);
AppendBuffersTo(buffers, &collected_buffer);
ASSERT_EQ(collected_buffer, reference_buffer);
}
}
TEST(FetchBufferPoolTest, MixedSizeWrites) {
FetchBufferPool fetch_buffer_pool;
std::vector<uint8_t> small_source_buffer(1023);
std::vector<uint8_t> large_source_buffer(1024 * 1024 * 16 + 1023);
FillTestData(&small_source_buffer);
FillTestData(&large_source_buffer);
{
// Small then large
std::vector<uint8_t> reference_buffer;
std::vector<uint8_t> collected_buffer;
fetch_buffer_pool.Write(small_source_buffer.data(),
static_cast<int>(small_source_buffer.size()));
reference_buffer.insert(reference_buffer.end(), small_source_buffer.begin(),
small_source_buffer.end());
fetch_buffer_pool.Write(large_source_buffer.data(),
static_cast<int>(large_source_buffer.size()));
reference_buffer.insert(reference_buffer.end(), large_source_buffer.begin(),
large_source_buffer.end());
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(false, &buffers);
ASSERT_FALSE(buffers.empty());
AppendBuffersTo(buffers, &collected_buffer);
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
ASSERT_EQ(fetch_buffer_pool.GetSize(), 0);
AppendBuffersTo(buffers, &collected_buffer);
ASSERT_EQ(collected_buffer, reference_buffer);
}
{
// Large then small
std::vector<uint8_t> reference_buffer;
std::vector<uint8_t> collected_buffer;
fetch_buffer_pool.Write(large_source_buffer.data(),
static_cast<int>(large_source_buffer.size()));
reference_buffer.insert(reference_buffer.end(), large_source_buffer.begin(),
large_source_buffer.end());
fetch_buffer_pool.Write(small_source_buffer.data(),
static_cast<int>(small_source_buffer.size()));
reference_buffer.insert(reference_buffer.end(), small_source_buffer.begin(),
small_source_buffer.end());
std::vector<script::PreallocatedArrayBufferData> buffers;
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(false, &buffers);
ASSERT_FALSE(buffers.empty());
AppendBuffersTo(buffers, &collected_buffer);
fetch_buffer_pool.ResetAndReturnAsArrayBuffers(true, &buffers);
ASSERT_EQ(fetch_buffer_pool.GetSize(), 0);
AppendBuffersTo(buffers, &collected_buffer);
ASSERT_EQ(collected_buffer, reference_buffer);
}
}
} // namespace
} // namespace xhr
} // namespace cobalt