]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/test_ClusterWatcher.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 #include "include/rados/librados.hpp"
4 #include "common/Cond.h"
5 #include "common/errno.h"
6 #include "common/Mutex.h"
7 #include "librbd/internal.h"
8 #include "librbd/api/Mirror.h"
9 #include "tools/rbd_mirror/ClusterWatcher.h"
10 #include "tools/rbd_mirror/ServiceDaemon.h"
11 #include "tools/rbd_mirror/types.h"
12 #include "test/rbd_mirror/test_fixture.h"
13 #include "test/librados/test.h"
14 #include "gtest/gtest.h"
15 #include <boost/scope_exit.hpp>
21 using rbd::mirror::ClusterWatcher
;
22 using rbd::mirror::peer_t
;
23 using rbd::mirror::RadosRef
;
28 void register_test_cluster_watcher() {
31 class TestClusterWatcher
: public ::rbd::mirror::TestFixture
{
34 TestClusterWatcher() : m_lock("TestClusterWatcherLock")
36 m_cluster
= std::make_shared
<librados::Rados
>();
37 EXPECT_EQ("", connect_cluster_pp(*m_cluster
));
40 ~TestClusterWatcher() override
{
41 m_cluster
->wait_for_latest_osdmap();
42 for (auto& pool
: m_pools
) {
43 EXPECT_EQ(0, m_cluster
->pool_delete(pool
.c_str()));
47 void SetUp() override
{
49 m_service_daemon
.reset(new rbd::mirror::ServiceDaemon
<>(g_ceph_context
,
52 m_cluster_watcher
.reset(new ClusterWatcher(m_cluster
, m_lock
,
53 m_service_daemon
.get()));
56 void TearDown() override
{
57 m_service_daemon
.reset();
58 m_cluster_watcher
.reset();
59 TestFixture::TearDown();
62 void create_pool(bool enable_mirroring
, const peer_t
&peer
,
63 string
*uuid
= nullptr, string
*name
=nullptr) {
64 string pool_name
= get_temp_pool_name("test-rbd-mirror-");
65 ASSERT_EQ(0, m_cluster
->pool_create(pool_name
.c_str()));
67 int64_t pool_id
= m_cluster
->pool_lookup(pool_name
.c_str());
68 ASSERT_GE(pool_id
, 0);
70 librados::IoCtx ioctx
;
71 ASSERT_EQ(0, m_cluster
->ioctx_create2(pool_id
, ioctx
));
72 ioctx
.application_enable("rbd", true);
74 m_pools
.insert(pool_name
);
75 if (enable_mirroring
) {
76 ASSERT_EQ(0, librbd::api::Mirror
<>::mode_set(ioctx
,
77 RBD_MIRROR_MODE_POOL
));
80 ASSERT_EQ(0, librbd::api::Mirror
<>::peer_add(ioctx
,
81 uuid
!= nullptr ? uuid
:
85 m_pool_peers
[pool_id
].insert(peer
);
87 if (name
!= nullptr) {
92 void delete_pool(const string
&name
, const peer_t
&peer
) {
93 int64_t pool_id
= m_cluster
->pool_lookup(name
.c_str());
94 ASSERT_GE(pool_id
, 0);
95 if (m_pool_peers
.find(pool_id
) != m_pool_peers
.end()) {
96 m_pool_peers
[pool_id
].erase(peer
);
97 if (m_pool_peers
[pool_id
].empty()) {
98 m_pool_peers
.erase(pool_id
);
102 ASSERT_EQ(0, m_cluster
->pool_delete(name
.c_str()));
105 void create_cache_pool(const string
&base_pool
, string
*cache_pool_name
) {
107 *cache_pool_name
= get_temp_pool_name("test-rbd-mirror-");
108 ASSERT_EQ(0, m_cluster
->pool_create(cache_pool_name
->c_str()));
110 ASSERT_EQ(0, m_cluster
->mon_command(
111 "{\"prefix\": \"osd tier add\", \"pool\": \"" + base_pool
+
112 "\", \"tierpool\": \"" + *cache_pool_name
+
113 "\", \"force_nonempty\": \"--force-nonempty\" }",
115 ASSERT_EQ(0, m_cluster
->mon_command(
116 "{\"prefix\": \"osd tier set-overlay\", \"pool\": \"" + base_pool
+
117 "\", \"overlaypool\": \"" + *cache_pool_name
+ "\"}",
119 ASSERT_EQ(0, m_cluster
->mon_command(
120 "{\"prefix\": \"osd tier cache-mode\", \"pool\": \"" + *cache_pool_name
+
121 "\", \"mode\": \"writeback\"}",
123 m_cluster
->wait_for_latest_osdmap();
126 void remove_cache_pool(const string
&base_pool
, const string
&cache_pool
) {
129 ASSERT_EQ(0, m_cluster
->mon_command(
130 "{\"prefix\": \"osd tier remove-overlay\", \"pool\": \"" + base_pool
+
133 ASSERT_EQ(0, m_cluster
->mon_command(
134 "{\"prefix\": \"osd tier remove\", \"pool\": \"" + base_pool
+
135 "\", \"tierpool\": \"" + cache_pool
+ "\"}",
137 m_cluster
->wait_for_latest_osdmap();
138 m_cluster
->pool_delete(cache_pool
.c_str());
142 m_cluster_watcher
->refresh_pools();
143 Mutex::Locker
l(m_lock
);
144 ASSERT_EQ(m_pool_peers
, m_cluster_watcher
->get_pool_peers());
149 unique_ptr
<rbd::mirror::ServiceDaemon
<>> m_service_daemon
;
150 unique_ptr
<ClusterWatcher
> m_cluster_watcher
;
153 ClusterWatcher::PoolPeers m_pool_peers
;
156 TEST_F(TestClusterWatcher
, NoPools
) {
160 TEST_F(TestClusterWatcher
, NoMirroredPools
) {
162 create_pool(false, peer_t());
164 create_pool(false, peer_t());
166 create_pool(false, peer_t());
170 TEST_F(TestClusterWatcher
, ReplicatedPools
) {
171 peer_t
site1("", "site1", "mirror1");
172 peer_t
site2("", "site2", "mirror2");
173 string first_pool
, last_pool
;
175 create_pool(true, site1
, &site1
.uuid
, &first_pool
);
177 create_pool(false, peer_t());
179 create_pool(false, peer_t());
181 create_pool(false, peer_t());
183 create_pool(true, site2
, &site2
.uuid
);
185 create_pool(true, site2
, &site2
.uuid
);
187 create_pool(true, site2
, &site2
.uuid
, &last_pool
);
189 delete_pool(first_pool
, site1
);
191 delete_pool(last_pool
, site2
);
195 TEST_F(TestClusterWatcher
, CachePools
) {
196 peer_t
site1("", "site1", "mirror1");
197 string base1
, base2
, cache1
, cache2
;
198 create_pool(true, site1
, &site1
.uuid
, &base1
);
201 create_cache_pool(base1
, &cache1
);
202 BOOST_SCOPE_EXIT( base1
, cache1
, this_
) {
203 this_
->remove_cache_pool(base1
, cache1
);
204 } BOOST_SCOPE_EXIT_END
;
207 create_pool(false, peer_t(), nullptr, &base2
);
208 create_cache_pool(base2
, &cache2
);
209 BOOST_SCOPE_EXIT( base2
, cache2
, this_
) {
210 this_
->remove_cache_pool(base2
, cache2
);
211 } BOOST_SCOPE_EXIT_END
;