]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/journal/test_Journaler.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / journal / test_Journaler.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "include/stringify.h"
5
6 #include "journal/Journaler.h"
7 #include "journal/Settings.h"
8
9 #include "test/librados/test.h"
10 #include "test/journal/RadosTestFixture.h"
11
12 #include "gtest/gtest.h"
13
14 // reinclude our assert to clobber the system one
15 #include "include/ceph_assert.h"
16
17 class TestJournaler : public RadosTestFixture {
18 public:
19
20 static const std::string CLIENT_ID;
21
22 static std::string get_temp_journal_id() {
23 return stringify(++_journal_id);
24 }
25
26 void SetUp() override {
27 RadosTestFixture::SetUp();
28 m_journal_id = get_temp_journal_id();
29 m_journaler = new journal::Journaler(m_work_queue, m_timer, &m_timer_lock,
30 m_ioctx, m_journal_id, CLIENT_ID, {},
31 nullptr);
32 }
33
34 void TearDown() override {
35 delete m_journaler;
36 RadosTestFixture::TearDown();
37 }
38
39 int create_journal(uint8_t order, uint8_t splay_width) {
40 C_SaferCond cond;
41 m_journaler->create(order, splay_width, -1, &cond);
42 return cond.wait();
43 }
44
45 int init_journaler() {
46 C_SaferCond cond;
47 m_journaler->init(&cond);
48 return cond.wait();
49 }
50
51 int shut_down_journaler() {
52 C_SaferCond ctx;
53 m_journaler->shut_down(&ctx);
54 return ctx.wait();
55 }
56
57 int register_client(const std::string &client_id, const std::string &desc) {
58 journal::Journaler journaler(m_work_queue, m_timer, &m_timer_lock, m_ioctx,
59 m_journal_id, client_id, {}, nullptr);
60 bufferlist data;
61 data.append(desc);
62 C_SaferCond cond;
63 journaler.register_client(data, &cond);
64 return cond.wait();
65 }
66
67 int update_client(const std::string &client_id, const std::string &desc) {
68 journal::Journaler journaler(m_work_queue, m_timer, &m_timer_lock, m_ioctx,
69 m_journal_id, client_id, {}, nullptr);
70 bufferlist data;
71 data.append(desc);
72 C_SaferCond cond;
73 journaler.update_client(data, &cond);
74 return cond.wait();
75 }
76
77 int unregister_client(const std::string &client_id) {
78 journal::Journaler journaler(m_work_queue, m_timer, &m_timer_lock, m_ioctx,
79 m_journal_id, client_id, {}, nullptr);
80 C_SaferCond cond;
81 journaler.unregister_client(&cond);
82 return cond.wait();
83 }
84
85 static uint64_t _journal_id;
86
87 std::string m_journal_id;
88 journal::Journaler *m_journaler;
89 };
90
91 const std::string TestJournaler::CLIENT_ID = "client1";
92 uint64_t TestJournaler::_journal_id = 0;
93
94 TEST_F(TestJournaler, Create) {
95 ASSERT_EQ(0, create_journal(12, 8));
96 }
97
98 TEST_F(TestJournaler, CreateDuplicate) {
99 ASSERT_EQ(0, create_journal(12, 8));
100 ASSERT_EQ(-EEXIST, create_journal(12, 8));
101 }
102
103 TEST_F(TestJournaler, CreateInvalidParams) {
104 ASSERT_EQ(-EDOM, create_journal(1, 8));
105 ASSERT_EQ(-EDOM, create_journal(123, 8));
106 ASSERT_EQ(-EINVAL, create_journal(12, 0));
107 }
108
109 TEST_F(TestJournaler, Init) {
110 ASSERT_EQ(0, create_journal(12, 8));
111 ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
112 ASSERT_EQ(0, init_journaler());
113 ASSERT_EQ(0, shut_down_journaler());
114 }
115
116 TEST_F(TestJournaler, InitDNE) {
117 ASSERT_EQ(-ENOENT, init_journaler());
118 ASSERT_EQ(0, shut_down_journaler());
119 }
120
121 TEST_F(TestJournaler, RegisterClientDuplicate) {
122 ASSERT_EQ(0, create_journal(12, 8));
123 ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
124 ASSERT_EQ(-EEXIST, register_client(CLIENT_ID, "foo2"));
125 }
126
127 TEST_F(TestJournaler, UpdateClient) {
128 ASSERT_EQ(0, create_journal(12, 8));
129 ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
130 ASSERT_EQ(0, update_client(CLIENT_ID, "foo2"));
131 }
132
133 TEST_F(TestJournaler, UpdateClientDNE) {
134 ASSERT_EQ(0, create_journal(12, 8));
135 ASSERT_EQ(-ENOENT, update_client(CLIENT_ID, "foo"));
136 }
137
138 TEST_F(TestJournaler, UnregisterClient) {
139 ASSERT_EQ(0, create_journal(12, 8));
140 ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
141 ASSERT_EQ(0, unregister_client(CLIENT_ID));
142 // Test it does not exist and can be registered again
143 ASSERT_EQ(-ENOENT, update_client(CLIENT_ID, "foo"));
144 ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
145 }
146
147 TEST_F(TestJournaler, UnregisterClientDNE) {
148 ASSERT_EQ(0, create_journal(12, 8));
149 ASSERT_EQ(-ENOENT, unregister_client(CLIENT_ID));
150 }
151
152 TEST_F(TestJournaler, AllocateTag) {
153 ASSERT_EQ(0, create_journal(12, 8));
154
155 cls::journal::Tag tag;
156
157 bufferlist data;
158 data.append(std::string(128, '1'));
159
160 // allocate a new tag class
161 C_SaferCond ctx1;
162 m_journaler->allocate_tag(data, &tag, &ctx1);
163 ASSERT_EQ(0, ctx1.wait());
164 ASSERT_EQ(cls::journal::Tag(0, 0, data), tag);
165
166 // re-use an existing tag class
167 C_SaferCond ctx2;
168 m_journaler->allocate_tag(tag.tag_class, bufferlist(), &tag, &ctx2);
169 ASSERT_EQ(0, ctx2.wait());
170 ASSERT_EQ(cls::journal::Tag(1, 0, bufferlist()), tag);
171 }
172
173 TEST_F(TestJournaler, GetTags) {
174 ASSERT_EQ(0, create_journal(12, 8));
175 ASSERT_EQ(0, register_client(CLIENT_ID, "foo"));
176
177 std::list<cls::journal::Tag> expected_tags;
178 for (size_t i = 0; i < 256; ++i) {
179 C_SaferCond ctx;
180 cls::journal::Tag tag;
181 if (i < 2) {
182 m_journaler->allocate_tag(bufferlist(), &tag, &ctx);
183 } else {
184 m_journaler->allocate_tag(i % 2, bufferlist(), &tag, &ctx);
185 }
186 ASSERT_EQ(0, ctx.wait());
187
188 if (i % 2 == 0) {
189 expected_tags.push_back(tag);
190 }
191 }
192
193 std::list<cls::journal::Tag> tags;
194 C_SaferCond ctx;
195 m_journaler->get_tags(0, &tags, &ctx);
196 ASSERT_EQ(0, ctx.wait());
197 ASSERT_EQ(expected_tags, tags);
198 }