| Index: net/filter/filter_unittest.cc
|
| diff --git a/net/filter/filter_unittest.cc b/net/filter/filter_unittest.cc
|
| index 08a2861699ea913c5adacf4c8668385d6fc9ed3e..506284d65e481dace5bf04dff648efc2deebf690 100644
|
| --- a/net/filter/filter_unittest.cc
|
| +++ b/net/filter/filter_unittest.cc
|
| @@ -2,12 +2,28 @@
|
| // Use of this source code is governed by a BSD-style license that can be
|
| // found in the LICENSE file.
|
|
|
| +#include "net/base/io_buffer.h"
|
| #include "net/filter/filter.h"
|
| #include "net/filter/mock_filter_context.h"
|
| #include "testing/gtest/include/gtest/gtest.h"
|
|
|
| namespace net {
|
|
|
| +namespace {
|
| +
|
| +class PassThroughFilter : public Filter {
|
| + public:
|
| + PassThroughFilter() {}
|
| +
|
| + FilterStatus ReadFilteredData(char* dest_buffer, int* dest_len) override {
|
| + return CopyOut(dest_buffer, dest_len);
|
| + }
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(PassThroughFilter);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| class FilterTest : public testing::Test {
|
| };
|
|
|
| @@ -364,4 +380,68 @@ TEST(FilterTest, SupportedMimeGzip) {
|
| EXPECT_TRUE(encoding_types.empty());
|
| }
|
|
|
| -} // namespace net
|
| +// Make sure a series of three pass-through filters copies the data cleanly.
|
| +// Regression test for http://crbug.com/418975.
|
| +TEST(FilterTest, ThreeFilterChain) {
|
| + scoped_ptr<PassThroughFilter> filter1(new PassThroughFilter);
|
| + scoped_ptr<PassThroughFilter> filter2(new PassThroughFilter);
|
| + scoped_ptr<PassThroughFilter> filter3(new PassThroughFilter);
|
| +
|
| + filter1->InitBuffer(32 * 1024);
|
| + filter2->InitBuffer(32 * 1024);
|
| + filter3->InitBuffer(32 * 1024);
|
| +
|
| + filter2->next_filter_ = filter3.Pass();
|
| + filter1->next_filter_ = filter2.Pass();
|
| +
|
| + // Initialize the input array with a varying byte sequence.
|
| + const size_t input_array_size = 64 * 1024;
|
| + char input_array[input_array_size];
|
| + size_t read_array_index = 0;
|
| + for (size_t i = 0; i < input_array_size; i++) {
|
| + input_array[i] = i % 113;
|
| + }
|
| +
|
| + const size_t output_array_size = 4 * 1024;
|
| + char output_array[output_array_size];
|
| +
|
| + size_t compare_array_index = 0;
|
| +
|
| + do {
|
| + // Read data from the filter chain.
|
| + int amount_read = output_array_size;
|
| + Filter::FilterStatus status = filter1->ReadData(output_array, &amount_read);
|
| + EXPECT_NE(Filter::FILTER_ERROR, status);
|
| + EXPECT_EQ(0, memcmp(output_array, input_array + compare_array_index,
|
| + amount_read));
|
| + compare_array_index += amount_read;
|
| +
|
| + // Detect the various indications that data transfer along the chain is
|
| + // complete.
|
| + if (Filter::FILTER_DONE == status || Filter::FILTER_ERROR == status ||
|
| + (Filter::FILTER_OK == status && amount_read == 0) ||
|
| + (Filter::FILTER_NEED_MORE_DATA == status &&
|
| + read_array_index == input_array_size))
|
| + break;
|
| +
|
| + if (Filter::FILTER_OK == status)
|
| + continue;
|
| +
|
| + // Write needed data into the filter chain.
|
| + ASSERT_EQ(Filter::FILTER_NEED_MORE_DATA, status);
|
| + ASSERT_NE(0, filter1->stream_buffer_size());
|
| + size_t amount_to_copy = std::min(
|
| + static_cast<size_t>(filter1->stream_buffer_size()),
|
| + input_array_size - read_array_index);
|
| + memcpy(filter1->stream_buffer()->data(),
|
| + input_array + read_array_index,
|
| + amount_to_copy);
|
| + filter1->FlushStreamBuffer(amount_to_copy);
|
| + read_array_index += amount_to_copy;
|
| + } while (true);
|
| +
|
| + EXPECT_EQ(read_array_index, input_array_size);
|
| + EXPECT_EQ(compare_array_index, input_array_size);
|
| +}
|
| +
|
| +} // Namespace net
|
|
|