proxygen
HPACKCodecTests.cpp File Reference

Go to the source code of this file.

Classes

class  HPACKCodecTests
 
class  HPACKQueueTests
 

Functions

bool isLowercase (StringPiece str)
 
 TEST_F (HPACKCodecTests, Request)
 
 TEST_F (HPACKCodecTests, Response)
 
 TEST_F (HPACKCodecTests, Headroom)
 
 TEST_F (HPACKCodecTests, LowercasingHeaderNames)
 
 TEST_F (HPACKCodecTests, MultivalueHeaders)
 
 TEST_F (HPACKCodecTests, DecodeError)
 
 TEST_F (HPACKCodecTests, HeaderCodecStats)
 
 TEST_F (HPACKCodecTests, UncompressedSizeLimit)
 
 TEST_F (HPACKCodecTests, SizeLimitStats)
 
 TEST_F (HPACKCodecTests, DefaultHeaderIndexingStrategy)
 
 TEST_F (HPACKQueueTests, QueueInline)
 
 TEST_F (HPACKQueueTests, QueueReorder)
 
 TEST_F (HPACKQueueTests, QueueReorderOoo)
 
 TEST_F (HPACKQueueTests, QueueError)
 
 TEST_P (HPACKQueueTests, QueueDeleted)
 
 INSTANTIATE_TEST_CASE_P (Queue, HPACKQueueTests,::testing::Values(0, 1, 2, 3))
 

Function Documentation

INSTANTIATE_TEST_CASE_P ( Queue  ,
HPACKQueueTests  ,
::testing::Values(0, 1, 2, 3)   
)

Referenced by TEST_P().

TEST_F ( HPACKCodecTests  ,
Request   
)

Definition at line 83 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), encodeDecode(), EXPECT_EQ, EXPECT_TRUE, and i.

83  {
84  for (int i = 0; i < 3; i++) {
85  auto result = encodeDecode(client, server, basicHeaders());
86  EXPECT_TRUE(!result.hasError());
87  EXPECT_EQ(result->headers.size(), 12);
88  }
89 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void encodeDecode(vector< HPACKHeader > &headers, HPACKEncoder &encoder, HPACKDecoder &decoder)
TEST_F ( HPACKCodecTests  ,
Response   
)

Definition at line 91 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), encodeDecode(), EXPECT_EQ, EXPECT_TRUE, proxygen::hpack::headersFromArray(), and i.

91  {
92  vector<vector<string>> headers = {
93  {"content-length", "80"},
94  {"content-encoding", "gzip"},
95  {"x-fb-debug", "sdfgrwer"}
96  };
97  vector<Header> req = headersFromArray(headers);
98 
99  for (int i = 0; i < 3; i++) {
100  auto result = encodeDecode(server, client, basicHeaders());
101  EXPECT_TRUE(!result.hasError());
102  EXPECT_EQ(result->headers.size(), 12);
103  }
104 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void encodeDecode(vector< HPACKHeader > &headers, HPACKEncoder &encoder, HPACKDecoder &decoder)
TEST_F ( HPACKCodecTests  ,
Headroom   
)

Definition at line 106 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), fizz::decode(), EXPECT_EQ, EXPECT_TRUE, folly::IOBuf::headroom(), and uint32_t.

106  {
107  vector<Header> req = basicHeaders();
108 
109  uint32_t headroom = 20;
110  client.setEncodeHeadroom(headroom);
111  unique_ptr<IOBuf> encodedReq = client.encode(req);
112  EXPECT_EQ(encodedReq->headroom(), headroom);
113  Cursor cursor(encodedReq.get());
114  auto result = decode(server, cursor, cursor.totalLength());
115  EXPECT_TRUE(!result.hasError());
116  EXPECT_EQ(result->headers.size(), 12);
117 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TokenBindingMessage decode(folly::io::Cursor &cursor)
Definition: Types.cpp:132
std::size_t headroom() const
Definition: IOBuf.h:542
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST_F ( HPACKCodecTests  ,
LowercasingHeaderNames   
)

makes sure that the encoder will lowercase the header names

Definition at line 122 of file HPACKCodecTests.cpp.

References encodeDecode(), EXPECT_TRUE, proxygen::hpack::headersFromArray(), i, and isLowercase().

122  {
123  vector<vector<string>> headers = {
124  {"Content-Length", "80"},
125  {"Content-Encoding", "gzip"},
126  {"X-FB-Debug", "bleah"}
127  };
128  auto result = encodeDecode(server, client, headersFromArray(headers));
129  EXPECT_TRUE(!result.hasError());
130  auto& decoded = result->headers;
131  CHECK_EQ(decoded.size(), 6);
132  for (int i = 0; i < 6; i += 2) {
133  EXPECT_TRUE(isLowercase(decoded[i].str));
134  }
135 }
bool isLowercase(StringPiece str)
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void encodeDecode(vector< HPACKHeader > &headers, HPACKEncoder &encoder, HPACKDecoder &decoder)
TEST_F ( HPACKCodecTests  ,
MultivalueHeaders   
)

make sure we mark multi-valued headers appropriately, as expected by the SPDY codec.

Definition at line 141 of file HPACKCodecTests.cpp.

References count, encodeDecode(), EXPECT_EQ, EXPECT_TRUE, proxygen::hpack::headersFromArray(), i, and uint32_t.

141  {
142  vector<vector<string>> headers = {
143  {"Content-Length", "80"},
144  {"Content-Encoding", "gzip"},
145  {"X-FB-Dup", "bleah"},
146  {"X-FB-Dup", "hahaha"}
147  };
148  auto result = encodeDecode(server, client, headersFromArray(headers));
149  EXPECT_TRUE(!result.hasError());
150  auto& decoded = result->headers;
151  CHECK_EQ(decoded.size(), 8);
152  uint32_t count = 0;
153  for (int i = 0; i < 8; i += 2) {
154  if (decoded[i].str == "x-fb-dup") {
155  count++;
156  }
157  }
158  EXPECT_EQ(count, 2);
159 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
int * count
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void encodeDecode(vector< HPACKHeader > &headers, HPACKEncoder &encoder, HPACKDecoder &decoder)
TEST_F ( HPACKCodecTests  ,
DecodeError   
)

test that we're propagating the error correctly in the decoder

Definition at line 164 of file HPACKCodecTests.cpp.

References fizz::decode(), EXPECT_EQ, EXPECT_TRUE, proxygen::hpack::headersFromArray(), and folly::IOBuf::writableData().

164  {
165  vector<vector<string>> headers = {
166  {"Content-Length", "80"}
167  };
168  vector<Header> req = headersFromArray(headers);
169 
170  unique_ptr<IOBuf> encodedReq = server.encode(req);
171  encodedReq->writableData()[0] = 0xFF;
172  Cursor cursor(encodedReq.get());
173 
174  TestHeaderCodecStats stats(HeaderCodec::Type::HPACK);
175  client.setStats(&stats);
176  auto result = decode(client, cursor, cursor.totalLength());
177  // this means there was an error
178  EXPECT_TRUE(result.hasError());
179  EXPECT_EQ(result.error(), HPACK::DecodeError::INVALID_INDEX);
180  EXPECT_EQ(stats.errors, 1);
181  client.setStats(nullptr);
182 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TokenBindingMessage decode(folly::io::Cursor &cursor)
Definition: Types.cpp:132
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
uint8_t * writableData()
Definition: IOBuf.h:509
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST_F ( HPACKCodecTests  ,
HeaderCodecStats   
)

testing that we're calling the stats callbacks appropriately

Definition at line 187 of file HPACKCodecTests.cpp.

References fizz::decode(), proxygen::hpack::TestHeaderCodecStats::decodedBytesCompr, proxygen::hpack::TestHeaderCodecStats::decodedBytesUncompr, proxygen::hpack::TestHeaderCodecStats::decodes, proxygen::hpack::TestHeaderCodecStats::encodedBytesCompr, proxygen::hpack::TestHeaderCodecStats::encodedBytesUncompr, proxygen::hpack::TestHeaderCodecStats::encodes, proxygen::hpack::TestHeaderCodecStats::errors, EXPECT_EQ, EXPECT_GT, EXPECT_TRUE, proxygen::hpack::headersFromArray(), and proxygen::hpack::TestHeaderCodecStats::reset().

187  {
188  vector<vector<string>> headers = {
189  {"Content-Length", "80"},
190  {"Content-Encoding", "gzip"},
191  {"X-FB-Debug", "eirtijvdgtccffkutnbttcgbfieghgev"}
192  };
193  vector<Header> resp = headersFromArray(headers);
194 
195  TestHeaderCodecStats stats(HeaderCodec::Type::HPACK);
196  // encode
197  server.setStats(&stats);
198  unique_ptr<IOBuf> encodedResp = server.encode(resp);
199  EXPECT_EQ(stats.encodes, 1);
200  EXPECT_EQ(stats.decodes, 0);
201  EXPECT_EQ(stats.errors, 0);
202  EXPECT_TRUE(stats.encodedBytesCompr > 0);
203  EXPECT_TRUE(stats.encodedBytesUncompr > 0);
204  EXPECT_EQ(stats.decodedBytesCompr, 0);
205  EXPECT_EQ(stats.decodedBytesUncompr, 0);
206  server.setStats(nullptr);
207 
208  // decode
209  Cursor cursor(encodedResp.get());
210  stats.reset();
211  client.setStats(&stats);
212  auto result = decode(client, cursor, cursor.totalLength());
213  EXPECT_TRUE(!result.hasError());
214  auto& decoded = result->headers;
215  CHECK_EQ(decoded.size(), 3 * 2);
216  EXPECT_EQ(stats.decodes, 1);
217  EXPECT_EQ(stats.encodes, 0);
218  EXPECT_GT(stats.decodedBytesCompr, 0);
219  EXPECT_GT(stats.decodedBytesUncompr, 0);
220  EXPECT_EQ(stats.encodedBytesCompr, 0);
221  EXPECT_EQ(stats.encodedBytesUncompr, 0);
222  client.setStats(nullptr);
223 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
TokenBindingMessage decode(folly::io::Cursor &cursor)
Definition: Types.cpp:132
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void reset(BufType *buf)
Definition: Cursor.h:87
#define EXPECT_GT(val1, val2)
Definition: gtest.h:1934
TEST_F ( HPACKCodecTests  ,
UncompressedSizeLimit   
)

check that we're enforcing the limit on total uncompressed size

Definition at line 228 of file HPACKCodecTests.cpp.

References encodeDecode(), EXPECT_EQ, EXPECT_TRUE, proxygen::hpack::headersFromArray(), i, and folly::value().

228  {
229  vector<vector<string>> headers;
230  // generate lots of small headers
231  string contentLength = "Content-Length";
232  for (int i = 0; i < 10000; i++) {
233  string value = folly::to<string>(i);
234  vector<string> header = {contentLength, value};
235  headers.push_back(header);
236  }
237  auto result = encodeDecode(server, client, headersFromArray(headers));
238  EXPECT_TRUE(result.hasError());
239  EXPECT_EQ(result.error(), HPACK::DecodeError::HEADERS_TOO_LARGE);
240 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
void encodeDecode(vector< HPACKHeader > &headers, HPACKEncoder &encoder, HPACKDecoder &decoder)
TEST_F ( HPACKCodecTests  ,
SizeLimitStats   
)

Size limit stats

Definition at line 246 of file HPACKCodecTests.cpp.

References EXPECT_EQ, EXPECT_TRUE, proxygen::hpack::headersFromArray(), i, proxygen::hpack::TestHeaderCodecStats::tooLarge, and folly::value().

246  {
247  vector<vector<string>> headers;
248  // generate lots of small headers
249  string contentLength = "Content-Length";
250  for (int i = 0; i < 10000; i++) {
251  string value = folly::to<string>(i);
252  vector<string> header = {contentLength, value};
253  headers.push_back(header);
254  }
255  auto encHeaders = headersFromArray(headers);
256  unique_ptr<IOBuf> encoded = client.encode(encHeaders);
257  Cursor cursor(encoded.get());
259  TestHeaderCodecStats stats(HeaderCodec::Type::HPACK);
260  server.setStats(&stats);
261  server.decodeStreaming(cursor, cursor.totalLength(), &cb);
262  auto result = cb.getResult();
263  EXPECT_TRUE(result.hasError());
264  EXPECT_EQ(result.error(), HPACK::DecodeError::HEADERS_TOO_LARGE);
265  EXPECT_EQ(stats.tooLarge, 1);
266 }
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
static const char *const value
Definition: Conv.cpp:50
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
TEST_F ( HPACKCodecTests  ,
DefaultHeaderIndexingStrategy   
)

Definition at line 268 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), proxygen::HPACKCodec::encode(), EXPECT_EQ, and proxygen::hpack::headersFromArray().

268  {
269  vector<Header> headers = basicHeaders();
270  size_t headersIndexableSize = 4;
271 
272  // Control equality check; all basic headers were indexed
273  client.encode(headers);
274  EXPECT_EQ(client.getHPACKTableInfo().egressHeadersStored_,
275  headersIndexableSize);
276 
277  // Verify HPACKCodec by default utilizes the default header indexing strategy
278  // by ensuring that it does not index any of the added headers below
279  // The below is quite verbose but that is because Header constructors use
280  // references and so we need the actual strings to not go out of scope
281  vector<vector<string>> noIndexHeadersStrings = {
282  {"content-length", "80"},
283  {":path", "/some/random/file.jpg"},
284  {":path", "checks_for_="},
285  {"if-modified-since", "some_value"},
286  {"last-modified", "some_value"}
287  };
288  vector<Header> noIndexHeaders = headersFromArray(noIndexHeadersStrings);
289  headers.insert(headers.end(), noIndexHeaders.begin(), noIndexHeaders.end());
290  HPACKCodec testCodec{TransportDirection::UPSTREAM};
291  testCodec.encode(headers);
292  EXPECT_EQ(
293  testCodec.getHPACKTableInfo().egressHeadersStored_, headersIndexableSize);
294 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
vector< compress::Header > headersFromArray(vector< vector< string >> &a)
Definition: TestUtil.cpp:108
std::unique_ptr< folly::IOBuf > encode(std::vector< compress::Header > &headers) noexcept
Definition: HPACKCodec.cpp:48
TEST_F ( HPACKQueueTests  ,
QueueInline   
)

Definition at line 309 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), EXPECT_EQ, EXPECT_TRUE, proxygen::TestStreamingCallback::getResult(), i, folly::gen::move, and proxygen::TestStreamingCallback::reset().

309  {
310  vector<Header> req = basicHeaders();
312 
313  for (int i = 0; i < 3; i++) {
314  unique_ptr<IOBuf> encodedReq = client.encode(req);
315  auto len = bufLen(encodedReq);
316  cb.reset();
317  queue->enqueueHeaderBlock(i, std::move(encodedReq), len, &cb, false);
318  auto result = cb.getResult();
319  EXPECT_TRUE(!result.hasError());
320  EXPECT_EQ(result->headers.size(), 12);
321  }
322 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
folly::Expected< HeaderDecodeResult, HPACK::DecodeError > getResult()
TEST_F ( HPACKQueueTests  ,
QueueReorder   
)

Definition at line 324 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), folly::data(), EXPECT_EQ, EXPECT_TRUE, i, and folly::gen::move.

324  {
325  vector<Header> req = basicHeaders();
326  vector<std::pair<unique_ptr<IOBuf>, TestStreamingCallback>> data;
327 
328  for (int i = 0; i < 4; i++) {
329  data.emplace_back(client.encode(req), TestStreamingCallback());
330  }
331 
332  std::vector<int> insertOrder{1, 3, 2, 0};
333  for (auto i: insertOrder) {
334  auto& encodedReq = data[i].first;
335  auto len = bufLen(encodedReq);
336  queue->enqueueHeaderBlock(i, std::move(encodedReq), len, &data[i].second,
337  false);
338  }
339  for (auto& d: data) {
340  auto result = d.second.getResult();
341  EXPECT_TRUE(!result.hasError());
342  EXPECT_EQ(result->headers.size(), 12);
343  }
344  EXPECT_EQ(queue->getHolBlockCount(), 3);
345 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43
TEST_F ( HPACKQueueTests  ,
QueueReorderOoo   
)

Definition at line 347 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), folly::data(), EXPECT_EQ, EXPECT_TRUE, i, and folly::gen::move.

347  {
348  vector<Header> req = basicHeaders();
349  vector<std::pair<unique_ptr<IOBuf>, TestStreamingCallback>> data;
350 
351  for (int i = 0; i < 4; i++) {
352  data.emplace_back(client.encode(req), TestStreamingCallback());
353  }
354 
355  std::vector<int> insertOrder{0, 3, 2, 1};
356  for (auto i: insertOrder) {
357  auto& encodedReq = data[i].first;
358  auto len = bufLen(encodedReq);
359  // Allow idx 3 to be decoded out of order
360  queue->enqueueHeaderBlock(i, std::move(encodedReq), len, &data[i].second,
361  i == 3);
362  }
363  for (auto& d: data) {
364  auto result = d.second.getResult();
365  EXPECT_TRUE(!result.hasError());
366  EXPECT_EQ(result->headers.size(), 12);
367  }
368  EXPECT_EQ(queue->getHolBlockCount(), 1);
369 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43
TEST_F ( HPACKQueueTests  ,
QueueError   
)

Definition at line 371 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), EXPECT_EQ, EXPECT_TRUE, proxygen::TestStreamingCallback::getResult(), i, folly::gen::move, and proxygen::TestStreamingCallback::reset().

371  {
372  vector<Header> req = basicHeaders();
374 
375  bool expectOk = true;
376  // ok, dup, ok, lower
377  for (auto i: std::vector<int>({0, 0, 1, 0, 3, 3, 2})) {
378  unique_ptr<IOBuf> encodedReq = client.encode(req);
379  auto len = bufLen(encodedReq);
380  cb.reset();
381  queue->enqueueHeaderBlock(i, std::move(encodedReq), len, &cb, true);
382  auto result = cb.getResult();
383  if (expectOk) {
384  EXPECT_TRUE(!result.hasError());
385  EXPECT_EQ(result->headers.size(), 12);
386  } else {
387  EXPECT_TRUE(result.hasError());
388  EXPECT_EQ(result.error(), HPACK::DecodeError::BAD_SEQUENCE_NUMBER);
389  }
390  expectOk = !expectOk;
391  }
392 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
folly::Expected< HeaderDecodeResult, HPACK::DecodeError > getResult()
TEST_P ( HPACKQueueTests  ,
QueueDeleted   
)

Definition at line 394 of file HPACKCodecTests.cpp.

References proxygen::hpack::basicHeaders(), folly::data(), i, INSTANTIATE_TEST_CASE_P(), and folly::gen::move.

394  {
395  vector<Header> req = basicHeaders();
396  vector<std::pair<unique_ptr<IOBuf>, TestStreamingCallback>> data;
397 
398  for (int i = 0; i < 4; i++) {
399  data.emplace_back(client.encode(req), TestStreamingCallback());
400  if (i == GetParam()) {
401  data.back().second.headersCompleteCb = [&] { queue.reset(); };
402  }
403  }
404 
405  std::vector<int> insertOrder{0, 3, 2, 1};
406  for (auto i: insertOrder) {
407  auto& encodedReq = data[i].first;
408  auto len = bufLen(encodedReq);
409 
410  // Allow idx 3 to be decoded out of order
411  queue->enqueueHeaderBlock(i, std::move(encodedReq), len, &data[i].second,
412  i == 3);
413  if (!queue) {
414  break;
415  }
416  }
417 }
vector< compress::Header > basicHeaders()
Definition: TestUtil.cpp:116
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
static constexpr uint64_t data[1]
Definition: Fingerprint.cpp:43