#include <gtest/gtest.h>
#include <folly/wangle/codec/FixedLengthFrameDecoder.h>
-#include <folly/wangle/codec/LineBasedFrameDecoder.h>
#include <folly/wangle/codec/LengthFieldBasedFrameDecoder.h>
#include <folly/wangle/codec/LengthFieldPrepender.h>
+#include <folly/wangle/codec/LineBasedFrameDecoder.h>
using namespace folly;
using namespace folly::wangle;
}
};
-TEST(CodecTest, FixedLengthFrameDecoder) {
+TEST(FixedLengthFrameDecoder, FailWhenLengthFieldEndOffset) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 3);
}
-TEST(CodecTest, LengthFieldFramePipeline) {
+TEST(LengthFieldFramePipeline, SimpleTest) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFramePipelineLittleEndian) {
+TEST(LengthFieldFramePipeline, LittleEndian) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderSimple) {
+TEST(LengthFieldFrameDecoder, Simple) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderNoStrip) {
+TEST(LengthFieldFrameDecoder, NoStrip) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderAdjustment) {
+TEST(LengthFieldFrameDecoder, Adjustment) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderPreHeader) {
+TEST(LengthFieldFrameDecoder, PreHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderPostHeader) {
+TEST(LengthFieldFrameDecoder, PostHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeader) {
+TEST(LengthFieldFrameDecoderStrip, PrePostHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LengthFieldFrameDecoderStripPrePostHeaderFrameInclHeader) {
+TEST(LengthFieldFrameDecoder, StripPrePostHeaderFrameInclHeader) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LineBasedFrameDecoder) {
+TEST(LengthFieldFrameDecoder, FailTestLengthFieldEndOffset) {
+ ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
+ int called = 0;
+
+ pipeline
+ .addBack(LengthFieldBasedFrameDecoder(4, 10, 4, -2, 4))
+ .addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
+ ASSERT_EQ(nullptr, buf);
+ called++;
+ }))
+ .finalize();
+
+ auto bufFrame = IOBuf::create(8);
+ bufFrame->append(8);
+ RWPrivateCursor c(bufFrame.get());
+ c.writeBE((uint32_t)0); // frame size
+ c.write((uint32_t)0); // crap
+
+ IOBufQueue q(IOBufQueue::cacheChainLength());
+
+ q.append(std::move(bufFrame));
+ pipeline.read(q);
+ EXPECT_EQ(called, 1);
+}
+
+TEST(LengthFieldFrameDecoder, FailTestLengthFieldFrameSize) {
+ ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
+ int called = 0;
+
+ pipeline
+ .addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 4))
+ .addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
+ ASSERT_EQ(nullptr, buf);
+ called++;
+ }))
+ .finalize();
+
+ auto bufFrame = IOBuf::create(16);
+ bufFrame->append(16);
+ RWPrivateCursor c(bufFrame.get());
+ c.writeBE((uint32_t)12); // frame size
+ c.write((uint32_t)0); // nothing
+ c.write((uint32_t)0); // nothing
+ c.write((uint32_t)0); // nothing
+
+ IOBufQueue q(IOBufQueue::cacheChainLength());
+
+ q.append(std::move(bufFrame));
+ pipeline.read(q);
+ EXPECT_EQ(called, 1);
+}
+
+TEST(LengthFieldFrameDecoder, FailTestLengthFieldInitialBytes) {
+ ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
+ int called = 0;
+
+ pipeline
+ .addBack(LengthFieldBasedFrameDecoder(4, 10, 0, 0, 10))
+ .addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
+ ASSERT_EQ(nullptr, buf);
+ called++;
+ }))
+ .finalize();
+
+ auto bufFrame = IOBuf::create(16);
+ bufFrame->append(16);
+ RWPrivateCursor c(bufFrame.get());
+ c.writeBE((uint32_t)4); // frame size
+ c.write((uint32_t)0); // nothing
+ c.write((uint32_t)0); // nothing
+ c.write((uint32_t)0); // nothing
+
+ IOBufQueue q(IOBufQueue::cacheChainLength());
+
+ q.append(std::move(bufFrame));
+ pipeline.read(q);
+ EXPECT_EQ(called, 1);
+}
+
+TEST(LineBasedFrameDecoder, Simple) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 2);
}
-TEST(CodecTest, LineBasedFrameDecoderSaveDelimiter) {
+TEST(LineBasedFrameDecoder, SaveDelimiter) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 2);
}
-TEST(CodecTest, LineBasedFrameDecoderFail) {
+TEST(LineBasedFrameDecoder, Fail) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
pipeline
.addBack(LineBasedFrameDecoder(10))
.addBack(FrameTester([&](std::unique_ptr<IOBuf> buf) {
+ ASSERT_EQ(nullptr, buf);
called++;
}))
.finalize();
EXPECT_EQ(called, 2);
}
-TEST(CodecTest, LineBasedFrameDecoderNewLineOnly) {
+TEST(LineBasedFrameDecoder, NewLineOnly) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
EXPECT_EQ(called, 1);
}
-TEST(CodecTest, LineBasedFrameDecoderCarriageNewLineOnly) {
+TEST(LineBasedFrameDecoder, CarriageNewLineOnly) {
ChannelPipeline<IOBufQueue&, std::unique_ptr<IOBuf>> pipeline;
int called = 0;
std::unique_ptr<IOBuf> LengthFieldBasedFrameDecoder::decode(
Context* ctx, IOBufQueue& buf, size_t&) {
// discarding too long frame
- if (buf.chainLength() <= lengthFieldEndOffset_) {
+ if (buf.chainLength() < lengthFieldEndOffset_) {
return nullptr;
}
frameLength += lengthAdjustment_ + lengthFieldEndOffset_;
if (frameLength < lengthFieldEndOffset_) {
- throw std::runtime_error("Frame too small");
+ buf.trimStart(lengthFieldEndOffset_);
+ ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
+ "Frame too small"));
+ return nullptr;
}
if (frameLength > maxFrameLength_) {
- throw std::runtime_error("Frame larger than " +
- folly::to<std::string>(maxFrameLength_));
+ buf.trimStart(frameLength);
+ ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
+ "Frame larger than " +
+ folly::to<std::string>(maxFrameLength_)));
+ return nullptr;
}
if (buf.chainLength() < frameLength) {
}
if (initialBytesToStrip_ > frameLength) {
- throw std::runtime_error("InitialBytesToSkip larger than frame");
+ buf.trimStart(frameLength);
+ ctx->fireReadException(folly::make_exception_wrapper<std::runtime_error>(
+ "InitialBytesToSkip larger than frame"));
+ return nullptr;
}
buf.trimStart(initialBytesToStrip_);