proxygen
CodecTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2017-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <gtest/gtest.h>
18 
24 
25 using namespace folly;
26 using namespace wangle;
27 using namespace folly::io;
28 
29 namespace {
30 auto createZeroedBuffer(size_t size) {
31  auto ret = IOBuf::create(size);
32  ret->append(size);
33  std::memset(ret->writableData(), 0x00, size);
34  return ret;
35 }
36 }
37 
38 TEST(FixedLengthFrameDecoder, FailWhenLengthFieldEndOffset) {
39  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
40  int called = 0;
41 
42  (*pipeline)
43  .addBack(FixedLengthFrameDecoder(10))
44  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
45  auto sz = buf->computeChainDataLength();
46  called++;
47  EXPECT_EQ(sz, 10);
48  }))
49  .finalize();
50 
51  auto buf3 = createZeroedBuffer(3);
52  auto buf11 = createZeroedBuffer(11);
53  auto buf16 = createZeroedBuffer(16);
54 
56 
57  q.append(std::move(buf3));
58  pipeline->read(q);
59  EXPECT_EQ(called, 0);
60 
61  q.append(std::move(buf11));
62  pipeline->read(q);
63  EXPECT_EQ(called, 1);
64 
65  q.append(std::move(buf16));
66  pipeline->read(q);
67  EXPECT_EQ(called, 3);
68 }
69 
70 TEST(LengthFieldFramePipeline, SimpleTest) {
71  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
72  int called = 0;
73 
74  (*pipeline)
75  .addBack(test::BytesReflector())
76  .addBack(LengthFieldPrepender())
78  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
79  auto sz = buf->computeChainDataLength();
80  called++;
81  EXPECT_EQ(sz, 2);
82  }))
83  .finalize();
84 
85  auto buf = createZeroedBuffer(2);
86  pipeline->write(std::move(buf));
87  EXPECT_EQ(called, 1);
88 }
89 
90 TEST(LengthFieldFramePipeline, LittleEndian) {
91  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
92  int called = 0;
93 
94  (*pipeline)
95  .addBack(test::BytesReflector())
96  .addBack(LengthFieldBasedFrameDecoder(4, 100, 0, 0, 4, false))
97  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
98  auto sz = buf->computeChainDataLength();
99  called++;
100  EXPECT_EQ(sz, 1);
101  }))
102  .addBack(LengthFieldPrepender(4, 0, false, false))
103  .finalize();
104 
105  auto buf = createZeroedBuffer(1);
106  pipeline->write(std::move(buf));
107  EXPECT_EQ(called, 1);
108 }
109 
110 TEST(LengthFieldFrameDecoder, Simple) {
111  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
112  int called = 0;
113 
114  (*pipeline)
115  .addBack(LengthFieldBasedFrameDecoder())
116  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
117  auto sz = buf->computeChainDataLength();
118  called++;
119  EXPECT_EQ(sz, 1);
120  }))
121  .finalize();
122 
123  auto bufFrame = createZeroedBuffer(4);
124  RWPrivateCursor c(bufFrame.get());
125  c.writeBE((uint32_t)1);
126  auto bufData = createZeroedBuffer(1);
127 
129 
130  q.append(std::move(bufFrame));
131  pipeline->read(q);
132  EXPECT_EQ(called, 0);
133 
134  q.append(std::move(bufData));
135  pipeline->read(q);
136  EXPECT_EQ(called, 1);
137 }
138 
139 TEST(LengthFieldFrameDecoder, NoStrip) {
140  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
141  int called = 0;
142 
143  (*pipeline)
144  .addBack(LengthFieldBasedFrameDecoder(2, 10, 0, 0, 0))
145  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
146  auto sz = buf->computeChainDataLength();
147  called++;
148  EXPECT_EQ(sz, 3);
149  }))
150  .finalize();
151 
152  auto bufFrame = createZeroedBuffer(2);
153  RWPrivateCursor c(bufFrame.get());
154  c.writeBE((uint16_t)1);
155  auto bufData = createZeroedBuffer(1);
156 
158 
159  q.append(std::move(bufFrame));
160  pipeline->read(q);
161  EXPECT_EQ(called, 0);
162 
163  q.append(std::move(bufData));
164  pipeline->read(q);
165  EXPECT_EQ(called, 1);
166 }
167 
168 TEST(LengthFieldFrameDecoder, Adjustment) {
169  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
170  int called = 0;
171 
172  (*pipeline)
173  .addBack(LengthFieldBasedFrameDecoder(2, 10, 0, -2, 0))
174  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
175  auto sz = buf->computeChainDataLength();
176  called++;
177  EXPECT_EQ(sz, 3);
178  }))
179  .finalize();
180 
181  auto bufFrame = createZeroedBuffer(2);
182  RWPrivateCursor c(bufFrame.get());
183  c.writeBE((uint16_t)3); // includes frame size
184  auto bufData = createZeroedBuffer(1);
185 
187 
188  q.append(std::move(bufFrame));
189  pipeline->read(q);
190  EXPECT_EQ(called, 0);
191 
192  q.append(std::move(bufData));
193  pipeline->read(q);
194  EXPECT_EQ(called, 1);
195 }
196 
197 TEST(LengthFieldFrameDecoder, PreHeader) {
198  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
199  int called = 0;
200 
201  (*pipeline)
202  .addBack(LengthFieldBasedFrameDecoder(2, 10, 2, 0, 0))
203  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
204  auto sz = buf->computeChainDataLength();
205  called++;
206  EXPECT_EQ(sz, 5);
207  }))
208  .finalize();
209 
210  auto bufFrame = createZeroedBuffer(4);
211  RWPrivateCursor c(bufFrame.get());
212  c.write((uint16_t)100); // header
213  c.writeBE((uint16_t)1); // frame size
214  auto bufData = createZeroedBuffer(1);
215 
217 
218  q.append(std::move(bufFrame));
219  pipeline->read(q);
220  EXPECT_EQ(called, 0);
221 
222  q.append(std::move(bufData));
223  pipeline->read(q);
224  EXPECT_EQ(called, 1);
225 }
226 
227 TEST(LengthFieldFrameDecoder, PostHeader) {
228  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
229  int called = 0;
230 
231  (*pipeline)
232  .addBack(LengthFieldBasedFrameDecoder(2, 10, 0, 2, 0))
233  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
234  auto sz = buf->computeChainDataLength();
235  called++;
236  EXPECT_EQ(sz, 5);
237  }))
238  .finalize();
239 
240  auto bufFrame = createZeroedBuffer(4);
241  RWPrivateCursor c(bufFrame.get());
242  c.writeBE((uint16_t)1); // frame size
243  c.write((uint16_t)100); // header
244  auto bufData = createZeroedBuffer(1);
245 
247 
248  q.append(std::move(bufFrame));
249  pipeline->read(q);
250  EXPECT_EQ(called, 0);
251 
252  q.append(std::move(bufData));
253  pipeline->read(q);
254  EXPECT_EQ(called, 1);
255 }
256 
257 TEST(LengthFieldFrameDecoderStrip, PrePostHeader) {
258  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
259  int called = 0;
260 
261  (*pipeline)
262  .addBack(LengthFieldBasedFrameDecoder(2, 10, 2, 2, 4))
263  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
264  auto sz = buf->computeChainDataLength();
265  called++;
266  EXPECT_EQ(sz, 3);
267  }))
268  .finalize();
269 
270  auto bufFrame = createZeroedBuffer(6);
271  RWPrivateCursor c(bufFrame.get());
272  c.write((uint16_t)100); // pre header
273  c.writeBE((uint16_t)1); // frame size
274  c.write((uint16_t)100); // post header
275  auto bufData = createZeroedBuffer(1);
276 
278 
279  q.append(std::move(bufFrame));
280  pipeline->read(q);
281  EXPECT_EQ(called, 0);
282 
283  q.append(std::move(bufData));
284  pipeline->read(q);
285  EXPECT_EQ(called, 1);
286 }
287 
288 TEST(LengthFieldFrameDecoder, StripPrePostHeaderFrameInclHeader) {
289  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
290  int called = 0;
291 
292  (*pipeline)
293  .addBack(LengthFieldBasedFrameDecoder(2, 10, 2, -2, 4))
294  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
295  auto sz = buf->computeChainDataLength();
296  called++;
297  EXPECT_EQ(sz, 3);
298  }))
299  .finalize();
300 
301  auto bufFrame = createZeroedBuffer(6);
302  RWPrivateCursor c(bufFrame.get());
303  c.write((uint16_t)100); // pre header
304  c.writeBE((uint16_t)5); // frame size
305  c.write((uint16_t)100); // post header
306  auto bufData = createZeroedBuffer(1);
307 
309 
310  q.append(std::move(bufFrame));
311  pipeline->read(q);
312  EXPECT_EQ(called, 0);
313 
314  q.append(std::move(bufData));
315  pipeline->read(q);
316  EXPECT_EQ(called, 1);
317 }
318 
319 TEST(LengthFieldFrameDecoder, FailTestLengthFieldEndOffset) {
320  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
321  int called = 0;
322 
323  (*pipeline)
324  .addBack(LengthFieldBasedFrameDecoder(4, 10, 4, -2, 4))
325  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
326  ASSERT_EQ(nullptr, buf);
327  called++;
328  }))
329  .finalize();
330 
331  auto bufFrame = createZeroedBuffer(8);
332  RWPrivateCursor c(bufFrame.get());
333  c.writeBE((uint32_t)0); // frame size
334  c.write((uint32_t)0); // crap
335 
337 
338  q.append(std::move(bufFrame));
339  pipeline->read(q);
340  EXPECT_EQ(called, 1);
341 }
342 
343 TEST(LengthFieldFrameDecoder, FailTestLengthFieldFrameSize) {
344  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
345  int called = 0;
346 
347  (*pipeline)
348  .addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 4))
349  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
350  ASSERT_EQ(nullptr, buf);
351  called++;
352  }))
353  .finalize();
354 
355  auto bufFrame = createZeroedBuffer(16);
356  RWPrivateCursor c(bufFrame.get());
357  c.writeBE((uint32_t)12); // frame size
358  c.write((uint32_t)0); // nothing
359  c.write((uint32_t)0); // nothing
360  c.write((uint32_t)0); // nothing
361 
363 
364  q.append(std::move(bufFrame));
365  pipeline->read(q);
366  EXPECT_EQ(called, 1);
367 }
368 
369 TEST(LengthFieldFrameDecoder, FailTestLengthFieldInitialBytes) {
370  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
371  int called = 0;
372 
373  (*pipeline)
374  .addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 10))
375  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
376  ASSERT_EQ(nullptr, buf);
377  called++;
378  }))
379  .finalize();
380 
381  auto bufFrame = createZeroedBuffer(16);
382  RWPrivateCursor c(bufFrame.get());
383  c.writeBE((uint32_t)4); // frame size
384  c.write((uint32_t)0); // nothing
385  c.write((uint32_t)0); // nothing
386  c.write((uint32_t)0); // nothing
387 
389 
390  q.append(std::move(bufFrame));
391  pipeline->read(q);
392  EXPECT_EQ(called, 1);
393 }
394 
395 TEST(LengthFieldFrameDecoder, FailTestNotEnoughBytes) {
396  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
397  int called = 0;
398 
399  (*pipeline)
400  .addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 0))
401  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
402  ASSERT_EQ(nullptr, buf);
403  called++;
404  }))
405  .finalize();
406 
407  auto bufFrame = createZeroedBuffer(16);
408  RWPrivateCursor c(bufFrame.get());
409  c.writeBE((uint32_t)7); // frame size - 1 byte too large (7 > 10 - 4)
410  c.write((uint32_t)0); // nothing
411  c.write((uint32_t)0); // nothing
412  c.write((uint32_t)0); // nothing
413 
415 
416  q.append(std::move(bufFrame));
417  pipeline->read(q);
418  EXPECT_EQ(called, 1);
419 }
420 
422  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
423  int called = 0;
424 
425  (*pipeline)
426  .addBack(LineBasedFrameDecoder(10))
427  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
428  auto sz = buf->computeChainDataLength();
429  called++;
430  EXPECT_EQ(sz, 3);
431  }))
432  .finalize();
433 
434  auto buf = createZeroedBuffer(3);
435 
437 
438  q.append(std::move(buf));
439  pipeline->read(q);
440  EXPECT_EQ(called, 0);
441 
442  buf = createZeroedBuffer(1);
443  RWPrivateCursor c(buf.get());
444  c.write<char>('\n');
445  q.append(std::move(buf));
446  pipeline->read(q);
447  EXPECT_EQ(called, 1);
448 
449  buf = createZeroedBuffer(4);
450  RWPrivateCursor c1(buf.get());
451  c1.write(' ');
452  c1.write(' ');
453  c1.write(' ');
454 
455  c1.write('\r');
456  q.append(std::move(buf));
457  pipeline->read(q);
458  EXPECT_EQ(called, 1);
459 
460  buf = createZeroedBuffer(1);
461  RWPrivateCursor c2(buf.get());
462  c2.write('\n');
463  q.append(std::move(buf));
464  pipeline->read(q);
465  EXPECT_EQ(called, 2);
466 }
467 
468 TEST(LineBasedFrameDecoder, SaveDelimiter) {
469  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
470  int called = 0;
471 
472  (*pipeline)
473  .addBack(LineBasedFrameDecoder(10, false))
474  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
475  auto sz = buf->computeChainDataLength();
476  called++;
477  EXPECT_EQ(sz, 4);
478  }))
479  .finalize();
480 
481  auto buf = createZeroedBuffer(3);
482 
484 
485  q.append(std::move(buf));
486  pipeline->read(q);
487  EXPECT_EQ(called, 0);
488 
489  buf = createZeroedBuffer(1);
490  RWPrivateCursor c(buf.get());
491  c.write<char>('\n');
492  q.append(std::move(buf));
493  pipeline->read(q);
494  EXPECT_EQ(called, 1);
495 
496  buf = createZeroedBuffer(3);
497  RWPrivateCursor c1(buf.get());
498  c1.write(' ');
499  c1.write(' ');
500  c1.write('\r');
501  q.append(std::move(buf));
502  pipeline->read(q);
503  EXPECT_EQ(called, 1);
504 
505  buf = createZeroedBuffer(1);
506  RWPrivateCursor c2(buf.get());
507  c2.write('\n');
508  q.append(std::move(buf));
509  pipeline->read(q);
510  EXPECT_EQ(called, 2);
511 }
512 
514  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
515  int called = 0;
516 
517  (*pipeline)
518  .addBack(LineBasedFrameDecoder(10))
519  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
520  ASSERT_EQ(nullptr, buf);
521  called++;
522  }))
523  .finalize();
524 
525  auto buf = createZeroedBuffer(11);
526 
528 
529  q.append(std::move(buf));
530  pipeline->read(q);
531  EXPECT_EQ(called, 1);
532 
533  buf = createZeroedBuffer(1);
534  q.append(std::move(buf));
535  pipeline->read(q);
536  EXPECT_EQ(called, 1);
537 
538  buf = createZeroedBuffer(2);
539  RWPrivateCursor c(buf.get());
540  c.write(' ');
541  c.write<char>('\n');
542  q.append(std::move(buf));
543  pipeline->read(q);
544  EXPECT_EQ(called, 1);
545 
546  buf = createZeroedBuffer(12);
547  RWPrivateCursor c2(buf.get());
548  for (int i = 0; i < 11; i++) {
549  c2.write(' ');
550  }
551  c2.write<char>('\n');
552  q.append(std::move(buf));
553  pipeline->read(q);
554  EXPECT_EQ(called, 2);
555 }
556 
558  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
559  int called = 0;
560 
561  (*pipeline)
562  .addBack(LineBasedFrameDecoder(
563  10, true, LineBasedFrameDecoder::TerminatorType::NEWLINE))
564  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
565  auto sz = buf->computeChainDataLength();
566  called++;
567  EXPECT_EQ(sz, 1);
568  }))
569  .finalize();
570 
571  auto buf = createZeroedBuffer(2);
572  RWPrivateCursor c(buf.get());
573  c.write<char>('\r');
574  c.write<char>('\n');
575 
577 
578  q.append(std::move(buf));
579  pipeline->read(q);
580  EXPECT_EQ(called, 1);
581 }
582 
583 TEST(LineBasedFrameDecoder, CarriageNewLineOnly) {
584  auto pipeline = Pipeline<IOBufQueue&, std::unique_ptr<IOBuf>>::create();
585  int called = 0;
586 
587  (*pipeline)
588  .addBack(LineBasedFrameDecoder(
589  10, true, LineBasedFrameDecoder::TerminatorType::CARRIAGENEWLINE))
590  .addBack(test::FrameTester([&](std::unique_ptr<IOBuf> buf) {
591  auto sz = buf->computeChainDataLength();
592  called++;
593  EXPECT_EQ(sz, 1);
594  }))
595  .finalize();
596 
597  auto buf = createZeroedBuffer(3);
598  RWPrivateCursor c(buf.get());
599  c.write<char>('\n');
600  c.write<char>('\r');
601  c.write<char>('\n');
602 
604 
605  q.append(std::move(buf));
606  pipeline->read(q);
607  EXPECT_EQ(called, 1);
608 }
void append(std::unique_ptr< folly::IOBuf > &&buf, bool pack=false)
Definition: IOBufQueue.cpp:143
#define ASSERT_EQ(val1, val2)
Definition: gtest.h:1956
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
void Fail(const char *msg)
std::enable_if< std::is_arithmetic< T >::value >::type write(T value)
Definition: Cursor.h:737
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
static Options cacheChainLength()
Definition: IOBufQueue.h:83
void SimpleTest(std::shared_ptr< folly::Executor > const &parent)
std::size_t computeChainDataLength() const
Definition: IOBuf.cpp:501
char c
TEST(SequencedExecutor, CPUThreadPoolExecutor)