]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rgw/test_cls_fifo_legacy.cc
import ceph pacific 16.2.5
[ceph.git] / ceph / src / test / rgw / test_cls_fifo_legacy.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 <cerrno>
16#include <iostream>
17#include <string_view>
18
19#include "include/scope_guard.h"
20#include "include/types.h"
21#include "include/rados/librados.hpp"
b3b6e05e 22#include "common/ceph_context.h"
f67539c2
TL
23
24#include "cls/fifo/cls_fifo_ops.h"
25#include "test/librados/test_cxx.h"
26#include "global/global_context.h"
27
28#include "rgw/rgw_tools.h"
29#include "rgw/cls_fifo_legacy.h"
30
31#include "gtest/gtest.h"
32
33namespace R = librados;
34namespace cb = ceph::buffer;
35namespace fifo = rados::cls::fifo;
36namespace RCf = rgw::cls::fifo;
37
b3b6e05e
TL
38auto cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
39const DoutPrefix dp(cct, 1, "test legacy cls fifo: ");
40
f67539c2 41namespace {
b3b6e05e 42int fifo_create(const DoutPrefixProvider *dpp, R::IoCtx& ioctx,
f67539c2
TL
43 const std::string& oid,
44 std::string_view id,
45 optional_yield y,
46 std::optional<fifo::objv> objv = std::nullopt,
47 std::optional<std::string_view> oid_prefix = std::nullopt,
48 bool exclusive = false,
49 std::uint64_t max_part_size = RCf::default_max_part_size,
50 std::uint64_t max_entry_size = RCf::default_max_entry_size)
51{
52 R::ObjectWriteOperation op;
53 RCf::create_meta(&op, id, objv, oid_prefix, exclusive, max_part_size,
54 max_entry_size);
b3b6e05e 55 return rgw_rados_operate(dpp, ioctx, oid, &op, y);
f67539c2
TL
56}
57}
58
59class LegacyFIFO : public testing::Test {
60protected:
61 const std::string pool_name = get_temp_pool_name();
62 const std::string fifo_id = "fifo";
63 R::Rados rados;
64 librados::IoCtx ioctx;
65
66 void SetUp() override {
67 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
68 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
69 }
70 void TearDown() override {
71 destroy_one_pool_pp(pool_name, rados);
72 }
73};
74
75using LegacyClsFIFO = LegacyFIFO;
76using AioLegacyFIFO = LegacyFIFO;
77
78
79TEST_F(LegacyClsFIFO, TestCreate)
80{
b3b6e05e 81 auto r = fifo_create(&dp, ioctx, fifo_id, ""s, null_yield);
f67539c2 82 EXPECT_EQ(-EINVAL, r);
b3b6e05e 83 r = fifo_create(&dp, ioctx, fifo_id, fifo_id, null_yield, std::nullopt,
f67539c2
TL
84 std::nullopt, false, 0);
85 EXPECT_EQ(-EINVAL, r);
b3b6e05e 86 r = fifo_create(&dp, ioctx, fifo_id, {}, null_yield,
f67539c2
TL
87 std::nullopt, std::nullopt,
88 false, RCf::default_max_part_size, 0);
89 EXPECT_EQ(-EINVAL, r);
b3b6e05e 90 r = fifo_create(&dp, ioctx, fifo_id, fifo_id, null_yield);
f67539c2
TL
91 EXPECT_EQ(0, r);
92 std::uint64_t size;
93 ioctx.stat(fifo_id, &size, nullptr);
94 EXPECT_GT(size, 0);
95 /* test idempotency */
b3b6e05e 96 r = fifo_create(&dp, ioctx, fifo_id, fifo_id, null_yield);
f67539c2 97 EXPECT_EQ(0, r);
b3b6e05e 98 r = fifo_create(&dp, ioctx, fifo_id, {}, null_yield, std::nullopt,
f67539c2
TL
99 std::nullopt, false);
100 EXPECT_EQ(-EINVAL, r);
b3b6e05e 101 r = fifo_create(&dp, ioctx, fifo_id, {}, null_yield, std::nullopt,
f67539c2
TL
102 "myprefix"sv, false);
103 EXPECT_EQ(-EINVAL, r);
b3b6e05e 104 r = fifo_create(&dp, ioctx, fifo_id, "foo"sv, null_yield,
f67539c2
TL
105 std::nullopt, std::nullopt, false);
106 EXPECT_EQ(-EEXIST, r);
107}
108
109TEST_F(LegacyClsFIFO, TestGetInfo)
110{
b3b6e05e 111 auto r = fifo_create(&dp, ioctx, fifo_id, fifo_id, null_yield);
f67539c2
TL
112 fifo::info info;
113 std::uint32_t part_header_size;
114 std::uint32_t part_entry_overhead;
b3b6e05e 115 r = RCf::get_meta(&dp, ioctx, fifo_id, std::nullopt, &info, &part_header_size,
f67539c2
TL
116 &part_entry_overhead, 0, null_yield);
117 EXPECT_EQ(0, r);
118 EXPECT_GT(part_header_size, 0);
119 EXPECT_GT(part_entry_overhead, 0);
120 EXPECT_FALSE(info.version.instance.empty());
121
b3b6e05e 122 r = RCf::get_meta(&dp, ioctx, fifo_id, info.version, &info, &part_header_size,
f67539c2
TL
123 &part_entry_overhead, 0, null_yield);
124 EXPECT_EQ(0, r);
125 fifo::objv objv;
126 objv.instance = "foo";
127 objv.ver = 12;
b3b6e05e 128 r = RCf::get_meta(&dp, ioctx, fifo_id, objv, &info, &part_header_size,
f67539c2
TL
129 &part_entry_overhead, 0, null_yield);
130 EXPECT_EQ(-ECANCELED, r);
131}
132
133TEST_F(LegacyFIFO, TestOpenDefault)
134{
135 std::unique_ptr<RCf::FIFO> fifo;
b3b6e05e 136 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &fifo, null_yield);
f67539c2
TL
137 ASSERT_EQ(0, r);
138 // force reading from backend
b3b6e05e 139 r = fifo->read_meta(&dp, null_yield);
f67539c2
TL
140 EXPECT_EQ(0, r);
141 auto info = fifo->meta();
142 EXPECT_EQ(info.id, fifo_id);
143}
144
145TEST_F(LegacyFIFO, TestOpenParams)
146{
147 const std::uint64_t max_part_size = 10 * 1024;
148 const std::uint64_t max_entry_size = 128;
149 auto oid_prefix = "foo.123."sv;
150 fifo::objv objv;
151 objv.instance = "fooz"s;
152 objv.ver = 10;
153
154 /* first successful create */
155 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 156 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, objv, oid_prefix,
f67539c2
TL
157 false, max_part_size, max_entry_size);
158 ASSERT_EQ(0, r);
159
160 /* force reading from backend */
b3b6e05e 161 r = f->read_meta(&dp, null_yield);
f67539c2
TL
162 auto info = f->meta();
163 EXPECT_EQ(info.id, fifo_id);
164 EXPECT_EQ(info.params.max_part_size, max_part_size);
165 EXPECT_EQ(info.params.max_entry_size, max_entry_size);
166 EXPECT_EQ(info.version, objv);
167}
168
169namespace {
170template<class T>
171std::pair<T, std::string> decode_entry(const RCf::list_entry& entry)
172{
173 T val;
174 auto iter = entry.data.cbegin();
175 decode(val, iter);
176 return std::make_pair(std::move(val), entry.marker);
177}
178}
179
180
181TEST_F(LegacyFIFO, TestPushListTrim)
182{
183 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 184 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield);
f67539c2
TL
185 ASSERT_EQ(0, r);
186 static constexpr auto max_entries = 10u;
187 for (uint32_t i = 0; i < max_entries; ++i) {
188 cb::list bl;
189 encode(i, bl);
b3b6e05e 190 r = f->push(&dp, bl, null_yield);
f67539c2
TL
191 ASSERT_EQ(0, r);
192 }
193
194 std::optional<std::string> marker;
195 /* get entries one by one */
196 std::vector<RCf::list_entry> result;
197 bool more = false;
198 for (auto i = 0u; i < max_entries; ++i) {
199
b3b6e05e 200 r = f->list(&dp, 1, marker, &result, &more, null_yield);
f67539c2
TL
201 ASSERT_EQ(0, r);
202
203 bool expected_more = (i != (max_entries - 1));
204 ASSERT_EQ(expected_more, more);
205 ASSERT_EQ(1, result.size());
206
207 std::uint32_t val;
208 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
209
210 ASSERT_EQ(i, val);
211 result.clear();
212 }
213
214 /* get all entries at once */
215 std::string markers[max_entries];
216 std::uint32_t min_entry = 0;
b3b6e05e 217 r = f->list(&dp, max_entries * 10, std::nullopt, &result, &more, null_yield);
f67539c2
TL
218 ASSERT_EQ(0, r);
219
220 ASSERT_FALSE(more);
221 ASSERT_EQ(max_entries, result.size());
222 for (auto i = 0u; i < max_entries; ++i) {
223 std::uint32_t val;
224 std::tie(val, markers[i]) = decode_entry<std::uint32_t>(result[i]);
225 ASSERT_EQ(i, val);
226 }
227
228 /* trim one entry */
b3b6e05e 229 r = f->trim(&dp, markers[min_entry], false, null_yield);
f67539c2
TL
230 ASSERT_EQ(0, r);
231 ++min_entry;
232
b3b6e05e 233 r = f->list(&dp, max_entries * 10, std::nullopt, &result, &more, null_yield);
f67539c2
TL
234 ASSERT_EQ(0, r);
235 ASSERT_FALSE(more);
236 ASSERT_EQ(max_entries - min_entry, result.size());
237
238 for (auto i = min_entry; i < max_entries; ++i) {
239 std::uint32_t val;
240 std::tie(val, markers[i - min_entry]) =
241 decode_entry<std::uint32_t>(result[i - min_entry]);
242 EXPECT_EQ(i, val);
243 }
244}
245
246
247TEST_F(LegacyFIFO, TestPushTooBig)
248{
249 static constexpr auto max_part_size = 2048ull;
250 static constexpr auto max_entry_size = 128ull;
251
252 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 253 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
254 std::nullopt, false, max_part_size, max_entry_size);
255 ASSERT_EQ(0, r);
256
257 char buf[max_entry_size + 1];
258 memset(buf, 0, sizeof(buf));
259
260 cb::list bl;
261 bl.append(buf, sizeof(buf));
262
b3b6e05e 263 r = f->push(&dp, bl, null_yield);
f67539c2
TL
264 EXPECT_EQ(-E2BIG, r);
265}
266
267
268TEST_F(LegacyFIFO, TestMultipleParts)
269{
270 static constexpr auto max_part_size = 2048ull;
271 static constexpr auto max_entry_size = 128ull;
272 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 273 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
274 std::nullopt, false, max_part_size,
275 max_entry_size);
276 ASSERT_EQ(0, r);
277
278 char buf[max_entry_size];
279 memset(buf, 0, sizeof(buf));
280 const auto [part_header_size, part_entry_overhead] =
281 f->get_part_layout_info();
282 const auto entries_per_part = ((max_part_size - part_header_size) /
283 (max_entry_size + part_entry_overhead));
284 const auto max_entries = entries_per_part * 4 + 1;
285 /* push enough entries */
286 for (auto i = 0u; i < max_entries; ++i) {
287 cb::list bl;
288 *(int *)buf = i;
289 bl.append(buf, sizeof(buf));
b3b6e05e 290 r = f->push(&dp, bl, null_yield);
f67539c2
TL
291 ASSERT_EQ(0, r);
292 }
293
294 auto info = f->meta();
295 ASSERT_EQ(info.id, fifo_id);
296 /* head should have advanced */
297 ASSERT_GT(info.head_part_num, 0);
298
299 /* list all at once */
300 std::vector<RCf::list_entry> result;
301 bool more = false;
b3b6e05e 302 r = f->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
303 ASSERT_EQ(0, r);
304 EXPECT_EQ(false, more);
305 ASSERT_EQ(max_entries, result.size());
306
307 for (auto i = 0u; i < max_entries; ++i) {
308 auto& bl = result[i].data;
309 ASSERT_EQ(i, *(int *)bl.c_str());
310 }
311
312 std::optional<std::string> marker;
313 /* get entries one by one */
314
315 for (auto i = 0u; i < max_entries; ++i) {
b3b6e05e 316 r = f->list(&dp, 1, marker, &result, &more, null_yield);
f67539c2
TL
317 ASSERT_EQ(0, r);
318 ASSERT_EQ(result.size(), 1);
319 const bool expected_more = (i != (max_entries - 1));
320 ASSERT_EQ(expected_more, more);
321
322 std::uint32_t val;
323 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
324
325 auto& entry = result.front();
326 auto& bl = entry.data;
327 ASSERT_EQ(i, *(int *)bl.c_str());
328 marker = entry.marker;
329 }
330
331 /* trim one at a time */
332 marker.reset();
333 for (auto i = 0u; i < max_entries; ++i) {
334 /* read single entry */
b3b6e05e 335 r = f->list(&dp, 1, marker, &result, &more, null_yield);
f67539c2
TL
336 ASSERT_EQ(0, r);
337 ASSERT_EQ(result.size(), 1);
338 const bool expected_more = (i != (max_entries - 1));
339 ASSERT_EQ(expected_more, more);
340
341 marker = result.front().marker;
b3b6e05e 342 r = f->trim(&dp, *marker, false, null_yield);
f67539c2
TL
343 ASSERT_EQ(0, r);
344
345 /* check tail */
346 info = f->meta();
347 ASSERT_EQ(info.tail_part_num, i / entries_per_part);
348
349 /* try to read all again, see how many entries left */
b3b6e05e 350 r = f->list(&dp, max_entries, marker, &result, &more, null_yield);
f67539c2
TL
351 ASSERT_EQ(max_entries - i - 1, result.size());
352 ASSERT_EQ(false, more);
353 }
354
355 /* tail now should point at head */
356 info = f->meta();
357 ASSERT_EQ(info.head_part_num, info.tail_part_num);
358
359 RCf::part_info partinfo;
360 /* check old tails are removed */
361 for (auto i = 0; i < info.tail_part_num; ++i) {
b3b6e05e 362 r = f->get_part_info(&dp, i, &partinfo, null_yield);
f67539c2
TL
363 ASSERT_EQ(-ENOENT, r);
364 }
365 /* check current tail exists */
b3b6e05e 366 r = f->get_part_info(&dp, info.tail_part_num, &partinfo, null_yield);
f67539c2
TL
367 ASSERT_EQ(0, r);
368}
369
370TEST_F(LegacyFIFO, TestTwoPushers)
371{
372 static constexpr auto max_part_size = 2048ull;
373 static constexpr auto max_entry_size = 128ull;
374
375 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 376 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
377 std::nullopt, false, max_part_size,
378 max_entry_size);
379 ASSERT_EQ(0, r);
380 char buf[max_entry_size];
381 memset(buf, 0, sizeof(buf));
382
383 auto [part_header_size, part_entry_overhead] = f->get_part_layout_info();
384 const auto entries_per_part = ((max_part_size - part_header_size) /
385 (max_entry_size + part_entry_overhead));
386 const auto max_entries = entries_per_part * 4 + 1;
387 std::unique_ptr<RCf::FIFO> f2;
b3b6e05e 388 r = RCf::FIFO::open(&dp, ioctx, fifo_id, &f2, null_yield);
f67539c2
TL
389 std::vector fifos{&f, &f2};
390
391 for (auto i = 0u; i < max_entries; ++i) {
392 cb::list bl;
393 *(int *)buf = i;
394 bl.append(buf, sizeof(buf));
395 auto& f = *fifos[i % fifos.size()];
b3b6e05e 396 r = f->push(&dp, bl, null_yield);
f67539c2
TL
397 ASSERT_EQ(0, r);
398 }
399
400 /* list all by both */
401 std::vector<RCf::list_entry> result;
402 bool more = false;
b3b6e05e 403 r = f2->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
404 ASSERT_EQ(0, r);
405 ASSERT_EQ(false, more);
406 ASSERT_EQ(max_entries, result.size());
407
b3b6e05e 408 r = f2->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
409 ASSERT_EQ(0, r);
410 ASSERT_EQ(false, more);
411 ASSERT_EQ(max_entries, result.size());
412
413 for (auto i = 0u; i < max_entries; ++i) {
414 auto& bl = result[i].data;
415 ASSERT_EQ(i, *(int *)bl.c_str());
416 }
417}
418
419TEST_F(LegacyFIFO, TestTwoPushersTrim)
420{
421 static constexpr auto max_part_size = 2048ull;
422 static constexpr auto max_entry_size = 128ull;
423 std::unique_ptr<RCf::FIFO> f1;
b3b6e05e 424 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f1, null_yield, std::nullopt,
f67539c2
TL
425 std::nullopt, false, max_part_size,
426 max_entry_size);
427 ASSERT_EQ(0, r);
428
429 char buf[max_entry_size];
430 memset(buf, 0, sizeof(buf));
431
432 auto [part_header_size, part_entry_overhead] = f1->get_part_layout_info();
433 const auto entries_per_part = ((max_part_size - part_header_size) /
434 (max_entry_size + part_entry_overhead));
435 const auto max_entries = entries_per_part * 4 + 1;
436
437 std::unique_ptr<RCf::FIFO> f2;
b3b6e05e 438 r = RCf::FIFO::open(&dp, ioctx, fifo_id, &f2, null_yield);
f67539c2
TL
439 ASSERT_EQ(0, r);
440
441 /* push one entry to f2 and the rest to f1 */
442 for (auto i = 0u; i < max_entries; ++i) {
443 cb::list bl;
444 *(int *)buf = i;
445 bl.append(buf, sizeof(buf));
446 auto& f = (i < 1 ? f2 : f1);
b3b6e05e 447 r = f->push(&dp, bl, null_yield);
f67539c2
TL
448 ASSERT_EQ(0, r);
449 }
450
451 /* trim half by fifo1 */
452 auto num = max_entries / 2;
453 std::string marker;
454 std::vector<RCf::list_entry> result;
455 bool more = false;
b3b6e05e 456 r = f1->list(&dp, num, std::nullopt, &result, &more, null_yield);
f67539c2
TL
457 ASSERT_EQ(0, r);
458 ASSERT_EQ(true, more);
459 ASSERT_EQ(num, result.size());
460
461 for (auto i = 0u; i < num; ++i) {
462 auto& bl = result[i].data;
463 ASSERT_EQ(i, *(int *)bl.c_str());
464 }
465
466 auto& entry = result[num - 1];
467 marker = entry.marker;
b3b6e05e 468 r = f1->trim(&dp, marker, false, null_yield);
f67539c2
TL
469 /* list what's left by fifo2 */
470
471 const auto left = max_entries - num;
b3b6e05e 472 f2->list(&dp, left, marker, &result, &more, null_yield);
f67539c2
TL
473 ASSERT_EQ(left, result.size());
474 ASSERT_EQ(false, more);
475
476 for (auto i = num; i < max_entries; ++i) {
477 auto& bl = result[i - num].data;
478 ASSERT_EQ(i, *(int *)bl.c_str());
479 }
480}
481
482TEST_F(LegacyFIFO, TestPushBatch)
483{
484 static constexpr auto max_part_size = 2048ull;
485 static constexpr auto max_entry_size = 128ull;
486
487 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 488 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
489 std::nullopt, false, max_part_size,
490 max_entry_size);
491 ASSERT_EQ(0, r);
492
493 char buf[max_entry_size];
494 memset(buf, 0, sizeof(buf));
495 auto [part_header_size, part_entry_overhead] = f->get_part_layout_info();
496 auto entries_per_part = ((max_part_size - part_header_size) /
497 (max_entry_size + part_entry_overhead));
498 auto max_entries = entries_per_part * 4 + 1; /* enough entries to span multiple parts */
499 std::vector<cb::list> bufs;
500 for (auto i = 0u; i < max_entries; ++i) {
501 cb::list bl;
502 *(int *)buf = i;
503 bl.append(buf, sizeof(buf));
504 bufs.push_back(bl);
505 }
506 ASSERT_EQ(max_entries, bufs.size());
507
b3b6e05e 508 r = f->push(&dp, bufs, null_yield);
f67539c2
TL
509 ASSERT_EQ(0, r);
510
511 /* list all */
512
513 std::vector<RCf::list_entry> result;
514 bool more = false;
b3b6e05e 515 r = f->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
516 ASSERT_EQ(0, r);
517 ASSERT_EQ(false, more);
518 ASSERT_EQ(max_entries, result.size());
519 for (auto i = 0u; i < max_entries; ++i) {
520 auto& bl = result[i].data;
521 ASSERT_EQ(i, *(int *)bl.c_str());
522 }
523 auto& info = f->meta();
524 ASSERT_EQ(info.head_part_num, 4);
525}
526
527TEST_F(LegacyFIFO, TestAioTrim)
528{
529 static constexpr auto max_part_size = 2048ull;
530 static constexpr auto max_entry_size = 128ull;
531 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 532 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
533 std::nullopt, false, max_part_size,
534 max_entry_size);
535 ASSERT_EQ(0, r);
536
537 char buf[max_entry_size];
538 memset(buf, 0, sizeof(buf));
539 const auto [part_header_size, part_entry_overhead] =
540 f->get_part_layout_info();
541 const auto entries_per_part = ((max_part_size - part_header_size) /
542 (max_entry_size + part_entry_overhead));
543 const auto max_entries = entries_per_part * 4 + 1;
544 /* push enough entries */
545 std::vector<cb::list> bufs;
546 for (auto i = 0u; i < max_entries; ++i) {
547 cb::list bl;
548 *(int *)buf = i;
549 bl.append(buf, sizeof(buf));
550 bufs.push_back(std::move(bl));
551 }
552 ASSERT_EQ(max_entries, bufs.size());
553
b3b6e05e 554 r = f->push(&dp, bufs, null_yield);
f67539c2
TL
555 ASSERT_EQ(0, r);
556
557 auto info = f->meta();
558 ASSERT_EQ(info.id, fifo_id);
559 /* head should have advanced */
560 ASSERT_GT(info.head_part_num, 0);
561
562 /* list all at once */
563 std::vector<RCf::list_entry> result;
564 bool more = false;
b3b6e05e 565 r = f->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
566 ASSERT_EQ(0, r);
567 ASSERT_EQ(false, more);
568 ASSERT_EQ(max_entries, result.size());
569
570 std::optional<std::string> marker;
571 /* trim one at a time */
572 result.clear();
573 more = false;
574 marker.reset();
575 for (auto i = 0u; i < max_entries; ++i) {
576 /* read single entry */
b3b6e05e 577 r = f->list(&dp, 1, marker, &result, &more, null_yield);
f67539c2
TL
578 ASSERT_EQ(0, r);
579 ASSERT_EQ(result.size(), 1);
580 const bool expected_more = (i != (max_entries - 1));
581 ASSERT_EQ(expected_more, more);
582
583 marker = result.front().marker;
584 std::unique_ptr<R::AioCompletion> c(rados.aio_create_completion(nullptr,
585 nullptr));
b3b6e05e 586 f->trim(&dp, *marker, false, c.get());
f67539c2
TL
587 c->wait_for_complete();
588 r = c->get_return_value();
589 ASSERT_EQ(0, r);
590
591 /* check tail */
592 info = f->meta();
593 ASSERT_EQ(info.tail_part_num, i / entries_per_part);
594
595 /* try to read all again, see how many entries left */
b3b6e05e 596 r = f->list(&dp, max_entries, marker, &result, &more, null_yield);
f67539c2
TL
597 ASSERT_EQ(max_entries - i - 1, result.size());
598 ASSERT_EQ(false, more);
599 }
600
601 /* tail now should point at head */
602 info = f->meta();
603 ASSERT_EQ(info.head_part_num, info.tail_part_num);
604
605 RCf::part_info partinfo;
606 /* check old tails are removed */
607 for (auto i = 0; i < info.tail_part_num; ++i) {
b3b6e05e 608 r = f->get_part_info(&dp, i, &partinfo, null_yield);
f67539c2
TL
609 ASSERT_EQ(-ENOENT, r);
610 }
611 /* check current tail exists */
b3b6e05e 612 r = f->get_part_info(&dp, info.tail_part_num, &partinfo, null_yield);
f67539c2
TL
613 ASSERT_EQ(0, r);
614}
615
616TEST_F(LegacyFIFO, TestTrimExclusive) {
617 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 618 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield);
f67539c2
TL
619 ASSERT_EQ(0, r);
620 std::vector<RCf::list_entry> result;
621 bool more = false;
622
623 static constexpr auto max_entries = 10u;
624 for (uint32_t i = 0; i < max_entries; ++i) {
625 cb::list bl;
626 encode(i, bl);
b3b6e05e 627 f->push(&dp, bl, null_yield);
f67539c2
TL
628 }
629
b3b6e05e 630 f->list(&dp, 1, std::nullopt, &result, &more, null_yield);
f67539c2
TL
631 auto [val, marker] = decode_entry<std::uint32_t>(result.front());
632 ASSERT_EQ(0, val);
b3b6e05e 633 f->trim(&dp, marker, true, null_yield);
f67539c2
TL
634
635 result.clear();
b3b6e05e 636 f->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
637 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
638 ASSERT_EQ(0, val);
b3b6e05e 639 f->trim(&dp, result[4].marker, true, null_yield);
f67539c2
TL
640
641 result.clear();
b3b6e05e 642 f->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
643 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
644 ASSERT_EQ(4, val);
b3b6e05e 645 f->trim(&dp, result.back().marker, true, null_yield);
f67539c2
TL
646
647 result.clear();
b3b6e05e 648 f->list(&dp, max_entries, std::nullopt, &result, &more, null_yield);
f67539c2
TL
649 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
650 ASSERT_EQ(result.size(), 1);
651 ASSERT_EQ(max_entries - 1, val);
652}
653
654TEST_F(AioLegacyFIFO, TestPushListTrim)
655{
656 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 657 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield);
f67539c2
TL
658 ASSERT_EQ(0, r);
659 static constexpr auto max_entries = 10u;
660 for (uint32_t i = 0; i < max_entries; ++i) {
661 cb::list bl;
662 encode(i, bl);
663 auto c = R::Rados::aio_create_completion();
b3b6e05e 664 f->push(&dp, bl, c);
f67539c2
TL
665 c->wait_for_complete();
666 r = c->get_return_value();
667 c->release();
668 ASSERT_EQ(0, r);
669 }
670
671 std::optional<std::string> marker;
672 /* get entries one by one */
673 std::vector<RCf::list_entry> result;
674 bool more = false;
675 for (auto i = 0u; i < max_entries; ++i) {
676 auto c = R::Rados::aio_create_completion();
b3b6e05e 677 f->list(&dp, 1, marker, &result, &more, c);
f67539c2
TL
678 c->wait_for_complete();
679 r = c->get_return_value();
680 c->release();
681 ASSERT_EQ(0, r);
682
683 bool expected_more = (i != (max_entries - 1));
684 ASSERT_EQ(expected_more, more);
685 ASSERT_EQ(1, result.size());
686
687 std::uint32_t val;
688 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
689
690 ASSERT_EQ(i, val);
691 result.clear();
692 }
693
694 /* get all entries at once */
695 std::string markers[max_entries];
696 std::uint32_t min_entry = 0;
697 auto c = R::Rados::aio_create_completion();
b3b6e05e 698 f->list(&dp, max_entries * 10, std::nullopt, &result, &more, c);
f67539c2
TL
699 c->wait_for_complete();
700 r = c->get_return_value();
701 c->release();
702 ASSERT_EQ(0, r);
703
704 ASSERT_FALSE(more);
705 ASSERT_EQ(max_entries, result.size());
706 for (auto i = 0u; i < max_entries; ++i) {
707 std::uint32_t val;
708 std::tie(val, markers[i]) = decode_entry<std::uint32_t>(result[i]);
709 ASSERT_EQ(i, val);
710 }
711
712 /* trim one entry */
713 c = R::Rados::aio_create_completion();
b3b6e05e 714 f->trim(&dp, markers[min_entry], false, c);
f67539c2
TL
715 c->wait_for_complete();
716 r = c->get_return_value();
717 c->release();
718 ASSERT_EQ(0, r);
719 ++min_entry;
720
721 c = R::Rados::aio_create_completion();
b3b6e05e 722 f->list(&dp, max_entries * 10, std::nullopt, &result, &more, c);
f67539c2
TL
723 c->wait_for_complete();
724 r = c->get_return_value();
725 c->release();
726 ASSERT_EQ(0, r);
727 ASSERT_FALSE(more);
728 ASSERT_EQ(max_entries - min_entry, result.size());
729
730 for (auto i = min_entry; i < max_entries; ++i) {
731 std::uint32_t val;
732 std::tie(val, markers[i - min_entry]) =
733 decode_entry<std::uint32_t>(result[i - min_entry]);
734 EXPECT_EQ(i, val);
735 }
736}
737
738
739TEST_F(AioLegacyFIFO, TestPushTooBig)
740{
741 static constexpr auto max_part_size = 2048ull;
742 static constexpr auto max_entry_size = 128ull;
743
744 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 745 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
746 std::nullopt, false, max_part_size, max_entry_size);
747 ASSERT_EQ(0, r);
748
749 char buf[max_entry_size + 1];
750 memset(buf, 0, sizeof(buf));
751
752 cb::list bl;
753 bl.append(buf, sizeof(buf));
754
755 auto c = R::Rados::aio_create_completion();
b3b6e05e 756 f->push(&dp, bl, c);
f67539c2
TL
757 c->wait_for_complete();
758 r = c->get_return_value();
759 ASSERT_EQ(-E2BIG, r);
760 c->release();
761
762 c = R::Rados::aio_create_completion();
b3b6e05e 763 f->push(&dp, std::vector<cb::list>{}, c);
f67539c2
TL
764 c->wait_for_complete();
765 r = c->get_return_value();
766 c->release();
767 EXPECT_EQ(0, r);
768}
769
770
771TEST_F(AioLegacyFIFO, TestMultipleParts)
772{
773 static constexpr auto max_part_size = 2048ull;
774 static constexpr auto max_entry_size = 128ull;
775 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 776 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
777 std::nullopt, false, max_part_size,
778 max_entry_size);
779 ASSERT_EQ(0, r);
780
781 {
782 auto c = R::Rados::aio_create_completion();
b3b6e05e 783 f->get_head_info(&dp, [&](int r, RCf::part_info&& p) {
f67539c2
TL
784 ASSERT_TRUE(p.tag.empty());
785 ASSERT_EQ(0, p.magic);
786 ASSERT_EQ(0, p.min_ofs);
787 ASSERT_EQ(0, p.last_ofs);
788 ASSERT_EQ(0, p.next_ofs);
789 ASSERT_EQ(0, p.min_index);
790 ASSERT_EQ(0, p.max_index);
791 ASSERT_EQ(ceph::real_time{}, p.max_time);
792 }, c);
793 c->wait_for_complete();
794 r = c->get_return_value();
795 c->release();
796 }
797
798 char buf[max_entry_size];
799 memset(buf, 0, sizeof(buf));
800 const auto [part_header_size, part_entry_overhead] =
801 f->get_part_layout_info();
802 const auto entries_per_part = ((max_part_size - part_header_size) /
803 (max_entry_size + part_entry_overhead));
804 const auto max_entries = entries_per_part * 4 + 1;
805 /* push enough entries */
806 for (auto i = 0u; i < max_entries; ++i) {
807 cb::list bl;
808 *(int *)buf = i;
809 bl.append(buf, sizeof(buf));
810 auto c = R::Rados::aio_create_completion();
b3b6e05e 811 f->push(&dp, bl, c);
f67539c2
TL
812 c->wait_for_complete();
813 r = c->get_return_value();
814 c->release();
815 EXPECT_EQ(0, r);
816 }
817
818 auto info = f->meta();
819 ASSERT_EQ(info.id, fifo_id);
820 /* head should have advanced */
821 ASSERT_GT(info.head_part_num, 0);
822
823 /* list all at once */
824 std::vector<RCf::list_entry> result;
825 bool more = false;
826 auto c = R::Rados::aio_create_completion();
b3b6e05e 827 f->list(&dp, max_entries, std::nullopt, &result, &more, c);
f67539c2
TL
828 c->wait_for_complete();
829 r = c->get_return_value();
830 c->release();
831 EXPECT_EQ(0, r);
832 EXPECT_EQ(false, more);
833 ASSERT_EQ(max_entries, result.size());
834
835 for (auto i = 0u; i < max_entries; ++i) {
836 auto& bl = result[i].data;
837 ASSERT_EQ(i, *(int *)bl.c_str());
838 }
839
840 std::optional<std::string> marker;
841 /* get entries one by one */
842
843 for (auto i = 0u; i < max_entries; ++i) {
844 c = R::Rados::aio_create_completion();
b3b6e05e 845 f->list(&dp, 1, marker, &result, &more, c);
f67539c2
TL
846 c->wait_for_complete();
847 r = c->get_return_value();
848 c->release();
849 EXPECT_EQ(0, r);
850 ASSERT_EQ(result.size(), 1);
851 const bool expected_more = (i != (max_entries - 1));
852 ASSERT_EQ(expected_more, more);
853
854 std::uint32_t val;
855 std::tie(val, marker) = decode_entry<std::uint32_t>(result.front());
856
857 auto& entry = result.front();
858 auto& bl = entry.data;
859 ASSERT_EQ(i, *(int *)bl.c_str());
860 marker = entry.marker;
861 }
862
863 /* trim one at a time */
864 marker.reset();
865 for (auto i = 0u; i < max_entries; ++i) {
866 /* read single entry */
867 c = R::Rados::aio_create_completion();
b3b6e05e 868 f->list(&dp, 1, marker, &result, &more, c);
f67539c2
TL
869 c->wait_for_complete();
870 r = c->get_return_value();
871 c->release();
872 EXPECT_EQ(0, r);
873 ASSERT_EQ(result.size(), 1);
874 const bool expected_more = (i != (max_entries - 1));
875 ASSERT_EQ(expected_more, more);
876
877 marker = result.front().marker;
878 c = R::Rados::aio_create_completion();
b3b6e05e 879 f->trim(&dp, *marker, false, c);
f67539c2
TL
880 c->wait_for_complete();
881 r = c->get_return_value();
882 c->release();
883 EXPECT_EQ(0, r);
884 ASSERT_EQ(result.size(), 1);
885
886 /* check tail */
887 info = f->meta();
888 ASSERT_EQ(info.tail_part_num, i / entries_per_part);
889
890 /* try to read all again, see how many entries left */
891 c = R::Rados::aio_create_completion();
b3b6e05e 892 f->list(&dp, max_entries, marker, &result, &more, c);
f67539c2
TL
893 c->wait_for_complete();
894 r = c->get_return_value();
895 c->release();
896 EXPECT_EQ(0, r);
897 ASSERT_EQ(max_entries - i - 1, result.size());
898 ASSERT_EQ(false, more);
899 }
900
901 /* tail now should point at head */
902 info = f->meta();
903 ASSERT_EQ(info.head_part_num, info.tail_part_num);
904
905 /* check old tails are removed */
906 for (auto i = 0; i < info.tail_part_num; ++i) {
907 c = R::Rados::aio_create_completion();
908 RCf::part_info partinfo;
909 f->get_part_info(i, &partinfo, c);
910 c->wait_for_complete();
911 r = c->get_return_value();
912 c->release();
913 ASSERT_EQ(-ENOENT, r);
914 }
915 /* check current tail exists */
916 std::uint64_t next_ofs;
917 {
918 c = R::Rados::aio_create_completion();
919 RCf::part_info partinfo;
920 f->get_part_info(info.tail_part_num, &partinfo, c);
921 c->wait_for_complete();
922 r = c->get_return_value();
923 c->release();
924 next_ofs = partinfo.next_ofs;
925 }
926 ASSERT_EQ(0, r);
927
928 c = R::Rados::aio_create_completion();
b3b6e05e 929 f->get_head_info(&dp, [&](int r, RCf::part_info&& p) {
f67539c2
TL
930 ASSERT_EQ(next_ofs, p.next_ofs);
931 }, c);
932 c->wait_for_complete();
933 r = c->get_return_value();
934 c->release();
935 ASSERT_EQ(0, r);
936}
937
938TEST_F(AioLegacyFIFO, TestTwoPushers)
939{
940 static constexpr auto max_part_size = 2048ull;
941 static constexpr auto max_entry_size = 128ull;
942
943 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 944 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
945 std::nullopt, false, max_part_size,
946 max_entry_size);
947 ASSERT_EQ(0, r);
948 char buf[max_entry_size];
949 memset(buf, 0, sizeof(buf));
950
951 auto [part_header_size, part_entry_overhead] = f->get_part_layout_info();
952 const auto entries_per_part = ((max_part_size - part_header_size) /
953 (max_entry_size + part_entry_overhead));
954 const auto max_entries = entries_per_part * 4 + 1;
955 std::unique_ptr<RCf::FIFO> f2;
b3b6e05e 956 r = RCf::FIFO::open(&dp, ioctx, fifo_id, &f2, null_yield);
f67539c2
TL
957 std::vector fifos{&f, &f2};
958
959 for (auto i = 0u; i < max_entries; ++i) {
960 cb::list bl;
961 *(int *)buf = i;
962 bl.append(buf, sizeof(buf));
963 auto& f = *fifos[i % fifos.size()];
964 auto c = R::Rados::aio_create_completion();
b3b6e05e 965 f->push(&dp, bl, c);
f67539c2
TL
966 c->wait_for_complete();
967 r = c->get_return_value();
968 c->release();
969 ASSERT_EQ(0, r);
970 }
971
972 /* list all by both */
973 std::vector<RCf::list_entry> result;
974 bool more = false;
975 auto c = R::Rados::aio_create_completion();
b3b6e05e 976 f2->list(&dp, max_entries, std::nullopt, &result, &more, c);
f67539c2
TL
977 c->wait_for_complete();
978 r = c->get_return_value();
979 c->release();
980 ASSERT_EQ(0, r);
981 ASSERT_EQ(false, more);
982 ASSERT_EQ(max_entries, result.size());
983
984 c = R::Rados::aio_create_completion();
b3b6e05e 985 f2->list(&dp, max_entries, std::nullopt, &result, &more, c);
f67539c2
TL
986 c->wait_for_complete();
987 r = c->get_return_value();
988 c->release();
989 ASSERT_EQ(0, r);
990 ASSERT_EQ(false, more);
991 ASSERT_EQ(max_entries, result.size());
992
993 for (auto i = 0u; i < max_entries; ++i) {
994 auto& bl = result[i].data;
995 ASSERT_EQ(i, *(int *)bl.c_str());
996 }
997}
998
999TEST_F(AioLegacyFIFO, TestTwoPushersTrim)
1000{
1001 static constexpr auto max_part_size = 2048ull;
1002 static constexpr auto max_entry_size = 128ull;
1003 std::unique_ptr<RCf::FIFO> f1;
b3b6e05e 1004 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f1, null_yield, std::nullopt,
f67539c2
TL
1005 std::nullopt, false, max_part_size,
1006 max_entry_size);
1007 ASSERT_EQ(0, r);
1008
1009 char buf[max_entry_size];
1010 memset(buf, 0, sizeof(buf));
1011
1012 auto [part_header_size, part_entry_overhead] = f1->get_part_layout_info();
1013 const auto entries_per_part = ((max_part_size - part_header_size) /
1014 (max_entry_size + part_entry_overhead));
1015 const auto max_entries = entries_per_part * 4 + 1;
1016
1017 std::unique_ptr<RCf::FIFO> f2;
b3b6e05e 1018 r = RCf::FIFO::open(&dp, ioctx, fifo_id, &f2, null_yield);
f67539c2
TL
1019 ASSERT_EQ(0, r);
1020
1021 /* push one entry to f2 and the rest to f1 */
1022 for (auto i = 0u; i < max_entries; ++i) {
1023 cb::list bl;
1024 *(int *)buf = i;
1025 bl.append(buf, sizeof(buf));
1026 auto& f = (i < 1 ? f2 : f1);
1027 auto c = R::Rados::aio_create_completion();
b3b6e05e 1028 f->push(&dp, bl, c);
f67539c2
TL
1029 c->wait_for_complete();
1030 r = c->get_return_value();
1031 c->release();
1032 ASSERT_EQ(0, r);
1033 }
1034
1035 /* trim half by fifo1 */
1036 auto num = max_entries / 2;
1037 std::string marker;
1038 std::vector<RCf::list_entry> result;
1039 bool more = false;
1040 auto c = R::Rados::aio_create_completion();
b3b6e05e 1041 f1->list(&dp, num, std::nullopt, &result, &more, c);
f67539c2
TL
1042 c->wait_for_complete();
1043 r = c->get_return_value();
1044 c->release();
1045 ASSERT_EQ(0, r);
1046 ASSERT_EQ(true, more);
1047 ASSERT_EQ(num, result.size());
1048
1049 for (auto i = 0u; i < num; ++i) {
1050 auto& bl = result[i].data;
1051 ASSERT_EQ(i, *(int *)bl.c_str());
1052 }
1053
1054 auto& entry = result[num - 1];
1055 marker = entry.marker;
1056 c = R::Rados::aio_create_completion();
b3b6e05e 1057 f1->trim(&dp, marker, false, c);
f67539c2
TL
1058 c->wait_for_complete();
1059 r = c->get_return_value();
1060 c->release();
1061 ASSERT_EQ(0, r);
1062 /* list what's left by fifo2 */
1063
1064 const auto left = max_entries - num;
1065 c = R::Rados::aio_create_completion();
b3b6e05e 1066 f2->list(&dp, left, marker, &result, &more, c);
f67539c2
TL
1067 c->wait_for_complete();
1068 r = c->get_return_value();
1069 c->release();
1070 ASSERT_EQ(0, r);
1071 ASSERT_EQ(left, result.size());
1072 ASSERT_EQ(false, more);
1073
1074 for (auto i = num; i < max_entries; ++i) {
1075 auto& bl = result[i - num].data;
1076 ASSERT_EQ(i, *(int *)bl.c_str());
1077 }
1078}
1079
1080TEST_F(AioLegacyFIFO, TestPushBatch)
1081{
1082 static constexpr auto max_part_size = 2048ull;
1083 static constexpr auto max_entry_size = 128ull;
1084
1085 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 1086 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield, std::nullopt,
f67539c2
TL
1087 std::nullopt, false, max_part_size,
1088 max_entry_size);
1089 ASSERT_EQ(0, r);
1090
1091 char buf[max_entry_size];
1092 memset(buf, 0, sizeof(buf));
1093 auto [part_header_size, part_entry_overhead] = f->get_part_layout_info();
1094 auto entries_per_part = ((max_part_size - part_header_size) /
1095 (max_entry_size + part_entry_overhead));
1096 auto max_entries = entries_per_part * 4 + 1; /* enough entries to span multiple parts */
1097 std::vector<cb::list> bufs;
1098 for (auto i = 0u; i < max_entries; ++i) {
1099 cb::list bl;
1100 *(int *)buf = i;
1101 bl.append(buf, sizeof(buf));
1102 bufs.push_back(bl);
1103 }
1104 ASSERT_EQ(max_entries, bufs.size());
1105
1106 auto c = R::Rados::aio_create_completion();
b3b6e05e 1107 f->push(&dp, bufs, c);
f67539c2
TL
1108 c->wait_for_complete();
1109 r = c->get_return_value();
1110 c->release();
1111 ASSERT_EQ(0, r);
1112
1113 /* list all */
1114
1115 std::vector<RCf::list_entry> result;
1116 bool more = false;
1117 c = R::Rados::aio_create_completion();
b3b6e05e 1118 f->list(&dp, max_entries, std::nullopt, &result, &more, c);
f67539c2
TL
1119 c->wait_for_complete();
1120 r = c->get_return_value();
1121 c->release();
1122 ASSERT_EQ(0, r);
1123 ASSERT_EQ(false, more);
1124 ASSERT_EQ(max_entries, result.size());
1125 for (auto i = 0u; i < max_entries; ++i) {
1126 auto& bl = result[i].data;
1127 ASSERT_EQ(i, *(int *)bl.c_str());
1128 }
1129 auto& info = f->meta();
1130 ASSERT_EQ(info.head_part_num, 4);
1131}
1132
1133TEST_F(LegacyFIFO, TrimAll)
1134{
1135 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 1136 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield);
f67539c2
TL
1137 ASSERT_EQ(0, r);
1138 static constexpr auto max_entries = 10u;
1139 for (uint32_t i = 0; i < max_entries; ++i) {
1140 cb::list bl;
1141 encode(i, bl);
b3b6e05e 1142 r = f->push(&dp, bl, null_yield);
f67539c2
TL
1143 ASSERT_EQ(0, r);
1144 }
1145
1146 /* trim one entry */
b3b6e05e 1147 r = f->trim(&dp, RCf::marker::max().to_string(), false, null_yield);
f67539c2
TL
1148 ASSERT_EQ(-ENODATA, r);
1149
1150 std::vector<RCf::list_entry> result;
1151 bool more;
b3b6e05e 1152 r = f->list(&dp, 1, std::nullopt, &result, &more, null_yield);
f67539c2
TL
1153 ASSERT_EQ(0, r);
1154 ASSERT_TRUE(result.empty());
1155}
1156
1157TEST_F(LegacyFIFO, AioTrimAll)
1158{
1159 std::unique_ptr<RCf::FIFO> f;
b3b6e05e 1160 auto r = RCf::FIFO::create(&dp, ioctx, fifo_id, &f, null_yield);
f67539c2
TL
1161 ASSERT_EQ(0, r);
1162 static constexpr auto max_entries = 10u;
1163 for (uint32_t i = 0; i < max_entries; ++i) {
1164 cb::list bl;
1165 encode(i, bl);
b3b6e05e 1166 r = f->push(&dp, bl, null_yield);
f67539c2
TL
1167 ASSERT_EQ(0, r);
1168 }
1169
1170 auto c = R::Rados::aio_create_completion();
b3b6e05e 1171 f->trim(&dp, RCf::marker::max().to_string(), false, c);
f67539c2
TL
1172 c->wait_for_complete();
1173 r = c->get_return_value();
1174 c->release();
1175 ASSERT_EQ(-ENODATA, r);
1176
1177 std::vector<RCf::list_entry> result;
1178 bool more;
b3b6e05e 1179 r = f->list(&dp, 1, std::nullopt, &result, &more, null_yield);
f67539c2
TL
1180 ASSERT_EQ(0, r);
1181 ASSERT_TRUE(result.empty());
1182}