]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/libs/iostreams/test/zstd_test.cpp
import new upstream nautilus stable release 14.2.8
[ceph.git] / ceph / src / boost / libs / iostreams / test / zstd_test.cpp
1 // (C) COPYRIGHT 2018 Reimar Döffinger
2 // Based on zstd_test.cpp by:
3 // (C) COPYRIGHT 2017 ARM Limited
4 // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
5 // (C) Copyright 2004-2007 Jonathan Turkanis
6 // Distributed under the Boost Software License, Version 1.0. (See accompanying
7 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
8
9 // See http://www.boost.org/libs/iostreams for documentation.
10
11 // Note: basically a copy-paste of the gzip test
12
13 #include <cstddef>
14 #include <string>
15 #include <boost/iostreams/copy.hpp>
16 #include <boost/iostreams/device/array.hpp>
17 #include <boost/iostreams/device/back_inserter.hpp>
18 #include <boost/iostreams/filter/zstd.hpp>
19 #include <boost/iostreams/filter/test.hpp>
20 #include <boost/iostreams/filtering_stream.hpp>
21 #include <boost/ref.hpp>
22 #include <boost/range/iterator_range.hpp>
23 #include <boost/test/test_tools.hpp>
24 #include <boost/test/unit_test.hpp>
25 #include "detail/sequence.hpp"
26 #include "detail/verification.hpp"
27
28 using namespace boost;
29 using namespace boost::iostreams;
30 using namespace boost::iostreams::test;
31 namespace io = boost::iostreams;
32 using boost::unit_test::test_suite;
33
34 struct zstd_alloc : std::allocator<char> {
35 zstd_alloc() { }
36 zstd_alloc(const zstd_alloc& other) { }
37 template<typename T>
38 zstd_alloc(const std::allocator<T>& other) { }
39 };
40
41 void compression_test()
42 {
43 text_sequence data;
44
45 // Test compression and decompression with custom allocator
46 BOOST_CHECK(
47 test_filter_pair( basic_zstd_compressor<zstd_alloc>(),
48 basic_zstd_decompressor<zstd_alloc>(),
49 std::string(data.begin(), data.end()) )
50 );
51 }
52
53 void multiple_member_test()
54 {
55 text_sequence data;
56 std::vector<char> temp, dest;
57
58 // Write compressed data to temp, twice in succession
59 filtering_ostream out;
60 out.push(zstd_compressor());
61 out.push(io::back_inserter(temp));
62 io::copy(make_iterator_range(data), out);
63 out.push(io::back_inserter(temp));
64 io::copy(make_iterator_range(data), out);
65 BOOST_CHECK(std::equal(temp.begin(), temp.begin() + temp.size()/2, temp.begin() + temp.size()/2));
66
67 // Read compressed data from temp into dest
68 filtering_istream in;
69 in.push(zstd_decompressor());
70 in.push(array_source(&temp[0], temp.size()));
71 io::copy(in, io::back_inserter(dest));
72
73 // Check that dest consists of two copies of data
74 BOOST_REQUIRE_EQUAL(data.size() * 2, dest.size());
75 BOOST_CHECK(std::equal(data.begin(), data.end(), dest.begin()));
76 BOOST_CHECK(std::equal(data.begin(), data.end(), dest.begin() + dest.size() / 2));
77
78 dest.clear();
79 io::copy(
80 array_source(&temp[0], temp.size()),
81 io::compose(zstd_decompressor(), io::back_inserter(dest)));
82
83 // Check that dest consists of two copies of data
84 BOOST_REQUIRE_EQUAL(data.size() * 2, dest.size());
85 BOOST_CHECK(std::equal(data.begin(), data.end(), dest.begin()));
86 BOOST_CHECK(std::equal(data.begin(), data.end(), dest.begin() + dest.size() / 2));
87 }
88
89 void array_source_test()
90 {
91 std::string data = "simple test string.";
92 std::string encoded;
93
94 filtering_ostream out;
95 out.push(zstd_compressor());
96 out.push(io::back_inserter(encoded));
97 io::copy(make_iterator_range(data), out);
98
99 std::string res;
100 io::array_source src(encoded.data(),encoded.length());
101 io::copy(io::compose(io::zstd_decompressor(), src), io::back_inserter(res));
102
103 BOOST_CHECK_EQUAL(data, res);
104 }
105
106 void empty_file_test()
107 {
108 // This test is in response to https://svn.boost.org/trac/boost/ticket/5237
109 // The previous implementation of gzip_compressor only wrote the gzip file
110 // header when the first bytes of uncompressed input were processed, causing
111 // incorrect behavior for empty files
112 BOOST_CHECK(
113 test_filter_pair( zstd_compressor(),
114 zstd_decompressor(),
115 std::string() )
116 );
117 }
118
119 void multipart_test()
120 {
121 // This test verifies that the zstd_decompressor properly handles a file
122 // that consists of multiple concatenated files (matches unzstd behaviour)
123 static const char multipart_file[] = {
124 '\x28', '\xb5', '\x2f', '\xfd', '\x24', '\x15', '\x95', '\x00', '\x00', '\x50', '\x4c', '\x69',
125 '\x6e', '\x65', '\x20', '\x31', '\x0a', '\x32', '\x33', '\x0a', '\x02', '\x00', '\x60', '\x84',
126 '\xae', '\x62', '\x04', '\x19', '\xf8', '\xe1', '\x2d', '\x28', '\xb5', '\x2f', '\xfd', '\x24',
127 '\x15', '\x95', '\x00', '\x00', '\x50', '\x4c', '\x69', '\x6e', '\x65', '\x20', '\x34', '\x0a',
128 '\x35', '\x36', '\x0a', '\x02', '\x00', '\x60', '\x84', '\xae', '\x62', '\x04', '\x5f', '\xcf',
129 '\xd5', '\xb8', '\x28', '\xb5', '\x2f', '\xfd', '\x24', '\x00', '\x01', '\x00', '\x00', '\x99',
130 '\xe9', '\xd8', '\x51', '\x28', '\xb5', '\x2f', '\xfd', '\x24', '\x15', '\x95', '\x00', '\x00',
131 '\x50', '\x4c', '\x69', '\x6e', '\x65', '\x20', '\x37', '\x0a', '\x38', '\x39', '\x0a', '\x02',
132 '\x00', '\x60', '\x84', '\xae', '\x62', '\x04', '\x94', '\x13', '\xdb', '\xae'
133 };
134
135 filtering_istream in;
136 std::string line;
137
138 in.push(zstd_decompressor());
139 in.push(io::array_source(multipart_file, sizeof(multipart_file)));
140
141 // First part
142 std::getline(in, line);
143 BOOST_CHECK_EQUAL("Line 1", line);
144 std::getline(in, line);
145 BOOST_CHECK_EQUAL("Line 2", line);
146 std::getline(in, line);
147 BOOST_CHECK_EQUAL("Line 3", line);
148
149 // Second part immediately follows
150 std::getline(in, line);
151 BOOST_CHECK_EQUAL("Line 4", line);
152 std::getline(in, line);
153 BOOST_CHECK_EQUAL("Line 5", line);
154 std::getline(in, line);
155 BOOST_CHECK_EQUAL("Line 6", line);
156
157 // Then an empty part, followed by one last 3-line part.
158 std::getline(in, line);
159 BOOST_CHECK_EQUAL("Line 7", line);
160 std::getline(in, line);
161 BOOST_CHECK_EQUAL("Line 8", line);
162 std::getline(in, line);
163 BOOST_CHECK_EQUAL("Line 9", line);
164
165 // Check for zstd errors too.
166 BOOST_CHECK(!in.bad());
167 }
168
169 test_suite* init_unit_test_suite(int, char* [])
170 {
171 test_suite* test = BOOST_TEST_SUITE("zstd test");
172 test->add(BOOST_TEST_CASE(&compression_test));
173 test->add(BOOST_TEST_CASE(&multiple_member_test));
174 test->add(BOOST_TEST_CASE(&array_source_test));
175 test->add(BOOST_TEST_CASE(&empty_file_test));
176 test->add(BOOST_TEST_CASE(&multipart_test));
177 return test;
178 }