Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / net / spdy / hpack_output_stream_test.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
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 "net/spdy/hpack_output_stream.h"
6
7 #include <cstddef>
8
9 #include "base/basictypes.h"
10 #include "testing/gtest/include/gtest/gtest.h"
11
12 namespace net {
13
14 namespace {
15
16 using std::string;
17
18 // Make sure that AppendBits() appends bits starting from the most
19 // significant bit, and that it can handle crossing a byte boundary.
20 TEST(HpackOutputStreamTest, AppendBits) {
21   HpackOutputStream output_stream(kuint32max);
22   string expected_str;
23
24   output_stream.AppendBitsForTest(0x1, 1);
25   expected_str.append(1, 0x00);
26   *expected_str.rbegin() |= (0x1 << 7);
27
28   output_stream.AppendBitsForTest(0x0, 1);
29
30   output_stream.AppendBitsForTest(0x3, 2);
31   *expected_str.rbegin() |= (0x3 << 4);
32
33   output_stream.AppendBitsForTest(0x0, 2);
34
35   // Byte-crossing append.
36   output_stream.AppendBitsForTest(0x7, 3);
37   *expected_str.rbegin() |= (0x7 >> 1);
38   expected_str.append(1, 0x00);
39   *expected_str.rbegin() |= (0x7 << 7);
40
41   output_stream.AppendBitsForTest(0x0, 7);
42
43   string str;
44   output_stream.TakeString(&str);
45   EXPECT_EQ(expected_str, str);
46 }
47
48 // Utility function to return I as a string encoded with an N-bit
49 // prefix.
50 string EncodeUint32(uint8 N, uint32 I) {
51   HpackOutputStream output_stream(kuint32max);
52   if (N < 8) {
53     output_stream.AppendBitsForTest(0x00, 8 - N);
54   }
55   output_stream.AppendUint32ForTest(I);
56   string str;
57   output_stream.TakeString(&str);
58   return str;
59 }
60
61 // The {Number}ByteIntegersEightBitPrefix tests below test that
62 // certain integers are encoded correctly with an 8-bit prefix in
63 // exactly {Number} bytes.
64
65 TEST(HpackOutputStreamTest, OneByteIntegersEightBitPrefix) {
66   // Minimum.
67   EXPECT_EQ(string("\x00", 1), EncodeUint32(8, 0x00));
68   EXPECT_EQ("\x7f", EncodeUint32(8, 0x7f));
69   // Maximum.
70   EXPECT_EQ("\xfe", EncodeUint32(8, 0xfe));
71 }
72
73 TEST(HpackOutputStreamTest, TwoByteIntegersEightBitPrefix) {
74   // Minimum.
75   EXPECT_EQ(string("\xff\x00", 2), EncodeUint32(8, 0xff));
76   EXPECT_EQ("\xff\x01", EncodeUint32(8, 0x0100));
77   // Maximum.
78   EXPECT_EQ("\xff\x7f", EncodeUint32(8, 0x017e));
79 }
80
81 TEST(HpackOutputStreamTest, ThreeByteIntegersEightBitPrefix) {
82   // Minimum.
83   EXPECT_EQ("\xff\x80\x01", EncodeUint32(8, 0x017f));
84   EXPECT_EQ("\xff\x80\x1e", EncodeUint32(8, 0x0fff));
85   // Maximum.
86   EXPECT_EQ("\xff\xff\x7f", EncodeUint32(8, 0x40fe));
87 }
88
89 TEST(HpackOutputStreamTest, FourByteIntegersEightBitPrefix) {
90   // Minimum.
91   EXPECT_EQ("\xff\x80\x80\x01", EncodeUint32(8, 0x40ff));
92   EXPECT_EQ("\xff\x80\xfe\x03", EncodeUint32(8, 0xffff));
93   // Maximum.
94   EXPECT_EQ("\xff\xff\xff\x7f", EncodeUint32(8, 0x002000fe));
95 }
96
97 TEST(HpackOutputStreamTest, FiveByteIntegersEightBitPrefix) {
98   // Minimum.
99   EXPECT_EQ("\xff\x80\x80\x80\x01", EncodeUint32(8, 0x002000ff));
100   EXPECT_EQ("\xff\x80\xfe\xff\x07", EncodeUint32(8, 0x00ffffff));
101   // Maximum.
102   EXPECT_EQ("\xff\xff\xff\xff\x7f", EncodeUint32(8, 0x100000fe));
103 }
104
105 TEST(HpackOutputStreamTest, SixByteIntegersEightBitPrefix) {
106   // Minimum.
107   EXPECT_EQ("\xff\x80\x80\x80\x80\x01", EncodeUint32(8, 0x100000ff));
108   // Maximum.
109   EXPECT_EQ("\xff\x80\xfe\xff\xff\x0f", EncodeUint32(8, 0xffffffff));
110 }
111
112 // The {Number}ByteIntegersOneToSevenBitPrefix tests below test that
113 // certain integers are encoded correctly with an N-bit prefix in
114 // exactly {Number} bytes for N in {1, 2, ..., 7}.
115
116 TEST(HpackOutputStreamTest, OneByteIntegersOneToSevenBitPrefixes) {
117   // Minimums.
118   EXPECT_EQ(string("\x00", 1), EncodeUint32(7, 0x00));
119   EXPECT_EQ(string("\x00", 1), EncodeUint32(6, 0x00));
120   EXPECT_EQ(string("\x00", 1), EncodeUint32(5, 0x00));
121   EXPECT_EQ(string("\x00", 1), EncodeUint32(4, 0x00));
122   EXPECT_EQ(string("\x00", 1), EncodeUint32(3, 0x00));
123   EXPECT_EQ(string("\x00", 1), EncodeUint32(2, 0x00));
124   EXPECT_EQ(string("\x00", 1), EncodeUint32(1, 0x00));
125
126   // Maximums.
127   EXPECT_EQ("\x7e", EncodeUint32(7, 0x7e));
128   EXPECT_EQ("\x3e", EncodeUint32(6, 0x3e));
129   EXPECT_EQ("\x1e", EncodeUint32(5, 0x1e));
130   EXPECT_EQ("\x0e", EncodeUint32(4, 0x0e));
131   EXPECT_EQ("\x06", EncodeUint32(3, 0x06));
132   EXPECT_EQ("\x02", EncodeUint32(2, 0x02));
133   EXPECT_EQ(string("\x00", 1), EncodeUint32(1, 0x00));
134 }
135
136 TEST(HpackOutputStreamTest, TwoByteIntegersOneToSevenBitPrefixes) {
137   // Minimums.
138   EXPECT_EQ(string("\x7f\x00", 2), EncodeUint32(7, 0x7f));
139   EXPECT_EQ(string("\x3f\x00", 2), EncodeUint32(6, 0x3f));
140   EXPECT_EQ(string("\x1f\x00", 2), EncodeUint32(5, 0x1f));
141   EXPECT_EQ(string("\x0f\x00", 2), EncodeUint32(4, 0x0f));
142   EXPECT_EQ(string("\x07\x00", 2), EncodeUint32(3, 0x07));
143   EXPECT_EQ(string("\x03\x00", 2), EncodeUint32(2, 0x03));
144   EXPECT_EQ(string("\x01\x00", 2), EncodeUint32(1, 0x01));
145
146   // Maximums.
147   EXPECT_EQ("\x7f\x7f", EncodeUint32(7, 0xfe));
148   EXPECT_EQ("\x3f\x7f", EncodeUint32(6, 0xbe));
149   EXPECT_EQ("\x1f\x7f", EncodeUint32(5, 0x9e));
150   EXPECT_EQ("\x0f\x7f", EncodeUint32(4, 0x8e));
151   EXPECT_EQ("\x07\x7f", EncodeUint32(3, 0x86));
152   EXPECT_EQ("\x03\x7f", EncodeUint32(2, 0x82));
153   EXPECT_EQ("\x01\x7f", EncodeUint32(1, 0x80));
154 }
155
156 TEST(HpackOutputStreamTest, ThreeByteIntegersOneToSevenBitPrefixes) {
157   // Minimums.
158   EXPECT_EQ("\x7f\x80\x01", EncodeUint32(7, 0xff));
159   EXPECT_EQ("\x3f\x80\x01", EncodeUint32(6, 0xbf));
160   EXPECT_EQ("\x1f\x80\x01", EncodeUint32(5, 0x9f));
161   EXPECT_EQ("\x0f\x80\x01", EncodeUint32(4, 0x8f));
162   EXPECT_EQ("\x07\x80\x01", EncodeUint32(3, 0x87));
163   EXPECT_EQ("\x03\x80\x01", EncodeUint32(2, 0x83));
164   EXPECT_EQ("\x01\x80\x01", EncodeUint32(1, 0x81));
165
166   // Maximums.
167   EXPECT_EQ("\x7f\xff\x7f", EncodeUint32(7, 0x407e));
168   EXPECT_EQ("\x3f\xff\x7f", EncodeUint32(6, 0x403e));
169   EXPECT_EQ("\x1f\xff\x7f", EncodeUint32(5, 0x401e));
170   EXPECT_EQ("\x0f\xff\x7f", EncodeUint32(4, 0x400e));
171   EXPECT_EQ("\x07\xff\x7f", EncodeUint32(3, 0x4006));
172   EXPECT_EQ("\x03\xff\x7f", EncodeUint32(2, 0x4002));
173   EXPECT_EQ("\x01\xff\x7f", EncodeUint32(1, 0x4000));
174 }
175
176 TEST(HpackOutputStreamTest, FourByteIntegersOneToSevenBitPrefixes) {
177   // Minimums.
178   EXPECT_EQ("\x7f\x80\x80\x01", EncodeUint32(7, 0x407f));
179   EXPECT_EQ("\x3f\x80\x80\x01", EncodeUint32(6, 0x403f));
180   EXPECT_EQ("\x1f\x80\x80\x01", EncodeUint32(5, 0x401f));
181   EXPECT_EQ("\x0f\x80\x80\x01", EncodeUint32(4, 0x400f));
182   EXPECT_EQ("\x07\x80\x80\x01", EncodeUint32(3, 0x4007));
183   EXPECT_EQ("\x03\x80\x80\x01", EncodeUint32(2, 0x4003));
184   EXPECT_EQ("\x01\x80\x80\x01", EncodeUint32(1, 0x4001));
185
186   // Maximums.
187   EXPECT_EQ("\x7f\xff\xff\x7f", EncodeUint32(7, 0x20007e));
188   EXPECT_EQ("\x3f\xff\xff\x7f", EncodeUint32(6, 0x20003e));
189   EXPECT_EQ("\x1f\xff\xff\x7f", EncodeUint32(5, 0x20001e));
190   EXPECT_EQ("\x0f\xff\xff\x7f", EncodeUint32(4, 0x20000e));
191   EXPECT_EQ("\x07\xff\xff\x7f", EncodeUint32(3, 0x200006));
192   EXPECT_EQ("\x03\xff\xff\x7f", EncodeUint32(2, 0x200002));
193   EXPECT_EQ("\x01\xff\xff\x7f", EncodeUint32(1, 0x200000));
194 }
195
196 TEST(HpackOutputStreamTest, FiveByteIntegersOneToSevenBitPrefixes) {
197   // Minimums.
198   EXPECT_EQ("\x7f\x80\x80\x80\x01", EncodeUint32(7, 0x20007f));
199   EXPECT_EQ("\x3f\x80\x80\x80\x01", EncodeUint32(6, 0x20003f));
200   EXPECT_EQ("\x1f\x80\x80\x80\x01", EncodeUint32(5, 0x20001f));
201   EXPECT_EQ("\x0f\x80\x80\x80\x01", EncodeUint32(4, 0x20000f));
202   EXPECT_EQ("\x07\x80\x80\x80\x01", EncodeUint32(3, 0x200007));
203   EXPECT_EQ("\x03\x80\x80\x80\x01", EncodeUint32(2, 0x200003));
204   EXPECT_EQ("\x01\x80\x80\x80\x01", EncodeUint32(1, 0x200001));
205
206   // Maximums.
207   EXPECT_EQ("\x7f\xff\xff\xff\x7f", EncodeUint32(7, 0x1000007e));
208   EXPECT_EQ("\x3f\xff\xff\xff\x7f", EncodeUint32(6, 0x1000003e));
209   EXPECT_EQ("\x1f\xff\xff\xff\x7f", EncodeUint32(5, 0x1000001e));
210   EXPECT_EQ("\x0f\xff\xff\xff\x7f", EncodeUint32(4, 0x1000000e));
211   EXPECT_EQ("\x07\xff\xff\xff\x7f", EncodeUint32(3, 0x10000006));
212   EXPECT_EQ("\x03\xff\xff\xff\x7f", EncodeUint32(2, 0x10000002));
213   EXPECT_EQ("\x01\xff\xff\xff\x7f", EncodeUint32(1, 0x10000000));
214 }
215
216 TEST(HpackOutputStreamTest, SixByteIntegersOneToSevenBitPrefixes) {
217   // Minimums.
218   EXPECT_EQ("\x7f\x80\x80\x80\x80\x01", EncodeUint32(7, 0x1000007f));
219   EXPECT_EQ("\x3f\x80\x80\x80\x80\x01", EncodeUint32(6, 0x1000003f));
220   EXPECT_EQ("\x1f\x80\x80\x80\x80\x01", EncodeUint32(5, 0x1000001f));
221   EXPECT_EQ("\x0f\x80\x80\x80\x80\x01", EncodeUint32(4, 0x1000000f));
222   EXPECT_EQ("\x07\x80\x80\x80\x80\x01", EncodeUint32(3, 0x10000007));
223   EXPECT_EQ("\x03\x80\x80\x80\x80\x01", EncodeUint32(2, 0x10000003));
224   EXPECT_EQ("\x01\x80\x80\x80\x80\x01", EncodeUint32(1, 0x10000001));
225
226   // Maximums.
227   EXPECT_EQ("\x7f\x80\xff\xff\xff\x0f", EncodeUint32(7, 0xffffffff));
228   EXPECT_EQ("\x3f\xc0\xff\xff\xff\x0f", EncodeUint32(6, 0xffffffff));
229   EXPECT_EQ("\x1f\xe0\xff\xff\xff\x0f", EncodeUint32(5, 0xffffffff));
230   EXPECT_EQ("\x0f\xf0\xff\xff\xff\x0f", EncodeUint32(4, 0xffffffff));
231   EXPECT_EQ("\x07\xf8\xff\xff\xff\x0f", EncodeUint32(3, 0xffffffff));
232   EXPECT_EQ("\x03\xfc\xff\xff\xff\x0f", EncodeUint32(2, 0xffffffff));
233   EXPECT_EQ("\x01\xfe\xff\xff\xff\x0f", EncodeUint32(1, 0xffffffff));
234 }
235
236 // Test that encoding an integer with an N-bit prefix preserves the
237 // upper (8-N) bits of the first byte.
238 TEST(HpackOutputStreamTest, AppendUint32PreservesUpperBits) {
239   HpackOutputStream output_stream(kuint32max);
240   output_stream.AppendBitsForTest(0x7f, 7);
241   output_stream.AppendUint32ForTest(0x01);
242   string str;
243   output_stream.TakeString(&str);
244   EXPECT_EQ(string("\xff\x00", 2), str);
245 }
246
247 // Test that encoding a string literal without huffman encoding
248 // encodes the size first with a 7-bit prefix and then the bytes of
249 // the string.
250 TEST(HpackOutputStreamTest, AppendStringLiteralNoHuffmanEncoding) {
251   HpackOutputStream output_stream(kuint32max);
252
253   string literal(0x7f, 'x');
254   EXPECT_TRUE(output_stream.AppendStringLiteralForTest(literal));
255
256   string str;
257   output_stream.TakeString(&str);
258   EXPECT_EQ(string("\x7f\x00", 2) + literal, str);
259 }
260
261 // Test that trying to encode a too-long string literal will fail.
262 TEST(HpackOutputStreamTest, AppendStringLiteralTooLong) {
263   HpackOutputStream output_stream(kuint32max - 1);
264
265   EXPECT_FALSE(output_stream.AppendStringLiteralForTest(
266       base::StringPiece(NULL, kuint32max)));
267 }
268
269 // Test that encoding an indexed header simply encodes the index.
270 TEST(HpackOutputStreamTest, AppendIndexedHeader) {
271   HpackOutputStream output_stream(kuint32max);
272   output_stream.AppendIndexedHeader(0xffffffff);
273
274   string str;
275   output_stream.TakeString(&str);
276   EXPECT_EQ("\xff\x80\xff\xff\xff\x0f", str);
277 }
278
279 // Test that encoding a literal header without indexing with a name
280 // encodes both the name and value as string literals.
281 TEST(HpackOutputStreamTest, AppendLiteralHeaderNoIndexingWithName) {
282   HpackOutputStream output_stream(kuint32max);
283   EXPECT_TRUE(
284       output_stream.AppendLiteralHeaderNoIndexingWithName("name", "value"));
285
286   string str;
287   output_stream.TakeString(&str);
288   EXPECT_EQ("\x40\x04name\x05value", str);
289 }
290
291 // Test that trying to encode a header with a too-long header name or
292 // value will fail.
293 TEST(HpackOutputStreamTest, AppendLiteralHeaderNoIndexingWithNameTooLong) {
294   {
295     HpackOutputStream output_stream(10);
296     EXPECT_FALSE(output_stream.AppendLiteralHeaderNoIndexingWithName(
297         "name", "too-long value"));
298   }
299   {
300     HpackOutputStream output_stream(10);
301     EXPECT_FALSE(output_stream.AppendLiteralHeaderNoIndexingWithName(
302         "too-long name", "value"));
303   }
304 }
305
306 }  // namespace
307
308 }  // namespace net