]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rgw/test_log_backing.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / test / rgw / test_log_backing.cc
CommitLineData
f67539c2
TL
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2019 Red Hat, Inc.
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#include "rgw_log_backing.h"
16
17#include <cerrno>
18#include <iostream>
19#include <string_view>
20
21#undef FMT_HEADER_ONLY
22#define FMT_HEADER_ONLY 1
23#include <fmt/format.h>
24
25#include "include/types.h"
26#include "include/rados/librados.hpp"
27
28#include "test/librados/test_cxx.h"
29#include "global/global_context.h"
30
31#include "cls/log/cls_log_client.h"
32
33#include "rgw/rgw_tools.h"
34#include "rgw/cls_fifo_legacy.h"
35
36#include "gtest/gtest.h"
37
38namespace lr = librados;
39namespace cb = ceph::buffer;
40namespace fifo = rados::cls::fifo;
41namespace RCf = rgw::cls::fifo;
42
b3b6e05e
TL
43auto cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
44const DoutPrefix dp(cct, 1, "test log backing: ");
45
f67539c2
TL
46class LogBacking : public testing::Test {
47protected:
48 static constexpr int SHARDS = 3;
49 const std::string pool_name = get_temp_pool_name();
50 lr::Rados rados;
51 lr::IoCtx ioctx;
52 lr::Rados rados2;
53 lr::IoCtx ioctx2;
54
55 void SetUp() override {
56 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
57 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
58 connect_cluster_pp(rados2);
59 ASSERT_EQ(0, rados2.ioctx_create(pool_name.c_str(), ioctx2));
60 }
61 void TearDown() override {
62 destroy_one_pool_pp(pool_name, rados);
63 }
64
65 std::string get_oid(uint64_t gen_id, int i) const {
66 return (gen_id > 0 ?
67 fmt::format("shard@G{}.{}", gen_id, i) :
68 fmt::format("shard.{}", i));
69 }
70
71 void make_omap() {
72 for (int i = 0; i < SHARDS; ++i) {
73 using ceph::encode;
74 lr::ObjectWriteOperation op;
75 cb::list bl;
76 encode(i, bl);
77 cls_log_add(op, ceph_clock_now(), {}, "meow", bl);
b3b6e05e 78 auto r = rgw_rados_operate(&dp, ioctx, get_oid(0, i), &op, null_yield);
f67539c2
TL
79 ASSERT_GE(r, 0);
80 }
81 }
82
83 void add_omap(int i) {
84 using ceph::encode;
85 lr::ObjectWriteOperation op;
86 cb::list bl;
87 encode(i, bl);
88 cls_log_add(op, ceph_clock_now(), {}, "meow", bl);
b3b6e05e 89 auto r = rgw_rados_operate(&dp, ioctx, get_oid(0, i), &op, null_yield);
f67539c2
TL
90 ASSERT_GE(r, 0);
91 }
92
93 void empty_omap() {
94 for (int i = 0; i < SHARDS; ++i) {
95 auto oid = get_oid(0, i);
96 std::string to_marker;
97 {
98 lr::ObjectReadOperation op;
99 std::list<cls_log_entry> entries;
100 bool truncated = false;
101 cls_log_list(op, {}, {}, {}, 1, entries, &to_marker, &truncated);
b3b6e05e 102 auto r = rgw_rados_operate(&dp, ioctx, oid, &op, nullptr, null_yield);
f67539c2
TL
103 ASSERT_GE(r, 0);
104 ASSERT_FALSE(entries.empty());
105 }
106 {
107 lr::ObjectWriteOperation op;
108 cls_log_trim(op, {}, {}, {}, to_marker);
b3b6e05e 109 auto r = rgw_rados_operate(&dp, ioctx, oid, &op, null_yield);
f67539c2
TL
110 ASSERT_GE(r, 0);
111 }
112 {
113 lr::ObjectReadOperation op;
114 std::list<cls_log_entry> entries;
115 bool truncated = false;
116 cls_log_list(op, {}, {}, {}, 1, entries, &to_marker, &truncated);
b3b6e05e 117 auto r = rgw_rados_operate(&dp, ioctx, oid, &op, nullptr, null_yield);
f67539c2
TL
118 ASSERT_GE(r, 0);
119 ASSERT_TRUE(entries.empty());
120 }
121 }
122 }
123
124 void make_fifo()
125 {
126 for (int i = 0; i < SHARDS; ++i) {
127 std::unique_ptr<RCf::FIFO> fifo;
b3b6e05e 128 auto r = RCf::FIFO::create(&dp, ioctx, get_oid(0, i), &fifo, null_yield);
f67539c2
TL
129 ASSERT_EQ(0, r);
130 ASSERT_TRUE(fifo);
131 }
132 }
133
134 void add_fifo(int i)
135 {
136 using ceph::encode;
137 std::unique_ptr<RCf::FIFO> fifo;
b3b6e05e 138 auto r = RCf::FIFO::open(&dp, ioctx, get_oid(0, i), &fifo, null_yield);
f67539c2
TL
139 ASSERT_GE(0, r);
140 ASSERT_TRUE(fifo);
141 cb::list bl;
142 encode(i, bl);
b3b6e05e 143 r = fifo->push(&dp, bl, null_yield);
f67539c2
TL
144 ASSERT_GE(0, r);
145 }
146
147 void assert_empty() {
148 std::vector<lr::ObjectItem> result;
149 lr::ObjectCursor next;
150 auto r = ioctx.object_list(ioctx.object_list_begin(), ioctx.object_list_end(),
151 100, {}, &result, &next);
152 ASSERT_GE(r, 0);
153 ASSERT_TRUE(result.empty());
154 }
155};
156
157TEST_F(LogBacking, TestOmap)
158{
159 make_omap();
b3b6e05e 160 auto stat = log_backing_type(&dp, ioctx, log_type::fifo, SHARDS,
f67539c2
TL
161 [this](int shard){ return get_oid(0, shard); },
162 null_yield);
163 ASSERT_EQ(log_type::omap, *stat);
164}
165
166TEST_F(LogBacking, TestOmapEmpty)
167{
b3b6e05e 168 auto stat = log_backing_type(&dp, ioctx, log_type::omap, SHARDS,
f67539c2
TL
169 [this](int shard){ return get_oid(0, shard); },
170 null_yield);
171 ASSERT_EQ(log_type::omap, *stat);
172}
173
174TEST_F(LogBacking, TestFIFO)
175{
176 make_fifo();
b3b6e05e 177 auto stat = log_backing_type(&dp, ioctx, log_type::fifo, SHARDS,
f67539c2
TL
178 [this](int shard){ return get_oid(0, shard); },
179 null_yield);
180 ASSERT_EQ(log_type::fifo, *stat);
181}
182
183TEST_F(LogBacking, TestFIFOEmpty)
184{
b3b6e05e 185 auto stat = log_backing_type(&dp, ioctx, log_type::fifo, SHARDS,
f67539c2
TL
186 [this](int shard){ return get_oid(0, shard); },
187 null_yield);
188 ASSERT_EQ(log_type::fifo, *stat);
189}
190
191TEST(CursorGen, RoundTrip) {
192 const auto pcurs = "fded"sv;
193 {
194 auto gc = gencursor(0, pcurs);
195 ASSERT_EQ(pcurs, gc);
196 auto [gen, cursor] = cursorgen(gc);
197 ASSERT_EQ(0, gen);
198 ASSERT_EQ(pcurs, cursor);
199 }
200 {
201 auto gc = gencursor(53, pcurs);
202 ASSERT_NE(pcurs, gc);
203 auto [gen, cursor] = cursorgen(gc);
204 ASSERT_EQ(53, gen);
205 ASSERT_EQ(pcurs, cursor);
206 }
207}
208
209class generations final : public logback_generations {
210public:
211
212 entries_t got_entries;
213 std::optional<uint64_t> tail;
214
215 using logback_generations::logback_generations;
216
217 bs::error_code handle_init(entries_t e) noexcept {
218 got_entries = e;
219 return {};
220 }
221
222 bs::error_code handle_new_gens(entries_t e) noexcept {
223 got_entries = e;
224 return {};
225 }
226
227 bs::error_code handle_empty_to(uint64_t new_tail) noexcept {
228 tail = new_tail;
229 return {};
230 }
231};
232
233TEST_F(LogBacking, GenerationSingle)
234{
235 auto lgr = logback_generations::init<generations>(
b3b6e05e 236 &dp, ioctx, "foobar", [this](uint64_t gen_id, int shard) {
f67539c2
TL
237 return get_oid(gen_id, shard);
238 }, SHARDS, log_type::fifo, null_yield);
239 ASSERT_TRUE(lgr);
240
241 auto lg = std::move(*lgr);
242
243 ASSERT_EQ(0, lg->got_entries.begin()->first);
244
245 ASSERT_EQ(0, lg->got_entries[0].gen_id);
246 ASSERT_EQ(log_type::fifo, lg->got_entries[0].type);
247 ASSERT_FALSE(lg->got_entries[0].pruned);
248
b3b6e05e 249 auto ec = lg->empty_to(&dp, 0, null_yield);
f67539c2
TL
250 ASSERT_TRUE(ec);
251
f67539c2
TL
252 lg.reset();
253
254 lg = *logback_generations::init<generations>(
b3b6e05e 255 &dp, ioctx, "foobar", [this](uint64_t gen_id, int shard) {
f67539c2
TL
256 return get_oid(gen_id, shard);
257 }, SHARDS, log_type::fifo, null_yield);
258
259 ASSERT_EQ(0, lg->got_entries.begin()->first);
260
261 ASSERT_EQ(0, lg->got_entries[0].gen_id);
262 ASSERT_EQ(log_type::fifo, lg->got_entries[0].type);
263 ASSERT_FALSE(lg->got_entries[0].pruned);
264
265 lg->got_entries.clear();
266
b3b6e05e 267 ec = lg->new_backing(&dp, log_type::omap, null_yield);
f67539c2
TL
268 ASSERT_FALSE(ec);
269
270 ASSERT_EQ(1, lg->got_entries.size());
271 ASSERT_EQ(1, lg->got_entries[1].gen_id);
272 ASSERT_EQ(log_type::omap, lg->got_entries[1].type);
273 ASSERT_FALSE(lg->got_entries[1].pruned);
274
275 lg.reset();
276
277 lg = *logback_generations::init<generations>(
b3b6e05e 278 &dp, ioctx, "foobar", [this](uint64_t gen_id, int shard) {
f67539c2
TL
279 return get_oid(gen_id, shard);
280 }, SHARDS, log_type::fifo, null_yield);
281
282 ASSERT_EQ(2, lg->got_entries.size());
283 ASSERT_EQ(0, lg->got_entries[0].gen_id);
284 ASSERT_EQ(log_type::fifo, lg->got_entries[0].type);
285 ASSERT_FALSE(lg->got_entries[0].pruned);
286
287 ASSERT_EQ(1, lg->got_entries[1].gen_id);
288 ASSERT_EQ(log_type::omap, lg->got_entries[1].type);
289 ASSERT_FALSE(lg->got_entries[1].pruned);
290
b3b6e05e 291 ec = lg->empty_to(&dp, 0, null_yield);
f67539c2
TL
292 ASSERT_FALSE(ec);
293
294 ASSERT_EQ(0, *lg->tail);
295
296 lg.reset();
297
298 lg = *logback_generations::init<generations>(
b3b6e05e 299 &dp, ioctx, "foobar", [this](uint64_t gen_id, int shard) {
f67539c2
TL
300 return get_oid(gen_id, shard);
301 }, SHARDS, log_type::fifo, null_yield);
302
303 ASSERT_EQ(1, lg->got_entries.size());
304 ASSERT_EQ(1, lg->got_entries[1].gen_id);
305 ASSERT_EQ(log_type::omap, lg->got_entries[1].type);
306 ASSERT_FALSE(lg->got_entries[1].pruned);
f67539c2
TL
307}
308
309TEST_F(LogBacking, GenerationWN)
310{
311 auto lg1 = *logback_generations::init<generations>(
b3b6e05e 312 &dp, ioctx, "foobar", [this](uint64_t gen_id, int shard) {
f67539c2
TL
313 return get_oid(gen_id, shard);
314 }, SHARDS, log_type::fifo, null_yield);
315
b3b6e05e 316 auto ec = lg1->new_backing(&dp, log_type::omap, null_yield);
f67539c2
TL
317 ASSERT_FALSE(ec);
318
319 ASSERT_EQ(1, lg1->got_entries.size());
320 ASSERT_EQ(1, lg1->got_entries[1].gen_id);
321 ASSERT_EQ(log_type::omap, lg1->got_entries[1].type);
322 ASSERT_FALSE(lg1->got_entries[1].pruned);
323
324 lg1->got_entries.clear();
325
326 auto lg2 = *logback_generations::init<generations>(
b3b6e05e 327 &dp, ioctx2, "foobar", [this](uint64_t gen_id, int shard) {
f67539c2
TL
328 return get_oid(gen_id, shard);
329 }, SHARDS, log_type::fifo, null_yield);
330
331 ASSERT_EQ(2, lg2->got_entries.size());
332
333 ASSERT_EQ(0, lg2->got_entries[0].gen_id);
334 ASSERT_EQ(log_type::fifo, lg2->got_entries[0].type);
335 ASSERT_FALSE(lg2->got_entries[0].pruned);
336
337 ASSERT_EQ(1, lg2->got_entries[1].gen_id);
338 ASSERT_EQ(log_type::omap, lg2->got_entries[1].type);
339 ASSERT_FALSE(lg2->got_entries[1].pruned);
340
341 lg2->got_entries.clear();
342
b3b6e05e 343 ec = lg1->new_backing(&dp, log_type::fifo, null_yield);
f67539c2
TL
344 ASSERT_FALSE(ec);
345
346 ASSERT_EQ(1, lg1->got_entries.size());
347 ASSERT_EQ(2, lg1->got_entries[2].gen_id);
348 ASSERT_EQ(log_type::fifo, lg1->got_entries[2].type);
349 ASSERT_FALSE(lg1->got_entries[2].pruned);
350
351 ASSERT_EQ(1, lg2->got_entries.size());
352 ASSERT_EQ(2, lg2->got_entries[2].gen_id);
353 ASSERT_EQ(log_type::fifo, lg2->got_entries[2].type);
354 ASSERT_FALSE(lg2->got_entries[2].pruned);
355
356 lg1->got_entries.clear();
357 lg2->got_entries.clear();
358
b3b6e05e 359 ec = lg2->empty_to(&dp, 1, null_yield);
f67539c2
TL
360 ASSERT_FALSE(ec);
361
362 ASSERT_EQ(1, *lg1->tail);
363 ASSERT_EQ(1, *lg2->tail);
364
365 lg1->tail.reset();
366 lg2->tail.reset();
367}