]>
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 #include <fmt/format.h>
23 #include "include/types.h"
24 #include "include/rados/librados.hpp"
26 #include "test/librados/test_cxx.h"
27 #include "global/global_context.h"
29 #include "cls/log/cls_log_client.h"
31 #include "rgw_tools.h"
32 #include "cls_fifo_legacy.h"
34 #include "gtest/gtest.h"
36 namespace lr
= librados
;
37 namespace cb
= ceph::buffer
;
38 namespace fifo
= rados::cls::fifo
;
39 namespace RCf
= rgw::cls::fifo
;
41 auto cct
= new CephContext(CEPH_ENTITY_TYPE_CLIENT
);
42 const DoutPrefix
dp(cct
, 1, "test log backing: ");
44 class LogBacking
: public testing::Test
{
46 static constexpr int SHARDS
= 3;
47 const std::string pool_name
= get_temp_pool_name();
53 void SetUp() override
{
54 ASSERT_EQ("", create_one_pool_pp(pool_name
, rados
));
55 ASSERT_EQ(0, rados
.ioctx_create(pool_name
.c_str(), ioctx
));
56 connect_cluster_pp(rados2
);
57 ASSERT_EQ(0, rados2
.ioctx_create(pool_name
.c_str(), ioctx2
));
59 void TearDown() override
{
60 destroy_one_pool_pp(pool_name
, rados
);
63 std::string
get_oid(uint64_t gen_id
, int i
) const {
65 fmt::format("shard@G{}.{}", gen_id
, i
) :
66 fmt::format("shard.{}", i
));
70 for (int i
= 0; i
< SHARDS
; ++i
) {
72 lr::ObjectWriteOperation op
;
75 cls_log_add(op
, ceph_clock_now(), {}, "meow", bl
);
76 auto r
= rgw_rados_operate(&dp
, ioctx
, get_oid(0, i
), &op
, null_yield
);
81 void add_omap(int i
) {
83 lr::ObjectWriteOperation op
;
86 cls_log_add(op
, ceph_clock_now(), {}, "meow", bl
);
87 auto r
= rgw_rados_operate(&dp
, ioctx
, get_oid(0, i
), &op
, null_yield
);
92 for (int i
= 0; i
< SHARDS
; ++i
) {
93 auto oid
= get_oid(0, i
);
94 std::string to_marker
;
96 lr::ObjectReadOperation op
;
97 std::list
<cls_log_entry
> entries
;
98 bool truncated
= false;
99 cls_log_list(op
, {}, {}, {}, 1, entries
, &to_marker
, &truncated
);
100 auto r
= rgw_rados_operate(&dp
, ioctx
, oid
, &op
, nullptr, null_yield
);
102 ASSERT_FALSE(entries
.empty());
105 lr::ObjectWriteOperation op
;
106 cls_log_trim(op
, {}, {}, {}, to_marker
);
107 auto r
= rgw_rados_operate(&dp
, ioctx
, oid
, &op
, null_yield
);
111 lr::ObjectReadOperation op
;
112 std::list
<cls_log_entry
> entries
;
113 bool truncated
= false;
114 cls_log_list(op
, {}, {}, {}, 1, entries
, &to_marker
, &truncated
);
115 auto r
= rgw_rados_operate(&dp
, ioctx
, oid
, &op
, nullptr, null_yield
);
117 ASSERT_TRUE(entries
.empty());
124 for (int i
= 0; i
< SHARDS
; ++i
) {
125 std::unique_ptr
<RCf::FIFO
> fifo
;
126 auto r
= RCf::FIFO::create(&dp
, ioctx
, get_oid(0, i
), &fifo
, null_yield
);
135 std::unique_ptr
<RCf::FIFO
> fifo
;
136 auto r
= RCf::FIFO::open(&dp
, ioctx
, get_oid(0, i
), &fifo
, null_yield
);
141 r
= fifo
->push(&dp
, bl
, null_yield
);
145 void assert_empty() {
146 std::vector
<lr::ObjectItem
> result
;
147 lr::ObjectCursor next
;
148 auto r
= ioctx
.object_list(ioctx
.object_list_begin(), ioctx
.object_list_end(),
149 100, {}, &result
, &next
);
151 ASSERT_TRUE(result
.empty());
155 TEST_F(LogBacking
, TestOmap
)
158 auto stat
= log_backing_type(&dp
, ioctx
, log_type::fifo
, SHARDS
,
159 [this](int shard
){ return get_oid(0, shard
); },
161 ASSERT_EQ(log_type::omap
, *stat
);
164 TEST_F(LogBacking
, TestOmapEmpty
)
166 auto stat
= log_backing_type(&dp
, ioctx
, log_type::omap
, SHARDS
,
167 [this](int shard
){ return get_oid(0, shard
); },
169 ASSERT_EQ(log_type::omap
, *stat
);
172 TEST_F(LogBacking
, TestFIFO
)
175 auto stat
= log_backing_type(&dp
, ioctx
, log_type::fifo
, SHARDS
,
176 [this](int shard
){ return get_oid(0, shard
); },
178 ASSERT_EQ(log_type::fifo
, *stat
);
181 TEST_F(LogBacking
, TestFIFOEmpty
)
183 auto stat
= log_backing_type(&dp
, ioctx
, log_type::fifo
, SHARDS
,
184 [this](int shard
){ return get_oid(0, shard
); },
186 ASSERT_EQ(log_type::fifo
, *stat
);
189 TEST(CursorGen
, RoundTrip
) {
190 const std::string_view pcurs
= "fded";
192 auto gc
= gencursor(0, pcurs
);
193 ASSERT_EQ(pcurs
, gc
);
194 auto [gen
, cursor
] = cursorgen(gc
);
196 ASSERT_EQ(pcurs
, cursor
);
199 auto gc
= gencursor(53, pcurs
);
200 ASSERT_NE(pcurs
, gc
);
201 auto [gen
, cursor
] = cursorgen(gc
);
203 ASSERT_EQ(pcurs
, cursor
);
207 class generations final
: public logback_generations
{
210 entries_t got_entries
;
211 std::optional
<uint64_t> tail
;
213 using logback_generations::logback_generations
;
215 bs::error_code
handle_init(entries_t e
) noexcept
{
220 bs::error_code
handle_new_gens(entries_t e
) noexcept
{
225 bs::error_code
handle_empty_to(uint64_t new_tail
) noexcept
{
231 TEST_F(LogBacking
, GenerationSingle
)
233 auto lgr
= logback_generations::init
<generations
>(
234 &dp
, ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
235 return get_oid(gen_id
, shard
);
236 }, SHARDS
, log_type::fifo
, null_yield
);
239 auto lg
= std::move(*lgr
);
241 ASSERT_EQ(0, lg
->got_entries
.begin()->first
);
243 ASSERT_EQ(0, lg
->got_entries
[0].gen_id
);
244 ASSERT_EQ(log_type::fifo
, lg
->got_entries
[0].type
);
245 ASSERT_FALSE(lg
->got_entries
[0].pruned
);
247 auto ec
= lg
->empty_to(&dp
, 0, null_yield
);
252 lg
= *logback_generations::init
<generations
>(
253 &dp
, 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(&dp
, 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 &dp
, 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(&dp
, 0, null_yield
);
292 ASSERT_EQ(0, *lg
->tail
);
296 lg
= *logback_generations::init
<generations
>(
297 &dp
, 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
);
307 TEST_F(LogBacking
, GenerationWN
)
309 auto lg1
= *logback_generations::init
<generations
>(
310 &dp
, ioctx
, "foobar", [this](uint64_t gen_id
, int shard
) {
311 return get_oid(gen_id
, shard
);
312 }, SHARDS
, log_type::fifo
, null_yield
);
314 auto ec
= lg1
->new_backing(&dp
, log_type::omap
, null_yield
);
317 ASSERT_EQ(1, lg1
->got_entries
.size());
318 ASSERT_EQ(1, lg1
->got_entries
[1].gen_id
);
319 ASSERT_EQ(log_type::omap
, lg1
->got_entries
[1].type
);
320 ASSERT_FALSE(lg1
->got_entries
[1].pruned
);
322 lg1
->got_entries
.clear();
324 auto lg2
= *logback_generations::init
<generations
>(
325 &dp
, ioctx2
, "foobar", [this](uint64_t gen_id
, int shard
) {
326 return get_oid(gen_id
, shard
);
327 }, SHARDS
, log_type::fifo
, null_yield
);
329 ASSERT_EQ(2, lg2
->got_entries
.size());
331 ASSERT_EQ(0, lg2
->got_entries
[0].gen_id
);
332 ASSERT_EQ(log_type::fifo
, lg2
->got_entries
[0].type
);
333 ASSERT_FALSE(lg2
->got_entries
[0].pruned
);
335 ASSERT_EQ(1, lg2
->got_entries
[1].gen_id
);
336 ASSERT_EQ(log_type::omap
, lg2
->got_entries
[1].type
);
337 ASSERT_FALSE(lg2
->got_entries
[1].pruned
);
339 lg2
->got_entries
.clear();
341 ec
= lg1
->new_backing(&dp
, log_type::fifo
, null_yield
);
344 ASSERT_EQ(1, lg1
->got_entries
.size());
345 ASSERT_EQ(2, lg1
->got_entries
[2].gen_id
);
346 ASSERT_EQ(log_type::fifo
, lg1
->got_entries
[2].type
);
347 ASSERT_FALSE(lg1
->got_entries
[2].pruned
);
349 ASSERT_EQ(1, lg2
->got_entries
.size());
350 ASSERT_EQ(2, lg2
->got_entries
[2].gen_id
);
351 ASSERT_EQ(log_type::fifo
, lg2
->got_entries
[2].type
);
352 ASSERT_FALSE(lg2
->got_entries
[2].pruned
);
354 lg1
->got_entries
.clear();
355 lg2
->got_entries
.clear();
357 ec
= lg2
->empty_to(&dp
, 1, null_yield
);
360 ASSERT_EQ(1, *lg1
->tail
);
361 ASSERT_EQ(1, *lg2
->tail
);