From: Loic Dachary Date: Wed, 12 Feb 2014 10:52:37 +0000 (+0100) Subject: tests: fix objectstore tests X-Git-Tag: v0.78~196^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=b64f1e39a885b94a767742cb7f583dfefd5887f9;p=ceph.git tests: fix objectstore tests The objectstore test from 1a588f18ba0e57df64f8a48c1393a4bc65019571 was missing a few changes. Signed-off-by: Loic Dachary --- diff --git a/src/test/objectstore/TestFileStoreState.cc b/src/test/objectstore/TestFileStoreState.cc deleted file mode 100644 index 34e25fb2e2c5..000000000000 --- a/src/test/objectstore/TestFileStoreState.cc +++ /dev/null @@ -1,296 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* -* Ceph - scalable distributed file system -* -* Copyright (C) 2012 New Dream Network -* -* This is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License version 2.1, as published by the Free Software -* Foundation. See file COPYING. -*/ -#include -#include -#include -#include -#include -#include -#include "os/ObjectStore.h" -#include "common/ceph_argparse.h" -#include "global/global_init.h" -#include "common/debug.h" -#include -#include -#include "TestObjectStoreState.h" -#include "include/assert.h" - -#define dout_subsys ceph_subsys_filestore -#undef dout_prefix -#define dout_prefix *_dout << "ceph_test_filestore_state " - -const coll_t TestObjectStoreState::META_COLL("meta"); -const coll_t TestObjectStoreState::TEMP_COLL("temp"); - -void TestObjectStoreState::init(int colls, int objs) -{ - dout(5) << "init " << colls << " colls " << objs << " objs" << dendl; - - ObjectStore::Transaction *t; - t = new ObjectStore::Transaction; - - t->create_collection(META_COLL); - t->create_collection(TEMP_COLL); - m_store->apply_transaction(*t); - - wait_for_ready(); - - int baseid = 0; - for (int i = 0; i < colls; i++) { - int coll_id = i; - coll_entry_t *entry = coll_create(coll_id); - dout(5) << "init create collection " << entry->m_coll.to_str() - << " meta " << entry->m_meta_obj.oid.name << dendl; - - t = new ObjectStore::Transaction; - t->create_collection(entry->m_coll); - t->touch(META_COLL, entry->m_meta_obj); - - for (int i = 0; i < objs; i++) { - hobject_t *obj = entry->touch_obj(i + baseid); - t->touch(entry->m_coll, *obj); - ceph_assert(i + baseid == m_num_objects); - m_num_objects++; - } - baseid += objs; - - m_store->queue_transaction(&(entry->m_osr), t, - new C_OnFinished(this, t)); - inc_in_flight(); - - m_collections.insert(make_pair(coll_id, entry)); - m_collections_ids.push_back(coll_id); - m_next_coll_nr++; - } - dout(5) << "init has " << m_in_flight.read() << "in-flight transactions" << dendl; - wait_for_done(); - dout(5) << "init finished" << dendl; -} - -TestObjectStoreState::coll_entry_t *TestObjectStoreState::coll_create(int id) -{ - char buf[100]; - char meta_buf[100]; - memset(buf, 0, 100); - memset(meta_buf, 0, 100); - snprintf(buf, 100, "0.%d_head", id); - snprintf(meta_buf, 100, "pglog_0.%d_head", id); - return (new coll_entry_t(id, buf, meta_buf)); -} - -TestObjectStoreState::coll_entry_t* -TestObjectStoreState::get_coll(int key, bool erase) -{ - dout(5) << "get_coll id " << key << dendl; - - coll_entry_t *entry = NULL; - map::iterator it = m_collections.find(key); - if (it != m_collections.end()) { - entry = it->second; - if (erase) { - m_collections.erase(it); - vector::iterator cid_it = m_collections_ids.begin()+(entry->m_id); - dout(20) << __func__ << " removing key " << key << " coll_id " << entry->m_id - << " iterator's entry id " << (*cid_it) << dendl; - m_collections_ids.erase(cid_it); - } - } - - dout(5) << "get_coll id " << key; - if (!entry) - *_dout << " non-existent"; - else - *_dout << " name " << entry->m_coll.to_str(); - *_dout << dendl; - return entry; -} - -TestObjectStoreState::coll_entry_t* -TestObjectStoreState::get_coll_at(int pos, bool erase) -{ - dout(5) << "get_coll_at pos " << pos << dendl; - - if (m_collections.empty()) - return NULL; - - assert((size_t) pos < m_collections_ids.size()); - - int coll_id = m_collections_ids[pos]; - coll_entry_t *entry = m_collections[coll_id]; - - if (entry == NULL) { - dout(5) << "get_coll_at pos " << pos << " non-existent" << dendl; - return NULL; - } - - if (erase) { - m_collections.erase(coll_id); - vector::iterator it = m_collections_ids.begin()+(pos); - dout(20) << __func__ << " removing pos " << pos << " coll_id " << coll_id - << " iterator's entry id " << (*it) << dendl; - m_collections_ids.erase(it); - } - - dout(5) << "get_coll_at pos " << pos << ": " - << entry->m_coll << "(removed: " << erase << ")" << dendl; - - return entry; -} - -TestObjectStoreState::coll_entry_t::~coll_entry_t() -{ - if (m_objects.size() > 0) { - map::iterator it = m_objects.begin(); - for (; it != m_objects.end(); ++it) { - hobject_t *obj = it->second; - if (obj) { - delete obj; - } - } - m_objects.clear(); - } -} - -bool TestObjectStoreState::coll_entry_t::check_for_obj(int id) -{ - if (m_objects.count(id)) - return true; - return false; -} - -hobject_t *TestObjectStoreState::coll_entry_t::touch_obj(int id) -{ - map::iterator it = m_objects.find(id); - if (it != m_objects.end()) { - dout(5) << "touch_obj coll id " << m_id - << " name " << it->second->oid.name << dendl; - return it->second; - } - - char buf[100]; - memset(buf, 0, 100); - snprintf(buf, 100, "obj%d", id); - - hobject_t *obj = new hobject_t(sobject_t(object_t(buf), CEPH_NOSNAP)); - m_objects.insert(make_pair(id, obj)); - - dout(5) << "touch_obj coll id " << m_id << " name " << buf << dendl; - return obj; -} - -hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id) -{ - return get_obj(id, false); -} - -/** - * remove_obj - Removes object without freeing it. - * @param id Object's id in the map. - * @return The object or NULL in case of error. - */ -hobject_t *TestObjectStoreState::coll_entry_t::remove_obj(int id) -{ - return get_obj(id, true); -} - -hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id, bool remove) -{ - map::iterator it = m_objects.find(id); - if (it == m_objects.end()) { - dout(5) << "get_obj coll " << m_coll.to_str() - << " obj #" << id << " non-existent" << dendl; - return NULL; - } - - hobject_t *obj = it->second; - if (remove) - m_objects.erase(it); - - dout(5) << "get_obj coll " << m_coll.to_str() << " id " << id - << ": " << obj->oid.name << "(removed: " << remove << ")" << dendl; - - return obj; -} - -hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos, int *key) -{ - return get_obj_at(pos, false, key); -} - -/** - * remove_obj_at - Removes object without freeing it. - * @param pos The map's position in which the object lies. - * @return The object or NULL in case of error. - */ -hobject_t *TestObjectStoreState::coll_entry_t::remove_obj_at(int pos, int *key) -{ - return get_obj_at(pos, true, key); -} - -hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos, - bool remove, int *key) -{ - if (m_objects.empty()) { - dout(5) << "get_obj_at coll " << m_coll.to_str() << " pos " << pos - << " in an empty collection" << dendl; - return NULL; - } - - hobject_t *ret = NULL; - map::iterator it = m_objects.begin(); - for (int i = 0; it != m_objects.end(); ++it, i++) { - if (i == pos) { - ret = it->second; - break; - } - } - - if (ret == NULL) { - dout(5) << "get_obj_at coll " << m_coll.to_str() << " pos " << pos - << " non-existent" << dendl; - return NULL; - } - - if (key != NULL) - *key = it->first; - - if (remove) - m_objects.erase(it); - - dout(5) << "get_obj_at coll id " << m_id << " pos " << pos - << ": " << ret->oid.name << "(removed: " << remove << ")" << dendl; - - return ret; -} - -hobject_t* -TestObjectStoreState::coll_entry_t::replace_obj(int id, hobject_t *obj) { - hobject_t *old_obj = remove_obj(id); - m_objects.insert(make_pair(id, obj)); - return old_obj; -} - -int TestObjectStoreState::coll_entry_t::get_random_obj_id(rngen_t& gen) -{ - ceph_assert(!m_objects.empty()); - - boost::uniform_int<> orig_obj_rng(0, m_objects.size()-1); - int pos = orig_obj_rng(gen); - map::iterator it = m_objects.begin(); - for (int i = 0; it != m_objects.end(); ++it, i++) { - if (i == pos) { - return it->first; - } - } - ceph_assert(0 == "INTERNAL ERROR"); -} diff --git a/src/test/objectstore/TestFileStoreState.h b/src/test/objectstore/TestFileStoreState.h deleted file mode 100644 index dad2aab73791..000000000000 --- a/src/test/objectstore/TestFileStoreState.h +++ /dev/null @@ -1,148 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* -* Ceph - scalable distributed file system -* -* Copyright (C) 2012 New Dream Network -* -* This is free software; you can redistribute it and/or -* modify it under the terms of the GNU Lesser General Public -* License version 2.1, as published by the Free Software -* Foundation. See file COPYING. -*/ -#ifndef TEST_OBJECTSTORE_STATE_H_ -#define TEST_OBJECTSTORE_STATE_H_ - -#include "os/ObjectStore.h" -#include -#include -#include -#include -#include - -typedef boost::mt11213b rngen_t; - -class TestObjectStoreState { -public: - struct coll_entry_t { - int m_id; - coll_t m_coll; - hobject_t m_meta_obj; - ObjectStore::Sequencer m_osr; - map m_objects; - int m_next_object_id; - - coll_entry_t(int i, char *coll_buf, char *meta_obj_buf) - : m_id(i), m_coll(coll_buf), - m_meta_obj(sobject_t(object_t(meta_obj_buf), CEPH_NOSNAP)), - m_osr(coll_buf), m_next_object_id(0) { - } - ~coll_entry_t(); - - hobject_t *touch_obj(int id); - bool check_for_obj(int id); - hobject_t *get_obj(int id); - hobject_t *remove_obj(int id); - hobject_t *get_obj_at(int pos, int *key = NULL); - hobject_t *remove_obj_at(int pos, int *key = NULL); - hobject_t *replace_obj(int id, hobject_t *obj); - int get_random_obj_id(rngen_t& gen); - - private: - hobject_t *get_obj(int id, bool remove); - hobject_t *get_obj_at(int pos, bool remove, int *key = NULL); - }; - - /* kept in upper case for consistency with coll_t's */ - static const coll_t META_COLL; - static const coll_t TEMP_COLL; - - protected: - boost::shared_ptr m_store; - map m_collections; - vector m_collections_ids; - int m_next_coll_nr; - int m_num_objs_per_coll; - int m_num_objects; - - int m_max_in_flight; - atomic_t m_in_flight; - Mutex m_finished_lock; - Cond m_finished_cond; - - void wait_for_ready() { - Mutex::Locker locker(m_finished_lock); - while ((m_max_in_flight > 0) && ((int)m_in_flight.read() >= m_max_in_flight)) - m_finished_cond.Wait(m_finished_lock); - } - - void wait_for_done() { - Mutex::Locker locker(m_finished_lock); - while (m_in_flight.read()) - m_finished_cond.Wait(m_finished_lock); - } - - void set_max_in_flight(int max) { - m_max_in_flight = max; - } - void set_num_objs_per_coll(int val) { - m_num_objs_per_coll = val; - } - - coll_entry_t *get_coll(int key, bool erase = false); - coll_entry_t *get_coll_at(int pos, bool erase = false); - - private: - static const int m_default_num_colls = 30; - - public: - TestObjectStoreState(ObjectStore *store) : - m_next_coll_nr(0), m_num_objs_per_coll(10), m_num_objects(0), - m_max_in_flight(0), m_finished_lock("Finished Lock") { - m_in_flight.set(0); - m_store.reset(store); - } - ~TestObjectStoreState() { - map::iterator it = m_collections.begin(); - while (it != m_collections.end()) { - if (it->second) - delete it->second; - m_collections.erase(it++); - } - } - - void init(int colls, int objs); - void init() { - init(m_default_num_colls, 0); - } - - int inc_in_flight() { - return ((int) m_in_flight.inc()); - } - - int dec_in_flight() { - return ((int) m_in_flight.dec()); - } - - coll_entry_t *coll_create(int id); - - class C_OnFinished: public Context { - protected: - TestObjectStoreState *m_state; - ObjectStore::Transaction *m_tx; - - public: - C_OnFinished(TestObjectStoreState *state, - ObjectStore::Transaction *t) : m_state(state), m_tx(t) { } - - void finish(int r) { - Mutex::Locker locker(m_state->m_finished_lock); - m_state->dec_in_flight(); - m_state->m_finished_cond.Signal(); - - delete m_tx; - } - }; -}; - -#endif /* TEST_OBJECTSTORE_STATE_H_ */ diff --git a/src/test/objectstore/TestObjectStoreState.cc b/src/test/objectstore/TestObjectStoreState.cc new file mode 100644 index 000000000000..34e25fb2e2c5 --- /dev/null +++ b/src/test/objectstore/TestObjectStoreState.cc @@ -0,0 +1,296 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2012 New Dream Network +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#include +#include +#include +#include +#include +#include +#include "os/ObjectStore.h" +#include "common/ceph_argparse.h" +#include "global/global_init.h" +#include "common/debug.h" +#include +#include +#include "TestObjectStoreState.h" +#include "include/assert.h" + +#define dout_subsys ceph_subsys_filestore +#undef dout_prefix +#define dout_prefix *_dout << "ceph_test_filestore_state " + +const coll_t TestObjectStoreState::META_COLL("meta"); +const coll_t TestObjectStoreState::TEMP_COLL("temp"); + +void TestObjectStoreState::init(int colls, int objs) +{ + dout(5) << "init " << colls << " colls " << objs << " objs" << dendl; + + ObjectStore::Transaction *t; + t = new ObjectStore::Transaction; + + t->create_collection(META_COLL); + t->create_collection(TEMP_COLL); + m_store->apply_transaction(*t); + + wait_for_ready(); + + int baseid = 0; + for (int i = 0; i < colls; i++) { + int coll_id = i; + coll_entry_t *entry = coll_create(coll_id); + dout(5) << "init create collection " << entry->m_coll.to_str() + << " meta " << entry->m_meta_obj.oid.name << dendl; + + t = new ObjectStore::Transaction; + t->create_collection(entry->m_coll); + t->touch(META_COLL, entry->m_meta_obj); + + for (int i = 0; i < objs; i++) { + hobject_t *obj = entry->touch_obj(i + baseid); + t->touch(entry->m_coll, *obj); + ceph_assert(i + baseid == m_num_objects); + m_num_objects++; + } + baseid += objs; + + m_store->queue_transaction(&(entry->m_osr), t, + new C_OnFinished(this, t)); + inc_in_flight(); + + m_collections.insert(make_pair(coll_id, entry)); + m_collections_ids.push_back(coll_id); + m_next_coll_nr++; + } + dout(5) << "init has " << m_in_flight.read() << "in-flight transactions" << dendl; + wait_for_done(); + dout(5) << "init finished" << dendl; +} + +TestObjectStoreState::coll_entry_t *TestObjectStoreState::coll_create(int id) +{ + char buf[100]; + char meta_buf[100]; + memset(buf, 0, 100); + memset(meta_buf, 0, 100); + snprintf(buf, 100, "0.%d_head", id); + snprintf(meta_buf, 100, "pglog_0.%d_head", id); + return (new coll_entry_t(id, buf, meta_buf)); +} + +TestObjectStoreState::coll_entry_t* +TestObjectStoreState::get_coll(int key, bool erase) +{ + dout(5) << "get_coll id " << key << dendl; + + coll_entry_t *entry = NULL; + map::iterator it = m_collections.find(key); + if (it != m_collections.end()) { + entry = it->second; + if (erase) { + m_collections.erase(it); + vector::iterator cid_it = m_collections_ids.begin()+(entry->m_id); + dout(20) << __func__ << " removing key " << key << " coll_id " << entry->m_id + << " iterator's entry id " << (*cid_it) << dendl; + m_collections_ids.erase(cid_it); + } + } + + dout(5) << "get_coll id " << key; + if (!entry) + *_dout << " non-existent"; + else + *_dout << " name " << entry->m_coll.to_str(); + *_dout << dendl; + return entry; +} + +TestObjectStoreState::coll_entry_t* +TestObjectStoreState::get_coll_at(int pos, bool erase) +{ + dout(5) << "get_coll_at pos " << pos << dendl; + + if (m_collections.empty()) + return NULL; + + assert((size_t) pos < m_collections_ids.size()); + + int coll_id = m_collections_ids[pos]; + coll_entry_t *entry = m_collections[coll_id]; + + if (entry == NULL) { + dout(5) << "get_coll_at pos " << pos << " non-existent" << dendl; + return NULL; + } + + if (erase) { + m_collections.erase(coll_id); + vector::iterator it = m_collections_ids.begin()+(pos); + dout(20) << __func__ << " removing pos " << pos << " coll_id " << coll_id + << " iterator's entry id " << (*it) << dendl; + m_collections_ids.erase(it); + } + + dout(5) << "get_coll_at pos " << pos << ": " + << entry->m_coll << "(removed: " << erase << ")" << dendl; + + return entry; +} + +TestObjectStoreState::coll_entry_t::~coll_entry_t() +{ + if (m_objects.size() > 0) { + map::iterator it = m_objects.begin(); + for (; it != m_objects.end(); ++it) { + hobject_t *obj = it->second; + if (obj) { + delete obj; + } + } + m_objects.clear(); + } +} + +bool TestObjectStoreState::coll_entry_t::check_for_obj(int id) +{ + if (m_objects.count(id)) + return true; + return false; +} + +hobject_t *TestObjectStoreState::coll_entry_t::touch_obj(int id) +{ + map::iterator it = m_objects.find(id); + if (it != m_objects.end()) { + dout(5) << "touch_obj coll id " << m_id + << " name " << it->second->oid.name << dendl; + return it->second; + } + + char buf[100]; + memset(buf, 0, 100); + snprintf(buf, 100, "obj%d", id); + + hobject_t *obj = new hobject_t(sobject_t(object_t(buf), CEPH_NOSNAP)); + m_objects.insert(make_pair(id, obj)); + + dout(5) << "touch_obj coll id " << m_id << " name " << buf << dendl; + return obj; +} + +hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id) +{ + return get_obj(id, false); +} + +/** + * remove_obj - Removes object without freeing it. + * @param id Object's id in the map. + * @return The object or NULL in case of error. + */ +hobject_t *TestObjectStoreState::coll_entry_t::remove_obj(int id) +{ + return get_obj(id, true); +} + +hobject_t *TestObjectStoreState::coll_entry_t::get_obj(int id, bool remove) +{ + map::iterator it = m_objects.find(id); + if (it == m_objects.end()) { + dout(5) << "get_obj coll " << m_coll.to_str() + << " obj #" << id << " non-existent" << dendl; + return NULL; + } + + hobject_t *obj = it->second; + if (remove) + m_objects.erase(it); + + dout(5) << "get_obj coll " << m_coll.to_str() << " id " << id + << ": " << obj->oid.name << "(removed: " << remove << ")" << dendl; + + return obj; +} + +hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos, int *key) +{ + return get_obj_at(pos, false, key); +} + +/** + * remove_obj_at - Removes object without freeing it. + * @param pos The map's position in which the object lies. + * @return The object or NULL in case of error. + */ +hobject_t *TestObjectStoreState::coll_entry_t::remove_obj_at(int pos, int *key) +{ + return get_obj_at(pos, true, key); +} + +hobject_t *TestObjectStoreState::coll_entry_t::get_obj_at(int pos, + bool remove, int *key) +{ + if (m_objects.empty()) { + dout(5) << "get_obj_at coll " << m_coll.to_str() << " pos " << pos + << " in an empty collection" << dendl; + return NULL; + } + + hobject_t *ret = NULL; + map::iterator it = m_objects.begin(); + for (int i = 0; it != m_objects.end(); ++it, i++) { + if (i == pos) { + ret = it->second; + break; + } + } + + if (ret == NULL) { + dout(5) << "get_obj_at coll " << m_coll.to_str() << " pos " << pos + << " non-existent" << dendl; + return NULL; + } + + if (key != NULL) + *key = it->first; + + if (remove) + m_objects.erase(it); + + dout(5) << "get_obj_at coll id " << m_id << " pos " << pos + << ": " << ret->oid.name << "(removed: " << remove << ")" << dendl; + + return ret; +} + +hobject_t* +TestObjectStoreState::coll_entry_t::replace_obj(int id, hobject_t *obj) { + hobject_t *old_obj = remove_obj(id); + m_objects.insert(make_pair(id, obj)); + return old_obj; +} + +int TestObjectStoreState::coll_entry_t::get_random_obj_id(rngen_t& gen) +{ + ceph_assert(!m_objects.empty()); + + boost::uniform_int<> orig_obj_rng(0, m_objects.size()-1); + int pos = orig_obj_rng(gen); + map::iterator it = m_objects.begin(); + for (int i = 0; it != m_objects.end(); ++it, i++) { + if (i == pos) { + return it->first; + } + } + ceph_assert(0 == "INTERNAL ERROR"); +} diff --git a/src/test/objectstore/TestObjectStoreState.h b/src/test/objectstore/TestObjectStoreState.h new file mode 100644 index 000000000000..dad2aab73791 --- /dev/null +++ b/src/test/objectstore/TestObjectStoreState.h @@ -0,0 +1,148 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* +* Ceph - scalable distributed file system +* +* Copyright (C) 2012 New Dream Network +* +* This is free software; you can redistribute it and/or +* modify it under the terms of the GNU Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +*/ +#ifndef TEST_OBJECTSTORE_STATE_H_ +#define TEST_OBJECTSTORE_STATE_H_ + +#include "os/ObjectStore.h" +#include +#include +#include +#include +#include + +typedef boost::mt11213b rngen_t; + +class TestObjectStoreState { +public: + struct coll_entry_t { + int m_id; + coll_t m_coll; + hobject_t m_meta_obj; + ObjectStore::Sequencer m_osr; + map m_objects; + int m_next_object_id; + + coll_entry_t(int i, char *coll_buf, char *meta_obj_buf) + : m_id(i), m_coll(coll_buf), + m_meta_obj(sobject_t(object_t(meta_obj_buf), CEPH_NOSNAP)), + m_osr(coll_buf), m_next_object_id(0) { + } + ~coll_entry_t(); + + hobject_t *touch_obj(int id); + bool check_for_obj(int id); + hobject_t *get_obj(int id); + hobject_t *remove_obj(int id); + hobject_t *get_obj_at(int pos, int *key = NULL); + hobject_t *remove_obj_at(int pos, int *key = NULL); + hobject_t *replace_obj(int id, hobject_t *obj); + int get_random_obj_id(rngen_t& gen); + + private: + hobject_t *get_obj(int id, bool remove); + hobject_t *get_obj_at(int pos, bool remove, int *key = NULL); + }; + + /* kept in upper case for consistency with coll_t's */ + static const coll_t META_COLL; + static const coll_t TEMP_COLL; + + protected: + boost::shared_ptr m_store; + map m_collections; + vector m_collections_ids; + int m_next_coll_nr; + int m_num_objs_per_coll; + int m_num_objects; + + int m_max_in_flight; + atomic_t m_in_flight; + Mutex m_finished_lock; + Cond m_finished_cond; + + void wait_for_ready() { + Mutex::Locker locker(m_finished_lock); + while ((m_max_in_flight > 0) && ((int)m_in_flight.read() >= m_max_in_flight)) + m_finished_cond.Wait(m_finished_lock); + } + + void wait_for_done() { + Mutex::Locker locker(m_finished_lock); + while (m_in_flight.read()) + m_finished_cond.Wait(m_finished_lock); + } + + void set_max_in_flight(int max) { + m_max_in_flight = max; + } + void set_num_objs_per_coll(int val) { + m_num_objs_per_coll = val; + } + + coll_entry_t *get_coll(int key, bool erase = false); + coll_entry_t *get_coll_at(int pos, bool erase = false); + + private: + static const int m_default_num_colls = 30; + + public: + TestObjectStoreState(ObjectStore *store) : + m_next_coll_nr(0), m_num_objs_per_coll(10), m_num_objects(0), + m_max_in_flight(0), m_finished_lock("Finished Lock") { + m_in_flight.set(0); + m_store.reset(store); + } + ~TestObjectStoreState() { + map::iterator it = m_collections.begin(); + while (it != m_collections.end()) { + if (it->second) + delete it->second; + m_collections.erase(it++); + } + } + + void init(int colls, int objs); + void init() { + init(m_default_num_colls, 0); + } + + int inc_in_flight() { + return ((int) m_in_flight.inc()); + } + + int dec_in_flight() { + return ((int) m_in_flight.dec()); + } + + coll_entry_t *coll_create(int id); + + class C_OnFinished: public Context { + protected: + TestObjectStoreState *m_state; + ObjectStore::Transaction *m_tx; + + public: + C_OnFinished(TestObjectStoreState *state, + ObjectStore::Transaction *t) : m_state(state), m_tx(t) { } + + void finish(int r) { + Mutex::Locker locker(m_state->m_finished_lock); + m_state->dec_in_flight(); + m_state->m_finished_cond.Signal(); + + delete m_tx; + } + }; +}; + +#endif /* TEST_OBJECTSTORE_STATE_H_ */ diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index 4f66bd6d8929..e51678e3ea78 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -18,6 +18,7 @@ #include #include #include "os/ObjectStore.h" +#include "os/FileStore.h" #include "os/KeyValueStore.h" #include "include/Context.h" #include "common/ceph_argparse.h"