proxygen
ZlibTests.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015-present, Facebook, Inc.
3  * All rights reserved.
4  *
5  * This source code is licensed under the BSD-style license found in the
6  * LICENSE file in the root directory of this source tree. An additional grant
7  * of patent rights can be found in the PATENTS file in the same directory.
8  *
9  */
10 #include <folly/Random.h>
11 #include <folly/ScopeGuard.h>
12 #include <folly/io/Cursor.h>
13 #include <folly/io/IOBuf.h>
15 #include <glog/logging.h>
18 
19 using namespace folly;
20 using namespace proxygen;
21 using namespace std;
22 using namespace testing;
23 
24 class ZlibTests : public testing::Test {};
25 
26 std::unique_ptr<folly::IOBuf> makeBuf(uint32_t size) {
27  auto out = folly::IOBuf::create(size);
28  out->append(size);
29  // fill with random junk
30  folly::io::RWPrivateCursor cursor(out.get());
31  while (cursor.length() >= 8) {
33  }
34  while (cursor.length()) {
35  cursor.write<uint8_t>((uint8_t)folly::Random::rand32());
36  }
37  return out;
38 }
39 
41  std::unique_ptr<IOBuf> original,
42  std::unique_ptr<IOBuf> compressed) {
43  auto zd = std::make_unique<ZlibStreamDecompressor>(type);
44 
45  auto decompressed = zd->decompress(compressed.get());
46  ASSERT_FALSE(zd->hasError()) << "Decompression error. r=" << zd->getStatus();
47 
49  ASSERT_TRUE(eq(original, decompressed));
50 }
51 
53  int level,
54  unique_ptr<IOBuf> buf) {
55 
56  unique_ptr<IOBuf> compressed;
57  unique_ptr<IOBuf> decompressed;
58 
59  unique_ptr<ZlibStreamCompressor> zc(new ZlibStreamCompressor(type, level));
60 
61  compressed = zc->compress(buf.get(), true);
62  ASSERT_FALSE(zc->hasError()) << "Compression error. r=" << zc->getStatus();
63 
64  verify(type, std::move(buf), std::move(compressed));
65 }
66 
67 // Try many different sizes because we've hit truncation problems before
68 TEST_F(ZlibTests, CompressDecompressGzip5000) {
70  { compressThenDecompress(ZlibCompressionType::GZIP, 6, makeBuf(5000)); });
71 }
72 
73 TEST_F(ZlibTests, CompressDecompressGzip2000) {
75  { compressThenDecompress(ZlibCompressionType::GZIP, 6, makeBuf(2000)); });
76 }
77 
78 TEST_F(ZlibTests, CompressDecompressGzip1024) {
80  { compressThenDecompress(ZlibCompressionType::GZIP, 6, makeBuf(1024)); });
81 }
82 
83 TEST_F(ZlibTests, CompressDecompressGzip500) {
85  { compressThenDecompress(ZlibCompressionType::GZIP, 6, makeBuf(500)); });
86 }
87 
88 TEST_F(ZlibTests, CompressDecompressGzip50) {
90  { compressThenDecompress(ZlibCompressionType::GZIP, 6, makeBuf(50)); });
91 }
92 
93 TEST_F(ZlibTests, CompressDecompressDeflate) {
95  compressThenDecompress(ZlibCompressionType::DEFLATE, 6, makeBuf(500));
96  });
97 }
98 
99 TEST_F(ZlibTests, CompressDecompressEmpty) {
101  { compressThenDecompress(ZlibCompressionType::GZIP, 4, makeBuf(0)); });
102 }
103 
104 TEST_F(ZlibTests, CompressDecompressChain) {
106  auto buf = makeBuf(4);
107  buf->appendChain(makeBuf(38));
108  buf->appendChain(makeBuf(12));
109  buf->appendChain(makeBuf(0));
110  compressThenDecompress(ZlibCompressionType::GZIP, 6, std::move(buf));
111  });
112 }
113 
114 TEST_F(ZlibTests, CompressDecompressStreaming) {
116  auto compressor =
117  std::make_unique<ZlibStreamCompressor>(ZlibCompressionType::GZIP, 6);
118 
119  auto first = makeBuf(38);
120  auto out = compressor->compress(first.get(), false);
121 
122  auto second = makeBuf(12);
123  out->prev()->appendChain(compressor->compress(second.get(), false));
124  first->prev()->appendChain(std::move(second));
125 
126  auto third = makeBuf(4096); // Larger than buffer size
127  out->prev()->appendChain(compressor->compress(third.get(), false));
128  first->prev()->appendChain(std::move(third));
129 
130  auto empty = IOBuf::create(0);
131  out->prev()->appendChain(compressor->compress(empty.get(), true));
132 
133  verify(ZlibCompressionType::GZIP, std::move(first), std::move(out));
134  });
135 }
136 
137 TEST_F(ZlibTests, CompressDecompressSmallBuffer) {
139  auto oldFlag = FLAGS_zlib_compressor_buffer_growth;
140  auto guard = folly::makeGuard([&] {
141  FLAGS_zlib_compressor_buffer_growth = oldFlag;
142  });
143  // NB: This is picked intentionally so we don't generate multiple
144  // zlib flush markers as ZlibStreamDecompressor fatals on them.
145  FLAGS_zlib_compressor_buffer_growth = 10;
146  compressThenDecompress(ZlibCompressionType::GZIP, 4, makeBuf(127));
147  });
148 }
static std::unique_ptr< IOBuf > create(std::size_t capacity)
Definition: IOBuf.cpp:229
std::enable_if< std::is_arithmetic< T >::value >::type write(T value)
Definition: Cursor.h:737
PskType type
std::unique_ptr< folly::IOBuf > compress(const folly::IOBuf *in, bool trailer=true)
constexpr detail::Map< Move > move
Definition: Base-inl.h:2567
STL namespace.
—— Concurrent Priority Queue Implementation ——
Definition: AtomicBitSet.h:29
std::unique_ptr< folly::IOBuf > makeBuf(uint32_t size)
Definition: ZlibTests.cpp:26
void compressThenDecompress(ZlibCompressionType type, int level, unique_ptr< IOBuf > buf)
Definition: ZlibTests.cpp:52
constexpr auto size(C const &c) -> decltype(c.size())
Definition: Access.h:45
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
GuardImpl guard(ErrorHandler &&handler)
Definition: Base.h:840
TEST_F(AsyncSSLSocketWriteTest, write_coalescing1)
void verify(ZlibCompressionType type, std::unique_ptr< IOBuf > original, std::unique_ptr< IOBuf > compressed)
Definition: ZlibTests.cpp:40
FOLLY_NODISCARD detail::ScopeGuardImplDecay< F, true > makeGuard(F &&f) noexcept(noexcept(detail::ScopeGuardImplDecay< F, true >(static_cast< F && >(f))))
Definition: ScopeGuard.h:184
#define ASSERT_NO_FATAL_FAILURE(statement)
Definition: gtest.h:2099
#define ASSERT_FALSE(condition)
Definition: gtest.h:1868
static uint32_t rand32()
Definition: Random.h:213
static uint64_t rand64()
Definition: Random.h:263
#define ASSERT_TRUE(condition)
Definition: gtest.h:1865
constexpr detail::First first
Definition: Base-inl.h:2553