From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/test/rbd_mirror/test_Instances.cc | 164 ++++++++++++++++++++++++++++++++++ 1 file changed, 164 insertions(+) create mode 100644 src/test/rbd_mirror/test_Instances.cc (limited to 'src/test/rbd_mirror/test_Instances.cc') diff --git a/src/test/rbd_mirror/test_Instances.cc b/src/test/rbd_mirror/test_Instances.cc new file mode 100644 index 000000000..4b189d903 --- /dev/null +++ b/src/test/rbd_mirror/test_Instances.cc @@ -0,0 +1,164 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "include/rados/librados.hpp" +#include "cls/rbd/cls_rbd_client.h" +#include "test/rbd_mirror/test_fixture.h" +#include "tools/rbd_mirror/InstanceWatcher.h" +#include "tools/rbd_mirror/Instances.h" +#include "tools/rbd_mirror/Threads.h" +#include "common/Cond.h" + +#include "test/librados/test.h" +#include "gtest/gtest.h" +#include + +using rbd::mirror::InstanceWatcher; +using rbd::mirror::Instances; + +void register_test_instances() { +} + +class TestInstances : public ::rbd::mirror::TestFixture { +public: + struct Listener : public rbd::mirror::instances::Listener { + std::mutex lock; + + struct Instance { + uint32_t count = 0; + std::set ids; + C_SaferCond ctx; + }; + + Instance add; + Instance remove; + + void handle(const InstanceIds& instance_ids, Instance* instance) { + std::unique_lock locker(lock); + for (auto& instance_id : instance_ids) { + ceph_assert(instance->count > 0); + --instance->count; + + instance->ids.insert(instance_id); + if (instance->count == 0) { + instance->ctx.complete(0); + } + } + } + + void handle_added(const InstanceIds& instance_ids) override { + handle(instance_ids, &add); + } + + void handle_removed(const InstanceIds& instance_ids) override { + handle(instance_ids, &remove); + } + }; + + virtual void SetUp() { + TestFixture::SetUp(); + m_local_io_ctx.remove(RBD_MIRROR_LEADER); + EXPECT_EQ(0, m_local_io_ctx.create(RBD_MIRROR_LEADER, true)); + + m_instance_id = stringify(m_local_io_ctx.get_instance_id()); + } + + Listener m_listener; + std::string m_instance_id; +}; + +TEST_F(TestInstances, InitShutdown) +{ + m_listener.add.count = 1; + Instances<> instances(m_threads, m_local_io_ctx, m_instance_id, m_listener); + + std::string instance_id = "instance_id"; + ASSERT_EQ(0, librbd::cls_client::mirror_instances_add(&m_local_io_ctx, + instance_id)); + + C_SaferCond on_init; + instances.init(&on_init); + ASSERT_EQ(0, on_init.wait()); + + ASSERT_LT(0U, m_listener.add.count); + instances.unblock_listener(); + + ASSERT_EQ(0, m_listener.add.ctx.wait()); + ASSERT_EQ(std::set({instance_id}), m_listener.add.ids); + + C_SaferCond on_shut_down; + instances.shut_down(&on_shut_down); + ASSERT_EQ(0, on_shut_down.wait()); +} + +TEST_F(TestInstances, InitEnoent) +{ + Instances<> instances(m_threads, m_local_io_ctx, m_instance_id, m_listener); + + m_local_io_ctx.remove(RBD_MIRROR_LEADER); + + C_SaferCond on_init; + instances.init(&on_init); + ASSERT_EQ(0, on_init.wait()); + + C_SaferCond on_shut_down; + instances.shut_down(&on_shut_down); + ASSERT_EQ(0, on_shut_down.wait()); +} + +TEST_F(TestInstances, NotifyRemove) +{ + // speed testing up a little + EXPECT_EQ(0, _rados->conf_set("rbd_mirror_leader_heartbeat_interval", "1")); + EXPECT_EQ(0, _rados->conf_set("rbd_mirror_leader_max_missed_heartbeats", + "2")); + EXPECT_EQ(0, _rados->conf_set("rbd_mirror_leader_max_acquire_attempts_before_break", + "0")); + + m_listener.add.count = 2; + m_listener.remove.count = 1; + Instances<> instances(m_threads, m_local_io_ctx, m_instance_id, m_listener); + + std::string instance_id1 = "instance_id1"; + std::string instance_id2 = "instance_id2"; + + ASSERT_EQ(0, librbd::cls_client::mirror_instances_add(&m_local_io_ctx, + instance_id1)); + + C_SaferCond on_init; + instances.init(&on_init); + ASSERT_EQ(0, on_init.wait()); + + instances.acked({instance_id2}); + + ASSERT_LT(0U, m_listener.add.count); + instances.unblock_listener(); + + ASSERT_EQ(0, m_listener.add.ctx.wait()); + ASSERT_EQ(std::set({instance_id1, instance_id2}), + m_listener.add.ids); + + std::vector instance_ids; + for (int i = 0; i < 100; i++) { + instances.acked({instance_id1}); + if (m_listener.remove.count > 0) { + usleep(250000); + } + } + + instances.acked({instance_id1}); + ASSERT_EQ(0, m_listener.remove.ctx.wait()); + ASSERT_EQ(std::set({instance_id2}), + m_listener.remove.ids); + + C_SaferCond on_get; + instances.acked({instance_id1}); + InstanceWatcher<>::get_instances(m_local_io_ctx, &instance_ids, &on_get); + EXPECT_EQ(0, on_get.wait()); + EXPECT_EQ(1U, instance_ids.size()); + ASSERT_EQ(instance_ids[0], instance_id1); + + C_SaferCond on_shut_down; + instances.shut_down(&on_shut_down); + ASSERT_EQ(0, on_shut_down.wait()); +} -- cgit v1.2.3