// -*- 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 class MockSafeTimer; namespace librbd { namespace operation { template 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 >& , 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 &, 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 snaps; std::map snap_info; std::map 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 lockers; bool exclusive_locked; std::string lock_tag; std::shared_ptr 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*> resize_reqs; xlist*> async_requests; std::list async_requests_waiters; std::map*> 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 config_overrides; }; } // namespace librbd #endif // CEPH_TEST_LIBRBD_MOCK_IMAGE_CTX_H