using ::testing::_;
using ::testing::DoAll;
using ::testing::InSequence;
+using ::testing::Invoke;
using ::testing::Return;
using ::testing::SetArgPointee;
using ::testing::StrEq;
EXPECT_CALL(*mock_image_ctx.image_watcher, flush(_))
.WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
}
+
+ void expect_prepare_lock(MockTestImageCtx &mock_image_ctx) {
+ EXPECT_CALL(*mock_image_ctx.state, prepare_lock(_))
+ .WillOnce(Invoke([](Context *on_ready) {
+ on_ready->complete(0);
+ }));
+ }
+
+ void expect_handle_prepare_lock_complete(MockTestImageCtx &mock_image_ctx) {
+ EXPECT_CALL(*mock_image_ctx.state, handle_prepare_lock_complete());
+ }
+
};
TEST_F(TestMockExclusiveLockAcquireRequest, Success) {
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, false);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_journal_disabled(mock_journal_policy, false);
expect_create_journal(mock_image_ctx, &mock_journal);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
expect_open_journal(mock_image_ctx, mock_journal, 0);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, true);
expect_test_features(mock_image_ctx, RBD_FEATURE_OBJECT_MAP, false);
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
mock_image_ctx.snap_lock, false);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond acquire_ctx;
C_SaferCond ctx;
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, false);
expect_test_features(mock_image_ctx, RBD_FEATURE_JOURNALING,
mock_image_ctx.snap_lock, false);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond acquire_ctx;
C_SaferCond ctx;
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, false);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_journal_disabled(mock_journal_policy, false);
expect_create_journal(mock_image_ctx, &mock_journal);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
expect_open_journal(mock_image_ctx, mock_journal, 0);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, true);
expect_refresh(mock_image_ctx, mock_refresh_request, -EINVAL);
expect_unlock(mock_image_ctx, 0);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond *acquire_ctx = new C_SaferCond();
C_SaferCond ctx;
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, false);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_journal_disabled(mock_journal_policy, false);
expect_create_journal(mock_image_ctx, mock_journal);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
expect_open_journal(mock_image_ctx, *mock_journal, -EINVAL);
expect_close_journal(mock_image_ctx, *mock_journal);
expect_close_object_map(mock_image_ctx, *mock_object_map);
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, false);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_journal_disabled(mock_journal_policy, false);
expect_create_journal(mock_image_ctx, mock_journal);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
expect_open_journal(mock_image_ctx, *mock_journal, 0);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, -EPERM);
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
expect_blacklist_add(mock_image_ctx, 0);
expect_break_lock(mock_image_ctx, 0);
expect_lock(mock_image_ctx, -ENOENT);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, -EINVAL, entity_name_t::CLIENT(1), "",
"", "", LOCK_EXCLUSIVE);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, -ENOENT, entity_name_t::CLIENT(1), "",
"", "", LOCK_EXCLUSIVE);
expect_lock(mock_image_ctx, -EINVAL);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
"auto 123", "external tag", LOCK_EXCLUSIVE);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
"auto 123", ExclusiveLock<>::WATCHER_LOCK_TAG,
LOCK_SHARED);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
"external cookie", ExclusiveLock<>::WATCHER_LOCK_TAG,
LOCK_EXCLUSIVE);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
"auto 123", ExclusiveLock<>::WATCHER_LOCK_TAG,
LOCK_EXCLUSIVE);
expect_list_watchers(mock_image_ctx, -EINVAL, "dead client", 123);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
"auto 123", ExclusiveLock<>::WATCHER_LOCK_TAG,
LOCK_EXCLUSIVE);
expect_list_watchers(mock_image_ctx, 0, "1.2.3.4", 123);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
mock_image_ctx.blacklist_on_break_lock = false;
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
expect_break_lock(mock_image_ctx, 0);
expect_lock(mock_image_ctx, -ENOENT);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
LOCK_EXCLUSIVE);
expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
expect_blacklist_add(mock_image_ctx, -EINVAL);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
expect_blacklist_add(mock_image_ctx, 0);
expect_break_lock(mock_image_ctx, -ENOENT);
expect_lock(mock_image_ctx, -EINVAL);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, -EBUSY);
expect_get_lock_info(mock_image_ctx, 0, entity_name_t::CLIENT(1), "1.2.3.4",
expect_list_watchers(mock_image_ctx, 0, "dead client", 123);
expect_blacklist_add(mock_image_ctx, 0);
expect_break_lock(mock_image_ctx, -EINVAL);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
C_SaferCond ctx;
MockAcquireRequest *req = MockAcquireRequest::create(mock_image_ctx,
expect_op_work_queue(mock_image_ctx);
InSequence seq;
+ expect_prepare_lock(mock_image_ctx);
expect_flush_notifies(mock_image_ctx);
expect_lock(mock_image_ctx, 0);
expect_is_refresh_required(mock_image_ctx, false);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_journal_disabled(mock_journal_policy, false);
expect_create_journal(mock_image_ctx, &mock_journal);
+ expect_handle_prepare_lock_complete(mock_image_ctx);
expect_open_journal(mock_image_ctx, mock_journal, 0);
expect_get_journal_policy(mock_image_ctx, mock_journal_policy);
expect_allocate_journal_tag(mock_image_ctx, mock_journal_policy, 0);
#include "test/librbd/test_mock_fixture.h"
#include "test/librbd/test_support.h"
#include "test/librbd/mock/MockImageCtx.h"
-#include "test/librbd/mock/MockImageState.h"
#include "librbd/ExclusiveLock.h"
#include "librbd/exclusive_lock/AcquireRequest.h"
#include "librbd/exclusive_lock/ReacquireRequest.h"
Context *on_finish = nullptr;
static T* create(MockExclusiveLockImageCtx &image_ctx, const std::string &cookie,
- Context *on_lock_unlock, Context *on_finish) {
+ Context *on_lock_unlock, Context *on_finish,
+ bool shutting_down = false) {
assert(!s_requests.empty());
T* req = s_requests.front();
req->on_lock_unlock = on_lock_unlock;
void expect_acquire_lock(MockExclusiveLockImageCtx &mock_image_ctx,
MockAcquireRequest &acquire_request, int r) {
expect_get_watch_handle(mock_image_ctx);
- expect_prepare_lock(mock_image_ctx);
EXPECT_CALL(acquire_request, send())
.WillOnce(DoAll(FinishLockUnlock(&acquire_request),
FinishRequest(&acquire_request, r, &mock_image_ctx)));
- expect_handle_prepare_lock_complete(mock_image_ctx);
if (r == 0) {
expect_notify_acquired_lock(mock_image_ctx);
expect_unblock_writes(mock_image_ctx);
void expect_release_lock(MockExclusiveLockImageCtx &mock_image_ctx,
MockReleaseRequest &release_request, int r,
bool shutting_down = false) {
- if (!shutting_down) {
- expect_prepare_lock(mock_image_ctx);
- }
EXPECT_CALL(release_request, send())
.WillOnce(DoAll(FinishLockUnlock(&release_request),
FinishRequest(&release_request, r, &mock_image_ctx)));
- if (!shutting_down) {
- expect_handle_prepare_lock_complete(mock_image_ctx);
- }
if (r == 0) {
if (shutting_down) {
expect_unblock_writes(mock_image_ctx);
.WillOnce(CompleteContext(0, mock_image_ctx.image_ctx->op_work_queue));
}
- void expect_prepare_lock(MockExclusiveLockImageCtx &mock_image_ctx) {
- EXPECT_CALL(*mock_image_ctx.state, prepare_lock(_))
- .WillOnce(Invoke([](Context *on_ready) {
- on_ready->complete(0);
- }));
- }
-
- void expect_handle_prepare_lock_complete(MockExclusiveLockImageCtx &mock_image_ctx) {
- EXPECT_CALL(*mock_image_ctx.state, handle_prepare_lock_complete());
- }
-
int when_init(MockExclusiveLockImageCtx &mock_image_ctx,
MockExclusiveLock &exclusive_lock) {
C_SaferCond ctx;
MockAcquireRequest try_lock_acquire;
C_SaferCond wait_for_send_ctx1;
expect_get_watch_handle(mock_image_ctx);
- expect_prepare_lock(mock_image_ctx);
EXPECT_CALL(try_lock_acquire, send())
.WillOnce(Notify(&wait_for_send_ctx1));
- expect_handle_prepare_lock_complete(mock_image_ctx);
MockAcquireRequest request_acquire;
expect_acquire_lock(mock_image_ctx, request_acquire, 0);
MockReleaseRequest release;
C_SaferCond wait_for_send_ctx2;
- expect_prepare_lock(mock_image_ctx);
EXPECT_CALL(release, send())
.WillOnce(Notify(&wait_for_send_ctx2));
- expect_handle_prepare_lock_complete(mock_image_ctx);
expect_notify_released_lock(mock_image_ctx);
expect_is_lock_request_needed(mock_image_ctx, false);