class TestRadosClient;
-class MockTestMemCluster : public TestCluster {
+class MockTestMemCluster : public TestMemCluster {
public:
TestRadosClient *create_rados_client(CephContext *cct) override {
return new ::testing::NiceMock<librados::MockTestMemRadosClient>(
- cct, &m_mem_cluster);
+ cct, this);
}
-private:
- TestMemCluster m_mem_cluster;
-
};
} // namespace librados
class TestCluster {
public:
+ struct ObjectHandler {
+ virtual ~ObjectHandler() {}
+
+ virtual void handle_removed(TestRadosClient* test_rados_client) = 0;
+ };
+
virtual ~TestCluster() {
}
virtual TestRadosClient *create_rados_client(CephContext *cct) = 0;
+ virtual int register_object_handler(int64_t pool_id, const std::string& o,
+ ObjectHandler* object_handler) = 0;
+ virtual void unregister_object_handler(int64_t pool_id, const std::string& o,
+ ObjectHandler* object_handler) = 0;
+
TestWatchNotify *get_watch_notify() {
return &m_watch_notify;
}
return new TestMemRadosClient(cct, this);
}
+int TestMemCluster::register_object_handler(int64_t pool_id,
+ const std::string& o,
+ ObjectHandler* object_handler) {
+ Mutex::Locker locker(m_lock);
+ auto pool = get_pool(m_lock, pool_id);
+ if (pool == nullptr) {
+ return -ENOENT;
+ }
+
+ RWLock::WLocker pool_locker(pool->file_lock);
+ auto file_it = pool->files.find(o);
+ if (file_it == pool->files.end()) {
+ return -ENOENT;
+ }
+
+ auto& object_handlers = pool->file_handlers[o];
+ auto it = object_handlers.find(object_handler);
+ assert(it == object_handlers.end());
+
+ object_handlers.insert(object_handler);
+ return 0;
+}
+
+void TestMemCluster::unregister_object_handler(int64_t pool_id,
+ const std::string& o,
+ ObjectHandler* object_handler) {
+ Mutex::Locker locker(m_lock);
+ auto pool = get_pool(m_lock, pool_id);
+ if (pool == nullptr) {
+ return;
+ }
+
+ RWLock::WLocker pool_locker(pool->file_lock);
+ auto handlers_it = pool->file_handlers.find(o);
+ if (handlers_it == pool->file_handlers.end()) {
+ return;
+ }
+
+ auto& object_handlers = handlers_it->second;
+ object_handlers.erase(object_handler);
+}
+
int TestMemCluster::pool_create(const std::string &pool_name) {
Mutex::Locker locker(m_lock);
if (m_pools.find(pool_name) != m_pools.end()) {
TestMemCluster::Pool *TestMemCluster::get_pool(int64_t pool_id) {
Mutex::Locker locker(m_lock);
+ return get_pool(m_lock, pool_id);
+}
+
+TestMemCluster::Pool *TestMemCluster::get_pool(const Mutex& lock,
+ int64_t pool_id) {
for (auto &pool_pair : m_pools) {
if (pool_pair.second->pool_id == pool_id) {
return pool_pair.second;
typedef std::map<std::string, bufferlist> FileTMaps;
typedef std::map<std::string, bufferlist> XAttrs;
typedef std::map<std::string, XAttrs> FileXAttrs;
+ typedef std::set<ObjectHandler*> ObjectHandlers;
+ typedef std::map<std::string, ObjectHandlers> FileHandlers;
struct File {
File();
FileOMaps file_omaps;
FileTMaps file_tmaps;
FileXAttrs file_xattrs;
+ FileHandlers file_handlers;
};
TestMemCluster();
TestRadosClient *create_rados_client(CephContext *cct) override;
+ int register_object_handler(int64_t pool_id, const std::string& o,
+ ObjectHandler* object_handler) override;
+ void unregister_object_handler(int64_t pool_id, const std::string& o,
+ ObjectHandler* object_handler) override;
+
int pool_create(const std::string &pool_name);
int pool_delete(const std::string &pool_name);
int pool_get_base_tier(int64_t pool_id, int64_t* base_tier);
Cond m_transaction_cond;
std::set<std::string> m_transactions;
+ Pool *get_pool(const Mutex& lock, int64_t pool_id);
+
};
} // namespace librados
}
file = get_file(oid, true, snapc);
- RWLock::WLocker l2(file->lock);
- file->exists = false;
+ {
+ RWLock::WLocker l2(file->lock);
+ file->exists = false;
+ }
TestMemCluster::Files::iterator it = m_pool->files.find(oid);
assert(it != m_pool->files.end());
+
+ if (*it->second.rbegin() == file) {
+ TestMemCluster::ObjectHandlers object_handlers;
+ std::swap(object_handlers, m_pool->file_handlers[oid]);
+ m_pool->file_handlers.erase(oid);
+
+ for (auto object_handler : object_handlers) {
+ object_handler->handle_removed(m_client);
+ }
+ }
+
if (it->second.size() == 1) {
m_pool->files.erase(it);
m_pool->file_omaps.erase(oid);