Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: net/filter/brotli_filter_unittest.cc

Issue 1431723002: Add brotli content-encoding filter. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added BrotliSlowRead to u_r_j_unittest Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
xunjieli 2015/12/02 18:26:31 nit: 2015.
eustas 2015/12/03 12:32:06 Done.
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 <fstream>
6 #include <ostream>
xunjieli 2015/12/02 18:26:31 Why do we need these?
eustas 2015/12/03 12:32:07 Copy-pasted from gzip filter unittest... Removed.
7
8 #include "base/files/file_util.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/path_service.h"
11 #include "net/base/io_buffer.h"
12 #include "net/filter/brotli_filter.h"
13 #include "net/filter/mock_filter_context.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15 #include "testing/platform_test.h"
16
17 namespace {
18 const int kDefaultBufferSize = 4096;
19 const int kSmallBufferSize = 128;
20 } // namespace
21
22 namespace net {
23
24 // These tests use the path service, which uses autoreleased objects on the
25 // Mac, so this needs to be a PlatformTest.
26 class BrotliUnitTest : public PlatformTest {
27 protected:
28 void SetUp() override {
29 PlatformTest::SetUp();
30
31 // Get the path of data directory.
32 base::FilePath data_dir;
33 PathService::Get(base::DIR_SOURCE_ROOT, &data_dir);
34 data_dir = data_dir.AppendASCII("net");
35 data_dir = data_dir.AppendASCII("data");
36 data_dir = data_dir.AppendASCII("filter_unittests");
37
38 // Read data from the original file into buffer.
39 base::FilePath file_path;
40 file_path = data_dir.AppendASCII("google.txt");
41 ASSERT_TRUE(base::ReadFileToString(file_path, &source_buffer_));
42
43 // Read data from the encoded file into buffer.
44 base::FilePath encoded_file_path;
45 encoded_file_path = data_dir.AppendASCII("google.br");
46 ASSERT_TRUE(base::ReadFileToString(encoded_file_path, &encoded_buffer_));
47 ASSERT_TRUE(encoded_buffer_.size() <= kDefaultBufferSize);
xunjieli 2015/12/02 18:26:31 nit: ASSERT_LE. ASSERT_GT(kDefaultBufferSize, enc
eustas 2015/12/03 12:32:07 Done. Thank you.
48 }
49
50 void TearDown() override { PlatformTest::TearDown(); }
51
52 // Use filter to decode compressed data, and compare the decoding result with
xunjieli 2015/12/02 18:26:31 nit: s/decoding/decoded
eustas 2015/12/03 12:32:07 Done.
53 // the orginal Data.
xunjieli 2015/12/02 18:26:31 nit: s/Data/data.
eustas 2015/12/03 12:32:06 Done.
54 // Parameters: Source and source_len are original data and its size.
xunjieli 2015/12/02 18:26:31 nit: s/Source/|source| s/source_len/|source_len| S
eustas 2015/12/03 12:32:07 Done.
55 // Encoded_source and encoded_source_len are compressed data and its size.
56 // Output_buffer_size specifies the size of buffer to read out data from
57 // filter.
58 void DecodeAndCompareWithFilter(Filter* filter,
59 const char* source,
60 int source_len,
61 const char* encoded_source,
62 int encoded_source_len,
63 int output_buffer_size) {
64 // Make sure we have enough space to hold the decoding output.
65 ASSERT_TRUE(source_len <= kDefaultBufferSize);
xunjieli 2015/12/02 18:26:31 ditto
eustas 2015/12/03 12:32:07 Done.
66 ASSERT_TRUE(output_buffer_size <= kDefaultBufferSize);
xunjieli 2015/12/02 18:26:31 ditto
eustas 2015/12/03 12:32:06 Done.
67
68 char decode_buffer[kDefaultBufferSize];
69 char* decode_next = decode_buffer;
70 int decode_avail_size = kDefaultBufferSize;
71
72 const char* encode_next = encoded_source;
73 int encode_avail_size = encoded_source_len;
74
75 int code = Filter::FILTER_OK;
76 while (code != Filter::FILTER_DONE) {
77 int encode_data_len;
78 encode_data_len =
79 std::min(encode_avail_size, filter->stream_buffer_size());
80 memcpy(filter->stream_buffer()->data(), encode_next, encode_data_len);
81 filter->FlushStreamBuffer(encode_data_len);
82 encode_next += encode_data_len;
83 encode_avail_size -= encode_data_len;
84
85 while (1) {
xunjieli 2015/12/02 18:26:30 nit: while (true)
eustas 2015/12/03 12:32:07 Sorry. Fixed.
86 int decode_data_len = std::min(decode_avail_size, output_buffer_size);
87
88 code = filter->ReadData(decode_next, &decode_data_len);
89 decode_next += decode_data_len;
90 decode_avail_size -= decode_data_len;
91
92 ASSERT_TRUE(code != Filter::FILTER_ERROR);
xunjieli 2015/12/02 18:26:31 nit: ASSERT_NE
eustas 2015/12/03 12:32:07 Done.
93
94 if (code == Filter::FILTER_NEED_MORE_DATA ||
95 code == Filter::FILTER_DONE) {
96 break;
97 }
98 }
99 }
100
101 // Compare the decoding result with source data
102 int decode_total_data_len = kDefaultBufferSize - decode_avail_size;
103 EXPECT_TRUE(decode_total_data_len == source_len);
xunjieli 2015/12/02 18:26:31 EXPECT_EQ
eustas 2015/12/03 12:32:07 Done.
104 EXPECT_EQ(memcmp(source, decode_buffer, source_len), 0);
105 }
106
107 // Unsafe function to use filter to decode compressed data.
108 // Parameters: Source and source_len are compressed data and its size.
109 // Dest is the buffer for decoding results. Upon entry, *dest_len is the size
110 // of the dest buffer. Upon exit, *dest_len is the number of chars written
111 // into the buffer.
112 int DecodeAllWithFilter(Filter* filter,
113 const char* source,
114 int source_len,
115 char* dest,
116 int* dest_len) {
117 memcpy(filter->stream_buffer()->data(), source, source_len);
118 filter->FlushStreamBuffer(source_len);
119 return filter->ReadData(dest, dest_len);
120 }
121
122 void InitFilter() {
123 std::vector<Filter::FilterType> filter_types;
124 filter_types.push_back(Filter::FILTER_TYPE_BROTLI);
125 filter_.reset(Filter::Factory(filter_types, filter_context_));
126 ASSERT_TRUE(filter_.get());
127 ASSERT_GE(filter_->stream_buffer_size(), kDefaultBufferSize);
128 }
129
130 void InitFilterWithBufferSize(int buffer_size) {
131 std::vector<Filter::FilterType> filter_types;
132 filter_types.push_back(Filter::FILTER_TYPE_BROTLI);
133 filter_.reset(
134 Filter::FactoryForTests(filter_types, filter_context_, buffer_size));
135 ASSERT_TRUE(filter_.get());
136 }
137
138 const char* source_buffer() const { return source_buffer_.data(); }
139 int source_len() const { return static_cast<int>(source_buffer_.size()); }
140
141 const char* encoded_buffer() const { return encoded_buffer_.data(); }
142 int encoded_len() const { return static_cast<int>(encoded_buffer_.size()); }
143
144 scoped_ptr<Filter> filter_;
145
146 std::string source_buffer_;
147 std::string encoded_buffer_;
148
149 private:
150 MockFilterContext filter_context_;
151 };
152
153 // Basic scenario: decoding gzip data with big enough buffer.
154 TEST_F(BrotliUnitTest, DecodeBrotli) {
155 InitFilter();
156 memcpy(filter_->stream_buffer()->data(), encoded_buffer(), encoded_len());
157 filter_->FlushStreamBuffer(encoded_len());
158
159 char decode_buffer[kDefaultBufferSize];
160 int decode_size = kDefaultBufferSize;
161 filter_->ReadData(decode_buffer, &decode_size);
162
163 // Compare the decoding result with source data
164 EXPECT_TRUE(decode_size == source_len());
xunjieli 2015/12/02 18:26:31 EXPECT_EQ
eustas 2015/12/03 12:32:07 Done.
165 EXPECT_EQ(memcmp(source_buffer(), decode_buffer, source_len()), 0);
166 }
167
168 // Tests we can call filter repeatedly to get all the data decoded.
169 // To do that, we create a filter with a small buffer that can not hold all
170 // the input data.
171 TEST_F(BrotliUnitTest, DecodeWithSmallBuffer) {
172 InitFilterWithBufferSize(kSmallBufferSize);
173 EXPECT_EQ(kSmallBufferSize, filter_->stream_buffer_size());
174 DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
175 encoded_buffer(), encoded_len(),
176 kDefaultBufferSize);
177 }
178
179 // Tests we can still decode with just 1 byte buffer in the filter.
180 // The purpose of this test: sometimes the filter will consume input without
181 // generating output. Verify filter can handle it correctly.
182 TEST_F(BrotliUnitTest, DecodeWithOneByteBuffer) {
183 InitFilterWithBufferSize(1);
184 EXPECT_EQ(1, filter_->stream_buffer_size());
185 DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
186 encoded_buffer(), encoded_len(),
187 kDefaultBufferSize);
188 }
189
190 // Tests we can decode when caller has small buffer to read out from filter.
191 TEST_F(BrotliUnitTest, DecodeWithSmallOutputBuffer) {
192 InitFilter();
193 DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
194 encoded_buffer(), encoded_len(), kSmallBufferSize);
195 }
196
197 // Tests we can still decode with just 1 byte buffer in the filter and just 1
198 // byte buffer in the caller.
199 TEST_F(BrotliUnitTest, DecodeWithOneByteInputAndOutputBuffer) {
200 InitFilterWithBufferSize(1);
201 EXPECT_EQ(1, filter_->stream_buffer_size());
202 DecodeAndCompareWithFilter(filter_.get(), source_buffer(), source_len(),
203 encoded_buffer(), encoded_len(), 1);
204 }
205
206 // Decoding deflate stream with corrupted data.
207 TEST_F(BrotliUnitTest, DecodeCorruptedData) {
208 char corrupt_data[kDefaultBufferSize];
209 int corrupt_data_len = encoded_len();
210 memcpy(corrupt_data, encoded_buffer(), encoded_len());
211
212 int pos = corrupt_data_len / 2;
213 corrupt_data[pos] = !corrupt_data[pos];
214
215 // Decode the corrupted data with filter
216 InitFilter();
217 char corrupt_decode_buffer[kDefaultBufferSize];
218 int corrupt_decode_size = kDefaultBufferSize;
219
220 int code = DecodeAllWithFilter(filter_.get(), corrupt_data, corrupt_data_len,
221 corrupt_decode_buffer, &corrupt_decode_size);
222
223 // Expect failures
224 EXPECT_TRUE(code == Filter::FILTER_ERROR);
xunjieli 2015/12/02 18:26:31 nit:EXPECT_EQ
eustas 2015/12/03 12:32:07 Done.
225 }
226
227 // Decoding deflate stream with missing data.
228 TEST_F(BrotliUnitTest, DecodeMissingData) {
229 char corrupt_data[kDefaultBufferSize];
230 int corrupt_data_len = encoded_len();
231 memcpy(corrupt_data, encoded_buffer(), encoded_len());
232
233 int pos = corrupt_data_len / 2;
234 int len = corrupt_data_len - pos - 1;
235 memmove(&corrupt_data[pos], &corrupt_data[pos + 1], len);
236 --corrupt_data_len;
237
238 // Decode the corrupted data with filter
239 InitFilter();
240 char corrupt_decode_buffer[kDefaultBufferSize];
241 int corrupt_decode_size = kDefaultBufferSize;
242
243 int code = DecodeAllWithFilter(filter_.get(), corrupt_data, corrupt_data_len,
244 corrupt_decode_buffer, &corrupt_decode_size);
245
246 // Expect failures
247 EXPECT_EQ(Filter::FILTER_ERROR, code);
248 }
249 } // namespace net
xunjieli 2015/12/02 18:26:31 nit: a blank line before namespace
eustas 2015/12/03 12:32:07 Fixed
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698