]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_log_backing.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2019 Red Hat, Inc.
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.
15 #include "rgw_log_backing.h"
19 #include <string_view>
21 #undef FMT_HEADER_ONLY
22 #define FMT_HEADER_ONLY 1
23 #include <fmt/format.h>
25 #include "include/types.h"
26 #include "include/rados/librados.hpp"
28 #include "test/librados/test_cxx.h"
29 #include "global/global_context.h"
31 #include "cls/log/cls_log_client.h"
33 #include "rgw/rgw_tools.h"
34 #include "rgw/cls_fifo_legacy.h"
36 #include "gtest/gtest.h"
38 namespace lr
= librados
;
39 namespace cb
= ceph::buffer
;
40 namespace fifo
= rados::cls::fifo
;
41 namespace RCf
= rgw::cls::fifo
;
43 class LogBacking
: public testing::Test
{
45 static constexpr int SHARDS
= 3;
46 const std::string pool_name
= get_temp_pool_name();
52 void SetUp() override
{
53 ASSERT_EQ("", create_one_pool_pp(pool_name
, rados
));
54 ASSERT_EQ(0, rados
.ioctx_create(pool_name
.c_str(), ioctx
));
55 connect_cluster_pp(rados2
);
56 ASSERT_EQ(0, rados2
.ioctx_create(pool_name
.c_str(), ioctx2
));
58 void TearDown() override
{
59 destroy_one_pool_pp(pool_name
, rados
);
62 std::string
get_oid(uint64_t gen_id
, int i
) const {
64 fmt::format("shard@G{}.{}", gen_id
, i
) :
65 fmt::format("shard.{}", i
));
69 for (int i
= 0; i
< SHARDS
; ++i
) {
71 lr::ObjectWriteOperation op
;
74 cls_log_add(op
, ceph_clock_now(), {}, "meow", bl
);
75 auto r
= rgw_rados_operate(ioctx
, get_oid(0, i
), &op
, null_yield
);
80 void add_omap(int i
) {
82 lr::ObjectWriteOperation op
;
85 cls_log_add(op
, ceph_clock_now(), {}, "meow", bl
);
86 auto r
= rgw_rados_operate(ioctx
, get_oid(0, i
), &op
, null_yield
);
91 for (int i
= 0; i
< SHARDS
; ++i
) {
92 auto oid
= get_oid(0, i
);
93 std::string to_marker
;
95 lr::ObjectReadOperation op
;
96 std::list
<cls_log_entry
> entries
;
97 bool truncated
= false;
98 cls_log_list(op
, {}, {}, {}, 1, entries
, &to_marker
, &truncated
);
99 auto r
= rgw_rados_operate(ioctx
, oid
, &op
, nullptr, null_yield
);
101 ASSERT_FALSE(entries
.empty());
104 lr::ObjectWriteOperation op
;
105 cls_log_trim(op
, {}, {}, {}, to_marker
);
106 auto r
= rgw_rados_operate(ioctx
, oid
, &op
, null_yield
);
110 lr::ObjectReadOperation op
;
111 std::list
<cls_log_entry
> entries
;
112 bool truncated
= false;
113 cls_log_list(op
, {}, {}, {}, 1, entries
, &to_marker
, &truncated
);
114 auto r
= rgw_rados_operate(ioctx
, oid
, &op
, nullptr, null_yield
);
116 ASSERT_TRUE(entries
.empty());
123 for (int i
= 0; i
< SHARDS
; ++i
) {
124 std::unique_ptr
<RCf::FIFO
> fifo
;
125 auto r
= RCf::FIFO::create(ioctx
, get_oid(0, i
), &fifo
, null_yield
);
134 std::unique_ptr
<RCf::FIFO
> fifo
;
135 auto r
= RCf::FIFO::open(ioctx
, get_oid(0, i
), &fifo
, null_yield
);
140 r
= fifo
->push(bl
, null_yield
);
144 void assert_empty() {
145 std::vector
<lr::ObjectItem
> result
;
146 lr::ObjectCursor next
;
147 auto r
= ioctx
.object_list(ioctx
.object_list_begin(), ioctx
.object_list_end(),
148 100, {}, &result
, &next
);
150 ASSERT_TRUE(result
.empty());
154 TEST_F(LogBacking
, TestOmap
)
157 auto stat
= log_backing_type(ioctx
, log_type::fifo
, SHARDS
,
158 [this](int shard
){ return get_oid(0, shard
); },
160 ASSERT_EQ(log_type::omap
, *stat
);
163 TEST_F(LogBacking
, TestOmapEmpty
)
165 auto stat
= log_backing_type(ioctx
, log_type::omap
, SHARDS
,
166 [this](int shard
){ return get_oid(0, shard
); },
168 ASSERT_EQ(log_type::omap
, *stat
);
171 TEST_F(LogBacking
, TestFIFO
)
174 auto stat
= log_backing_type(ioctx
, log_type::fifo
, SHARDS
,
175 [this](int shard
){ return get_oid(0, shard
); },
177 ASSERT_EQ(log_type::fifo
, *stat
);
180 TEST_F(LogBacking
, TestFIFOEmpty
)
182 auto stat
= log_backing_type(ioctx
, log_type::fifo
, SHARDS
,
183 [this](int shard
){ return get_oid(0, shard
); },
185 ASSERT_EQ(log_type::fifo
, *stat
);
188 TEST(CursorGen
, RoundTrip
) {
189 const auto pcurs
= "fded"sv
;
191 auto gc
= gencursor(0, pcurs
);
192 ASSERT_EQ(pcurs
, gc
);
193 auto [gen
, cursor
] = cursorgen(gc
);
195 ASSERT_EQ(pcurs
, cursor
);
198 auto gc
= gencursor(53, pcurs
);
199 ASSERT_NE(pcurs
, gc
);
200 auto [gen
, cursor
] = cursorgen(gc
);
202 ASSERT_EQ(pcurs
, cursor
);
206 class generations final
: public logback_generations
{
209 entries_t got_entries
;
210 std::optional
<uint64_t> tail
;
212 using logback_generations::logback_generations
;
214 bs::error_code
handle_init(entries_t e
) noexcept
{
219 bs::error_code
handle_new_gens(entries_t e
) noexcept
{
224 bs::error_code
handle_empty_to(uint64_t new_tail
) noexcept
{
230 TEST_F(LogBacking
, GenerationSingle
)
232 auto lgr
= logback_generations::init
<generations
>(
233 ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
234 return get_oid(gen_id
, shard
);
235 }, SHARDS
, log_type::fifo
, null_yield
);
238 auto lg
= std::move(*lgr
);
240 ASSERT_EQ(0, lg
->got_entries
.begin()->first
);
242 ASSERT_EQ(0, lg
->got_entries
[0].gen_id
);
243 ASSERT_EQ(log_type::fifo
, lg
->got_entries
[0].type
);
244 ASSERT_FALSE(lg
->got_entries
[0].pruned
);
246 auto ec
= lg
->empty_to(0, null_yield
);
252 lg
= *logback_generations::init
<generations
>(
253 ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
254 return get_oid(gen_id
, shard
);
255 }, SHARDS
, log_type::fifo
, null_yield
);
257 ASSERT_EQ(0, lg
->got_entries
.begin()->first
);
259 ASSERT_EQ(0, lg
->got_entries
[0].gen_id
);
260 ASSERT_EQ(log_type::fifo
, lg
->got_entries
[0].type
);
261 ASSERT_FALSE(lg
->got_entries
[0].pruned
);
263 lg
->got_entries
.clear();
265 ec
= lg
->new_backing(log_type::omap
, null_yield
);
268 ASSERT_EQ(1, lg
->got_entries
.size());
269 ASSERT_EQ(1, lg
->got_entries
[1].gen_id
);
270 ASSERT_EQ(log_type::omap
, lg
->got_entries
[1].type
);
271 ASSERT_FALSE(lg
->got_entries
[1].pruned
);
275 lg
= *logback_generations::init
<generations
>(
276 ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
277 return get_oid(gen_id
, shard
);
278 }, SHARDS
, log_type::fifo
, null_yield
);
280 ASSERT_EQ(2, lg
->got_entries
.size());
281 ASSERT_EQ(0, lg
->got_entries
[0].gen_id
);
282 ASSERT_EQ(log_type::fifo
, lg
->got_entries
[0].type
);
283 ASSERT_FALSE(lg
->got_entries
[0].pruned
);
285 ASSERT_EQ(1, lg
->got_entries
[1].gen_id
);
286 ASSERT_EQ(log_type::omap
, lg
->got_entries
[1].type
);
287 ASSERT_FALSE(lg
->got_entries
[1].pruned
);
289 ec
= lg
->empty_to(0, null_yield
);
292 ASSERT_EQ(0, *lg
->tail
);
296 lg
= *logback_generations::init
<generations
>(
297 ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
298 return get_oid(gen_id
, shard
);
299 }, SHARDS
, log_type::fifo
, null_yield
);
301 ASSERT_EQ(1, lg
->got_entries
.size());
302 ASSERT_EQ(1, lg
->got_entries
[1].gen_id
);
303 ASSERT_EQ(log_type::omap
, lg
->got_entries
[1].type
);
304 ASSERT_FALSE(lg
->got_entries
[1].pruned
);
306 ec
= lg
->remove_empty(null_yield
);
309 auto entries
= lg
->entries();
310 ASSERT_EQ(1, entries
.size());
312 ASSERT_EQ(1, entries
[1].gen_id
);
313 ASSERT_EQ(log_type::omap
, entries
[1].type
);
314 ASSERT_FALSE(entries
[1].pruned
);
319 TEST_F(LogBacking
, GenerationWN
)
321 auto lg1
= *logback_generations::init
<generations
>(
322 ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
323 return get_oid(gen_id
, shard
);
324 }, SHARDS
, log_type::fifo
, null_yield
);
326 auto ec
= lg1
->new_backing(log_type::omap
, null_yield
);
329 ASSERT_EQ(1, lg1
->got_entries
.size());
330 ASSERT_EQ(1, lg1
->got_entries
[1].gen_id
);
331 ASSERT_EQ(log_type::omap
, lg1
->got_entries
[1].type
);
332 ASSERT_FALSE(lg1
->got_entries
[1].pruned
);
334 lg1
->got_entries
.clear();
336 auto lg2
= *logback_generations::init
<generations
>(
337 ioctx2
, "foobar", [this](uint64_t gen_id
, int shard
) {
338 return get_oid(gen_id
, shard
);
339 }, SHARDS
, log_type::fifo
, null_yield
);
341 ASSERT_EQ(2, lg2
->got_entries
.size());
343 ASSERT_EQ(0, lg2
->got_entries
[0].gen_id
);
344 ASSERT_EQ(log_type::fifo
, lg2
->got_entries
[0].type
);
345 ASSERT_FALSE(lg2
->got_entries
[0].pruned
);
347 ASSERT_EQ(1, lg2
->got_entries
[1].gen_id
);
348 ASSERT_EQ(log_type::omap
, lg2
->got_entries
[1].type
);
349 ASSERT_FALSE(lg2
->got_entries
[1].pruned
);
351 lg2
->got_entries
.clear();
353 ec
= lg1
->new_backing(log_type::fifo
, null_yield
);
356 ASSERT_EQ(1, lg1
->got_entries
.size());
357 ASSERT_EQ(2, lg1
->got_entries
[2].gen_id
);
358 ASSERT_EQ(log_type::fifo
, lg1
->got_entries
[2].type
);
359 ASSERT_FALSE(lg1
->got_entries
[2].pruned
);
361 ASSERT_EQ(1, lg2
->got_entries
.size());
362 ASSERT_EQ(2, lg2
->got_entries
[2].gen_id
);
363 ASSERT_EQ(log_type::fifo
, lg2
->got_entries
[2].type
);
364 ASSERT_FALSE(lg2
->got_entries
[2].pruned
);
366 lg1
->got_entries
.clear();
367 lg2
->got_entries
.clear();
369 ec
= lg2
->empty_to(1, null_yield
);
372 ASSERT_EQ(1, *lg1
->tail
);
373 ASSERT_EQ(1, *lg2
->tail
);