diff options
Diffstat (limited to '')
26 files changed, 1499 insertions, 0 deletions
diff --git a/src/test/librbd/mock/MockContextWQ.h b/src/test/librbd/mock/MockContextWQ.h new file mode 100644 index 000000000..f900b627d --- /dev/null +++ b/src/test/librbd/mock/MockContextWQ.h @@ -0,0 +1,19 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_CONTEXT_WQ_H +#define CEPH_TEST_LIBRBD_MOCK_CONTEXT_WQ_H + +#include "gmock/gmock.h" + +struct Context; + +namespace librbd { + +struct MockContextWQ { + MOCK_METHOD2(queue, void(Context *, int r)); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_CONTEXT_WQ_H diff --git a/src/test/librbd/mock/MockExclusiveLock.h b/src/test/librbd/mock/MockExclusiveLock.h new file mode 100644 index 000000000..db675abf0 --- /dev/null +++ b/src/test/librbd/mock/MockExclusiveLock.h @@ -0,0 +1,50 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_EXCLUSIVE_LOCK_H +#define CEPH_TEST_LIBRBD_MOCK_EXCLUSIVE_LOCK_H + +#include "common/RefCountedObj.h" +#include "include/int_types.h" +#include "include/rados/librados.hpp" +#include "librbd/exclusive_lock/Policy.h" +#include "librbd/io/Types.h" +#include "gmock/gmock.h" + +class Context; + +namespace librbd { + +struct MockExclusiveLock { + MOCK_CONST_METHOD0(is_lock_owner, bool()); + + MOCK_METHOD2(init, void(uint64_t features, Context*)); + MOCK_METHOD1(shut_down, void(Context*)); + + MOCK_METHOD1(reacquire_lock, void(Context*)); + MOCK_METHOD1(try_acquire_lock, void(Context*)); + + MOCK_METHOD1(block_requests, void(int)); + MOCK_METHOD0(unblock_requests, void()); + + MOCK_METHOD1(acquire_lock, void(Context *)); + MOCK_METHOD1(release_lock, void(Context *)); + + MOCK_METHOD2(accept_request, bool(exclusive_lock::OperationRequestType, + int *)); + MOCK_METHOD0(accept_ops, bool()); + MOCK_METHOD0(get_unlocked_op_error, int()); + + MOCK_METHOD3(set_require_lock, void(bool init_shutdown, io::Direction, + Context*)); + MOCK_METHOD1(unset_require_lock, void(io::Direction)); + + MOCK_METHOD1(start_op, Context*(int*)); + + void get() {} + void put() {} +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_EXCLUSIVE_LOCK_H diff --git a/src/test/librbd/mock/MockImageCtx.cc b/src/test/librbd/mock/MockImageCtx.cc new file mode 100644 index 000000000..743b9c633 --- /dev/null +++ b/src/test/librbd/mock/MockImageCtx.cc @@ -0,0 +1,56 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "include/neorados/RADOS.hpp" +#include "test/librbd/mock/MockImageCtx.h" +#include "test/librbd/mock/MockSafeTimer.h" +#include "librbd/io/AsyncOperation.h" + +static MockSafeTimer *s_timer; +static ceph::mutex *s_timer_lock; + +namespace librbd { + +MockImageCtx* MockImageCtx::s_instance = nullptr; + +void MockImageCtx::set_timer_instance(MockSafeTimer *timer, + ceph::mutex *timer_lock) { + s_timer = timer; + s_timer_lock = timer_lock; +} + +void MockImageCtx::get_timer_instance(CephContext *cct, MockSafeTimer **timer, + ceph::mutex **timer_lock) { + *timer = s_timer; + *timer_lock = s_timer_lock; +} + +void MockImageCtx::wait_for_async_ops() { + io::AsyncOperation async_op; + async_op.start_op(*image_ctx); + + C_SaferCond ctx; + async_op.flush(&ctx); + ctx.wait(); + + async_op.finish_op(); +} + +IOContext MockImageCtx::get_data_io_context() { + auto ctx = std::make_shared<neorados::IOContext>( + data_ctx.get_id(), data_ctx.get_namespace()); + if (snap_id != CEPH_NOSNAP) { + ctx->read_snap(snap_id); + } + if (!snapc.snaps.empty()) { + ctx->write_snap_context( + {{snapc.seq, {snapc.snaps.begin(), snapc.snaps.end()}}}); + } + return ctx; +} + +IOContext MockImageCtx::duplicate_data_io_context() { + return std::make_shared<neorados::IOContext>(*get_data_io_context()); +} + +} // namespace librbd diff --git a/src/test/librbd/mock/MockImageCtx.h b/src/test/librbd/mock/MockImageCtx.h new file mode 100644 index 000000000..521ecff0c --- /dev/null +++ b/src/test/librbd/mock/MockImageCtx.h @@ -0,0 +1,343 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IMAGE_CTX_H +#define CEPH_TEST_LIBRBD_MOCK_IMAGE_CTX_H + +#include "include/rados/librados.hpp" +#include "test/librbd/mock/MockContextWQ.h" +#include "test/librbd/mock/MockExclusiveLock.h" +#include "test/librbd/mock/MockImageState.h" +#include "test/librbd/mock/MockImageWatcher.h" +#include "test/librbd/mock/MockJournal.h" +#include "test/librbd/mock/MockObjectMap.h" +#include "test/librbd/mock/MockOperations.h" +#include "test/librbd/mock/MockPluginRegistry.h" +#include "test/librbd/mock/MockReadahead.h" +#include "test/librbd/mock/io/MockImageDispatcher.h" +#include "test/librbd/mock/io/MockObjectDispatcher.h" +#include "common/RWLock.h" +#include "common/WorkQueue.h" +#include "common/zipkin_trace.h" +#include "librbd/ImageCtx.h" +#include "gmock/gmock.h" +#include <string> + +class MockSafeTimer; + +namespace librbd { + +namespace operation { +template <typename> class ResizeRequest; +} + +struct MockImageCtx { + static MockImageCtx *s_instance; + static MockImageCtx *create(const std::string &image_name, + const std::string &image_id, + const char *snap, librados::IoCtx& p, + bool read_only) { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + MockImageCtx(librbd::ImageCtx &image_ctx) + : image_ctx(&image_ctx), + cct(image_ctx.cct), + perfcounter(image_ctx.perfcounter), + snap_namespace(image_ctx.snap_namespace), + snap_name(image_ctx.snap_name), + snap_id(image_ctx.snap_id), + snap_exists(image_ctx.snap_exists), + snapc(image_ctx.snapc), + snaps(image_ctx.snaps), + snap_info(image_ctx.snap_info), + snap_ids(image_ctx.snap_ids), + old_format(image_ctx.old_format), + read_only(image_ctx.read_only), + read_only_flags(image_ctx.read_only_flags), + read_only_mask(image_ctx.read_only_mask), + clone_copy_on_read(image_ctx.clone_copy_on_read), + lockers(image_ctx.lockers), + exclusive_locked(image_ctx.exclusive_locked), + lock_tag(image_ctx.lock_tag), + asio_engine(image_ctx.asio_engine), + rados_api(image_ctx.rados_api), + owner_lock(image_ctx.owner_lock), + image_lock(image_ctx.image_lock), + timestamp_lock(image_ctx.timestamp_lock), + async_ops_lock(image_ctx.async_ops_lock), + copyup_list_lock(image_ctx.copyup_list_lock), + order(image_ctx.order), + size(image_ctx.size), + features(image_ctx.features), + flags(image_ctx.flags), + op_features(image_ctx.op_features), + operations_disabled(image_ctx.operations_disabled), + stripe_unit(image_ctx.stripe_unit), + stripe_count(image_ctx.stripe_count), + object_prefix(image_ctx.object_prefix), + header_oid(image_ctx.header_oid), + id(image_ctx.id), + name(image_ctx.name), + parent_md(image_ctx.parent_md), + format_string(image_ctx.format_string), + group_spec(image_ctx.group_spec), + layout(image_ctx.layout), + io_image_dispatcher(new io::MockImageDispatcher()), + io_object_dispatcher(new io::MockObjectDispatcher()), + op_work_queue(new MockContextWQ()), + plugin_registry(new MockPluginRegistry()), + readahead_max_bytes(image_ctx.readahead_max_bytes), + event_socket(image_ctx.event_socket), + parent(NULL), operations(new MockOperations()), + state(new MockImageState()), + image_watcher(NULL), object_map(NULL), + exclusive_lock(NULL), journal(NULL), + trace_endpoint(image_ctx.trace_endpoint), + sparse_read_threshold_bytes(image_ctx.sparse_read_threshold_bytes), + discard_granularity_bytes(image_ctx.discard_granularity_bytes), + mirroring_replay_delay(image_ctx.mirroring_replay_delay), + non_blocking_aio(image_ctx.non_blocking_aio), + blkin_trace_all(image_ctx.blkin_trace_all), + enable_alloc_hint(image_ctx.enable_alloc_hint), + alloc_hint_flags(image_ctx.alloc_hint_flags), + read_flags(image_ctx.read_flags), + ignore_migrating(image_ctx.ignore_migrating), + enable_sparse_copyup(image_ctx.enable_sparse_copyup), + mtime_update_interval(image_ctx.mtime_update_interval), + atime_update_interval(image_ctx.atime_update_interval), + cache(image_ctx.cache), + config(image_ctx.config) + { + md_ctx.dup(image_ctx.md_ctx); + data_ctx.dup(image_ctx.data_ctx); + + if (image_ctx.image_watcher != NULL) { + image_watcher = new MockImageWatcher(); + } + } + + virtual ~MockImageCtx() { + wait_for_async_requests(); + wait_for_async_ops(); + image_ctx->md_ctx.aio_flush(); + image_ctx->data_ctx.aio_flush(); + image_ctx->op_work_queue->drain(); + delete state; + delete operations; + delete image_watcher; + delete op_work_queue; + delete plugin_registry; + delete io_image_dispatcher; + delete io_object_dispatcher; + } + + void wait_for_async_ops(); + void wait_for_async_requests() { + async_ops_lock.lock(); + if (async_requests.empty()) { + async_ops_lock.unlock(); + return; + } + + C_SaferCond ctx; + async_requests_waiters.push_back(&ctx); + async_ops_lock.unlock(); + + ctx.wait(); + } + + MOCK_METHOD1(init_layout, void(int64_t)); + + MOCK_CONST_METHOD1(get_object_name, std::string(uint64_t)); + MOCK_CONST_METHOD0(get_object_size, uint64_t()); + MOCK_CONST_METHOD0(get_current_size, uint64_t()); + MOCK_CONST_METHOD1(get_image_size, uint64_t(librados::snap_t)); + MOCK_CONST_METHOD1(get_effective_image_size, uint64_t(librados::snap_t)); + MOCK_CONST_METHOD1(get_object_count, uint64_t(librados::snap_t)); + MOCK_CONST_METHOD1(get_read_flags, int(librados::snap_t)); + MOCK_CONST_METHOD2(get_flags, int(librados::snap_t in_snap_id, + uint64_t *flags)); + MOCK_CONST_METHOD2(get_snap_id, + librados::snap_t(cls::rbd::SnapshotNamespace snap_namespace, + std::string in_snap_name)); + MOCK_CONST_METHOD1(get_snap_info, const SnapInfo*(librados::snap_t)); + MOCK_CONST_METHOD2(get_snap_name, int(librados::snap_t, std::string *)); + MOCK_CONST_METHOD2(get_snap_namespace, int(librados::snap_t, + cls::rbd::SnapshotNamespace *out_snap_namespace)); + MOCK_CONST_METHOD2(get_parent_spec, int(librados::snap_t in_snap_id, + cls::rbd::ParentImageSpec *pspec)); + MOCK_CONST_METHOD1(get_parent_info, const ParentImageInfo*(librados::snap_t)); + MOCK_CONST_METHOD2(get_parent_overlap, int(librados::snap_t in_snap_id, + uint64_t *overlap)); + MOCK_CONST_METHOD2(prune_parent_extents, uint64_t(vector<pair<uint64_t,uint64_t> >& , + uint64_t)); + + MOCK_CONST_METHOD2(is_snap_protected, int(librados::snap_t in_snap_id, + bool *is_protected)); + MOCK_CONST_METHOD2(is_snap_unprotected, int(librados::snap_t in_snap_id, + bool *is_unprotected)); + + MOCK_CONST_METHOD0(get_create_timestamp, utime_t()); + MOCK_CONST_METHOD0(get_access_timestamp, utime_t()); + MOCK_CONST_METHOD0(get_modify_timestamp, utime_t()); + + MOCK_METHOD1(set_access_timestamp, void(const utime_t at)); + MOCK_METHOD1(set_modify_timestamp, void(const utime_t at)); + + MOCK_METHOD8(add_snap, void(cls::rbd::SnapshotNamespace in_snap_namespace, + std::string in_snap_name, + librados::snap_t id, + uint64_t in_size, const ParentImageInfo &parent, + uint8_t protection_status, uint64_t flags, utime_t timestamp)); + MOCK_METHOD3(rm_snap, void(cls::rbd::SnapshotNamespace in_snap_namespace, + std::string in_snap_name, + librados::snap_t id)); + + MOCK_METHOD0(user_flushed, void()); + MOCK_METHOD1(flush_copyup, void(Context *)); + + MOCK_CONST_METHOD1(test_features, bool(uint64_t test_features)); + MOCK_CONST_METHOD2(test_features, bool(uint64_t test_features, + const ceph::shared_mutex &in_image_lock)); + + MOCK_CONST_METHOD1(test_op_features, bool(uint64_t op_features)); + + MOCK_METHOD1(cancel_async_requests, void(Context*)); + + MOCK_METHOD0(create_exclusive_lock, MockExclusiveLock*()); + MOCK_METHOD1(create_object_map, MockObjectMap*(uint64_t)); + MOCK_METHOD0(create_journal, MockJournal*()); + + MOCK_METHOD0(notify_update, void()); + MOCK_METHOD1(notify_update, void(Context *)); + + MOCK_CONST_METHOD0(get_exclusive_lock_policy, exclusive_lock::Policy*()); + MOCK_METHOD1(set_exclusive_lock_policy, void(exclusive_lock::Policy*)); + MOCK_CONST_METHOD0(get_journal_policy, journal::Policy*()); + MOCK_METHOD1(set_journal_policy, void(journal::Policy*)); + + MOCK_METHOD2(apply_metadata, int(const std::map<std::string, bufferlist> &, + bool)); + + MOCK_CONST_METHOD0(get_stripe_count, uint64_t()); + MOCK_CONST_METHOD0(get_stripe_period, uint64_t()); + + MOCK_METHOD0(rebuild_data_io_context, void()); + IOContext get_data_io_context(); + IOContext duplicate_data_io_context(); + + static void set_timer_instance(MockSafeTimer *timer, ceph::mutex *timer_lock); + static void get_timer_instance(CephContext *cct, MockSafeTimer **timer, + ceph::mutex **timer_lock); + + ImageCtx *image_ctx; + CephContext *cct; + PerfCounters *perfcounter; + + cls::rbd::SnapshotNamespace snap_namespace; + std::string snap_name; + uint64_t snap_id; + bool snap_exists; + + ::SnapContext snapc; + std::vector<librados::snap_t> snaps; + std::map<librados::snap_t, SnapInfo> snap_info; + std::map<ImageCtx::SnapKey, librados::snap_t, ImageCtx::SnapKeyComparator> snap_ids; + + bool old_format; + bool read_only; + uint32_t read_only_flags; + uint32_t read_only_mask; + + bool clone_copy_on_read; + + std::map<rados::cls::lock::locker_id_t, + rados::cls::lock::locker_info_t> lockers; + bool exclusive_locked; + std::string lock_tag; + + std::shared_ptr<AsioEngine> asio_engine; + neorados::RADOS& rados_api; + + librados::IoCtx md_ctx; + librados::IoCtx data_ctx; + + ceph::shared_mutex &owner_lock; + ceph::shared_mutex &image_lock; + ceph::shared_mutex ×tamp_lock; + ceph::mutex &async_ops_lock; + ceph::mutex ©up_list_lock; + + uint8_t order; + uint64_t size; + uint64_t features; + uint64_t flags; + uint64_t op_features; + bool operations_disabled; + uint64_t stripe_unit; + uint64_t stripe_count; + std::string object_prefix; + std::string header_oid; + std::string id; + std::string name; + ParentImageInfo parent_md; + MigrationInfo migration_info; + char *format_string; + cls::rbd::GroupSpec group_spec; + + file_layout_t layout; + + xlist<operation::ResizeRequest<MockImageCtx>*> resize_reqs; + xlist<AsyncRequest<MockImageCtx>*> async_requests; + std::list<Context*> async_requests_waiters; + + std::map<uint64_t, io::CopyupRequest<MockImageCtx>*> copyup_list; + + io::MockImageDispatcher *io_image_dispatcher; + io::MockObjectDispatcher *io_object_dispatcher; + MockContextWQ *op_work_queue; + + MockPluginRegistry* plugin_registry; + + MockReadahead readahead; + uint64_t readahead_max_bytes; + + EventSocket &event_socket; + + MockImageCtx *child = nullptr; + MockImageCtx *parent; + MockOperations *operations; + MockImageState *state; + + MockImageWatcher *image_watcher; + MockObjectMap *object_map; + MockExclusiveLock *exclusive_lock; + MockJournal *journal; + + ZTracer::Endpoint trace_endpoint; + + crypto::CryptoInterface* crypto = nullptr; + + uint64_t sparse_read_threshold_bytes; + uint32_t discard_granularity_bytes; + int mirroring_replay_delay; + bool non_blocking_aio; + bool blkin_trace_all; + bool enable_alloc_hint; + uint32_t alloc_hint_flags; + uint32_t read_flags; + bool ignore_migrating; + bool enable_sparse_copyup; + uint64_t mtime_update_interval; + uint64_t atime_update_interval; + bool cache; + + ConfigProxy config; + std::set<std::string> config_overrides; +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IMAGE_CTX_H diff --git a/src/test/librbd/mock/MockImageState.h b/src/test/librbd/mock/MockImageState.h new file mode 100644 index 000000000..f510c4a0f --- /dev/null +++ b/src/test/librbd/mock/MockImageState.h @@ -0,0 +1,39 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IMAGE_STATE_H +#define CEPH_TEST_LIBRBD_MOCK_IMAGE_STATE_H + +#include <gmock/gmock.h> + +#include "cls/rbd/cls_rbd_types.h" + +class Context; + +namespace librbd { + +class UpdateWatchCtx; + +struct MockImageState { + MOCK_CONST_METHOD0(is_refresh_required, bool()); + MOCK_METHOD1(refresh, void(Context*)); + + MOCK_METHOD2(open, void(bool, Context*)); + + MOCK_METHOD0(close, int()); + MOCK_METHOD1(close, void(Context*)); + + MOCK_METHOD2(snap_set, void(uint64_t snap_id, Context*)); + + MOCK_METHOD1(prepare_lock, void(Context*)); + MOCK_METHOD0(handle_prepare_lock_complete, void()); + + MOCK_METHOD2(register_update_watcher, int(UpdateWatchCtx *, uint64_t *)); + MOCK_METHOD2(unregister_update_watcher, void(uint64_t, Context *)); + + MOCK_METHOD0(handle_update_notification, void()); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IMAGE_STATE_H diff --git a/src/test/librbd/mock/MockImageWatcher.h b/src/test/librbd/mock/MockImageWatcher.h new file mode 100644 index 000000000..c44238ae1 --- /dev/null +++ b/src/test/librbd/mock/MockImageWatcher.h @@ -0,0 +1,34 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IMAGE_WATCHER_H +#define CEPH_TEST_LIBRBD_MOCK_IMAGE_WATCHER_H + +#include "gmock/gmock.h" + +class Context; + +namespace librbd { + +class ProgressContext; + +struct MockImageWatcher { + MOCK_METHOD0(is_registered, bool()); + MOCK_METHOD0(is_unregistered, bool()); + MOCK_METHOD0(is_blocklisted, bool()); + MOCK_METHOD0(unregister_watch, void()); + MOCK_METHOD1(flush, void(Context *)); + + MOCK_CONST_METHOD0(get_watch_handle, uint64_t()); + + MOCK_METHOD0(notify_acquired_lock, void()); + MOCK_METHOD0(notify_released_lock, void()); + MOCK_METHOD0(notify_request_lock, void()); + + MOCK_METHOD3(notify_quiesce, void(uint64_t *, ProgressContext &, Context *)); + MOCK_METHOD2(notify_unquiesce, void(uint64_t, Context *)); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IMAGE_WATCHER_H diff --git a/src/test/librbd/mock/MockJournal.cc b/src/test/librbd/mock/MockJournal.cc new file mode 100644 index 000000000..97feb0187 --- /dev/null +++ b/src/test/librbd/mock/MockJournal.cc @@ -0,0 +1,10 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#include "test/librbd/mock/MockJournal.h" + +namespace librbd { + +MockJournal *MockJournal::s_instance = nullptr; + +} // namespace librbd diff --git a/src/test/librbd/mock/MockJournal.h b/src/test/librbd/mock/MockJournal.h new file mode 100644 index 000000000..15baf7903 --- /dev/null +++ b/src/test/librbd/mock/MockJournal.h @@ -0,0 +1,96 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_JOURNAL_H +#define CEPH_TEST_LIBRBD_MOCK_JOURNAL_H + +#include "common/RefCountedObj.h" +#include "gmock/gmock.h" +#include "include/rados/librados_fwd.hpp" +#include "librbd/Journal.h" +#include "librbd/journal/Types.h" +#include <list> + +struct Context; +struct ContextWQ; + +namespace librbd { + +struct ImageCtx; + +struct MockJournal { + static MockJournal *s_instance; + static MockJournal *get_instance() { + ceph_assert(s_instance != nullptr); + return s_instance; + } + + template <typename ImageCtxT> + static int is_tag_owner(ImageCtxT *image_ctx, bool *is_tag_owner) { + return get_instance()->is_tag_owner(is_tag_owner); + } + + static void get_tag_owner(librados::IoCtx &, + const std::string &global_image_id, + std::string *tag_owner, ContextWQ *work_queue, + Context *on_finish) { + get_instance()->get_tag_owner(global_image_id, tag_owner, + work_queue, on_finish); + } + + MockJournal() { + s_instance = this; + } + + void get() {} + void put() {} + + MOCK_CONST_METHOD0(is_journal_ready, bool()); + MOCK_CONST_METHOD0(is_journal_replaying, bool()); + MOCK_CONST_METHOD0(is_journal_appending, bool()); + + MOCK_METHOD1(wait_for_journal_ready, void(Context *)); + + MOCK_METHOD4(get_tag_owner, void(const std::string &, + std::string *, ContextWQ *, + Context *)); + + MOCK_CONST_METHOD0(is_tag_owner, bool()); + MOCK_CONST_METHOD1(is_tag_owner, int(bool *)); + MOCK_METHOD3(allocate_tag, void(const std::string &mirror_uuid, + const journal::TagPredecessor &predecessor, + Context *on_finish)); + + MOCK_METHOD1(open, void(Context *)); + MOCK_METHOD1(close, void(Context *)); + + MOCK_CONST_METHOD0(get_tag_tid, uint64_t()); + MOCK_CONST_METHOD0(get_tag_data, journal::TagData()); + + MOCK_METHOD0(allocate_op_tid, uint64_t()); + + MOCK_METHOD0(user_flushed, void()); + + MOCK_METHOD3(append_op_event_mock, void(uint64_t, const journal::EventEntry&, + Context *)); + void append_op_event(uint64_t op_tid, journal::EventEntry &&event_entry, + Context *on_safe) { + // googlemock doesn't support move semantics + append_op_event_mock(op_tid, event_entry, on_safe); + } + + MOCK_METHOD2(flush_event, void(uint64_t, Context *)); + MOCK_METHOD2(wait_event, void(uint64_t, Context *)); + + MOCK_METHOD3(commit_op_event, void(uint64_t, int, Context *)); + MOCK_METHOD2(replay_op_ready, void(uint64_t, Context *)); + + MOCK_METHOD1(add_listener, void(journal::Listener *)); + MOCK_METHOD1(remove_listener, void(journal::Listener *)); + + MOCK_METHOD1(is_resync_requested, int(bool *)); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_JOURNAL_H diff --git a/src/test/librbd/mock/MockJournalPolicy.h b/src/test/librbd/mock/MockJournalPolicy.h new file mode 100644 index 000000000..33bb252ac --- /dev/null +++ b/src/test/librbd/mock/MockJournalPolicy.h @@ -0,0 +1,22 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_JOURNAL_POLICY_H +#define CEPH_TEST_LIBRBD_MOCK_JOURNAL_POLICY_H + +#include "librbd/journal/Policy.h" +#include "gmock/gmock.h" + +namespace librbd { + +struct MockJournalPolicy : public journal::Policy { + + MOCK_CONST_METHOD0(append_disabled, bool()); + MOCK_CONST_METHOD0(journal_disabled, bool()); + MOCK_METHOD1(allocate_tag_on_lock, void(Context*)); + +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_JOURNAL_POLICY_H diff --git a/src/test/librbd/mock/MockObjectMap.h b/src/test/librbd/mock/MockObjectMap.h new file mode 100644 index 000000000..d72408403 --- /dev/null +++ b/src/test/librbd/mock/MockObjectMap.h @@ -0,0 +1,73 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_OBJECT_MAP_H +#define CEPH_TEST_LIBRBD_MOCK_OBJECT_MAP_H + +#include "common/RWLock.h" +#include "librbd/Utils.h" +#include "gmock/gmock.h" + +namespace librbd { + +struct MockObjectMap { + MOCK_METHOD1(at, uint8_t(uint64_t)); + uint8_t operator[](uint64_t object_no) { + return at(object_no); + } + + MOCK_CONST_METHOD1(enabled, bool(const RWLock &object_map_lock)); + + MOCK_CONST_METHOD0(size, uint64_t()); + + MOCK_METHOD1(open, void(Context *on_finish)); + MOCK_METHOD1(close, void(Context *on_finish)); + + MOCK_METHOD3(aio_resize, void(uint64_t new_size, uint8_t default_object_state, + Context *on_finish)); + + void get() {} + void put() {} + + template <typename T, void(T::*MF)(int) = &T::complete> + bool aio_update(uint64_t snap_id, uint64_t start_object_no, uint8_t new_state, + const boost::optional<uint8_t> ¤t_state, + const ZTracer::Trace &parent_trace, bool ignore_enoent, + T *callback_object) { + return aio_update<T, MF>(snap_id, start_object_no, start_object_no + 1, + new_state, current_state, parent_trace, + ignore_enoent, callback_object); + } + + template <typename T, void(T::*MF)(int) = &T::complete> + bool aio_update(uint64_t snap_id, uint64_t start_object_no, + uint64_t end_object_no, uint8_t new_state, + const boost::optional<uint8_t> ¤t_state, + const ZTracer::Trace &parent_trace, bool ignore_enoent, + T *callback_object) { + auto ctx = util::create_context_callback<T, MF>(callback_object); + bool updated = aio_update(snap_id, start_object_no, end_object_no, + new_state, current_state, parent_trace, + ignore_enoent, ctx); + if (!updated) { + delete ctx; + } + return updated; + } + MOCK_METHOD8(aio_update, bool(uint64_t snap_id, uint64_t start_object_no, + uint64_t end_object_no, uint8_t new_state, + const boost::optional<uint8_t> ¤t_state, + const ZTracer::Trace &parent_trace, + bool ignore_enoent, Context *on_finish)); + + MOCK_METHOD2(snapshot_add, void(uint64_t snap_id, Context *on_finish)); + MOCK_METHOD2(snapshot_remove, void(uint64_t snap_id, Context *on_finish)); + MOCK_METHOD2(rollback, void(uint64_t snap_id, Context *on_finish)); + + MOCK_CONST_METHOD1(object_may_exist, bool(uint64_t)); + +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_OBJECT_MAP_H diff --git a/src/test/librbd/mock/MockOperations.h b/src/test/librbd/mock/MockOperations.h new file mode 100644 index 000000000..99dc253d1 --- /dev/null +++ b/src/test/librbd/mock/MockOperations.h @@ -0,0 +1,72 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_OPERATIONS_H +#define CEPH_TEST_LIBRBD_MOCK_OPERATIONS_H + +#include "cls/rbd/cls_rbd_types.h" +#include "include/int_types.h" +#include "include/rbd/librbd.hpp" +#include "gmock/gmock.h" +#include <string> + +class Context; + +namespace librbd { + +struct MockOperations { + MOCK_METHOD2(execute_flatten, void(ProgressContext &prog_ctx, + Context *on_finish)); + MOCK_METHOD2(execute_rebuild_object_map, void(ProgressContext &prog_ctx, + Context *on_finish)); + MOCK_METHOD2(execute_rename, void(const std::string &dstname, + Context *on_finish)); + MOCK_METHOD5(execute_resize, void(uint64_t size, bool allow_shrink, + ProgressContext &prog_ctx, + Context *on_finish, + uint64_t journal_op_tid)); + MOCK_METHOD5(snap_create, void(const cls::rbd::SnapshotNamespace &snapshot_namespace, + const std::string &snap_name, + uint64_t flags, + ProgressContext &prog_ctx, + Context *on_finish)); + MOCK_METHOD6(execute_snap_create, void(const cls::rbd::SnapshotNamespace &snapshot_namespace, + const std::string &snap_name, + Context *on_finish, + uint64_t journal_op_tid, + uint64_t flags, + ProgressContext &prog_ctx)); + MOCK_METHOD3(snap_remove, void(const cls::rbd::SnapshotNamespace &snap_namespace, + const std::string &snap_name, + Context *on_finish)); + MOCK_METHOD3(execute_snap_remove, void(const cls::rbd::SnapshotNamespace &snap_namespace, + const std::string &snap_name, + Context *on_finish)); + MOCK_METHOD3(execute_snap_rename, void(uint64_t src_snap_id, + const std::string &snap_name, + Context *on_finish)); + MOCK_METHOD4(execute_snap_rollback, void(const cls::rbd::SnapshotNamespace &snap_namespace, + const std::string &snap_name, + ProgressContext &prog_ctx, + Context *on_finish)); + MOCK_METHOD3(execute_snap_protect, void(const cls::rbd::SnapshotNamespace &snap_namespace, + const std::string &snap_name, + Context *on_finish)); + MOCK_METHOD3(execute_snap_unprotect, void(const cls::rbd::SnapshotNamespace &snap_namespace, + const std::string &snap_name, + Context *on_finish)); + MOCK_METHOD2(execute_snap_set_limit, void(uint64_t limit, + Context *on_finish)); + MOCK_METHOD4(execute_update_features, void(uint64_t features, bool enabled, + Context *on_finish, + uint64_t journal_op_tid)); + MOCK_METHOD3(execute_metadata_set, void(const std::string &key, + const std::string &value, + Context *on_finish)); + MOCK_METHOD2(execute_metadata_remove, void(const std::string &key, + Context *on_finish)); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_OPERATIONS_H diff --git a/src/test/librbd/mock/MockPluginRegistry.h b/src/test/librbd/mock/MockPluginRegistry.h new file mode 100644 index 000000000..8854a7426 --- /dev/null +++ b/src/test/librbd/mock/MockPluginRegistry.h @@ -0,0 +1,21 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_PLUGIN_REGISTRY_H +#define CEPH_TEST_LIBRBD_MOCK_PLUGIN_REGISTRY_H + +#include <gmock/gmock.h> + +class Context; + +namespace librbd { + +struct MockPluginRegistry{ + MOCK_METHOD2(init, void(const std::string&, Context*)); + MOCK_METHOD1(acquired_exclusive_lock, void(Context*)); + MOCK_METHOD1(prerelease_exclusive_lock, void(Context*)); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_PLUGIN_REGISTRY_H diff --git a/src/test/librbd/mock/MockReadahead.h b/src/test/librbd/mock/MockReadahead.h new file mode 100644 index 000000000..40fceaa7a --- /dev/null +++ b/src/test/librbd/mock/MockReadahead.h @@ -0,0 +1,21 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_READAHEAD_H +#define CEPH_TEST_LIBRBD_MOCK_READAHEAD_H + +#include "include/int_types.h" +#include "gmock/gmock.h" + +class Context; + +namespace librbd { + +struct MockReadahead { + MOCK_METHOD1(set_max_readahead_size, void(uint64_t)); + MOCK_METHOD1(wait_for_pending, void(Context *)); +}; + +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_READAHEAD_H diff --git a/src/test/librbd/mock/MockSafeTimer.h b/src/test/librbd/mock/MockSafeTimer.h new file mode 100644 index 000000000..9f6be1960 --- /dev/null +++ b/src/test/librbd/mock/MockSafeTimer.h @@ -0,0 +1,20 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_MOCK_SAFE_TIMER_H +#define CEPH_MOCK_SAFE_TIMER_H + +#include <gmock/gmock.h> + +struct Context; + +struct MockSafeTimer { + virtual ~MockSafeTimer() { + } + + MOCK_METHOD2(add_event_after, Context*(double, Context *)); + MOCK_METHOD2(add_event_at, Context*(ceph::real_clock::time_point, Context *)); + MOCK_METHOD1(cancel_event, bool(Context *)); +}; + +#endif // CEPH_MOCK_SAFE_TIMER_H diff --git a/src/test/librbd/mock/cache/MockImageCache.h b/src/test/librbd/mock/cache/MockImageCache.h new file mode 100644 index 000000000..c9a3cc335 --- /dev/null +++ b/src/test/librbd/mock/cache/MockImageCache.h @@ -0,0 +1,58 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_CACHE_MOCK_IMAGE_CACHE_H +#define CEPH_TEST_LIBRBD_CACHE_MOCK_IMAGE_CACHE_H + +#include "gmock/gmock.h" +#include "librbd/io/Types.h" +#include <vector> + +namespace librbd { +namespace cache { + +struct MockImageCache { + typedef std::vector<std::pair<uint64_t,uint64_t> > Extents; + + MOCK_METHOD4(aio_read_mock, void(const Extents &, ceph::bufferlist*, int, + Context *)); + void aio_read(Extents&& image_extents, ceph::bufferlist* bl, + int fadvise_flags, Context *on_finish) { + aio_read_mock(image_extents, bl, fadvise_flags, on_finish); + } + + + MOCK_METHOD4(aio_write_mock, void(const Extents &, const ceph::bufferlist &, + int, Context *)); + void aio_write(Extents&& image_extents, ceph::bufferlist&& bl, + int fadvise_flags, Context *on_finish) { + aio_write_mock(image_extents, bl, fadvise_flags, on_finish); + } + + MOCK_METHOD4(aio_discard, void(uint64_t, uint64_t, uint32_t, Context *)); + MOCK_METHOD1(aio_flush, void(Context *)); + MOCK_METHOD2(aio_flush, void(librbd::io::FlushSource, Context *)); + MOCK_METHOD5(aio_writesame_mock, void(uint64_t, uint64_t, ceph::bufferlist& bl, + int, Context *)); + void aio_writesame(uint64_t off, uint64_t len, ceph::bufferlist&& bl, + int fadvise_flags, Context *on_finish) { + aio_writesame_mock(off, len, bl, fadvise_flags, on_finish); + } + + MOCK_METHOD6(aio_compare_and_write_mock, void(const Extents &, + const ceph::bufferlist &, + const ceph::bufferlist &, + uint64_t *, int, Context *)); + + void aio_compare_and_write(Extents&& image_extents, ceph::bufferlist&& cmp_bl, + ceph::bufferlist&& bl, uint64_t *mismatch_offset, + int fadvise_flags, Context *on_finish) { + aio_compare_and_write_mock(image_extents, cmp_bl, bl, mismatch_offset, + fadvise_flags, on_finish); + } +}; + +} // namespace cache +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_CACHE_MOCK_IMAGE_CACHE_H diff --git a/src/test/librbd/mock/crypto/MockCryptoInterface.h b/src/test/librbd/mock/crypto/MockCryptoInterface.h new file mode 100644 index 000000000..027ebde62 --- /dev/null +++ b/src/test/librbd/mock/crypto/MockCryptoInterface.h @@ -0,0 +1,33 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_CRYPTO_INTERFACE_H +#define CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_CRYPTO_INTERFACE_H + +#include "include/buffer.h" +#include "gmock/gmock.h" +#include "librbd/crypto/CryptoInterface.h" + +namespace librbd { +namespace crypto { + +struct MockCryptoInterface : CryptoInterface { + + MOCK_METHOD2(encrypt, int(ceph::bufferlist*, uint64_t)); + MOCK_METHOD2(decrypt, int(ceph::bufferlist*, uint64_t)); + MOCK_CONST_METHOD0(get_key, const unsigned char*()); + MOCK_CONST_METHOD0(get_key_length, int()); + + uint64_t get_block_size() const override { + return 4096; + } + + uint64_t get_data_offset() const override { + return 4 * 1024 * 1024; + } +}; + +} // namespace crypto +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_CRYPTO_INTERFACE_H diff --git a/src/test/librbd/mock/crypto/MockDataCryptor.h b/src/test/librbd/mock/crypto/MockDataCryptor.h new file mode 100644 index 000000000..51a738862 --- /dev/null +++ b/src/test/librbd/mock/crypto/MockDataCryptor.h @@ -0,0 +1,43 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_DATA_CRYPTOR_H +#define CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_DATA_CRYPTOR_H + +#include "gmock/gmock.h" +#include "librbd/crypto/DataCryptor.h" + +namespace librbd { +namespace crypto { + +struct MockCryptoContext {}; + +class MockDataCryptor : public DataCryptor<MockCryptoContext> { + +public: + uint32_t block_size = 16; + uint32_t iv_size = 16; + + uint32_t get_block_size() const override { + return block_size; + } + + uint32_t get_iv_size() const override { + return iv_size; + } + + MOCK_METHOD1(get_context, MockCryptoContext*(CipherMode)); + MOCK_METHOD2(return_context, void(MockCryptoContext*, CipherMode)); + MOCK_CONST_METHOD3(init_context, int(MockCryptoContext*, + const unsigned char*, uint32_t)); + MOCK_CONST_METHOD4(update_context, int(MockCryptoContext*, + const unsigned char*, unsigned char*, + uint32_t)); + MOCK_CONST_METHOD0(get_key, const unsigned char*()); + MOCK_CONST_METHOD0(get_key_length, int()); +}; + +} // namespace crypto +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_DATA_CRYPTOR_H diff --git a/src/test/librbd/mock/crypto/MockEncryptionFormat.h b/src/test/librbd/mock/crypto/MockEncryptionFormat.h new file mode 100644 index 000000000..1caf99eb0 --- /dev/null +++ b/src/test/librbd/mock/crypto/MockEncryptionFormat.h @@ -0,0 +1,41 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_ENCRYPTION_FORMAT_H +#define CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_ENCRYPTION_FORMAT_H + +#include "gmock/gmock.h" +#include "librbd/crypto/EncryptionFormat.h" +#include "test/librbd/mock/MockImageCtx.h" + +namespace librbd { +namespace crypto { + +struct MockEncryptionFormat : EncryptionFormat<MockImageCtx> { + + MOCK_METHOD2(format, void(MockImageCtx* ictx, Context* on_finish)); + MOCK_METHOD2(load, void(MockImageCtx* ictx, Context* on_finish)); + MOCK_METHOD0(get_crypto, ceph::ref_t<CryptoInterface>()); +}; + +} // namespace crypto + +namespace api { +namespace util { + +inline int create_encryption_format( + CephContext* cct, encryption_format_t format, + encryption_options_t opts, size_t opts_size, bool c_api, + crypto::EncryptionFormat<MockImageCtx>** result_format) { + if (opts == nullptr) { + return -ENOTSUP; + } + *result_format = (crypto::MockEncryptionFormat*)opts; + return 0; +} + +} // namespace util +} // namespace api +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_CRYPTO_MOCK_ENCRYPTION_FORMAT_H diff --git a/src/test/librbd/mock/exclusive_lock/MockPolicy.h b/src/test/librbd/mock/exclusive_lock/MockPolicy.h new file mode 100644 index 000000000..f49eeb23f --- /dev/null +++ b/src/test/librbd/mock/exclusive_lock/MockPolicy.h @@ -0,0 +1,23 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_EXCLUSIVE_LOCK_POLICY_H +#define CEPH_TEST_LIBRBD_MOCK_EXCLUSIVE_LOCK_POLICY_H + +#include "librbd/exclusive_lock/Policy.h" +#include <gmock/gmock.h> + +namespace librbd { +namespace exclusive_lock { + +struct MockPolicy : public Policy { + + MOCK_METHOD0(may_auto_request_lock, bool()); + MOCK_METHOD1(lock_requested, int(bool)); + MOCK_METHOD1(accept_blocked_request, bool(OperationRequestType)); +}; + +} // namespace exclusive_lock +} // librbd + +#endif diff --git a/src/test/librbd/mock/io/MockImageDispatch.h b/src/test/librbd/mock/io/MockImageDispatch.h new file mode 100644 index 000000000..02dff3487 --- /dev/null +++ b/src/test/librbd/mock/io/MockImageDispatch.h @@ -0,0 +1,99 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IO_IMAGE_DISPATCH_H +#define CEPH_TEST_LIBRBD_MOCK_IO_IMAGE_DISPATCH_H + +#include "gmock/gmock.h" +#include "include/Context.h" +#include "librbd/io/ImageDispatchInterface.h" +#include "librbd/io/Types.h" + +class Context; + +namespace librbd { +namespace io { + +struct MockImageDispatch : public ImageDispatchInterface { +public: + MOCK_CONST_METHOD0(get_dispatch_layer, ImageDispatchLayer()); + + MOCK_METHOD1(shut_down, void(Context*)); + + bool read( + AioCompletion* aio_comp, Extents &&image_extents, + ReadResult &&read_result, IOContext io_context, int op_flags, + int read_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool discard( + AioCompletion* aio_comp, Extents &&image_extents, + uint32_t discard_granularity_bytes, IOContext io_context, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool write_same( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&bl, + IOContext io_context, int op_flags, const ZTracer::Trace &parent_trace, + uint64_t tid, std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool compare_and_write( + AioCompletion* aio_comp, Extents &&image_extents, bufferlist &&cmp_bl, + bufferlist &&bl, uint64_t *mismatch_offset, IOContext io_context, + int op_flags, const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool flush( + AioCompletion* aio_comp, FlushSource flush_source, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool list_snaps( + AioCompletion* aio_comp, Extents&& image_extents, SnapIds&& snap_ids, + int list_snaps_flags, SnapshotDelta* snapshot_delta, + const ZTracer::Trace &parent_trace, uint64_t tid, + std::atomic<uint32_t>* image_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return false; + } + + bool invalidate_cache(Context* on_finish) override { + return false; + } + +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IO_IMAGE_DISPATCH_H diff --git a/src/test/librbd/mock/io/MockImageDispatcher.h b/src/test/librbd/mock/io/MockImageDispatcher.h new file mode 100644 index 000000000..9e95f1d5c --- /dev/null +++ b/src/test/librbd/mock/io/MockImageDispatcher.h @@ -0,0 +1,48 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IO_IMAGE_DISPATCHER_H +#define CEPH_TEST_LIBRBD_MOCK_IO_IMAGE_DISPATCHER_H + +#include "gmock/gmock.h" +#include "include/Context.h" +#include "librbd/io/ImageDispatcher.h" +#include "librbd/io/ImageDispatchSpec.h" +#include "librbd/io/Types.h" + +class Context; + +namespace librbd { +namespace io { + +struct ImageDispatchInterface; + +struct MockImageDispatcher : public ImageDispatcherInterface { +public: + MOCK_METHOD1(shut_down, void(Context*)); + + MOCK_METHOD1(register_dispatch, void(ImageDispatchInterface*)); + MOCK_METHOD1(exists, bool(ImageDispatchLayer)); + MOCK_METHOD2(shut_down_dispatch, void(ImageDispatchLayer, Context*)); + MOCK_METHOD1(invalidate_cache, void(Context *)); + + MOCK_METHOD1(send, void(ImageDispatchSpec*)); + MOCK_METHOD3(finish, void(int r, ImageDispatchLayer, uint64_t)); + + MOCK_METHOD1(apply_qos_schedule_tick_min, void(uint64_t)); + MOCK_METHOD4(apply_qos_limit, void(uint64_t, uint64_t, uint64_t, uint64_t)); + + MOCK_CONST_METHOD0(writes_blocked, bool()); + MOCK_METHOD0(block_writes, int()); + MOCK_METHOD1(block_writes, void(Context*)); + + MOCK_METHOD0(unblock_writes, void()); + MOCK_METHOD1(wait_on_writes_unblocked, void(Context*)); + + MOCK_METHOD2(remap_extents, void(Extents&, ImageExtentsMapType)); +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IO_IMAGE_DISPATCHER_H diff --git a/src/test/librbd/mock/io/MockObjectDispatch.h b/src/test/librbd/mock/io/MockObjectDispatch.h new file mode 100644 index 000000000..baf86d9fb --- /dev/null +++ b/src/test/librbd/mock/io/MockObjectDispatch.h @@ -0,0 +1,137 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCH_H +#define CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCH_H + +#include "gmock/gmock.h" +#include "librbd/io/ObjectDispatchInterface.h" +#include "librbd/io/Types.h" + +class Context; + +namespace librbd { +namespace io { + +struct MockObjectDispatch : public ObjectDispatchInterface { +public: + RWLock lock; + + MockObjectDispatch() : lock("MockObjectDispatch::lock", true, false) { + } + + MOCK_CONST_METHOD0(get_dispatch_layer, ObjectDispatchLayer()); + + MOCK_METHOD1(shut_down, void(Context*)); + + MOCK_METHOD6(execute_read, + bool(uint64_t, ReadExtents*, IOContext io_context, uint64_t*, + DispatchResult*, Context*)); + bool read( + uint64_t object_no, ReadExtents* extents, IOContext io_context, + int op_flags, int read_flags, const ZTracer::Trace& parent_trace, + uint64_t* version, int* dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) { + return execute_read(object_no, extents, io_context, version, + dispatch_result, on_dispatched); + } + + MOCK_METHOD9(execute_discard, + bool(uint64_t, uint64_t, uint64_t, IOContext, int, + int*, uint64_t*, DispatchResult*, Context*)); + bool discard( + uint64_t object_no, uint64_t object_off, uint64_t object_len, + IOContext io_context, int discard_flags, + const ZTracer::Trace &parent_trace, int* dispatch_flags, + uint64_t* journal_tid, DispatchResult* dispatch_result, + Context** on_finish, Context* on_dispatched) { + return execute_discard(object_no, object_off, object_len, io_context, + discard_flags, dispatch_flags, journal_tid, + dispatch_result, on_dispatched); + } + + MOCK_METHOD10(execute_write, + bool(uint64_t, uint64_t, const ceph::bufferlist&, + IOContext, int, std::optional<uint64_t>, int*, + uint64_t*, DispatchResult*, Context *)); + bool write( + uint64_t object_no, uint64_t object_off, ceph::bufferlist&& data, + IOContext io_context, int op_flags, int write_flags, + std::optional<uint64_t> assert_version, + const ZTracer::Trace &parent_trace, int* dispatch_flags, + uint64_t* journal_tid, DispatchResult* dispatch_result, + Context** on_finish, Context* on_dispatched) override { + return execute_write(object_no, object_off, data, io_context, write_flags, + assert_version, dispatch_flags, journal_tid, + dispatch_result, on_dispatched); + } + + MOCK_METHOD10(execute_write_same, + bool(uint64_t, uint64_t, uint64_t, + const LightweightBufferExtents&, + const ceph::bufferlist&, IOContext, int*, + uint64_t*, DispatchResult*, Context *)); + bool write_same( + uint64_t object_no, uint64_t object_off, uint64_t object_len, + LightweightBufferExtents&& buffer_extents, ceph::bufferlist&& data, + IOContext io_context, int op_flags, + const ZTracer::Trace &parent_trace, int* dispatch_flags, + uint64_t* journal_tid, DispatchResult* dispatch_result, + Context* *on_finish, Context* on_dispatched) override { + return execute_write_same(object_no, object_off, object_len, buffer_extents, + data, io_context, dispatch_flags, journal_tid, + dispatch_result, on_dispatched); + } + + MOCK_METHOD9(execute_compare_and_write, + bool(uint64_t, uint64_t, const ceph::bufferlist&, + const ceph::bufferlist&, uint64_t*, int*, uint64_t*, + DispatchResult*, Context *)); + bool compare_and_write( + uint64_t object_no, uint64_t object_off, ceph::bufferlist&& cmp_data, + ceph::bufferlist&& write_data, IOContext io_context, int op_flags, + const ZTracer::Trace &parent_trace, uint64_t* mismatch_offset, + int* dispatch_flags, uint64_t* journal_tid, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return execute_compare_and_write(object_no, object_off, cmp_data, + write_data, mismatch_offset, + dispatch_flags, journal_tid, + dispatch_result, on_dispatched); + } + + MOCK_METHOD4(execute_flush, bool(FlushSource, uint64_t*, DispatchResult*, + Context*)); + bool flush(FlushSource flush_source, const ZTracer::Trace &parent_trace, + uint64_t* journal_tid, DispatchResult* dispatch_result, + Context** on_finish, Context* on_dispatched) { + return execute_flush(flush_source, journal_tid, dispatch_result, + on_dispatched); + } + + MOCK_METHOD7(execute_list_snaps, bool(uint64_t, const Extents&, + const SnapIds&, int, SnapshotDelta*, + DispatchResult*, Context*)); + bool list_snaps( + uint64_t object_no, io::Extents&& extents, SnapIds&& snap_ids, + int list_snaps_flags, const ZTracer::Trace &parent_trace, + SnapshotDelta* snapshot_delta, int* object_dispatch_flags, + DispatchResult* dispatch_result, Context** on_finish, + Context* on_dispatched) override { + return execute_list_snaps(object_no, extents, snap_ids, list_snaps_flags, + snapshot_delta, dispatch_result, on_dispatched); + } + + MOCK_METHOD1(invalidate_cache, bool(Context*)); + MOCK_METHOD1(reset_existence_cache, bool(Context*)); + + MOCK_METHOD5(extent_overwritten, void(uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t)); + MOCK_METHOD2(prepare_copyup, int(uint64_t, SnapshotSparseBufferlist*)); +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCH_H diff --git a/src/test/librbd/mock/io/MockObjectDispatcher.h b/src/test/librbd/mock/io/MockObjectDispatcher.h new file mode 100644 index 000000000..5e700397b --- /dev/null +++ b/src/test/librbd/mock/io/MockObjectDispatcher.h @@ -0,0 +1,44 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCHER_H +#define CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCHER_H + +#include "gmock/gmock.h" +#include "include/Context.h" +#include "librbd/io/ObjectDispatcher.h" +#include "librbd/io/ObjectDispatchSpec.h" +#include "librbd/io/Types.h" + +class Context; + +namespace librbd { +namespace io { + +struct ObjectDispatchInterface; + +struct MockObjectDispatcher : public ObjectDispatcherInterface { +public: + MOCK_METHOD1(shut_down, void(Context*)); + + MOCK_METHOD1(register_dispatch, void(ObjectDispatchInterface*)); + MOCK_METHOD1(exists, bool(ObjectDispatchLayer)); + MOCK_METHOD2(shut_down_dispatch, void(ObjectDispatchLayer, Context*)); + + MOCK_METHOD2(flush, void(FlushSource, Context*)); + + MOCK_METHOD1(invalidate_cache, void(Context*)); + MOCK_METHOD1(reset_existence_cache, void(Context*)); + + MOCK_METHOD5(extent_overwritten, void(uint64_t, uint64_t, uint64_t, uint64_t, + uint64_t)); + + MOCK_METHOD2(prepare_copyup, int(uint64_t, SnapshotSparseBufferlist*)); + + MOCK_METHOD1(send, void(ObjectDispatchSpec*)); +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IO_OBJECT_DISPATCHER_H diff --git a/src/test/librbd/mock/io/MockQosImageDispatch.h b/src/test/librbd/mock/io/MockQosImageDispatch.h new file mode 100644 index 000000000..e49897816 --- /dev/null +++ b/src/test/librbd/mock/io/MockQosImageDispatch.h @@ -0,0 +1,24 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_IO_QOS_IMAGE_DISPATCH_H +#define CEPH_TEST_LIBRBD_MOCK_IO_QOS_IMAGE_DISPATCH_H + +#include "gmock/gmock.h" +#include "librbd/io/Types.h" +#include <atomic> + +struct Context; + +namespace librbd { +namespace io { + +struct MockQosImageDispatch { + MOCK_METHOD4(needs_throttle, bool(bool, const Extents&, + std::atomic<uint32_t>*, Context*)); +}; + +} // namespace io +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_IO_QOS_IMAGE_DISPATCH_H diff --git a/src/test/librbd/mock/migration/MockSnapshotInterface.h b/src/test/librbd/mock/migration/MockSnapshotInterface.h new file mode 100644 index 000000000..abb6d1a08 --- /dev/null +++ b/src/test/librbd/mock/migration/MockSnapshotInterface.h @@ -0,0 +1,44 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_MIGRATION_MOCK_SNAPSHOT_INTERFACE_H +#define CEPH_TEST_LIBRBD_MOCK_MIGRATION_MOCK_SNAPSHOT_INTERFACE_H + +#include "include/buffer.h" +#include "gmock/gmock.h" +#include "librbd/io/AioCompletion.h" +#include "librbd/io/ReadResult.h" +#include "librbd/io/Types.h" +#include "librbd/migration/SnapshotInterface.h" + +namespace librbd { +namespace migration { + +struct MockSnapshotInterface : public SnapshotInterface { + MOCK_METHOD2(open, void(SnapshotInterface*, Context*)); + MOCK_METHOD1(close, void(Context*)); + + MOCK_CONST_METHOD0(get_snap_info, const SnapInfo&()); + + MOCK_METHOD3(read, void(io::AioCompletion*, const io::Extents&, + io::ReadResult&)); + void read(io::AioCompletion* aio_comp, io::Extents&& image_extents, + io::ReadResult&& read_result, int op_flags, int read_flags, + const ZTracer::Trace &parent_trace) override { + read(aio_comp, image_extents, read_result); + } + + MOCK_METHOD3(list_snap, void(const io::Extents&, io::SparseExtents*, + Context*)); + void list_snap(io::Extents&& image_extents, int list_snaps_flags, + io::SparseExtents* sparse_extents, + const ZTracer::Trace &parent_trace, + Context* on_finish) override { + list_snap(image_extents, sparse_extents, on_finish); + } +}; + +} // namespace migration +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_MIGRATION_MOCK_SNAPSHOT_INTERFACE_H diff --git a/src/test/librbd/mock/migration/MockStreamInterface.h b/src/test/librbd/mock/migration/MockStreamInterface.h new file mode 100644 index 000000000..36df86638 --- /dev/null +++ b/src/test/librbd/mock/migration/MockStreamInterface.h @@ -0,0 +1,29 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab + +#ifndef CEPH_TEST_LIBRBD_MOCK_MIGRATION_MOCK_STREAM_INTERFACE_H +#define CEPH_TEST_LIBRBD_MOCK_MIGRATION_MOCK_STREAM_INTERFACE_H + +#include "include/buffer.h" +#include "gmock/gmock.h" +#include "librbd/migration/StreamInterface.h" + +namespace librbd { +namespace migration { + +struct MockStreamInterface : public StreamInterface { + MOCK_METHOD1(open, void(Context*)); + MOCK_METHOD1(close, void(Context*)); + + MOCK_METHOD2(get_size, void(uint64_t*, Context*)); + + MOCK_METHOD3(read, void(const io::Extents&, bufferlist*, Context*)); + void read(io::Extents&& byte_extents, bufferlist* bl, Context* on_finish) { + read(byte_extents, bl, on_finish); + } +}; + +} // namespace migration +} // namespace librbd + +#endif // CEPH_TEST_LIBRBD_MOCK_MIGRATION_MOCK_STREAM_INTERFACE_H |