1 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "cls/journal/cls_journal_client.h"
5 #include "include/stringify.h"
6 #include "common/Cond.h"
7 #include "test/librados/test_cxx.h"
8 #include "gtest/gtest.h"
13 using namespace cls::journal
;
15 static bool is_sparse_read_supported(librados::IoCtx
&ioctx
,
16 const std::string
&oid
) {
17 EXPECT_EQ(0, ioctx
.create(oid
, true));
19 inbl
.append(std::string(1, 'X'));
20 EXPECT_EQ(0, ioctx
.write(oid
, inbl
, inbl
.length(), 1));
21 EXPECT_EQ(0, ioctx
.write(oid
, inbl
, inbl
.length(), 3));
23 std::map
<uint64_t, uint64_t> m
;
25 int r
= ioctx
.sparse_read(oid
, m
, outbl
, 4, 0);
29 std::map
<uint64_t, uint64_t> expected_m
= {{1, 1}, {3, 1}};
30 bufferlist expected_outbl
;
31 expected_outbl
.append(std::string(2, 'X'));
33 return (r
== expected_r
&& m
== expected_m
&&
34 outbl
.contents_equal(expected_outbl
));
37 class TestClsJournal
: public ::testing::Test
{
40 static void SetUpTestCase() {
41 _pool_name
= get_temp_pool_name();
42 ASSERT_EQ("", create_one_pool_pp(_pool_name
, _rados
));
45 static void TearDownTestCase() {
46 ASSERT_EQ(0, destroy_one_pool_pp(_pool_name
, _rados
));
49 std::string
get_temp_image_name() {
51 return "image" + stringify(_image_number
);
54 static std::string _pool_name
;
55 static librados::Rados _rados
;
56 static uint64_t _image_number
;
60 std::string
TestClsJournal::_pool_name
;
61 librados::Rados
TestClsJournal::_rados
;
62 uint64_t TestClsJournal::_image_number
= 0;
64 TEST_F(TestClsJournal
, Create
) {
65 librados::IoCtx ioctx
;
66 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
68 std::string oid
= get_temp_image_name();
71 uint8_t splay_width
= 2;
72 int64_t pool_id
= ioctx
.get_id();
73 ASSERT_EQ(0, client::create(ioctx
, oid
, order
, splay_width
, pool_id
));
76 uint8_t read_splay_width
;
79 client::get_immutable_metadata(ioctx
, oid
, &read_order
, &read_splay_width
,
80 &read_pool_id
, &cond
);
81 ASSERT_EQ(0, cond
.wait());
82 ASSERT_EQ(order
, read_order
);
83 ASSERT_EQ(splay_width
, read_splay_width
);
84 ASSERT_EQ(pool_id
, read_pool_id
);
87 TEST_F(TestClsJournal
, MinimumSet
) {
88 librados::IoCtx ioctx
;
89 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
91 std::string oid
= get_temp_image_name();
93 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
95 librados::ObjectWriteOperation op1
;
96 client::set_active_set(&op1
, 300);
97 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
99 uint64_t minimum_set
= 123;
100 librados::ObjectWriteOperation op2
;
101 client::set_minimum_set(&op2
, minimum_set
);
102 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
105 uint64_t read_minimum_set
;
106 uint64_t read_active_set
;
107 std::set
<cls::journal::Client
> read_clients
;
108 client::get_mutable_metadata(ioctx
, oid
, &read_minimum_set
, &read_active_set
,
109 &read_clients
, &cond
);
110 ASSERT_EQ(0, cond
.wait());
111 ASSERT_EQ(minimum_set
, read_minimum_set
);
114 TEST_F(TestClsJournal
, MinimumSetStale
) {
115 librados::IoCtx ioctx
;
116 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
118 std::string oid
= get_temp_image_name();
120 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
122 librados::ObjectWriteOperation op1
;
123 client::set_active_set(&op1
, 300);
124 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
126 uint64_t minimum_set
= 123;
127 librados::ObjectWriteOperation op2
;
128 client::set_minimum_set(&op2
, minimum_set
);
129 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
131 librados::ObjectWriteOperation op3
;
132 client::set_minimum_set(&op3
, 1);
133 ASSERT_EQ(-ESTALE
, ioctx
.operate(oid
, &op3
));
136 uint64_t read_minimum_set
;
137 uint64_t read_active_set
;
138 std::set
<cls::journal::Client
> read_clients
;
139 client::get_mutable_metadata(ioctx
, oid
, &read_minimum_set
, &read_active_set
,
140 &read_clients
, &cond
);
141 ASSERT_EQ(0, cond
.wait());
142 ASSERT_EQ(minimum_set
, read_minimum_set
);
145 TEST_F(TestClsJournal
, MinimumSetOrderConstraint
) {
146 librados::IoCtx ioctx
;
147 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
149 std::string oid
= get_temp_image_name();
151 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
153 librados::ObjectWriteOperation op1
;
154 client::set_minimum_set(&op1
, 123);
155 ASSERT_EQ(-EINVAL
, ioctx
.operate(oid
, &op1
));
158 uint64_t read_minimum_set
;
159 uint64_t read_active_set
;
160 std::set
<cls::journal::Client
> read_clients
;
161 client::get_mutable_metadata(ioctx
, oid
, &read_minimum_set
, &read_active_set
,
162 &read_clients
, &cond
);
163 ASSERT_EQ(0, cond
.wait());
164 ASSERT_EQ(0U, read_minimum_set
);
167 TEST_F(TestClsJournal
, ActiveSet
) {
168 librados::IoCtx ioctx
;
169 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
171 std::string oid
= get_temp_image_name();
173 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
175 uint64_t active_set
= 234;
176 librados::ObjectWriteOperation op1
;
177 client::set_active_set(&op1
, active_set
);
178 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
181 uint64_t read_minimum_set
;
182 uint64_t read_active_set
;
183 std::set
<cls::journal::Client
> read_clients
;
184 client::get_mutable_metadata(ioctx
, oid
, &read_minimum_set
, &read_active_set
,
185 &read_clients
, &cond
);
186 ASSERT_EQ(0, cond
.wait());
187 ASSERT_EQ(active_set
, read_active_set
);
190 TEST_F(TestClsJournal
, ActiveSetStale
) {
191 librados::IoCtx ioctx
;
192 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
194 std::string oid
= get_temp_image_name();
196 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
198 librados::ObjectWriteOperation op1
;
199 client::set_active_set(&op1
, 345);
200 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
202 librados::ObjectWriteOperation op2
;
203 client::set_active_set(&op2
, 3);
204 ASSERT_EQ(-ESTALE
, ioctx
.operate(oid
, &op2
));
207 TEST_F(TestClsJournal
, CreateDuplicate
) {
208 librados::IoCtx ioctx
;
209 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
211 std::string oid
= get_temp_image_name();
213 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
214 ASSERT_EQ(-EEXIST
, client::create(ioctx
, oid
, 3, 5, ioctx
.get_id()));
217 TEST_F(TestClsJournal
, GetClient
) {
218 librados::IoCtx ioctx
;
219 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
221 std::string oid
= get_temp_image_name();
222 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
225 ASSERT_EQ(-ENOENT
, client::get_client(ioctx
, oid
, "id", &client
));
228 data
.append(std::string(128, '1'));
229 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", data
));
231 ASSERT_EQ(0, client::get_client(ioctx
, oid
, "id1", &client
));
232 Client
expected_client("id1", data
);
233 ASSERT_EQ(expected_client
, client
);
236 TEST_F(TestClsJournal
, ClientRegister
) {
237 librados::IoCtx ioctx
;
238 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
240 std::string oid
= get_temp_image_name();
241 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
243 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
245 std::set
<Client
> clients
;
246 ASSERT_EQ(0, client::client_list(ioctx
, oid
, &clients
));
248 std::set
<Client
> expected_clients
= {Client("id1", bufferlist())};
249 ASSERT_EQ(expected_clients
, clients
);
252 TEST_F(TestClsJournal
, ClientRegisterDuplicate
) {
253 librados::IoCtx ioctx
;
254 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
256 std::string oid
= get_temp_image_name();
257 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
259 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
260 ASSERT_EQ(-EEXIST
, client::client_register(ioctx
, oid
, "id1", bufferlist()));
263 TEST_F(TestClsJournal
, ClientUpdateData
) {
264 librados::IoCtx ioctx
;
265 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
267 std::string oid
= get_temp_image_name();
268 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
270 ASSERT_EQ(-ENOENT
, client::client_update_data(ioctx
, oid
, "id1",
273 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
276 data
.append(std::string(128, '1'));
277 ASSERT_EQ(0, client::client_update_data(ioctx
, oid
, "id1", data
));
280 ASSERT_EQ(0, client::get_client(ioctx
, oid
, "id1", &client
));
281 Client
expected_client("id1", data
);
282 ASSERT_EQ(expected_client
, client
);
285 TEST_F(TestClsJournal
, ClientUpdateState
) {
286 librados::IoCtx ioctx
;
287 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
289 std::string oid
= get_temp_image_name();
290 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
292 ASSERT_EQ(-ENOENT
, client::client_update_state(ioctx
, oid
, "id1",
293 CLIENT_STATE_DISCONNECTED
));
295 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
298 data
.append(std::string(128, '1'));
299 ASSERT_EQ(0, client::client_update_state(ioctx
, oid
, "id1",
300 CLIENT_STATE_DISCONNECTED
));
303 ASSERT_EQ(0, client::get_client(ioctx
, oid
, "id1", &client
));
304 Client expected_client
;
305 expected_client
.id
= "id1";
306 expected_client
.state
= CLIENT_STATE_DISCONNECTED
;
307 ASSERT_EQ(expected_client
, client
);
310 TEST_F(TestClsJournal
, ClientUnregister
) {
311 librados::IoCtx ioctx
;
312 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
314 std::string oid
= get_temp_image_name();
315 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
317 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
318 ASSERT_EQ(0, client::client_unregister(ioctx
, oid
, "id1"));
321 TEST_F(TestClsJournal
, ClientUnregisterDNE
) {
322 librados::IoCtx ioctx
;
323 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
325 std::string oid
= get_temp_image_name();
326 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 4, ioctx
.get_id()));
328 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
329 ASSERT_EQ(0, client::client_unregister(ioctx
, oid
, "id1"));
330 ASSERT_EQ(-ENOENT
, client::client_unregister(ioctx
, oid
, "id1"));
333 TEST_F(TestClsJournal
, ClientUnregisterPruneTags
) {
334 librados::IoCtx ioctx
;
335 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
337 std::string oid
= get_temp_image_name();
339 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
340 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
341 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id2", bufferlist()));
343 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 0, Tag::TAG_CLASS_NEW
,
345 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 1, Tag::TAG_CLASS_NEW
,
348 for (uint32_t i
= 2; i
<= 96; ++i
) {
349 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, i
, 1, bufferlist()));
352 librados::ObjectWriteOperation op1
;
353 client::client_commit(&op1
, "id1", {{{1, 32, 120}}});
354 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
356 ASSERT_EQ(0, client::client_unregister(ioctx
, oid
, "id2"));
358 std::set
<Tag
> expected_tags
= {{0, 0, {}}};
359 for (uint32_t i
= 32; i
<= 96; ++i
) {
360 expected_tags
.insert({i
, 1, {}});
363 ASSERT_EQ(0, client::tag_list(ioctx
, oid
, "id1",
364 boost::optional
<uint64_t>(), &tags
));
365 ASSERT_EQ(expected_tags
, tags
);
368 TEST_F(TestClsJournal
, ClientCommit
) {
369 librados::IoCtx ioctx
;
370 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
372 std::string oid
= get_temp_image_name();
374 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
375 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
377 cls::journal::ObjectPositions object_positions
;
379 cls::journal::ObjectPosition(0, 234, 120),
380 cls::journal::ObjectPosition(3, 235, 121)};
381 cls::journal::ObjectSetPosition
object_set_position(
384 librados::ObjectWriteOperation op2
;
385 client::client_commit(&op2
, "id1", object_set_position
);
386 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
388 std::set
<Client
> clients
;
389 ASSERT_EQ(0, client::client_list(ioctx
, oid
, &clients
));
391 std::set
<Client
> expected_clients
= {
392 Client("id1", bufferlist(), object_set_position
)};
393 ASSERT_EQ(expected_clients
, clients
);
396 TEST_F(TestClsJournal
, ClientCommitInvalid
) {
397 librados::IoCtx ioctx
;
398 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
400 std::string oid
= get_temp_image_name();
402 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
403 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
405 cls::journal::ObjectPositions object_positions
;
407 cls::journal::ObjectPosition(0, 234, 120),
408 cls::journal::ObjectPosition(4, 234, 121),
409 cls::journal::ObjectPosition(5, 235, 121)};
410 cls::journal::ObjectSetPosition
object_set_position(
413 librados::ObjectWriteOperation op2
;
414 client::client_commit(&op2
, "id1", object_set_position
);
415 ASSERT_EQ(-EINVAL
, ioctx
.operate(oid
, &op2
));
418 TEST_F(TestClsJournal
, ClientCommitDNE
) {
419 librados::IoCtx ioctx
;
420 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
422 std::string oid
= get_temp_image_name();
424 cls::journal::ObjectSetPosition object_set_position
;
426 librados::ObjectWriteOperation op1
;
427 client::client_commit(&op1
, "id1", object_set_position
);
428 ASSERT_EQ(-ENOENT
, ioctx
.operate(oid
, &op1
));
431 TEST_F(TestClsJournal
, ClientList
) {
432 librados::IoCtx ioctx
;
433 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
435 std::string oid
= get_temp_image_name();
437 ASSERT_EQ(0, client::create(ioctx
, oid
, 12, 5, ioctx
.get_id()));
439 std::set
<Client
> expected_clients
;
440 librados::ObjectWriteOperation op1
;
441 for (uint32_t i
= 0; i
< 512; ++i
) {
442 std::string id
= "id" + stringify(i
+ 1);
443 expected_clients
.insert(Client(id
, bufferlist()));
444 client::client_register(&op1
, id
, bufferlist());
446 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
448 std::set
<Client
> clients
;
449 ASSERT_EQ(0, client::client_list(ioctx
, oid
, &clients
));
450 ASSERT_EQ(expected_clients
, clients
);
453 uint64_t read_minimum_set
;
454 uint64_t read_active_set
;
455 std::set
<cls::journal::Client
> read_clients
;
456 client::get_mutable_metadata(ioctx
, oid
, &read_minimum_set
, &read_active_set
,
457 &read_clients
, &cond
);
458 ASSERT_EQ(0, cond
.wait());
459 ASSERT_EQ(expected_clients
, read_clients
);
462 TEST_F(TestClsJournal
, GetNextTagTid
) {
463 librados::IoCtx ioctx
;
464 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
466 std::string oid
= get_temp_image_name();
469 ASSERT_EQ(-ENOENT
, client::get_next_tag_tid(ioctx
, oid
, &tag_tid
));
471 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
472 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
474 ASSERT_EQ(0, client::get_next_tag_tid(ioctx
, oid
, &tag_tid
));
475 ASSERT_EQ(0U, tag_tid
);
477 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 0, Tag::TAG_CLASS_NEW
,
479 ASSERT_EQ(0, client::get_next_tag_tid(ioctx
, oid
, &tag_tid
));
480 ASSERT_EQ(1U, tag_tid
);
483 TEST_F(TestClsJournal
, TagCreate
) {
484 librados::IoCtx ioctx
;
485 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
487 std::string oid
= get_temp_image_name();
489 ASSERT_EQ(-ENOENT
, client::tag_create(ioctx
, oid
, 0, Tag::TAG_CLASS_NEW
,
492 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
493 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
495 ASSERT_EQ(-ESTALE
, client::tag_create(ioctx
, oid
, 1, Tag::TAG_CLASS_NEW
,
497 ASSERT_EQ(-EINVAL
, client::tag_create(ioctx
, oid
, 0, 1, bufferlist()));
499 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 0, Tag::TAG_CLASS_NEW
,
501 ASSERT_EQ(-EEXIST
, client::tag_create(ioctx
, oid
, 0, Tag::TAG_CLASS_NEW
,
503 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 1, Tag::TAG_CLASS_NEW
,
505 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 2, 1, bufferlist()));
507 std::set
<Tag
> expected_tags
= {
508 {0, 0, {}}, {1, 1, {}}, {2, 1, {}}};
510 ASSERT_EQ(0, client::tag_list(ioctx
, oid
, "id1",
511 boost::optional
<uint64_t>(), &tags
));
512 ASSERT_EQ(expected_tags
, tags
);
515 TEST_F(TestClsJournal
, TagCreatePrunesTags
) {
516 librados::IoCtx ioctx
;
517 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
519 std::string oid
= get_temp_image_name();
521 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
522 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
524 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 0, Tag::TAG_CLASS_NEW
,
526 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 1, Tag::TAG_CLASS_NEW
,
528 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 2, 1, bufferlist()));
530 librados::ObjectWriteOperation op1
;
531 client::client_commit(&op1
, "id1", {{{1, 2, 120}}});
532 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
534 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, 3, 0, bufferlist()));
536 std::set
<Tag
> expected_tags
= {
537 {0, 0, {}}, {2, 1, {}}, {3, 0, {}}};
539 ASSERT_EQ(0, client::tag_list(ioctx
, oid
, "id1",
540 boost::optional
<uint64_t>(), &tags
));
541 ASSERT_EQ(expected_tags
, tags
);
544 TEST_F(TestClsJournal
, TagList
) {
545 librados::IoCtx ioctx
;
546 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
548 std::string oid
= get_temp_image_name();
550 ASSERT_EQ(0, client::create(ioctx
, oid
, 2, 2, ioctx
.get_id()));
551 ASSERT_EQ(0, client::client_register(ioctx
, oid
, "id1", bufferlist()));
553 std::set
<Tag
> expected_all_tags
;
554 std::set
<Tag
> expected_filtered_tags
;
555 for (uint32_t i
= 0; i
< 96; ++i
) {
556 uint64_t tag_class
= Tag::TAG_CLASS_NEW
;
558 tag_class
= i
% 2 == 0 ? 0 : 1;
561 Tag
tag(i
, i
% 2 == 0 ? 0 : 1, bufferlist());
562 expected_all_tags
.insert(tag
);
564 expected_filtered_tags
.insert(tag
);
566 ASSERT_EQ(0, client::tag_create(ioctx
, oid
, i
, tag_class
,
571 ASSERT_EQ(0, client::tag_list(ioctx
, oid
, "id1", boost::optional
<uint64_t>(),
573 ASSERT_EQ(expected_all_tags
, tags
);
575 ASSERT_EQ(0, client::tag_list(ioctx
, oid
, "id1", boost::optional
<uint64_t>(0),
577 ASSERT_EQ(expected_filtered_tags
, tags
);
579 librados::ObjectWriteOperation op1
;
580 client::client_commit(&op1
, "id1", {{{96, 0, 120}}});
581 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
583 ASSERT_EQ(0, client::tag_list(ioctx
, oid
, "id1", boost::optional
<uint64_t>(),
585 ASSERT_EQ(expected_all_tags
, tags
);
588 TEST_F(TestClsJournal
, GuardAppend
) {
589 librados::IoCtx ioctx
;
590 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
592 std::string oid
= get_temp_image_name();
595 bl
.append("journal entry!");
597 librados::ObjectWriteOperation op1
;
599 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
601 librados::ObjectWriteOperation op2
;
602 client::guard_append(&op2
, 1024);
603 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
606 TEST_F(TestClsJournal
, GuardAppendDNE
) {
607 librados::IoCtx ioctx
;
608 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
610 std::string oid
= get_temp_image_name();
612 librados::ObjectWriteOperation op2
;
613 client::guard_append(&op2
, 1024);
614 ASSERT_EQ(0, ioctx
.operate(oid
, &op2
));
617 TEST_F(TestClsJournal
, GuardAppendOverflow
) {
618 librados::IoCtx ioctx
;
619 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
621 std::string oid
= get_temp_image_name();
624 bl
.append("journal entry!");
626 librados::ObjectWriteOperation op1
;
628 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
630 librados::ObjectWriteOperation op2
;
631 client::guard_append(&op2
, 1);
632 ASSERT_EQ(-EOVERFLOW
, ioctx
.operate(oid
, &op2
));
635 TEST_F(TestClsJournal
, Append
) {
636 librados::IoCtx ioctx
;
637 ASSERT_EQ(0, _rados
.ioctx_create(_pool_name
.c_str(), ioctx
));
639 std::string oid
= get_temp_image_name();
642 bool sparse_read_supported
= is_sparse_read_supported(ioctx
, oid
);
645 bl
.append("journal entry!");
647 librados::ObjectWriteOperation op1
;
648 client::append(&op1
, 1, bl
);
649 ASSERT_EQ(0, ioctx
.operate(oid
, &op1
));
651 librados::ObjectWriteOperation op2
;
652 client::append(&op2
, 1, bl
);
653 ASSERT_EQ(-EOVERFLOW
, ioctx
.operate(oid
, &op2
));
656 ASSERT_LE(bl
.length(), ioctx
.read(oid
, outbl
, 0, 0));
659 tmpbl
.substr_of(outbl
, 0, bl
.length());
660 ASSERT_TRUE(bl
.contents_equal(tmpbl
));
662 if (outbl
.length() == bl
.length()) {
663 std::cout
<< "padding is not enabled" << std::endl
;
668 tmpbl
.substr_of(outbl
, bl
.length(), outbl
.length() - bl
.length());
669 ASSERT_TRUE(tmpbl
.is_zero());
671 if (!sparse_read_supported
) {
672 std::cout
<< "sparse_read is not supported" << std::endl
;
676 librados::ObjectWriteOperation op3
;
677 client::append(&op3
, 1 << 24, bl
);
678 ASSERT_EQ(0, ioctx
.operate(oid
, &op3
));
680 std::map
<uint64_t, uint64_t> m
;
681 uint64_t pad_len
= outbl
.length();
683 std::map
<uint64_t, uint64_t> expected_m
=
684 {{0, bl
.length()}, {pad_len
, bl
.length()}};
685 ASSERT_EQ(expected_m
.size(), ioctx
.sparse_read(oid
, m
, outbl
, 2 * pad_len
, 0));
686 ASSERT_EQ(m
, expected_m
);
688 uint64_t buffer_offset
= 0;
691 tmpbl
.substr_of(outbl
, buffer_offset
, it
.second
);
692 ASSERT_TRUE(bl
.contents_equal(tmpbl
));
693 buffer_offset
+= it
.second
;