virtual void post_acquire_lock_handler(int, Context *) = 0;
virtual void pre_release_lock_handler(bool, Context *) = 0;
virtual void post_release_lock_handler(bool, int, Context *) = 0;
+ virtual void post_reacquire_lock_handler(int, Context *) = 0;
MOCK_CONST_METHOD0(is_lock_owner, bool());
struct PreReleaseRequest<MockExclusiveLockImageCtx> : public BaseRequest<PreReleaseRequest<MockExclusiveLockImageCtx> > {
static PreReleaseRequest<MockExclusiveLockImageCtx> *create(
MockExclusiveLockImageCtx &image_ctx, bool shutting_down,
- Context *on_finish) {
+ AsyncOpTracker &async_op_tracker, Context *on_finish) {
return BaseRequest::create(image_ctx, nullptr, on_finish);
}
MOCK_METHOD0(send, void());
return ctx.wait();
}
+ int when_post_reacquire_lock_handler(MockManagedLock &managed_lock, int r) {
+ C_SaferCond ctx;
+ managed_lock.post_reacquire_lock_handler(r, &ctx);
+ return ctx.wait();
+ }
+
int when_shut_down(MockExclusiveLockImageCtx &mock_image_ctx,
MockExclusiveLock &exclusive_lock) {
C_SaferCond ctx;
-EINVAL));
}
+TEST_F(TestMockExclusiveLock, ReacquireLock) {
+ REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);
+
+ librbd::ImageCtx *ictx;
+ ASSERT_EQ(0, open_image(m_image_name, &ictx));
+
+ MockExclusiveLockImageCtx mock_image_ctx(*ictx);
+ MockExclusiveLock exclusive_lock(mock_image_ctx);
+ expect_op_work_queue(mock_image_ctx);
+
+ InSequence seq;
+ expect_set_state_initializing(exclusive_lock);
+ expect_block_writes(mock_image_ctx);
+ expect_set_state_unlocked(exclusive_lock);
+ ASSERT_EQ(0, when_init(mock_image_ctx, exclusive_lock));
+
+ // (try) acquire lock
+ MockPreAcquireRequest try_lock_pre_acquire;
+ expect_pre_acquire_request(try_lock_pre_acquire, 0);
+ ASSERT_EQ(0, when_pre_acquire_lock_handler(exclusive_lock));
+
+ MockPostAcquireRequest try_lock_post_acquire;
+ expect_post_acquire_request(try_lock_post_acquire, 0);
+ expect_is_state_acquiring(exclusive_lock, true);
+ expect_notify_acquired_lock(mock_image_ctx);
+ expect_unblock_writes(mock_image_ctx);
+ ASSERT_EQ(0, when_post_acquire_lock_handler(exclusive_lock, 0));
+
+ // reacquire lock
+ expect_notify_acquired_lock(mock_image_ctx);
+ ASSERT_EQ(0, when_post_reacquire_lock_handler(exclusive_lock, 0));
+
+ // shut down (and release)
+ expect_shut_down(exclusive_lock);
+ expect_is_state_waiting_for_lock(exclusive_lock, false);
+ ASSERT_EQ(0, when_shut_down(mock_image_ctx, exclusive_lock));
+
+ MockPreReleaseRequest shutdown_pre_release;
+ expect_pre_release_request(shutdown_pre_release, 0);
+ ASSERT_EQ(0, when_pre_release_lock_handler(exclusive_lock, true));
+
+ expect_unblock_writes(mock_image_ctx);
+ expect_notify_released_lock(mock_image_ctx);
+ ASSERT_EQ(0, when_post_release_lock_handler(exclusive_lock, true, 0));
+}
+
TEST_F(TestMockExclusiveLock, BlockRequests) {
REQUIRE_FEATURE(RBD_FEATURE_EXCLUSIVE_LOCK);