1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "journal/JournalTrimmer.h"
5 #include "journal/JournalMetadata.h"
6 #include "include/stringify.h"
7 #include "test/journal/RadosTestFixture.h"
11 class TestJournalTrimmer
: public RadosTestFixture
{
14 void TearDown() override
{
15 for (MetadataList::iterator it
= m_metadata_list
.begin();
16 it
!= m_metadata_list
.end(); ++it
) {
17 (*it
)->remove_listener(&m_listener
);
19 m_metadata_list
.clear();
21 for (std::list
<journal::JournalTrimmer
*>::iterator it
= m_trimmers
.begin();
22 it
!= m_trimmers
.end(); ++it
) {
24 (*it
)->shut_down(&ctx
);
25 ASSERT_EQ(0, ctx
.wait());
28 RadosTestFixture::TearDown();
31 int append_payload(const ceph::ref_t
<journal::JournalMetadata
>& metadata
,
32 const std::string
&oid
, uint64_t object_num
,
33 const std::string
&payload
, uint64_t *commit_tid
) {
34 int r
= append(oid
+ "." + stringify(object_num
), create_payload(payload
));
35 uint64_t tid
= metadata
->allocate_commit_tid(object_num
, 234, 123);
36 if (commit_tid
!= NULL
) {
42 auto create_metadata(const std::string
&oid
) {
43 auto metadata
= RadosTestFixture::create_metadata(oid
);
44 m_metadata_list
.push_back(metadata
);
45 metadata
->add_listener(&m_listener
);
49 journal::JournalTrimmer
*create_trimmer(const std::string
&oid
,
50 const ceph::ref_t
<journal::JournalMetadata
>& metadata
) {
51 journal::JournalTrimmer
*trimmer(new journal::JournalTrimmer(
52 m_ioctx
, oid
+ ".", metadata
));
53 m_trimmers
.push_back(trimmer
);
57 int assert_exists(const std::string
&oid
) {
58 librados::ObjectWriteOperation op
;
60 return m_ioctx
.operate(oid
, &op
);
63 typedef std::list
<ceph::ref_t
<journal::JournalMetadata
>> MetadataList
;
64 MetadataList m_metadata_list
;
65 std::list
<journal::JournalTrimmer
*> m_trimmers
;
68 TEST_F(TestJournalTrimmer
, Committed
) {
69 std::string oid
= get_temp_oid();
70 ASSERT_EQ(0, create(oid
, 12, 2));
71 ASSERT_EQ(0, client_register(oid
));
73 auto metadata
= create_metadata(oid
);
74 ASSERT_EQ(0, init_metadata(metadata
));
75 ASSERT_TRUE(wait_for_update(metadata
));
77 ASSERT_EQ(0, metadata
->set_active_set(10));
78 ASSERT_TRUE(wait_for_update(metadata
));
86 ASSERT_EQ(0, append_payload(metadata
, oid
, 0, "payload", &commit_tid1
));
87 ASSERT_EQ(0, append_payload(metadata
, oid
, 4, "payload", &commit_tid2
));
88 ASSERT_EQ(0, append_payload(metadata
, oid
, 5, "payload", &commit_tid3
));
89 ASSERT_EQ(0, append_payload(metadata
, oid
, 0, "payload", &commit_tid4
));
90 ASSERT_EQ(0, append_payload(metadata
, oid
, 4, "payload", &commit_tid5
));
91 ASSERT_EQ(0, append_payload(metadata
, oid
, 5, "payload", &commit_tid6
));
93 journal::JournalTrimmer
*trimmer
= create_trimmer(oid
, metadata
);
95 trimmer
->committed(commit_tid4
);
96 trimmer
->committed(commit_tid6
);
97 trimmer
->committed(commit_tid2
);
98 trimmer
->committed(commit_tid5
);
99 trimmer
->committed(commit_tid3
);
100 trimmer
->committed(commit_tid1
);
101 while (metadata
->get_minimum_set() != 2U) {
102 ASSERT_TRUE(wait_for_update(metadata
));
105 ASSERT_EQ(-ENOENT
, assert_exists(oid
+ ".0"));
106 ASSERT_EQ(-ENOENT
, assert_exists(oid
+ ".2"));
107 ASSERT_EQ(0, assert_exists(oid
+ ".5"));
110 TEST_F(TestJournalTrimmer
, CommittedWithOtherClient
) {
111 std::string oid
= get_temp_oid();
112 ASSERT_EQ(0, create(oid
, 12, 2));
113 ASSERT_EQ(0, client_register(oid
));
114 ASSERT_EQ(0, client_register(oid
, "client2", "slow client"));
116 auto metadata
= create_metadata(oid
);
117 ASSERT_EQ(0, init_metadata(metadata
));
118 ASSERT_TRUE(wait_for_update(metadata
));
120 ASSERT_EQ(0, metadata
->set_active_set(10));
121 ASSERT_TRUE(wait_for_update(metadata
));
123 uint64_t commit_tid1
;
124 uint64_t commit_tid2
;
125 uint64_t commit_tid3
;
126 uint64_t commit_tid4
;
127 ASSERT_EQ(0, append_payload(metadata
, oid
, 0, "payload", &commit_tid1
));
128 ASSERT_EQ(0, append_payload(metadata
, oid
, 2, "payload", &commit_tid2
));
129 ASSERT_EQ(0, append_payload(metadata
, oid
, 3, "payload", &commit_tid3
));
130 ASSERT_EQ(0, append_payload(metadata
, oid
, 5, "payload", &commit_tid4
));
132 journal::JournalTrimmer
*trimmer
= create_trimmer(oid
, metadata
);
134 trimmer
->committed(commit_tid1
);
135 trimmer
->committed(commit_tid2
);
136 trimmer
->committed(commit_tid3
);
137 trimmer
->committed(commit_tid4
);
138 ASSERT_TRUE(wait_for_update(metadata
));
140 ASSERT_EQ(0, assert_exists(oid
+ ".0"));
141 ASSERT_EQ(0, assert_exists(oid
+ ".2"));
142 ASSERT_EQ(0, assert_exists(oid
+ ".3"));
143 ASSERT_EQ(0, assert_exists(oid
+ ".5"));
146 TEST_F(TestJournalTrimmer
, RemoveObjects
) {
147 std::string oid
= get_temp_oid();
148 ASSERT_EQ(0, create(oid
, 12, 2));
149 ASSERT_EQ(0, client_register(oid
));
151 auto metadata
= create_metadata(oid
);
152 ASSERT_EQ(0, init_metadata(metadata
));
153 ASSERT_TRUE(wait_for_update(metadata
));
155 ASSERT_EQ(0, metadata
->set_active_set(10));
156 ASSERT_TRUE(wait_for_update(metadata
));
158 ASSERT_EQ(0, append(oid
+ ".0", create_payload("payload")));
159 ASSERT_EQ(0, append(oid
+ ".2", create_payload("payload")));
160 ASSERT_EQ(0, append(oid
+ ".3", create_payload("payload")));
161 ASSERT_EQ(0, append(oid
+ ".5", create_payload("payload")));
163 journal::JournalTrimmer
*trimmer
= create_trimmer(oid
, metadata
);
166 trimmer
->remove_objects(false, &cond
);
167 ASSERT_EQ(0, cond
.wait());
169 ASSERT_TRUE(wait_for_update(metadata
));
171 ASSERT_EQ(-ENOENT
, assert_exists(oid
+ ".0"));
172 ASSERT_EQ(-ENOENT
, assert_exists(oid
+ ".2"));
173 ASSERT_EQ(-ENOENT
, assert_exists(oid
+ ".3"));
174 ASSERT_EQ(-ENOENT
, assert_exists(oid
+ ".5"));
177 TEST_F(TestJournalTrimmer
, RemoveObjectsWithOtherClient
) {
178 std::string oid
= get_temp_oid();
179 ASSERT_EQ(0, create(oid
, 12, 2));
180 ASSERT_EQ(0, client_register(oid
));
181 ASSERT_EQ(0, client_register(oid
, "client2", "other client"));
183 auto metadata
= create_metadata(oid
);
184 ASSERT_EQ(0, init_metadata(metadata
));
185 ASSERT_TRUE(wait_for_update(metadata
));
187 journal::JournalTrimmer
*trimmer
= create_trimmer(oid
, metadata
);
190 trimmer
->remove_objects(false, &ctx1
);
191 ASSERT_EQ(-EBUSY
, ctx1
.wait());
194 trimmer
->remove_objects(true, &ctx2
);
195 ASSERT_EQ(0, ctx2
.wait());