From: Sage Weil Date: Thu, 26 Jan 2017 22:25:23 +0000 (-0500) Subject: librados: remove deprecated object listing interfaces X-Git-Tag: v12.0.1~413^2~3 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=1785b98b8fc219d26fef6ccd46c8163744a0679f;p=ceph.git librados: remove deprecated object listing interfaces These have been deprecated since giant. Signed-off-by: Sage Weil --- diff --git a/src/include/rados/librados.h b/src/include/rados/librados.h index 8f88375d0000..9f6f343c35eb 100644 --- a/src/include/rados/librados.h +++ b/src/include/rados/librados.h @@ -968,7 +968,7 @@ CEPH_RADOS_API void rados_ioctx_set_namespace(rados_ioctx_t io, /** @} obj_loc */ /** - * @name New Listing Objects + * @name Listing Objects * @{ */ /** @@ -1002,7 +1002,7 @@ CEPH_RADOS_API uint32_t rados_nobjects_list_seek(rados_list_ctx_t ctx, /** * Get the next object name and locator in the pool * - * *entry and *key are valid until next call to rados_objects_list_* + * *entry and *key are valid until next call to rados_nobjects_list_* * * @param ctx iterator marking where you are in the listing * @param entry where to store the name of the entry @@ -1076,43 +1076,6 @@ CEPH_RADOS_API void rados_object_list_slice(rados_ioctx_t io, rados_object_list_cursor *split_finish); -/** @} New Listing Objects */ - -/** - * @name Deprecated Listing Objects - * - * Older listing objects interface. Please use the new interface. - * @{ - */ -/** - * @warning Deprecated: Use rados_nobjects_list_open() instead - */ -CEPH_RADOS_API int rados_objects_list_open(rados_ioctx_t io, - rados_list_ctx_t *ctx); - -/** - * @warning Deprecated: Use rados_nobjects_list_get_pg_hash_position() instead - */ -CEPH_RADOS_API uint32_t rados_objects_list_get_pg_hash_position(rados_list_ctx_t ctx); - -/** - * @warning Deprecated: Use rados_nobjects_list_seek() instead - */ -CEPH_RADOS_API uint32_t rados_objects_list_seek(rados_list_ctx_t ctx, - uint32_t pos); - -/** - * @warning Deprecated: Use rados_nobjects_list_next() instead - */ -CEPH_RADOS_API int rados_objects_list_next(rados_list_ctx_t ctx, - const char **entry, - const char **key); - -/** - * @warning Deprecated: Use rados_nobjects_list_close() instead - */ -CEPH_RADOS_API void rados_objects_list_close(rados_list_ctx_t ctx); - /** @} Listing Objects */ /** diff --git a/src/include/rados/librados.hpp b/src/include/rados/librados.hpp index bb9ed6d5dd65..6c7dcec10d76 100644 --- a/src/include/rados/librados.hpp +++ b/src/include/rados/librados.hpp @@ -107,36 +107,6 @@ namespace librados NObjectIteratorImpl *impl; }; - // DEPRECATED; Use NObjectIterator - class CEPH_RADOS_API ObjectIterator : public std::iterator > { - public: - static const ObjectIterator __EndObjectIterator; - ObjectIterator() {} - ObjectIterator(ObjListCtx *ctx_); - ~ObjectIterator(); - ObjectIterator(const ObjectIterator &rhs); - ObjectIterator& operator=(const ObjectIterator& rhs); - - bool operator==(const ObjectIterator& rhs) const; - bool operator!=(const ObjectIterator& rhs) const; - const std::pair& operator*() const; - const std::pair* operator->() const; - ObjectIterator &operator++(); // Preincrement - ObjectIterator operator++(int); // Postincrement - friend class IoCtx; - - /// get current hash position of the iterator, rounded to the current pg - uint32_t get_pg_hash_position() const; - - /// move the iterator to a given hash position. this may (will!) be rounded to the nearest pg. - uint32_t seek(uint32_t pos); - - private: - void get_next(); - ceph::shared_ptr < ObjListCtx > ctx; - std::pair cur_obj; - }; - class CEPH_RADOS_API ObjectCursor { public: @@ -895,13 +865,6 @@ namespace librados /// Iterator indicating the end of a pool const NObjectIterator& nobjects_end() const; - // DEPRECATED - ObjectIterator objects_begin() __attribute__ ((deprecated)); - /// Start enumerating objects for a pool starting from a hash position - ObjectIterator objects_begin(uint32_t start_hash_position) __attribute__ ((deprecated)); - /// Iterator indicating the end of a pool - const ObjectIterator& objects_end() const __attribute__ ((deprecated)); - ObjectCursor object_list_begin(); ObjectCursor object_list_end(); bool object_list_is_end(const ObjectCursor &oc); diff --git a/src/librados/librados.cc b/src/librados/librados.cc index ef8c71a24e58..ad25a518d859 100644 --- a/src/librados/librados.cc +++ b/src/librados/librados.cc @@ -867,103 +867,6 @@ uint32_t librados::NObjectIterator::get_pg_hash_position() const const librados::NObjectIterator librados::NObjectIterator::__EndObjectIterator(NULL); -// DEPRECATED; Use NObjectIterator instead -///////////////////////////// ObjectIterator ///////////////////////////// -librados::ObjectIterator::ObjectIterator(ObjListCtx *ctx_) - : ctx(ctx_) -{ -} - -librados::ObjectIterator::~ObjectIterator() -{ - ctx.reset(); -} - -librados::ObjectIterator::ObjectIterator(const ObjectIterator &rhs) -{ - *this = rhs; -} - -librados::ObjectIterator& librados::ObjectIterator::operator=( - const librados::ObjectIterator &rhs) -{ - if (&rhs == this) - return *this; - if (rhs.ctx.get() == NULL) { - ctx.reset(); - return *this; - } - Objecter::NListContext *list_ctx = new Objecter::NListContext(*rhs.ctx->nlc); - ctx.reset(new ObjListCtx(rhs.ctx->ctx, list_ctx, true)); - cur_obj = rhs.cur_obj; - return *this; -} - -bool librados::ObjectIterator::operator==(const librados::ObjectIterator& rhs) const { - if (ctx.get() == NULL) - return rhs.ctx.get() == NULL || rhs.ctx->nlc->at_end(); - if (rhs.ctx.get() == NULL) - return ctx.get() == NULL || ctx->nlc->at_end(); - return ctx.get() == rhs.ctx.get(); -} - -bool librados::ObjectIterator::operator!=(const librados::ObjectIterator& rhs) const { - return !(*this == rhs); -} - -const pair& librados::ObjectIterator::operator*() const { - return cur_obj; -} - -const pair* librados::ObjectIterator::operator->() const { - return &cur_obj; -} - -librados::ObjectIterator& librados::ObjectIterator::operator++() -{ - get_next(); - return *this; -} - -librados::ObjectIterator librados::ObjectIterator::operator++(int) -{ - librados::ObjectIterator ret(*this); - get_next(); - return ret; -} - -uint32_t librados::ObjectIterator::seek(uint32_t pos) -{ - uint32_t r = rados_objects_list_seek(ctx.get(), pos); - get_next(); - return r; -} - -void librados::ObjectIterator::get_next() -{ - const char *entry, *key; - if (ctx->nlc->at_end()) - return; - int ret = rados_objects_list_next(ctx.get(), &entry, &key); - if (ret == -ENOENT) { - return; - } - else if (ret) { - ostringstream oss; - oss << "rados returned " << cpp_strerror(ret); - throw std::runtime_error(oss.str()); - } - - cur_obj = make_pair(entry, key ? key : string()); -} - -uint32_t librados::ObjectIterator::get_pg_hash_position() const -{ - return ctx->nlc->get_pg_hash_position(); -} - -const librados::ObjectIterator librados::ObjectIterator::__EndObjectIterator(NULL); - ///////////////////////////// PoolAsyncCompletion ////////////////////////////// int librados::PoolAsyncCompletion::PoolAsyncCompletion::set_callback(void *cb_arg, rados_callback_t cb) @@ -1804,40 +1707,6 @@ const librados::NObjectIterator& librados::IoCtx::nobjects_end() const return NObjectIterator::__EndObjectIterator; } -// DEPRECATED; use n versions above -librados::ObjectIterator librados::IoCtx::objects_begin() -{ - rados_list_ctx_t listh; - if (io_ctx_impl->oloc.nspace == librados::all_nspaces) { - ostringstream oss; - oss << "rados returned " << cpp_strerror(-EINVAL); - throw std::runtime_error(oss.str()); - } - rados_objects_list_open(io_ctx_impl, &listh); - ObjectIterator iter((ObjListCtx*)listh); - iter.get_next(); - return iter; -} - -librados::ObjectIterator librados::IoCtx::objects_begin(uint32_t pos) -{ - rados_list_ctx_t listh; - if (io_ctx_impl->oloc.nspace == librados::all_nspaces) { - ostringstream oss; - oss << "rados returned " << cpp_strerror(-EINVAL); - throw std::runtime_error(oss.str()); - } - rados_objects_list_open(io_ctx_impl, &listh); - ObjectIterator iter((ObjListCtx*)listh); - iter.seek(pos); - return iter; -} - -const librados::ObjectIterator& librados::IoCtx::objects_end() const -{ - return ObjectIterator::__EndObjectIterator; -} - int librados::IoCtx::hit_set_list(uint32_t hash, AioCompletion *c, std::list< std::pair > *pls) { @@ -4255,10 +4124,6 @@ extern "C" int rados_nobjects_list_open(rados_ioctx_t io, rados_list_ctx_t *list { librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io; - // Let's do it the old way for backward compatbility if not using ANY_NSPACES - if (ctx->oloc.nspace != librados::all_nspaces) - return rados_objects_list_open(io, listh); - tracepoint(librados, rados_nobjects_list_open_enter, io); Objecter::NListContext *h = new Objecter::NListContext; @@ -4298,51 +4163,6 @@ extern "C" uint32_t rados_nobjects_list_get_pg_hash_position( return retval; } -// Deprecated, but using it for compatibility with older OSDs -extern "C" int rados_objects_list_open(rados_ioctx_t io, rados_list_ctx_t *listh) -{ - tracepoint(librados, rados_objects_list_open_enter, io); - librados::IoCtxImpl *ctx = (librados::IoCtxImpl *)io; - if (ctx->oloc.nspace == librados::all_nspaces) - return -EINVAL; - Objecter::NListContext *h = new Objecter::NListContext; - h->pool_id = ctx->poolid; - h->pool_snap_seq = ctx->snap_seq; - h->nspace = ctx->oloc.nspace; - *listh = (void *)new librados::ObjListCtx(ctx, h, true); - tracepoint(librados, rados_objects_list_open_exit, 0, *listh); - return 0; -} - -// Deprecated, but using it for compatibility with older OSDs -extern "C" void rados_objects_list_close(rados_list_ctx_t h) -{ - tracepoint(librados, rados_objects_list_close_enter, h); - librados::ObjListCtx *lh = (librados::ObjListCtx *)h; - delete lh; - tracepoint(librados, rados_objects_list_close_exit); -} - -extern "C" uint32_t rados_objects_list_seek(rados_list_ctx_t listctx, - uint32_t pos) -{ - tracepoint(librados, rados_objects_list_seek_enter, listctx, pos); - librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx; - uint32_t r = lh->ctx->nlist_seek(lh->nlc, pos); - tracepoint(librados, rados_objects_list_seek_exit, r); - return r; -} - -extern "C" uint32_t rados_objects_list_get_pg_hash_position( - rados_list_ctx_t listctx) -{ - tracepoint(librados, rados_objects_list_get_pg_hash_position_enter, listctx); - librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx; - uint32_t retval = lh->nlc->get_pg_hash_position(); - tracepoint(librados, rados_objects_list_get_pg_hash_position_exit, retval); - return retval; -} - extern "C" int rados_nobjects_list_next(rados_list_ctx_t listctx, const char **entry, const char **key, const char **nspace) { tracepoint(librados, rados_nobjects_list_next_enter, listctx); @@ -4380,47 +4200,6 @@ extern "C" int rados_nobjects_list_next(rados_list_ctx_t listctx, const char **e return 0; } -// DEPRECATED -extern "C" int rados_objects_list_next(rados_list_ctx_t listctx, const char **entry, const char **key) -{ - tracepoint(librados, rados_objects_list_next_enter, listctx); - librados::ObjListCtx *lh = (librados::ObjListCtx *)listctx; - Objecter::NListContext *h = lh->nlc; - - // Calling wrong interface after rados_nobjects_list_open() - if (!lh->legacy_list_api) - return -EINVAL; - - // if the list is non-empty, this method has been called before - if (!h->list.empty()) - // so let's kill the previously-returned object - h->list.pop_front(); - - if (h->list.empty()) { - int ret = lh->ctx->nlist(lh->nlc, RADOS_LIST_MAX_ENTRIES); - if (ret < 0) { - tracepoint(librados, rados_objects_list_next_exit, ret, NULL, NULL); - return ret; - } - if (h->list.empty()) { - tracepoint(librados, rados_objects_list_next_exit, -ENOENT, NULL, NULL); - return -ENOENT; - } - } - - *entry = h->list.front().get_oid().c_str(); - - if (key) { - if (h->list.front().get_locator().size()) - *key = h->list.front().get_locator().c_str(); - else - *key = NULL; - } - tracepoint(librados, rados_objects_list_next_exit, 0, *entry, key); - return 0; -} - - // ------------------------- // aio diff --git a/src/test/librados/CMakeLists.txt b/src/test/librados/CMakeLists.txt index 60939020f60b..2194a3e1fa67 100644 --- a/src/test/librados/CMakeLists.txt +++ b/src/test/librados/CMakeLists.txt @@ -61,15 +61,6 @@ set_target_properties(ceph_test_rados_api_list PROPERTIES COMPILE_FLAGS target_link_libraries(ceph_test_rados_api_list rados_a global ${UNITTEST_LIBS} radostest) -# ceph_test_rados_api_nlist -add_executable(ceph_test_rados_api_nlist - nlist.cc - ) -set_target_properties(ceph_test_rados_api_nlist PROPERTIES COMPILE_FLAGS - ${UNITTEST_CXX_FLAGS}) -target_link_libraries(ceph_test_rados_api_nlist - rados_a ${UNITTEST_LIBS} radostest) - # ceph_test_rados_api_pool add_executable(ceph_test_rados_api_pool pool.cc diff --git a/src/test/librados/list.cc b/src/test/librados/list.cc index e250be34aea8..a843ce33608a 100644 --- a/src/test/librados/list.cc +++ b/src/test/librados/list.cc @@ -22,38 +22,34 @@ typedef RadosTestECNS LibRadosListEC; typedef RadosTestECPPNS LibRadosListECPP; typedef RadosTestNP LibRadosListNP; + TEST_F(LibRadosList, ListObjects) { char buf[128]; memset(buf, 0xcc, sizeof(buf)); ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); const char *entry; bool foundit = false; - while (rados_objects_list_next(ctx, &entry, NULL) != -ENOENT) { + while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) != -ENOENT) { foundit = true; ASSERT_EQ(std::string(entry), "foo"); } ASSERT_TRUE(foundit); - rados_objects_list_close(ctx); + rados_nobjects_list_close(ctx); } - -#pragma GCC diagnostic ignored "-Wpragmas" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - TEST_F(LibRadosListPP, ListObjectsPP) { char buf[128]; memset(buf, 0xcc, sizeof(buf)); bufferlist bl1; bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - ObjectIterator iter(ioctx.objects_begin()); + NObjectIterator iter(ioctx.nobjects_begin()); bool foundit = false; - while (iter != ioctx.objects_end()) { + while (iter != ioctx.nobjects_end()) { foundit = true; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; } ASSERT_TRUE(foundit); @@ -65,21 +61,21 @@ TEST_F(LibRadosListPP, ListObjectsTwicePP) { bufferlist bl1; bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - ObjectIterator iter(ioctx.objects_begin()); + NObjectIterator iter(ioctx.nobjects_begin()); bool foundit = false; - while (iter != ioctx.objects_end()) { + while (iter != ioctx.nobjects_end()) { foundit = true; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; } ASSERT_TRUE(foundit); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); foundit = false; iter.seek(0); - while (iter != ioctx.objects_end()) { + while (iter != ioctx.nobjects_end()) { foundit = true; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; } ASSERT_TRUE(foundit); @@ -93,28 +89,28 @@ TEST_F(LibRadosListPP, ListObjectsCopyIterPP) { ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); // make sure this is still valid after the original iterators are gone - ObjectIterator iter3; + NObjectIterator iter3; { - ObjectIterator iter(ioctx.objects_begin()); - ObjectIterator iter2(iter); + NObjectIterator iter(ioctx.nobjects_begin()); + NObjectIterator iter2(iter); iter3 = iter2; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); - ASSERT_EQ(iter2->first, "foo"); - ASSERT_EQ(iter3->first, "foo"); + ASSERT_EQ(iter2->get_oid(), "foo"); + ASSERT_EQ(iter3->get_oid(), "foo"); ++iter2; - ASSERT_TRUE(iter2 == ioctx.objects_end()); + ASSERT_TRUE(iter2 == ioctx.nobjects_end()); } - ASSERT_EQ(iter3->first, "foo"); + ASSERT_EQ(iter3->get_oid(), "foo"); iter3 = iter3; - ASSERT_EQ(iter3->first, "foo"); + ASSERT_EQ(iter3->get_oid(), "foo"); ++iter3; - ASSERT_TRUE(iter3 == ioctx.objects_end()); + ASSERT_TRUE(iter3 == ioctx.nobjects_end()); } TEST_F(LibRadosListPP, ListObjectsEndIter) { @@ -124,27 +120,27 @@ TEST_F(LibRadosListPP, ListObjectsEndIter) { bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - ObjectIterator iter(ioctx.objects_begin()); - ObjectIterator iter_end(ioctx.objects_end()); - ObjectIterator iter_end2 = ioctx.objects_end(); + NObjectIterator iter(ioctx.nobjects_begin()); + NObjectIterator iter_end(ioctx.nobjects_end()); + NObjectIterator iter_end2 = ioctx.nobjects_end(); ASSERT_TRUE(iter_end == iter_end2); - ASSERT_TRUE(iter_end == ioctx.objects_end()); - ASSERT_TRUE(iter_end2 == ioctx.objects_end()); + ASSERT_TRUE(iter_end == ioctx.nobjects_end()); + ASSERT_TRUE(iter_end2 == ioctx.nobjects_end()); - ASSERT_EQ(iter->first, "foo"); + ASSERT_EQ(iter->get_oid(), "foo"); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); ASSERT_TRUE(iter == iter_end); ASSERT_TRUE(iter == iter_end2); - ObjectIterator iter2 = iter; - ASSERT_TRUE(iter2 == ioctx.objects_end()); + NObjectIterator iter2 = iter; + ASSERT_TRUE(iter2 == ioctx.nobjects_end()); ASSERT_TRUE(iter2 == iter_end); ASSERT_TRUE(iter2 == iter_end2); } -static void check_list(std::set& myset, rados_list_ctx_t& ctx) +static void check_list(std::set& myset, rados_list_ctx_t& ctx, std::string check_nspace) { - const char *entry; + const char *entry, *nspace; std::set orig_set(myset); /** * During splitting, we might see duplicate items. @@ -152,16 +148,23 @@ static void check_list(std::set& myset, rados_list_ctx_t& ctx) * we don't hit ENOENT until we have hit every item in myset * at least once. */ - while (rados_objects_list_next(ctx, &entry, NULL) != -ENOENT) { - ASSERT_TRUE(orig_set.end() != orig_set.find(std::string(entry))); - myset.erase(std::string(entry)); + int ret; + while ((ret = rados_nobjects_list_next(ctx, &entry, NULL, &nspace)) == 0) { + std::string test_name; + if (check_nspace == all_nspaces) { + test_name = std::string(nspace) + ":" + std::string(entry); + } else { + ASSERT_TRUE(std::string(nspace) == check_nspace); + test_name = std::string(entry); + } + + ASSERT_TRUE(orig_set.end() != orig_set.find(test_name)); + myset.erase(test_name); } + ASSERT_EQ(-ENOENT, ret); ASSERT_TRUE(myset.empty()); } -#pragma GCC diagnostic pop -#pragma GCC diagnostic warning "-Wpragmas" - TEST_F(LibRadosList, ListObjectsNS) { char buf[128]; memset(buf, 0xcc, sizeof(buf)); @@ -180,7 +183,7 @@ TEST_F(LibRadosList, ListObjectsNS) { ASSERT_EQ(0, rados_write(ioctx, "foo6", buf, sizeof(buf), 0)); ASSERT_EQ(0, rados_write(ioctx, "foo7", buf, sizeof(buf), 0)); - std::set def, ns1, ns2; + std::set def, ns1, ns2, all; def.insert(std::string("foo1")); def.insert(std::string("foo2")); def.insert(std::string("foo3")); @@ -189,38 +192,44 @@ TEST_F(LibRadosList, ListObjectsNS) { ns1.insert(std::string("foo5")); ns2.insert(std::string("foo6")); ns2.insert(std::string("foo7")); + all.insert(std::string(":foo1")); + all.insert(std::string(":foo2")); + all.insert(std::string(":foo3")); + all.insert(std::string("ns1:foo1")); + all.insert(std::string("ns1:foo4")); + all.insert(std::string("ns1:foo5")); + all.insert(std::string("ns2:foo6")); + all.insert(std::string("ns2:foo7")); rados_list_ctx_t ctx; // Check default namespace "" rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - check_list(def, ctx); - rados_objects_list_close(ctx); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(def, ctx, ""); + rados_nobjects_list_close(ctx); - // Check default namespace "ns1" + // Check namespace "ns1" rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - check_list(ns1, ctx); - rados_objects_list_close(ctx); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(ns1, ctx, "ns1"); + rados_nobjects_list_close(ctx); - // Check default namespace "ns2" + // Check namespace "ns2" rados_ioctx_set_namespace(ioctx, "ns2"); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - check_list(ns2, ctx); - rados_objects_list_close(ctx); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(ns2, ctx, "ns2"); + rados_nobjects_list_close(ctx); - // Can't specify all namespaces using old interface + // Check ALL namespaces rados_ioctx_set_namespace(ioctx, LIBRADOS_ALL_NSPACES); - ASSERT_EQ(-EINVAL, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(all, ctx, all_nspaces); + rados_nobjects_list_close(ctx); } -#pragma GCC diagnostic ignored "-Wpragmas" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -static void check_listpp(std::set& myset, IoCtx& ioctx) +static void check_listpp(std::set& myset, IoCtx& ioctx, std::string check_nspace) { - ObjectIterator iter(ioctx.objects_begin()); + NObjectIterator iter(ioctx.nobjects_begin()); std::set orig_set(myset); /** * During splitting, we might see duplicate items. @@ -228,9 +237,16 @@ static void check_listpp(std::set& myset, IoCtx& ioctx) * we don't hit ENOENT until we have hit every item in myset * at least once. */ - while (iter != ioctx.objects_end()) { - ASSERT_TRUE(orig_set.end() != orig_set.find(std::string((*iter).first))); - myset.erase(std::string((*iter).first)); + while (iter != ioctx.nobjects_end()) { + std::string test_name; + if (check_nspace == all_nspaces) { + test_name = iter->get_nspace() + ":" + iter->get_oid(); + } else { + ASSERT_TRUE(iter->get_nspace() == check_nspace); + test_name = iter->get_oid(); + } + ASSERT_TRUE(orig_set.end() != orig_set.find(test_name)); + myset.erase(test_name); ++iter; } ASSERT_TRUE(myset.empty()); @@ -256,7 +272,7 @@ TEST_F(LibRadosListPP, ListObjectsPPNS) { ASSERT_EQ(0, ioctx.write("foo6", bl1, sizeof(buf), 0)); ASSERT_EQ(0, ioctx.write("foo7", bl1, sizeof(buf), 0)); - std::set def, ns1, ns2; + std::set def, ns1, ns2, all; def.insert(std::string("foo1")); def.insert(std::string("foo2")); def.insert(std::string("foo3")); @@ -265,18 +281,26 @@ TEST_F(LibRadosListPP, ListObjectsPPNS) { ns1.insert(std::string("foo5")); ns2.insert(std::string("foo6")); ns2.insert(std::string("foo7")); + all.insert(std::string(":foo1")); + all.insert(std::string(":foo2")); + all.insert(std::string(":foo3")); + all.insert(std::string("ns1:foo1")); + all.insert(std::string("ns1:foo4")); + all.insert(std::string("ns1:foo5")); + all.insert(std::string("ns2:foo6")); + all.insert(std::string("ns2:foo7")); ioctx.set_namespace(""); - check_listpp(def, ioctx); + check_listpp(def, ioctx, ""); ioctx.set_namespace("ns1"); - check_listpp(ns1, ioctx); + check_listpp(ns1, ioctx, "ns1"); ioctx.set_namespace("ns2"); - check_listpp(ns2, ioctx); + check_listpp(ns2, ioctx, "ns2"); ioctx.set_namespace(all_nspaces); - EXPECT_THROW(check_listpp(def, ioctx), std::runtime_error); + check_listpp(all, ioctx, all_nspaces); } TEST_F(LibRadosListPP, ListObjectsManyPP) { @@ -289,13 +313,13 @@ TEST_F(LibRadosListPP, ListObjectsManyPP) { ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); } - librados::ObjectIterator it = ioctx.objects_begin(); + librados::NObjectIterator it = ioctx.nobjects_begin(); std::set saw_obj; std::set saw_pg; - for (; it != ioctx.objects_end(); ++it) { - std::cout << it->first + for (; it != ioctx.nobjects_end(); ++it) { + std::cout << it->get_oid() << " " << it.get_pg_hash_position() << std::endl; - saw_obj.insert(it->first); + saw_obj.insert(it->get_oid()); saw_pg.insert(it.get_pg_hash_position()); } std::cout << "saw " << saw_pg.size() << " pgs " << std::endl; @@ -315,27 +339,27 @@ TEST_F(LibRadosList, ListObjectsStart) { } rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); std::map > pg_to_obj; const char *entry; - while (rados_objects_list_next(ctx, &entry, NULL) == 0) { - uint32_t pos = rados_objects_list_get_pg_hash_position(ctx); + while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) == 0) { + uint32_t pos = rados_nobjects_list_get_pg_hash_position(ctx); std::cout << entry << " " << pos << std::endl; pg_to_obj[pos].insert(entry); } - rados_objects_list_close(ctx); + rados_nobjects_list_close(ctx); std::map >::reverse_iterator p = pg_to_obj.rbegin(); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); while (p != pg_to_obj.rend()) { - ASSERT_EQ((uint32_t)p->first, rados_objects_list_seek(ctx, p->first)); - ASSERT_EQ(0, rados_objects_list_next(ctx, &entry, NULL)); + ASSERT_EQ((uint32_t)p->first, rados_nobjects_list_seek(ctx, p->first)); + ASSERT_EQ(0, rados_nobjects_list_next(ctx, &entry, NULL, NULL)); std::cout << "have " << entry << " expect one of " << p->second << std::endl; ASSERT_TRUE(p->second.count(entry)); ++p; } - rados_objects_list_close(ctx); + rados_nobjects_list_close(ctx); } TEST_F(LibRadosListPP, ListObjectsStartPP) { @@ -348,20 +372,20 @@ TEST_F(LibRadosListPP, ListObjectsStartPP) { ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); } - librados::ObjectIterator it = ioctx.objects_begin(); + librados::NObjectIterator it = ioctx.nobjects_begin(); std::map > pg_to_obj; - for (; it != ioctx.objects_end(); ++it) { - std::cout << it->first << " " << it.get_pg_hash_position() << std::endl; - pg_to_obj[it.get_pg_hash_position()].insert(it->first); + for (; it != ioctx.nobjects_end(); ++it) { + std::cout << it->get_oid() << " " << it.get_pg_hash_position() << std::endl; + pg_to_obj[it.get_pg_hash_position()].insert(it->get_oid()); } std::map >::reverse_iterator p = pg_to_obj.rbegin(); - it = ioctx.objects_begin(p->first); + it = ioctx.nobjects_begin(p->first); while (p != pg_to_obj.rend()) { ASSERT_EQ((uint32_t)p->first, it.seek(p->first)); - std::cout << "have " << it->first << " expect one of " << p->second << std::endl; - ASSERT_TRUE(p->second.count(it->first)); + std::cout << "have " << it->get_oid() << " expect one of " << p->second << std::endl; + ASSERT_TRUE(p->second.count(it->get_oid())); ++p; } } @@ -371,15 +395,15 @@ TEST_F(LibRadosListEC, ListObjects) { memset(buf, 0xcc, sizeof(buf)); ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); const char *entry; bool foundit = false; - while (rados_objects_list_next(ctx, &entry, NULL) != -ENOENT) { + while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) != -ENOENT) { foundit = true; ASSERT_EQ(std::string(entry), "foo"); } ASSERT_TRUE(foundit); - rados_objects_list_close(ctx); + rados_nobjects_list_close(ctx); } TEST_F(LibRadosListECPP, ListObjectsPP) { @@ -388,11 +412,11 @@ TEST_F(LibRadosListECPP, ListObjectsPP) { bufferlist bl1; bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - ObjectIterator iter(ioctx.objects_begin()); + NObjectIterator iter(ioctx.nobjects_begin()); bool foundit = false; - while (iter != ioctx.objects_end()) { + while (iter != ioctx.nobjects_end()) { foundit = true; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; } ASSERT_TRUE(foundit); @@ -404,21 +428,21 @@ TEST_F(LibRadosListECPP, ListObjectsTwicePP) { bufferlist bl1; bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - ObjectIterator iter(ioctx.objects_begin()); + NObjectIterator iter(ioctx.nobjects_begin()); bool foundit = false; - while (iter != ioctx.objects_end()) { + while (iter != ioctx.nobjects_end()) { foundit = true; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; } ASSERT_TRUE(foundit); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); foundit = false; iter.seek(0); - while (iter != ioctx.objects_end()) { + while (iter != ioctx.nobjects_end()) { foundit = true; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; } ASSERT_TRUE(foundit); @@ -432,28 +456,28 @@ TEST_F(LibRadosListECPP, ListObjectsCopyIterPP) { ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); // make sure this is still valid after the original iterators are gone - ObjectIterator iter3; + NObjectIterator iter3; { - ObjectIterator iter(ioctx.objects_begin()); - ObjectIterator iter2(iter); + NObjectIterator iter(ioctx.nobjects_begin()); + NObjectIterator iter2(iter); iter3 = iter2; - ASSERT_EQ((*iter).first, "foo"); + ASSERT_EQ((*iter).get_oid(), "foo"); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); - ASSERT_EQ(iter2->first, "foo"); - ASSERT_EQ(iter3->first, "foo"); + ASSERT_EQ(iter2->get_oid(), "foo"); + ASSERT_EQ(iter3->get_oid(), "foo"); ++iter2; - ASSERT_TRUE(iter2 == ioctx.objects_end()); + ASSERT_TRUE(iter2 == ioctx.nobjects_end()); } - ASSERT_EQ(iter3->first, "foo"); + ASSERT_EQ(iter3->get_oid(), "foo"); iter3 = iter3; - ASSERT_EQ(iter3->first, "foo"); + ASSERT_EQ(iter3->get_oid(), "foo"); ++iter3; - ASSERT_TRUE(iter3 == ioctx.objects_end()); + ASSERT_TRUE(iter3 == ioctx.nobjects_end()); } TEST_F(LibRadosListECPP, ListObjectsEndIter) { @@ -463,27 +487,24 @@ TEST_F(LibRadosListECPP, ListObjectsEndIter) { bl1.append(buf, sizeof(buf)); ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - ObjectIterator iter(ioctx.objects_begin()); - ObjectIterator iter_end(ioctx.objects_end()); - ObjectIterator iter_end2 = ioctx.objects_end(); + NObjectIterator iter(ioctx.nobjects_begin()); + NObjectIterator iter_end(ioctx.nobjects_end()); + NObjectIterator iter_end2 = ioctx.nobjects_end(); ASSERT_TRUE(iter_end == iter_end2); - ASSERT_TRUE(iter_end == ioctx.objects_end()); - ASSERT_TRUE(iter_end2 == ioctx.objects_end()); + ASSERT_TRUE(iter_end == ioctx.nobjects_end()); + ASSERT_TRUE(iter_end2 == ioctx.nobjects_end()); - ASSERT_EQ(iter->first, "foo"); + ASSERT_EQ(iter->get_oid(), "foo"); ++iter; - ASSERT_TRUE(iter == ioctx.objects_end()); + ASSERT_TRUE(iter == ioctx.nobjects_end()); ASSERT_TRUE(iter == iter_end); ASSERT_TRUE(iter == iter_end2); - ObjectIterator iter2 = iter; - ASSERT_TRUE(iter2 == ioctx.objects_end()); + NObjectIterator iter2 = iter; + ASSERT_TRUE(iter2 == ioctx.nobjects_end()); ASSERT_TRUE(iter2 == iter_end); ASSERT_TRUE(iter2 == iter_end2); } -#pragma GCC diagnostic pop -#pragma GCC diagnostic warning "-Wpragmas" - TEST_F(LibRadosListEC, ListObjectsNS) { char buf[128]; memset(buf, 0xcc, sizeof(buf)); @@ -502,7 +523,7 @@ TEST_F(LibRadosListEC, ListObjectsNS) { ASSERT_EQ(0, rados_write(ioctx, "foo6", buf, sizeof(buf), 0)); ASSERT_EQ(0, rados_write(ioctx, "foo7", buf, sizeof(buf), 0)); - std::set def, ns1, ns2; + std::set def, ns1, ns2, all; def.insert(std::string("foo1")); def.insert(std::string("foo2")); def.insert(std::string("foo3")); @@ -511,29 +532,39 @@ TEST_F(LibRadosListEC, ListObjectsNS) { ns1.insert(std::string("foo5")); ns2.insert(std::string("foo6")); ns2.insert(std::string("foo7")); + all.insert(std::string(":foo1")); + all.insert(std::string(":foo2")); + all.insert(std::string(":foo3")); + all.insert(std::string("ns1:foo1")); + all.insert(std::string("ns1:foo4")); + all.insert(std::string("ns1:foo5")); + all.insert(std::string("ns2:foo6")); + all.insert(std::string("ns2:foo7")); rados_list_ctx_t ctx; // Check default namespace "" rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - check_list(def, ctx); - rados_objects_list_close(ctx); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(def, ctx, ""); + rados_nobjects_list_close(ctx); // Check default namespace "ns1" rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - check_list(ns1, ctx); - rados_objects_list_close(ctx); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(ns1, ctx, "ns1"); + rados_nobjects_list_close(ctx); // Check default namespace "ns2" rados_ioctx_set_namespace(ioctx, "ns2"); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - check_list(ns2, ctx); - rados_objects_list_close(ctx); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(ns2, ctx, "ns2"); + rados_nobjects_list_close(ctx); - // Can't specify all namespaces using old interface + // Check all namespaces rados_ioctx_set_namespace(ioctx, LIBRADOS_ALL_NSPACES); - ASSERT_EQ(-EINVAL, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + check_list(all, ctx, all_nspaces); + rados_nobjects_list_close(ctx); } TEST_F(LibRadosListECPP, ListObjectsPPNS) { @@ -567,22 +598,15 @@ TEST_F(LibRadosListECPP, ListObjectsPPNS) { ns2.insert(std::string("foo7")); ioctx.set_namespace(""); - check_listpp(def, ioctx); + check_listpp(def, ioctx, ""); ioctx.set_namespace("ns1"); - check_listpp(ns1, ioctx); + check_listpp(ns1, ioctx, "ns1"); ioctx.set_namespace("ns2"); - check_listpp(ns2, ioctx); - - ioctx.set_namespace(all_nspaces); - EXPECT_THROW(check_listpp(def, ioctx), std::runtime_error); + check_listpp(ns2, ioctx, "ns2"); } -#pragma GCC diagnostic ignored "-Wpragmas" -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - TEST_F(LibRadosListECPP, ListObjectsManyPP) { char buf[128]; memset(buf, 0xcc, sizeof(buf)); @@ -593,13 +617,13 @@ TEST_F(LibRadosListECPP, ListObjectsManyPP) { ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); } - librados::ObjectIterator it = ioctx.objects_begin(); + librados::NObjectIterator it = ioctx.nobjects_begin(); std::set saw_obj; std::set saw_pg; - for (; it != ioctx.objects_end(); ++it) { - std::cout << it->first + for (; it != ioctx.nobjects_end(); ++it) { + std::cout << it->get_oid() << " " << it.get_pg_hash_position() << std::endl; - saw_obj.insert(it->first); + saw_obj.insert(it->get_oid()); saw_pg.insert(it.get_pg_hash_position()); } std::cout << "saw " << saw_pg.size() << " pgs " << std::endl; @@ -619,27 +643,27 @@ TEST_F(LibRadosListEC, ListObjectsStart) { } rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); std::map > pg_to_obj; const char *entry; - while (rados_objects_list_next(ctx, &entry, NULL) == 0) { - uint32_t pos = rados_objects_list_get_pg_hash_position(ctx); + while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) == 0) { + uint32_t pos = rados_nobjects_list_get_pg_hash_position(ctx); std::cout << entry << " " << pos << std::endl; pg_to_obj[pos].insert(entry); } - rados_objects_list_close(ctx); + rados_nobjects_list_close(ctx); std::map >::reverse_iterator p = pg_to_obj.rbegin(); - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); while (p != pg_to_obj.rend()) { - ASSERT_EQ((uint32_t)p->first, rados_objects_list_seek(ctx, p->first)); - ASSERT_EQ(0, rados_objects_list_next(ctx, &entry, NULL)); + ASSERT_EQ((uint32_t)p->first, rados_nobjects_list_seek(ctx, p->first)); + ASSERT_EQ(0, rados_nobjects_list_next(ctx, &entry, NULL, NULL)); std::cout << "have " << entry << " expect one of " << p->second << std::endl; ASSERT_TRUE(p->second.count(entry)); ++p; } - rados_objects_list_close(ctx); + rados_nobjects_list_close(ctx); } TEST_F(LibRadosListECPP, ListObjectsStartPP) { @@ -652,24 +676,91 @@ TEST_F(LibRadosListECPP, ListObjectsStartPP) { ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); } - librados::ObjectIterator it = ioctx.objects_begin(); + librados::NObjectIterator it = ioctx.nobjects_begin(); std::map > pg_to_obj; - for (; it != ioctx.objects_end(); ++it) { - std::cout << it->first << " " << it.get_pg_hash_position() << std::endl; - pg_to_obj[it.get_pg_hash_position()].insert(it->first); + for (; it != ioctx.nobjects_end(); ++it) { + std::cout << it->get_oid() << " " << it.get_pg_hash_position() << std::endl; + pg_to_obj[it.get_pg_hash_position()].insert(it->get_oid()); } std::map >::reverse_iterator p = pg_to_obj.rbegin(); - it = ioctx.objects_begin(p->first); + it = ioctx.nobjects_begin(p->first); while (p != pg_to_obj.rend()) { ASSERT_EQ((uint32_t)p->first, it.seek(p->first)); - std::cout << "have " << it->first << " expect one of " << p->second << std::endl; - ASSERT_TRUE(p->second.count(it->first)); + std::cout << "have " << it->get_oid() << " expect one of " << p->second << std::endl; + ASSERT_TRUE(p->second.count(it->get_oid())); ++p; } } +TEST_F(LibRadosListPP, ListObjectsFilterPP) { + char buf[128]; + memset(buf, 0xcc, sizeof(buf)); + bufferlist obj_content; + obj_content.append(buf, sizeof(buf)); + + std::string target_str = "content"; + + // Write xattr bare, no ::encod'ing + bufferlist target_val; + target_val.append(target_str); + bufferlist nontarget_val; + nontarget_val.append("rhubarb"); + + ASSERT_EQ(0, ioctx.write("has_xattr", obj_content, obj_content.length(), 0)); + ASSERT_EQ(0, ioctx.write("has_wrong_xattr", obj_content, obj_content.length(), 0)); + ASSERT_EQ(0, ioctx.write("no_xattr", obj_content, obj_content.length(), 0)); + + ASSERT_EQ(0, ioctx.setxattr("has_xattr", "theattr", target_val)); + ASSERT_EQ(0, ioctx.setxattr("has_wrong_xattr", "theattr", nontarget_val)); + + bufferlist filter_bl; + std::string filter_name = "plain"; + ::encode(filter_name, filter_bl); + ::encode("_theattr", filter_bl); + ::encode(target_str, filter_bl); + + NObjectIterator iter(ioctx.nobjects_begin(filter_bl)); + bool foundit = false; + int k = 0; + while (iter != ioctx.nobjects_end()) { + foundit = true; + // We should only see the object that matches the filter + ASSERT_EQ((*iter).get_oid(), "has_xattr"); + // We should only see it once + ASSERT_EQ(k, 0); + ++iter; + ++k; + } + ASSERT_TRUE(foundit); +} + +TEST_F(LibRadosListNP, ListObjectsError) { + std::string pool_name; + rados_t cluster; + rados_ioctx_t ioctx; + pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + ASSERT_EQ(0, rados_ioctx_create(cluster, pool_name.c_str(), &ioctx)); + char buf[128]; + memset(buf, 0xcc, sizeof(buf)); + rados_ioctx_set_namespace(ioctx, ""); + ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); + ASSERT_EQ(0, rados_pool_delete(cluster, pool_name.c_str())); + + rados_list_ctx_t ctx; + ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); + const char *entry; + ASSERT_EQ(-ENOENT, rados_nobjects_list_next(ctx, &entry, NULL, NULL)); + rados_nobjects_list_close(ctx); + rados_ioctx_destroy(ioctx); + rados_shutdown(cluster); +} + + + +// --------------------------------------------- TEST_F(LibRadosList, EnumerateObjects) { char buf[128]; @@ -886,27 +977,6 @@ TEST_F(LibRadosListPP, EnumerateObjectsSplitPP) { ASSERT_EQ(n_objects, saw_obj.size()); } -TEST_F(LibRadosListNP, ListObjectsError) { - std::string pool_name; - rados_t cluster; - rados_ioctx_t ioctx; - pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool(pool_name, &cluster)); - ASSERT_EQ(0, rados_ioctx_create(cluster, pool_name.c_str(), &ioctx)); - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_pool_delete(cluster, pool_name.c_str())); - - rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_objects_list_open(ioctx, &ctx)); - const char *entry; - ASSERT_EQ(-ENOENT, rados_objects_list_next(ctx, &entry, NULL)); - rados_objects_list_close(ctx); - rados_ioctx_destroy(ioctx); - rados_shutdown(cluster); -} TEST_F(LibRadosListPP, EnumerateObjectsFilterPP) { char buf[128]; diff --git a/src/test/librados/nlist.cc b/src/test/librados/nlist.cc deleted file mode 100644 index c6fa82db7651..000000000000 --- a/src/test/librados/nlist.cc +++ /dev/null @@ -1,755 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -#include "include/rados/librados.h" -#include "include/rados/librados.hpp" -#include "include/stringify.h" -#include "test/librados/test.h" -#include "test/librados/TestCase.h" - -#include "include/types.h" -#include "gtest/gtest.h" -#include -#include - -using namespace librados; - -typedef RadosTestNS LibRadosList; -typedef RadosTestPPNS LibRadosListPP; -typedef RadosTestECNS LibRadosListEC; -typedef RadosTestECPPNS LibRadosListECPP; -typedef RadosTestNP LibRadosListNP; - -TEST_F(LibRadosList, ListObjects) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); - rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - const char *entry; - bool foundit = false; - while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) != -ENOENT) { - foundit = true; - ASSERT_EQ(std::string(entry), "foo"); - } - ASSERT_TRUE(foundit); - rados_nobjects_list_close(ctx); -} - -TEST_F(LibRadosListPP, ListObjectsPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - NObjectIterator iter(ioctx.nobjects_begin()); - bool foundit = false; - while (iter != ioctx.nobjects_end()) { - foundit = true; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - } - ASSERT_TRUE(foundit); -} - -TEST_F(LibRadosListPP, ListObjectsTwicePP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - NObjectIterator iter(ioctx.nobjects_begin()); - bool foundit = false; - while (iter != ioctx.nobjects_end()) { - foundit = true; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - } - ASSERT_TRUE(foundit); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - foundit = false; - iter.seek(0); - while (iter != ioctx.nobjects_end()) { - foundit = true; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - } - ASSERT_TRUE(foundit); -} - -TEST_F(LibRadosListPP, ListObjectsCopyIterPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - - // make sure this is still valid after the original iterators are gone - NObjectIterator iter3; - { - NObjectIterator iter(ioctx.nobjects_begin()); - NObjectIterator iter2(iter); - iter3 = iter2; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - - ASSERT_EQ(iter2->get_oid(), "foo"); - ASSERT_EQ(iter3->get_oid(), "foo"); - ++iter2; - ASSERT_TRUE(iter2 == ioctx.nobjects_end()); - } - - ASSERT_EQ(iter3->get_oid(), "foo"); - iter3 = iter3; - ASSERT_EQ(iter3->get_oid(), "foo"); - ++iter3; - ASSERT_TRUE(iter3 == ioctx.nobjects_end()); -} - -TEST_F(LibRadosListPP, ListObjectsEndIter) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - - NObjectIterator iter(ioctx.nobjects_begin()); - NObjectIterator iter_end(ioctx.nobjects_end()); - NObjectIterator iter_end2 = ioctx.nobjects_end(); - ASSERT_TRUE(iter_end == iter_end2); - ASSERT_TRUE(iter_end == ioctx.nobjects_end()); - ASSERT_TRUE(iter_end2 == ioctx.nobjects_end()); - - ASSERT_EQ(iter->get_oid(), "foo"); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - ASSERT_TRUE(iter == iter_end); - ASSERT_TRUE(iter == iter_end2); - NObjectIterator iter2 = iter; - ASSERT_TRUE(iter2 == ioctx.nobjects_end()); - ASSERT_TRUE(iter2 == iter_end); - ASSERT_TRUE(iter2 == iter_end2); -} - -static void check_list(std::set& myset, rados_list_ctx_t& ctx, std::string check_nspace) -{ - const char *entry, *nspace; - std::set orig_set(myset); - /** - * During splitting, we might see duplicate items. - * We assert that every object returned is in myset and that - * we don't hit ENOENT until we have hit every item in myset - * at least once. - */ - int ret; - while ((ret = rados_nobjects_list_next(ctx, &entry, NULL, &nspace)) == 0) { - std::string test_name; - if (check_nspace == all_nspaces) { - test_name = std::string(nspace) + ":" + std::string(entry); - } else { - ASSERT_TRUE(std::string(nspace) == check_nspace); - test_name = std::string(entry); - } - - ASSERT_TRUE(orig_set.end() != orig_set.find(test_name)); - myset.erase(test_name); - } - ASSERT_EQ(-ENOENT, ret); - ASSERT_TRUE(myset.empty()); -} - -TEST_F(LibRadosList, ListObjectsNS) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - // Create :foo1, :foo2, :foo3, n1:foo1, ns1:foo4, ns1:foo5, ns2:foo6, n2:foo7 - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_write(ioctx, "foo1", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_write(ioctx, "foo1", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_write(ioctx, "foo2", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_write(ioctx, "foo3", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_write(ioctx, "foo4", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_write(ioctx, "foo5", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, "ns2"); - ASSERT_EQ(0, rados_write(ioctx, "foo6", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_write(ioctx, "foo7", buf, sizeof(buf), 0)); - - std::set def, ns1, ns2, all; - def.insert(std::string("foo1")); - def.insert(std::string("foo2")); - def.insert(std::string("foo3")); - ns1.insert(std::string("foo1")); - ns1.insert(std::string("foo4")); - ns1.insert(std::string("foo5")); - ns2.insert(std::string("foo6")); - ns2.insert(std::string("foo7")); - all.insert(std::string(":foo1")); - all.insert(std::string(":foo2")); - all.insert(std::string(":foo3")); - all.insert(std::string("ns1:foo1")); - all.insert(std::string("ns1:foo4")); - all.insert(std::string("ns1:foo5")); - all.insert(std::string("ns2:foo6")); - all.insert(std::string("ns2:foo7")); - - rados_list_ctx_t ctx; - // Check default namespace "" - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(def, ctx, ""); - rados_nobjects_list_close(ctx); - - // Check namespace "ns1" - rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(ns1, ctx, "ns1"); - rados_nobjects_list_close(ctx); - - // Check namespace "ns2" - rados_ioctx_set_namespace(ioctx, "ns2"); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(ns2, ctx, "ns2"); - rados_nobjects_list_close(ctx); - - // Check ALL namespaces - rados_ioctx_set_namespace(ioctx, LIBRADOS_ALL_NSPACES); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(all, ctx, all_nspaces); - rados_nobjects_list_close(ctx); -} - -static void check_listpp(std::set& myset, IoCtx& ioctx, std::string check_nspace) -{ - NObjectIterator iter(ioctx.nobjects_begin()); - std::set orig_set(myset); - /** - * During splitting, we might see duplicate items. - * We assert that every object returned is in myset and that - * we don't hit ENOENT until we have hit every item in myset - * at least once. - */ - while (iter != ioctx.nobjects_end()) { - std::string test_name; - if (check_nspace == all_nspaces) { - test_name = iter->get_nspace() + ":" + iter->get_oid(); - } else { - ASSERT_TRUE(iter->get_nspace() == check_nspace); - test_name = iter->get_oid(); - } - ASSERT_TRUE(orig_set.end() != orig_set.find(test_name)); - myset.erase(test_name); - ++iter; - } - ASSERT_TRUE(myset.empty()); -} - -TEST_F(LibRadosListPP, ListObjectsPPNS) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - // Create :foo1, :foo2, :foo3, n1:foo1, ns1:foo4, ns1:foo5, ns2:foo6, n2:foo7 - ioctx.set_namespace(""); - ASSERT_EQ(0, ioctx.write("foo1", bl1, sizeof(buf), 0)); - ioctx.set_namespace("ns1"); - ASSERT_EQ(0, ioctx.write("foo1", bl1, sizeof(buf), 0)); - ioctx.set_namespace(""); - ASSERT_EQ(0, ioctx.write("foo2", bl1, sizeof(buf), 0)); - ASSERT_EQ(0, ioctx.write("foo3", bl1, sizeof(buf), 0)); - ioctx.set_namespace("ns1"); - ASSERT_EQ(0, ioctx.write("foo4", bl1, sizeof(buf), 0)); - ASSERT_EQ(0, ioctx.write("foo5", bl1, sizeof(buf), 0)); - ioctx.set_namespace("ns2"); - ASSERT_EQ(0, ioctx.write("foo6", bl1, sizeof(buf), 0)); - ASSERT_EQ(0, ioctx.write("foo7", bl1, sizeof(buf), 0)); - - std::set def, ns1, ns2, all; - def.insert(std::string("foo1")); - def.insert(std::string("foo2")); - def.insert(std::string("foo3")); - ns1.insert(std::string("foo1")); - ns1.insert(std::string("foo4")); - ns1.insert(std::string("foo5")); - ns2.insert(std::string("foo6")); - ns2.insert(std::string("foo7")); - all.insert(std::string(":foo1")); - all.insert(std::string(":foo2")); - all.insert(std::string(":foo3")); - all.insert(std::string("ns1:foo1")); - all.insert(std::string("ns1:foo4")); - all.insert(std::string("ns1:foo5")); - all.insert(std::string("ns2:foo6")); - all.insert(std::string("ns2:foo7")); - - ioctx.set_namespace(""); - check_listpp(def, ioctx, ""); - - ioctx.set_namespace("ns1"); - check_listpp(ns1, ioctx, "ns1"); - - ioctx.set_namespace("ns2"); - check_listpp(ns2, ioctx, "ns2"); - - ioctx.set_namespace(all_nspaces); - check_listpp(all, ioctx, all_nspaces); -} - -TEST_F(LibRadosListPP, ListObjectsManyPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl; - bl.append(buf, sizeof(buf)); - - for (int i=0; i<256; ++i) { - ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); - } - - librados::NObjectIterator it = ioctx.nobjects_begin(); - std::set saw_obj; - std::set saw_pg; - for (; it != ioctx.nobjects_end(); ++it) { - std::cout << it->get_oid() - << " " << it.get_pg_hash_position() << std::endl; - saw_obj.insert(it->get_oid()); - saw_pg.insert(it.get_pg_hash_position()); - } - std::cout << "saw " << saw_pg.size() << " pgs " << std::endl; - - // make sure they are 0..n - for (unsigned i = 0; i < saw_pg.size(); ++i) - ASSERT_TRUE(saw_pg.count(i)); -} - -TEST_F(LibRadosList, ListObjectsStart) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - - for (int i=0; i<16; ++i) { - string n = stringify(i); - ASSERT_EQ(0, rados_write(ioctx, n.c_str(), buf, sizeof(buf), 0)); - } - - rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - std::map > pg_to_obj; - const char *entry; - while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) == 0) { - uint32_t pos = rados_objects_list_get_pg_hash_position(ctx); - std::cout << entry << " " << pos << std::endl; - pg_to_obj[pos].insert(entry); - } - rados_nobjects_list_close(ctx); - - std::map >::reverse_iterator p = - pg_to_obj.rbegin(); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - while (p != pg_to_obj.rend()) { - ASSERT_EQ((uint32_t)p->first, rados_objects_list_seek(ctx, p->first)); - ASSERT_EQ(0, rados_nobjects_list_next(ctx, &entry, NULL, NULL)); - std::cout << "have " << entry << " expect one of " << p->second << std::endl; - ASSERT_TRUE(p->second.count(entry)); - ++p; - } - rados_nobjects_list_close(ctx); -} - -TEST_F(LibRadosListPP, ListObjectsStartPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl; - bl.append(buf, sizeof(buf)); - - for (int i=0; i<16; ++i) { - ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); - } - - librados::NObjectIterator it = ioctx.nobjects_begin(); - std::map > pg_to_obj; - for (; it != ioctx.nobjects_end(); ++it) { - std::cout << it->get_oid() << " " << it.get_pg_hash_position() << std::endl; - pg_to_obj[it.get_pg_hash_position()].insert(it->get_oid()); - } - - std::map >::reverse_iterator p = - pg_to_obj.rbegin(); - it = ioctx.nobjects_begin(p->first); - while (p != pg_to_obj.rend()) { - ASSERT_EQ((uint32_t)p->first, it.seek(p->first)); - std::cout << "have " << it->get_oid() << " expect one of " << p->second << std::endl; - ASSERT_TRUE(p->second.count(it->get_oid())); - ++p; - } -} - -TEST_F(LibRadosListEC, ListObjects) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); - rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - const char *entry; - bool foundit = false; - while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) != -ENOENT) { - foundit = true; - ASSERT_EQ(std::string(entry), "foo"); - } - ASSERT_TRUE(foundit); - rados_nobjects_list_close(ctx); -} - -TEST_F(LibRadosListECPP, ListObjectsPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - NObjectIterator iter(ioctx.nobjects_begin()); - bool foundit = false; - while (iter != ioctx.nobjects_end()) { - foundit = true; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - } - ASSERT_TRUE(foundit); -} - -TEST_F(LibRadosListECPP, ListObjectsTwicePP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - NObjectIterator iter(ioctx.nobjects_begin()); - bool foundit = false; - while (iter != ioctx.nobjects_end()) { - foundit = true; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - } - ASSERT_TRUE(foundit); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - foundit = false; - iter.seek(0); - while (iter != ioctx.nobjects_end()) { - foundit = true; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - } - ASSERT_TRUE(foundit); -} - -TEST_F(LibRadosListECPP, ListObjectsCopyIterPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - - // make sure this is still valid after the original iterators are gone - NObjectIterator iter3; - { - NObjectIterator iter(ioctx.nobjects_begin()); - NObjectIterator iter2(iter); - iter3 = iter2; - ASSERT_EQ((*iter).get_oid(), "foo"); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - - ASSERT_EQ(iter2->get_oid(), "foo"); - ASSERT_EQ(iter3->get_oid(), "foo"); - ++iter2; - ASSERT_TRUE(iter2 == ioctx.nobjects_end()); - } - - ASSERT_EQ(iter3->get_oid(), "foo"); - iter3 = iter3; - ASSERT_EQ(iter3->get_oid(), "foo"); - ++iter3; - ASSERT_TRUE(iter3 == ioctx.nobjects_end()); -} - -TEST_F(LibRadosListECPP, ListObjectsEndIter) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - ASSERT_EQ(0, ioctx.write("foo", bl1, sizeof(buf), 0)); - - NObjectIterator iter(ioctx.nobjects_begin()); - NObjectIterator iter_end(ioctx.nobjects_end()); - NObjectIterator iter_end2 = ioctx.nobjects_end(); - ASSERT_TRUE(iter_end == iter_end2); - ASSERT_TRUE(iter_end == ioctx.nobjects_end()); - ASSERT_TRUE(iter_end2 == ioctx.nobjects_end()); - - ASSERT_EQ(iter->get_oid(), "foo"); - ++iter; - ASSERT_TRUE(iter == ioctx.nobjects_end()); - ASSERT_TRUE(iter == iter_end); - ASSERT_TRUE(iter == iter_end2); - NObjectIterator iter2 = iter; - ASSERT_TRUE(iter2 == ioctx.nobjects_end()); - ASSERT_TRUE(iter2 == iter_end); - ASSERT_TRUE(iter2 == iter_end2); -} - -TEST_F(LibRadosListEC, ListObjectsNS) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - // Create :foo1, :foo2, :foo3, n1:foo1, ns1:foo4, ns1:foo5, ns2:foo6, n2:foo7 - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_write(ioctx, "foo1", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_write(ioctx, "foo1", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_write(ioctx, "foo2", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_write(ioctx, "foo3", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_write(ioctx, "foo4", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_write(ioctx, "foo5", buf, sizeof(buf), 0)); - rados_ioctx_set_namespace(ioctx, "ns2"); - ASSERT_EQ(0, rados_write(ioctx, "foo6", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_write(ioctx, "foo7", buf, sizeof(buf), 0)); - - std::set def, ns1, ns2, all; - def.insert(std::string("foo1")); - def.insert(std::string("foo2")); - def.insert(std::string("foo3")); - ns1.insert(std::string("foo1")); - ns1.insert(std::string("foo4")); - ns1.insert(std::string("foo5")); - ns2.insert(std::string("foo6")); - ns2.insert(std::string("foo7")); - all.insert(std::string(":foo1")); - all.insert(std::string(":foo2")); - all.insert(std::string(":foo3")); - all.insert(std::string("ns1:foo1")); - all.insert(std::string("ns1:foo4")); - all.insert(std::string("ns1:foo5")); - all.insert(std::string("ns2:foo6")); - all.insert(std::string("ns2:foo7")); - - rados_list_ctx_t ctx; - // Check default namespace "" - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(def, ctx, ""); - rados_nobjects_list_close(ctx); - - // Check default namespace "ns1" - rados_ioctx_set_namespace(ioctx, "ns1"); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(ns1, ctx, "ns1"); - rados_nobjects_list_close(ctx); - - // Check default namespace "ns2" - rados_ioctx_set_namespace(ioctx, "ns2"); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(ns2, ctx, "ns2"); - rados_nobjects_list_close(ctx); - - // Check all namespaces - rados_ioctx_set_namespace(ioctx, LIBRADOS_ALL_NSPACES); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - check_list(all, ctx, all_nspaces); - rados_nobjects_list_close(ctx); -} - -TEST_F(LibRadosListECPP, ListObjectsPPNS) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl1; - bl1.append(buf, sizeof(buf)); - // Create :foo1, :foo2, :foo3, n1:foo1, ns1:foo4, ns1:foo5, ns2:foo6, n2:foo7 - ioctx.set_namespace(""); - ASSERT_EQ(0, ioctx.write("foo1", bl1, sizeof(buf), 0)); - ioctx.set_namespace("ns1"); - ASSERT_EQ(0, ioctx.write("foo1", bl1, sizeof(buf), 0)); - ioctx.set_namespace(""); - ASSERT_EQ(0, ioctx.write("foo2", bl1, sizeof(buf), 0)); - ASSERT_EQ(0, ioctx.write("foo3", bl1, sizeof(buf), 0)); - ioctx.set_namespace("ns1"); - ASSERT_EQ(0, ioctx.write("foo4", bl1, sizeof(buf), 0)); - ASSERT_EQ(0, ioctx.write("foo5", bl1, sizeof(buf), 0)); - ioctx.set_namespace("ns2"); - ASSERT_EQ(0, ioctx.write("foo6", bl1, sizeof(buf), 0)); - ASSERT_EQ(0, ioctx.write("foo7", bl1, sizeof(buf), 0)); - - std::set def, ns1, ns2; - def.insert(std::string("foo1")); - def.insert(std::string("foo2")); - def.insert(std::string("foo3")); - ns1.insert(std::string("foo1")); - ns1.insert(std::string("foo4")); - ns1.insert(std::string("foo5")); - ns2.insert(std::string("foo6")); - ns2.insert(std::string("foo7")); - - ioctx.set_namespace(""); - check_listpp(def, ioctx, ""); - - ioctx.set_namespace("ns1"); - check_listpp(ns1, ioctx, "ns1"); - - ioctx.set_namespace("ns2"); - check_listpp(ns2, ioctx, "ns2"); -} - -TEST_F(LibRadosListECPP, ListObjectsManyPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl; - bl.append(buf, sizeof(buf)); - - for (int i=0; i<256; ++i) { - ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); - } - - librados::NObjectIterator it = ioctx.nobjects_begin(); - std::set saw_obj; - std::set saw_pg; - for (; it != ioctx.nobjects_end(); ++it) { - std::cout << it->get_oid() - << " " << it.get_pg_hash_position() << std::endl; - saw_obj.insert(it->get_oid()); - saw_pg.insert(it.get_pg_hash_position()); - } - std::cout << "saw " << saw_pg.size() << " pgs " << std::endl; - - // make sure they are 0..n - for (unsigned i = 0; i < saw_pg.size(); ++i) - ASSERT_TRUE(saw_pg.count(i)); -} - -TEST_F(LibRadosListEC, ListObjectsStart) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - - for (int i=0; i<16; ++i) { - string n = stringify(i); - ASSERT_EQ(0, rados_write(ioctx, n.c_str(), buf, sizeof(buf), 0)); - } - - rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - std::map > pg_to_obj; - const char *entry; - while (rados_nobjects_list_next(ctx, &entry, NULL, NULL) == 0) { - uint32_t pos = rados_objects_list_get_pg_hash_position(ctx); - std::cout << entry << " " << pos << std::endl; - pg_to_obj[pos].insert(entry); - } - rados_nobjects_list_close(ctx); - - std::map >::reverse_iterator p = - pg_to_obj.rbegin(); - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - while (p != pg_to_obj.rend()) { - ASSERT_EQ((uint32_t)p->first, rados_objects_list_seek(ctx, p->first)); - ASSERT_EQ(0, rados_nobjects_list_next(ctx, &entry, NULL, NULL)); - std::cout << "have " << entry << " expect one of " << p->second << std::endl; - ASSERT_TRUE(p->second.count(entry)); - ++p; - } - rados_nobjects_list_close(ctx); -} - -TEST_F(LibRadosListECPP, ListObjectsStartPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist bl; - bl.append(buf, sizeof(buf)); - - for (int i=0; i<16; ++i) { - ASSERT_EQ(0, ioctx.write(stringify(i), bl, bl.length(), 0)); - } - - librados::NObjectIterator it = ioctx.nobjects_begin(); - std::map > pg_to_obj; - for (; it != ioctx.nobjects_end(); ++it) { - std::cout << it->get_oid() << " " << it.get_pg_hash_position() << std::endl; - pg_to_obj[it.get_pg_hash_position()].insert(it->get_oid()); - } - - std::map >::reverse_iterator p = - pg_to_obj.rbegin(); - it = ioctx.nobjects_begin(p->first); - while (p != pg_to_obj.rend()) { - ASSERT_EQ((uint32_t)p->first, it.seek(p->first)); - std::cout << "have " << it->get_oid() << " expect one of " << p->second << std::endl; - ASSERT_TRUE(p->second.count(it->get_oid())); - ++p; - } -} - -TEST_F(LibRadosListPP, ListObjectsFilterPP) { - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - bufferlist obj_content; - obj_content.append(buf, sizeof(buf)); - - std::string target_str = "content"; - - // Write xattr bare, no ::encod'ing - bufferlist target_val; - target_val.append(target_str); - bufferlist nontarget_val; - nontarget_val.append("rhubarb"); - - ASSERT_EQ(0, ioctx.write("has_xattr", obj_content, obj_content.length(), 0)); - ASSERT_EQ(0, ioctx.write("has_wrong_xattr", obj_content, obj_content.length(), 0)); - ASSERT_EQ(0, ioctx.write("no_xattr", obj_content, obj_content.length(), 0)); - - ASSERT_EQ(0, ioctx.setxattr("has_xattr", "theattr", target_val)); - ASSERT_EQ(0, ioctx.setxattr("has_wrong_xattr", "theattr", nontarget_val)); - - bufferlist filter_bl; - std::string filter_name = "plain"; - ::encode(filter_name, filter_bl); - ::encode("_theattr", filter_bl); - ::encode(target_str, filter_bl); - - NObjectIterator iter(ioctx.nobjects_begin(filter_bl)); - bool foundit = false; - int k = 0; - while (iter != ioctx.nobjects_end()) { - foundit = true; - // We should only see the object that matches the filter - ASSERT_EQ((*iter).get_oid(), "has_xattr"); - // We should only see it once - ASSERT_EQ(k, 0); - ++iter; - ++k; - } - ASSERT_TRUE(foundit); -} - -TEST_F(LibRadosListNP, ListObjectsError) { - std::string pool_name; - rados_t cluster; - rados_ioctx_t ioctx; - pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool(pool_name, &cluster)); - ASSERT_EQ(0, rados_ioctx_create(cluster, pool_name.c_str(), &ioctx)); - char buf[128]; - memset(buf, 0xcc, sizeof(buf)); - rados_ioctx_set_namespace(ioctx, ""); - ASSERT_EQ(0, rados_write(ioctx, "foo", buf, sizeof(buf), 0)); - ASSERT_EQ(0, rados_pool_delete(cluster, pool_name.c_str())); - - rados_list_ctx_t ctx; - ASSERT_EQ(0, rados_nobjects_list_open(ioctx, &ctx)); - const char *entry; - ASSERT_EQ(-ENOENT, rados_nobjects_list_next(ctx, &entry, NULL, NULL)); - rados_nobjects_list_close(ctx); - rados_ioctx_destroy(ioctx); - rados_shutdown(cluster); -} -