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