From: Sage Weil Date: Sun, 4 Nov 2012 11:54:35 +0000 (-0800) Subject: cls_lock: reorg test_cls_lock X-Git-Tag: v0.55~130^2~15^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e4aa6d7ad70461da78d773c39ff4480cd12f9963;p=ceph.git cls_lock: reorg test_cls_lock Signed-off-by: Sage Weil --- diff --git a/src/Makefile.am b/src/Makefile.am index a275ed2683dc5..81fd1aa262f04 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -833,7 +833,7 @@ test_cls_refcount_LDADD = librados.la libcls_refcount_client.a ${UNITTEST_STATIC test_cls_refcount_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} bin_DEBUGPROGRAMS += test_cls_refcount -test_cls_lock_SOURCES = test/rados-api/cls_lock.cc test/rados-api/test.cc +test_cls_lock_SOURCES = test/cls_lock/test_cls_lock.cc test/rados-api/test.cc test_cls_lock_LDFLAGS = ${AM_LDFLAGS} test_cls_lock_LDADD = libcls_lock_client.a librados.la ${UNITTEST_STATIC_LDADD} test_cls_lock_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} diff --git a/src/test/cls_lock/test_cls_lock.cc b/src/test/cls_lock/test_cls_lock.cc new file mode 100644 index 0000000000000..316bc3f596c9b --- /dev/null +++ b/src/test/cls_lock/test_cls_lock.cc @@ -0,0 +1,291 @@ +// -*- 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) 2004-2006 Sage Weil + * + * 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/types.h" +#include "msg/msg_types.h" +#include "include/rados/librados.hpp" + +#include "test/rados-api/test.h" +#include "gtest/gtest.h" + +using namespace librados; + +#include "cls/lock/cls_lock_client.h" +#include "cls/lock/cls_lock_ops.h" + +using namespace rados::cls::lock; + +void lock_info(IoCtx *ioctx, string& oid, string& name, map& lockers, + ClsLockType *assert_type, string *assert_tag) +{ + ClsLockType lock_type = LOCK_NONE; + string tag; + lockers.clear(); + ASSERT_EQ(0, get_lock_info(ioctx, oid, name, &lockers, &lock_type, &tag)); + cout << "lock: " << name << std::endl; + cout << " lock_type: " << cls_lock_type_str(lock_type) << std::endl; + cout << " tag: " << tag << std::endl; + cout << " lockers:" << std::endl; + + if (assert_type) + ASSERT_EQ(*assert_type, lock_type); + + if (assert_tag) + ASSERT_EQ(*assert_tag, tag); + + map::iterator liter; + for (liter = lockers.begin(); liter != lockers.end(); ++liter) { + const locker_id_t& locker = liter->first; + cout << " " << locker.locker << " expiration=" << liter->second.expiration + << " addr=" << liter->second.addr << " cookie=" << locker.cookie << std::endl; + } +} + +void lock_info(IoCtx *ioctx, string& oid, string& name, map& lockers) +{ + lock_info(ioctx, oid, name, lockers, NULL, NULL); +} + +TEST(ClsLock, TestMultiLocking) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + ClsLockType lock_type_shared = LOCK_SHARED; + ClsLockType lock_type_exclusive = LOCK_EXCLUSIVE; + + + Rados cluster2; + IoCtx ioctx2; + ASSERT_EQ("", connect_cluster_pp(cluster2)); + cluster2.ioctx_create(pool_name.c_str(), ioctx2); + + string oid = "foo"; + bufferlist bl; + string lock_name = "mylock"; + + ASSERT_EQ(0, ioctx.write(oid, bl, bl.length(), 0)); + + Lock l(lock_name); + + /* test lock object */ + + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + /* test exclusive lock */ + ASSERT_EQ(-EEXIST, l.lock_exclusive(&ioctx, oid)); + + /* test idempotency */ + l.set_renew(true); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + l.set_renew(false); + + /* test second client */ + Lock l2(lock_name); + ASSERT_EQ(-EBUSY, l2.lock_exclusive(&ioctx2, oid)); + ASSERT_EQ(-EBUSY, l2.lock_shared(&ioctx2, oid)); + + list locks; + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + + ASSERT_EQ(1, (int)locks.size()); + list::iterator iter = locks.begin(); + map lockers; + lock_info(&ioctx, oid, *iter, lockers, &lock_type_exclusive, NULL); + + ASSERT_EQ(1, (int)lockers.size()); + + /* test unlock */ + ASSERT_EQ(0, l.unlock(&ioctx, oid)); + locks.clear(); + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + + /* test shared lock */ + ASSERT_EQ(0, l2.lock_shared(&ioctx2, oid)); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + locks.clear(); + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + ASSERT_EQ(1, (int)locks.size()); + iter = locks.begin(); + lock_info(&ioctx, oid, *iter, lockers, &lock_type_shared, NULL); + ASSERT_EQ(2, (int)lockers.size()); + + /* test break locks */ + entity_name_t name = entity_name_t::CLIENT(cluster.get_instance_id()); + entity_name_t name2 = entity_name_t::CLIENT(cluster2.get_instance_id()); + + l2.break_lock(&ioctx2, oid, name); + lock_info(&ioctx, oid, *iter, lockers); + ASSERT_EQ(1, (int)lockers.size()); + map::iterator liter = lockers.begin(); + const locker_id_t& id = liter->first; + ASSERT_EQ(name2, id.locker); + + /* test lock tag */ + Lock l_tag(lock_name); + l_tag.set_tag("non-default tag"); + ASSERT_EQ(-EBUSY, l_tag.lock_shared(&ioctx, oid)); + + + /* test modify description */ + string description = "new description"; + l.set_description(description); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestMeta) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + + Rados cluster2; + IoCtx ioctx2; + ASSERT_EQ("", connect_cluster_pp(cluster2)); + cluster2.ioctx_create(pool_name.c_str(), ioctx2); + + string oid = "foo"; + bufferlist bl; + string lock_name = "mylock"; + + ASSERT_EQ(0, ioctx.write(oid, bl, bl.length(), 0)); + + Lock l(lock_name); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + /* test lock tag */ + Lock l_tag(lock_name); + l_tag.set_tag("non-default tag"); + ASSERT_EQ(-EBUSY, l_tag.lock_shared(&ioctx2, oid)); + + + ASSERT_EQ(0, l.unlock(&ioctx, oid)); + + /* test description */ + Lock l2(lock_name); + string description = "new description"; + l2.set_description(description); + ASSERT_EQ(0, l2.lock_shared(&ioctx2, oid)); + + map lockers; + lock_info(&ioctx, oid, lock_name, lockers, NULL, NULL); + ASSERT_EQ(1, (int)lockers.size()); + + map::iterator iter = lockers.begin(); + locker_info_t locker = iter->second; + ASSERT_EQ("new description", locker.description); + + ASSERT_EQ(0, l2.unlock(&ioctx2, oid)); + + /* check new tag */ + string new_tag = "new_tag"; + l.set_tag(new_tag); + l.set_renew(true); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + lock_info(&ioctx, oid, lock_name, lockers, NULL, &new_tag); + ASSERT_EQ(1, (int)lockers.size()); + l.set_tag(""); + ASSERT_EQ(-EBUSY, l.lock_exclusive(&ioctx, oid)); + l.set_tag(new_tag); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestCookie) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + string oid = "foo"; + string lock_name = "mylock"; + Lock l(lock_name); + + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + /* new cookie */ + string cookie = "new cookie"; + l.set_cookie(cookie); + ASSERT_EQ(-EBUSY, l.lock_exclusive(&ioctx, oid)); + ASSERT_EQ(-ENOENT, l.unlock(&ioctx, oid)); + l.set_cookie(""); + ASSERT_EQ(0, l.unlock(&ioctx, oid)); + + map lockers; + lock_info(&ioctx, oid, lock_name, lockers); + ASSERT_EQ(0, (int)lockers.size()); + + l.set_cookie(cookie); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + l.set_cookie(""); + ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); + + lock_info(&ioctx, oid, lock_name, lockers); + ASSERT_EQ(2, (int)lockers.size()); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestMultipleLocks) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + string oid = "foo"; + Lock l("lock1"); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + Lock l2("lock2"); + ASSERT_EQ(0, l2.lock_exclusive(&ioctx, oid)); + + list locks; + ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); + + ASSERT_EQ(2, (int)locks.size()); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} + +TEST(ClsLock, TestLockDuration) { + Rados cluster; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); + IoCtx ioctx; + cluster.ioctx_create(pool_name.c_str(), ioctx); + + string oid = "foo"; + Lock l("lock"); + l.set_duration(utime_t(5, 0)); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + ASSERT_EQ(-EEXIST, l.lock_exclusive(&ioctx, oid)); + + sleep(5); + ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); + + ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); +} diff --git a/src/test/rados-api/cls_lock.cc b/src/test/rados-api/cls_lock.cc deleted file mode 100644 index 316bc3f596c9b..0000000000000 --- a/src/test/rados-api/cls_lock.cc +++ /dev/null @@ -1,291 +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) 2004-2006 Sage Weil - * - * 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/types.h" -#include "msg/msg_types.h" -#include "include/rados/librados.hpp" - -#include "test/rados-api/test.h" -#include "gtest/gtest.h" - -using namespace librados; - -#include "cls/lock/cls_lock_client.h" -#include "cls/lock/cls_lock_ops.h" - -using namespace rados::cls::lock; - -void lock_info(IoCtx *ioctx, string& oid, string& name, map& lockers, - ClsLockType *assert_type, string *assert_tag) -{ - ClsLockType lock_type = LOCK_NONE; - string tag; - lockers.clear(); - ASSERT_EQ(0, get_lock_info(ioctx, oid, name, &lockers, &lock_type, &tag)); - cout << "lock: " << name << std::endl; - cout << " lock_type: " << cls_lock_type_str(lock_type) << std::endl; - cout << " tag: " << tag << std::endl; - cout << " lockers:" << std::endl; - - if (assert_type) - ASSERT_EQ(*assert_type, lock_type); - - if (assert_tag) - ASSERT_EQ(*assert_tag, tag); - - map::iterator liter; - for (liter = lockers.begin(); liter != lockers.end(); ++liter) { - const locker_id_t& locker = liter->first; - cout << " " << locker.locker << " expiration=" << liter->second.expiration - << " addr=" << liter->second.addr << " cookie=" << locker.cookie << std::endl; - } -} - -void lock_info(IoCtx *ioctx, string& oid, string& name, map& lockers) -{ - lock_info(ioctx, oid, name, lockers, NULL, NULL); -} - -TEST(ClsLock, TestMultiLocking) { - Rados cluster; - std::string pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); - IoCtx ioctx; - cluster.ioctx_create(pool_name.c_str(), ioctx); - ClsLockType lock_type_shared = LOCK_SHARED; - ClsLockType lock_type_exclusive = LOCK_EXCLUSIVE; - - - Rados cluster2; - IoCtx ioctx2; - ASSERT_EQ("", connect_cluster_pp(cluster2)); - cluster2.ioctx_create(pool_name.c_str(), ioctx2); - - string oid = "foo"; - bufferlist bl; - string lock_name = "mylock"; - - ASSERT_EQ(0, ioctx.write(oid, bl, bl.length(), 0)); - - Lock l(lock_name); - - /* test lock object */ - - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - - /* test exclusive lock */ - ASSERT_EQ(-EEXIST, l.lock_exclusive(&ioctx, oid)); - - /* test idempotency */ - l.set_renew(true); - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - - l.set_renew(false); - - /* test second client */ - Lock l2(lock_name); - ASSERT_EQ(-EBUSY, l2.lock_exclusive(&ioctx2, oid)); - ASSERT_EQ(-EBUSY, l2.lock_shared(&ioctx2, oid)); - - list locks; - ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); - - ASSERT_EQ(1, (int)locks.size()); - list::iterator iter = locks.begin(); - map lockers; - lock_info(&ioctx, oid, *iter, lockers, &lock_type_exclusive, NULL); - - ASSERT_EQ(1, (int)lockers.size()); - - /* test unlock */ - ASSERT_EQ(0, l.unlock(&ioctx, oid)); - locks.clear(); - ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); - - /* test shared lock */ - ASSERT_EQ(0, l2.lock_shared(&ioctx2, oid)); - ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); - - locks.clear(); - ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); - ASSERT_EQ(1, (int)locks.size()); - iter = locks.begin(); - lock_info(&ioctx, oid, *iter, lockers, &lock_type_shared, NULL); - ASSERT_EQ(2, (int)lockers.size()); - - /* test break locks */ - entity_name_t name = entity_name_t::CLIENT(cluster.get_instance_id()); - entity_name_t name2 = entity_name_t::CLIENT(cluster2.get_instance_id()); - - l2.break_lock(&ioctx2, oid, name); - lock_info(&ioctx, oid, *iter, lockers); - ASSERT_EQ(1, (int)lockers.size()); - map::iterator liter = lockers.begin(); - const locker_id_t& id = liter->first; - ASSERT_EQ(name2, id.locker); - - /* test lock tag */ - Lock l_tag(lock_name); - l_tag.set_tag("non-default tag"); - ASSERT_EQ(-EBUSY, l_tag.lock_shared(&ioctx, oid)); - - - /* test modify description */ - string description = "new description"; - l.set_description(description); - ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); - - ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); -} - -TEST(ClsLock, TestMeta) { - Rados cluster; - std::string pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); - IoCtx ioctx; - cluster.ioctx_create(pool_name.c_str(), ioctx); - - - Rados cluster2; - IoCtx ioctx2; - ASSERT_EQ("", connect_cluster_pp(cluster2)); - cluster2.ioctx_create(pool_name.c_str(), ioctx2); - - string oid = "foo"; - bufferlist bl; - string lock_name = "mylock"; - - ASSERT_EQ(0, ioctx.write(oid, bl, bl.length(), 0)); - - Lock l(lock_name); - ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); - - /* test lock tag */ - Lock l_tag(lock_name); - l_tag.set_tag("non-default tag"); - ASSERT_EQ(-EBUSY, l_tag.lock_shared(&ioctx2, oid)); - - - ASSERT_EQ(0, l.unlock(&ioctx, oid)); - - /* test description */ - Lock l2(lock_name); - string description = "new description"; - l2.set_description(description); - ASSERT_EQ(0, l2.lock_shared(&ioctx2, oid)); - - map lockers; - lock_info(&ioctx, oid, lock_name, lockers, NULL, NULL); - ASSERT_EQ(1, (int)lockers.size()); - - map::iterator iter = lockers.begin(); - locker_info_t locker = iter->second; - ASSERT_EQ("new description", locker.description); - - ASSERT_EQ(0, l2.unlock(&ioctx2, oid)); - - /* check new tag */ - string new_tag = "new_tag"; - l.set_tag(new_tag); - l.set_renew(true); - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - lock_info(&ioctx, oid, lock_name, lockers, NULL, &new_tag); - ASSERT_EQ(1, (int)lockers.size()); - l.set_tag(""); - ASSERT_EQ(-EBUSY, l.lock_exclusive(&ioctx, oid)); - l.set_tag(new_tag); - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - - ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); -} - -TEST(ClsLock, TestCookie) { - Rados cluster; - std::string pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); - IoCtx ioctx; - cluster.ioctx_create(pool_name.c_str(), ioctx); - - string oid = "foo"; - string lock_name = "mylock"; - Lock l(lock_name); - - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - - /* new cookie */ - string cookie = "new cookie"; - l.set_cookie(cookie); - ASSERT_EQ(-EBUSY, l.lock_exclusive(&ioctx, oid)); - ASSERT_EQ(-ENOENT, l.unlock(&ioctx, oid)); - l.set_cookie(""); - ASSERT_EQ(0, l.unlock(&ioctx, oid)); - - map lockers; - lock_info(&ioctx, oid, lock_name, lockers); - ASSERT_EQ(0, (int)lockers.size()); - - l.set_cookie(cookie); - ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); - l.set_cookie(""); - ASSERT_EQ(0, l.lock_shared(&ioctx, oid)); - - lock_info(&ioctx, oid, lock_name, lockers); - ASSERT_EQ(2, (int)lockers.size()); - - ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); -} - -TEST(ClsLock, TestMultipleLocks) { - Rados cluster; - std::string pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); - IoCtx ioctx; - cluster.ioctx_create(pool_name.c_str(), ioctx); - - string oid = "foo"; - Lock l("lock1"); - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - - Lock l2("lock2"); - ASSERT_EQ(0, l2.lock_exclusive(&ioctx, oid)); - - list locks; - ASSERT_EQ(0, list_locks(&ioctx, oid, &locks)); - - ASSERT_EQ(2, (int)locks.size()); - - ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); -} - -TEST(ClsLock, TestLockDuration) { - Rados cluster; - std::string pool_name = get_temp_pool_name(); - ASSERT_EQ("", create_one_pool_pp(pool_name, cluster)); - IoCtx ioctx; - cluster.ioctx_create(pool_name.c_str(), ioctx); - - string oid = "foo"; - Lock l("lock"); - l.set_duration(utime_t(5, 0)); - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - ASSERT_EQ(-EEXIST, l.lock_exclusive(&ioctx, oid)); - - sleep(5); - ASSERT_EQ(0, l.lock_exclusive(&ioctx, oid)); - - ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster)); -}