]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rgw/test_rgw_compression.cc
update sources to v12.1.1
[ceph.git] / ceph / src / test / rgw / test_rgw_compression.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3#include "gtest/gtest.h"
4
5#include "rgw/rgw_compression.h"
6
224ce89b
WB
7class ut_get_sink : public RGWGetDataCB {
8 bufferlist sink;
9public:
10 ut_get_sink() {}
11 virtual ~ut_get_sink() {}
12
13 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override
14 {
15 auto bl_buffers = bl.buffers();
16 auto i = bl_buffers.begin();
17 while (bl_len > 0)
18 {
19 assert(i != bl_buffers.end());
20 off_t len = std::min<off_t>(bl_len, i->length());
21 sink.append(*i, 0, len);
22 bl_len -= len;
23 i++;
24 }
25 return 0;
26 }
27 bufferlist& get_sink()
28 {
29 return sink;
30 }
31};
32
33class ut_get_sink_size : public RGWGetDataCB {
34 size_t max_size = 0;
35public:
36 ut_get_sink_size() {}
37 virtual ~ut_get_sink_size() {}
38
39 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override
40 {
41 if (bl_len > (off_t)max_size)
42 max_size = bl_len;
43 return 0;
44 }
45 size_t get_size()
46 {
47 return max_size;
48 }
49};
50
51class ut_put_sink: public RGWPutObjDataProcessor
52{
53 bufferlist sink;
54public:
55 ut_put_sink(){}
56 virtual ~ut_put_sink(){}
57 int handle_data(bufferlist& bl, off_t ofs, void **phandle, rgw_raw_obj *pobj, bool *again) override
58 {
59 sink.append(bl);
60 *again = false;
61 return 0;
62 }
63 int throttle_data(void *handle, const rgw_raw_obj& obj, uint64_t size, bool need_to_wait) override
64 {
65 return 0;
66 }
67 bufferlist& get_sink()
68 {
69 return sink;
70 }
71};
72
73
7c673cae
FG
74struct MockGetDataCB : public RGWGetDataCB {
75 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) override {
76 return 0;
77 }
78} cb;
79
80using range_t = std::pair<off_t, off_t>;
81
82// call filter->fixup_range() and return the range as a pair. this makes it easy
83// to fit on a single line for ASSERT_EQ()
84range_t fixup_range(RGWGetObj_Decompress *filter, off_t ofs, off_t end)
85{
86 filter->fixup_range(ofs, end);
87 return {ofs, end};
88}
89
90
91TEST(Decompress, FixupRangePartial)
92{
93 RGWCompressionInfo cs_info;
94
95 // array of blocks with original len=8, compressed to len=6
96 auto& blocks = cs_info.blocks;
97 blocks.emplace_back(compression_block{0, 0, 6});
98 blocks.emplace_back(compression_block{8, 6, 6});
99 blocks.emplace_back(compression_block{16, 12, 6});
100 blocks.emplace_back(compression_block{24, 18, 6});
101
102 const bool partial = true;
103 RGWGetObj_Decompress decompress(g_ceph_context, &cs_info, partial, &cb);
104
105 // test translation from logical ranges to compressed ranges
31f18b77
FG
106 ASSERT_EQ(range_t(0, 5), fixup_range(&decompress, 0, 1));
107 ASSERT_EQ(range_t(0, 5), fixup_range(&decompress, 1, 7));
108 ASSERT_EQ(range_t(0, 11), fixup_range(&decompress, 7, 8));
109 ASSERT_EQ(range_t(0, 11), fixup_range(&decompress, 0, 9));
110 ASSERT_EQ(range_t(0, 11), fixup_range(&decompress, 7, 9));
111 ASSERT_EQ(range_t(6, 11), fixup_range(&decompress, 8, 9));
112 ASSERT_EQ(range_t(6, 17), fixup_range(&decompress, 8, 16));
113 ASSERT_EQ(range_t(6, 17), fixup_range(&decompress, 8, 17));
114 ASSERT_EQ(range_t(12, 23), fixup_range(&decompress, 16, 24));
115 ASSERT_EQ(range_t(12, 23), fixup_range(&decompress, 16, 999));
116 ASSERT_EQ(range_t(18, 23), fixup_range(&decompress, 998, 999));
7c673cae 117}
224ce89b
WB
118
119TEST(Compress, LimitedChunkSize)
120{
121 CompressorRef plugin;
122 plugin = Compressor::create(g_ceph_context, Compressor::COMP_ALG_ZLIB);
123 ASSERT_NE(plugin.get(), nullptr);
124
125 for (size_t s = 100 ; s < 10000000 ; s = s*5/4)
126 {
127 bufferptr bp(s);
128 bufferlist bl;
129 bl.append(bp);
130
131 void* handle;
132 rgw_raw_obj obj;
133 bool again = false;
134
135 ut_put_sink c_sink;
136 RGWPutObj_Compress compressor(g_ceph_context, plugin, &c_sink);
137 compressor.handle_data(bl, 0, &handle, &obj, &again);
138
139 bufferlist empty;
140 compressor.handle_data(empty, s, &handle, &obj, &again);
141
142 RGWCompressionInfo cs_info;
143 cs_info.compression_type = plugin->get_type_name();
144 cs_info.orig_size = s;
145 cs_info.blocks = move(compressor.get_compression_blocks());
146
147 ut_get_sink_size d_sink;
148 RGWGetObj_Decompress decompress(g_ceph_context, &cs_info, false, &d_sink);
149
150 off_t f_begin = 0;
151 off_t f_end = s - 1;
152 decompress.fixup_range(f_begin, f_end);
153
154 decompress.handle_data(c_sink.get_sink(), 0, c_sink.get_sink().length());
155 decompress.handle_data(empty, 0, 0);
156
157 ASSERT_LE(d_sink.get_size(), (size_t)g_ceph_context->_conf->rgw_max_chunk_size);
158 }
159}
160
161
162TEST(Compress, BillionZeros)
163{
164 CompressorRef plugin;
165 ut_put_sink c_sink;
166 plugin = Compressor::create(g_ceph_context, Compressor::COMP_ALG_ZLIB);
167 ASSERT_NE(plugin.get(), nullptr);
168 RGWPutObj_Compress compressor(g_ceph_context, plugin, &c_sink);
169
170 constexpr size_t size = 1000000;
171 bufferptr bp(size);
172 bufferlist bl;
173 bl.append(bp);
174
175 void* handle;
176 rgw_raw_obj obj;
177 bool again = false;
178
179 for (int i=0; i<1000;i++)
180 compressor.handle_data(bl, size*i, &handle, &obj, &again);
181
182 bufferlist empty;
183 compressor.handle_data(empty, size*1000, &handle, &obj, &again);
184
185 RGWCompressionInfo cs_info;
186 cs_info.compression_type = plugin->get_type_name();
187 cs_info.orig_size = size*1000;
188 cs_info.blocks = move(compressor.get_compression_blocks());
189
190 ut_get_sink d_sink;
191 RGWGetObj_Decompress decompress(g_ceph_context, &cs_info, false, &d_sink);
192
193 off_t f_begin = 0;
194 off_t f_end = size*1000 - 1;
195 decompress.fixup_range(f_begin, f_end);
196
197 decompress.handle_data(c_sink.get_sink(), 0, c_sink.get_sink().length());
198 decompress.handle_data(empty, 0, 0);
199
200 ASSERT_EQ(d_sink.get_sink().length() , size*1000);
201}