1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "include/rados/librados.hpp"
5 #include "include/stringify.h"
6 #include "cls/rbd/cls_rbd_types.h"
7 #include "cls/rbd/cls_rbd_client.h"
8 #include "librbd/Utils.h"
9 #include "librbd/internal.h"
10 #include "test/rbd_mirror/test_fixture.h"
11 #include "tools/rbd_mirror/InstanceWatcher.h"
12 #include "tools/rbd_mirror/Threads.h"
13 #include "common/Cond.h"
15 #include "test/librados/test_cxx.h"
16 #include "gtest/gtest.h"
18 using rbd::mirror::InstanceWatcher
;
20 void register_test_instance_watcher() {
23 class TestInstanceWatcher
: public ::rbd::mirror::TestFixture
{
25 std::string m_instance_id
;
28 void SetUp() override
{
30 m_local_io_ctx
.remove(RBD_MIRROR_LEADER
);
31 EXPECT_EQ(0, m_local_io_ctx
.create(RBD_MIRROR_LEADER
, true));
33 m_instance_id
= stringify(m_local_io_ctx
.get_instance_id());
34 m_oid
= RBD_MIRROR_INSTANCE_PREFIX
+ m_instance_id
;
37 void get_instances(std::vector
<std::string
> *instance_ids
) {
38 instance_ids
->clear();
40 InstanceWatcher
<>::get_instances(m_local_io_ctx
, instance_ids
, &on_get
);
41 EXPECT_EQ(0, on_get
.wait());
45 TEST_F(TestInstanceWatcher
, InitShutdown
)
47 InstanceWatcher
<> instance_watcher(m_local_io_ctx
, m_threads
->work_queue
,
48 nullptr, nullptr, m_instance_id
);
49 std::vector
<std::string
> instance_ids
;
50 get_instances(&instance_ids
);
51 ASSERT_EQ(0U, instance_ids
.size());
54 ASSERT_EQ(-ENOENT
, m_local_io_ctx
.stat(m_oid
, &size
, nullptr));
57 ASSERT_EQ(0, instance_watcher
.init());
59 get_instances(&instance_ids
);
60 ASSERT_EQ(1U, instance_ids
.size());
61 ASSERT_EQ(m_instance_id
, instance_ids
[0]);
63 ASSERT_EQ(0, m_local_io_ctx
.stat(m_oid
, &size
, nullptr));
64 std::list
<obj_watch_t
> watchers
;
65 ASSERT_EQ(0, m_local_io_ctx
.list_watchers(m_oid
, &watchers
));
66 ASSERT_EQ(1U, watchers
.size());
67 ASSERT_EQ(m_instance_id
, stringify(watchers
.begin()->watcher_id
));
69 get_instances(&instance_ids
);
70 ASSERT_EQ(1U, instance_ids
.size());
73 instance_watcher
.shut_down();
75 ASSERT_EQ(-ENOENT
, m_local_io_ctx
.stat(m_oid
, &size
, nullptr));
76 get_instances(&instance_ids
);
77 ASSERT_EQ(0U, instance_ids
.size());
80 TEST_F(TestInstanceWatcher
, Remove
)
82 std::string instance_id
= "instance_id";
83 std::string oid
= RBD_MIRROR_INSTANCE_PREFIX
+ instance_id
;
85 std::vector
<std::string
> instance_ids
;
86 get_instances(&instance_ids
);
87 ASSERT_EQ(0U, instance_ids
.size());
90 ASSERT_EQ(-ENOENT
, m_local_io_ctx
.stat(oid
, &size
, nullptr));
92 librados::Rados cluster
;
93 librados::IoCtx io_ctx
;
94 ASSERT_EQ("", connect_cluster_pp(cluster
));
95 ASSERT_EQ(0, cluster
.ioctx_create(_local_pool_name
.c_str(), io_ctx
));
96 InstanceWatcher
<> instance_watcher(m_local_io_ctx
, m_threads
->work_queue
,
97 nullptr, nullptr, "instance_id");
99 ASSERT_EQ(0, instance_watcher
.init());
101 get_instances(&instance_ids
);
102 ASSERT_EQ(1U, instance_ids
.size());
103 ASSERT_EQ(instance_id
, instance_ids
[0]);
105 ASSERT_EQ(0, m_local_io_ctx
.stat(oid
, &size
, nullptr));
106 std::list
<obj_watch_t
> watchers
;
107 ASSERT_EQ(0, m_local_io_ctx
.list_watchers(oid
, &watchers
));
108 ASSERT_EQ(1U, watchers
.size());
111 C_SaferCond on_remove
;
112 InstanceWatcher
<>::remove_instance(m_local_io_ctx
, m_threads
->work_queue
,
113 "instance_id", &on_remove
);
114 ASSERT_EQ(0, on_remove
.wait());
116 ASSERT_EQ(-ENOENT
, m_local_io_ctx
.stat(oid
, &size
, nullptr));
117 get_instances(&instance_ids
);
118 ASSERT_EQ(0U, instance_ids
.size());
121 instance_watcher
.shut_down();
123 ASSERT_EQ(-ENOENT
, m_local_io_ctx
.stat(m_oid
, &size
, nullptr));
124 get_instances(&instance_ids
);
125 ASSERT_EQ(0U, instance_ids
.size());
128 C_SaferCond on_remove_noent
;
129 InstanceWatcher
<>::remove_instance(m_local_io_ctx
, m_threads
->work_queue
,
130 instance_id
, &on_remove_noent
);
131 ASSERT_EQ(0, on_remove_noent
.wait());