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"
14 #include "test/librados/test.h"
15 #include "gtest/gtest.h"
17 using rbd::mirror::InstanceWatcher;
19 void register_test_instance_watcher() {
22 class TestInstanceWatcher : public ::rbd::mirror::TestFixture {
24 std::string m_instance_id;
27 void SetUp() override {
29 m_local_io_ctx.remove(RBD_MIRROR_LEADER);
30 EXPECT_EQ(0, m_local_io_ctx.create(RBD_MIRROR_LEADER, true));
32 m_instance_id = stringify(m_local_io_ctx.get_instance_id());
33 m_oid = RBD_MIRROR_INSTANCE_PREFIX + m_instance_id;
36 void get_instances(std::vector<std::string> *instance_ids) {
37 instance_ids->clear();
39 InstanceWatcher<>::get_instances(m_local_io_ctx, instance_ids, &on_get);
40 EXPECT_EQ(0, on_get.wait());
44 TEST_F(TestInstanceWatcher, InitShutdown)
46 InstanceWatcher<> instance_watcher(m_local_io_ctx, m_threads->work_queue,
47 nullptr, m_instance_id);
48 std::vector<std::string> instance_ids;
49 get_instances(&instance_ids);
50 ASSERT_EQ(0U, instance_ids.size());
53 ASSERT_EQ(-ENOENT, m_local_io_ctx.stat(m_oid, &size, nullptr));
56 ASSERT_EQ(0, instance_watcher.init());
58 get_instances(&instance_ids);
59 ASSERT_EQ(1U, instance_ids.size());
60 ASSERT_EQ(m_instance_id, instance_ids[0]);
62 ASSERT_EQ(0, m_local_io_ctx.stat(m_oid, &size, nullptr));
63 std::list<obj_watch_t> watchers;
64 ASSERT_EQ(0, m_local_io_ctx.list_watchers(m_oid, &watchers));
65 ASSERT_EQ(1U, watchers.size());
66 ASSERT_EQ(m_instance_id, stringify(watchers.begin()->watcher_id));
68 get_instances(&instance_ids);
69 ASSERT_EQ(1U, instance_ids.size());
72 instance_watcher.shut_down();
74 ASSERT_EQ(-ENOENT, m_local_io_ctx.stat(m_oid, &size, nullptr));
75 get_instances(&instance_ids);
76 ASSERT_EQ(0U, instance_ids.size());
79 TEST_F(TestInstanceWatcher, Remove)
81 std::string instance_id = "instance_id";
82 std::string oid = RBD_MIRROR_INSTANCE_PREFIX + instance_id;
84 std::vector<std::string> instance_ids;
85 get_instances(&instance_ids);
86 ASSERT_EQ(0U, instance_ids.size());
89 ASSERT_EQ(-ENOENT, m_local_io_ctx.stat(oid, &size, nullptr));
91 librados::Rados cluster;
92 librados::IoCtx io_ctx;
93 ASSERT_EQ("", connect_cluster_pp(cluster));
94 ASSERT_EQ(0, cluster.ioctx_create(_local_pool_name.c_str(), io_ctx));
95 InstanceWatcher<> instance_watcher(m_local_io_ctx, m_threads->work_queue,
96 nullptr, "instance_id");
98 ASSERT_EQ(0, instance_watcher.init());
100 get_instances(&instance_ids);
101 ASSERT_EQ(1U, instance_ids.size());
102 ASSERT_EQ(instance_id, instance_ids[0]);
104 ASSERT_EQ(0, m_local_io_ctx.stat(oid, &size, nullptr));
105 std::list<obj_watch_t> watchers;
106 ASSERT_EQ(0, m_local_io_ctx.list_watchers(oid, &watchers));
107 ASSERT_EQ(1U, watchers.size());
110 C_SaferCond on_remove;
111 InstanceWatcher<>::remove_instance(m_local_io_ctx, m_threads->work_queue,
112 "instance_id", &on_remove);
113 ASSERT_EQ(0, on_remove.wait());
115 ASSERT_EQ(-ENOENT, m_local_io_ctx.stat(oid, &size, nullptr));
116 get_instances(&instance_ids);
117 ASSERT_EQ(0U, instance_ids.size());
120 instance_watcher.shut_down();
122 ASSERT_EQ(-ENOENT, m_local_io_ctx.stat(m_oid, &size, nullptr));
123 get_instances(&instance_ids);
124 ASSERT_EQ(0U, instance_ids.size());
127 C_SaferCond on_remove_noent;
128 InstanceWatcher<>::remove_instance(m_local_io_ctx, m_threads->work_queue,
129 instance_id, &on_remove_noent);
130 ASSERT_EQ(0, on_remove_noent.wait());